... and do the right things:
nothing: selection = rubberband
ctrl: selection = selection OR rubberband
shift: selection = selection AND (NOT rubberband)
ctrl+shift: selection = selection XOR rubberband
(not sure this one makes sense, but toggling is fun)
Instead of storing the active items as we go, compute the affected items
whenever the rubberband changes and in particular when the rubberband
ends.
That way, the rubberband is guaranteed to select a rectangle even
after scrolling very far.
This is achieved by having a get_items_in_rect() vfunc that selects all
the items in the rubberbanded rectangle and returns them as a bitset.
The rubberband is now handled on the list coordinate system.
When starting the rubberband, we track the item under the pointer and
follow it when it is moving.
This may lead to the rubberband start position changing position and
while this may be confusing, it alerts users to the fact that something
crazy is going on.
In particular, track which items remain in ::items-changed
signal emissions.
But the main use case is sorting, which causes items-changed(0, n, n)
to be emitted.
We only want to send grab-notify to widgets that might have been
interacting with devices via events. Instead of going through all
widgets in all toplevels, we have the window/pointer focus information,
so we can just traverse the widget stacks for every involved foci.
Move away from grab_notify, and use the set_child_focus() vfunc to track
child widgets being set the keyboard focus. This is not 1:1, but seems
good enough at the moment.
Fix various issues that prevented inline completion
and inline selection from working reliably. We were
passing byte counts to gtk_editable_select_region in
one place, but that function expects char counts.
We were listening for GtkEditable::insert-text on
the GtkText widget, but that does not emit those signals,
so listen for GtkEntryBuffer::inserted-text instead.
Finally, we were not clearing the stored completion_prefix
enough, leading to situations where the stored prefix
does not match the text in the entry anymore.
In 99.9% of all cases, these are just NULL, NULL.
So just do away with these arguments, people can
use the setters for the rare cases where they want
the scrolled window to use a different adjustment.
While it's worth thinking about bringing the "windows can be dragged
with open popovers" behavior back, this does not kick in anymore, nor
should be the way to handle this given all the autoclose surface
semantic changes.
This got stuck in ancient times when widgets were windowed, so the devices
in a window to know the devices in that widget would pan out. We do only
want here the devices that are inside the widget, not spread over the
surface, so rewrite this helper function to poke the toplevel foci, and
look they are contained inside the widget.
Crossing events are now detached from widget state, all tricky consequences
from getting multiple crossing events are now somewhat moot. Resort to sending
all generated crossing events, and drop this barely (ever?) used API.
When a gesture (group) claims a sequence, all other gesture groups
in the same widget should get cancelled. Not just previously claimed
ones, that shouldn't happen actually.