Hold gestures are used to bring existing gestures on touchpad
semantically closer to touchscreen gestures.
Touchpad gestures observe hold gestures with a matching amount of
fingers and emit their begin and end signals when fingers are detected
or removed on/from the touchpad.
When a hold cancel event is detected, it is required to wait a few
milliseconds until the next event(s) are received to avoid emitting
multiple begin signals.
Part-of: <!3454>
Handle hold events:
- GDK_TOUCHPAD_GESTURE_PHASE_BEGIN: scroll-begin is emitted.
- GDK_TOUCHPAD_GESTURE_PHASE_END: A hold gesture ends only when all
fingers are lifted from the touchpad without movement, so
scroll-end is emitted right away.
- GDK_TOUCHPAD_GESTURE_PHASE_CANCEL: A hold gesture is cancelled when
some fingers are lifted/put down or movement is detected. In this
case, scroll-end is emitted after a small timeout only if
GDK_SCROLL wasn't detected.
Part-of: <!3454>
Since the addition of GdkEventSequence in touchpad events, these
are now stored in the gesture using that sequence. This bit of touchpad
gesture handling was however missing to be updated, still looking up
the special NULL sequence.
Use the last sequence here, which will be the one coming from touchpad
gesture events.
Despite touchpad gestures having a sequence, these must use the logical
pointer focus. Avoid using the sequence for GtkPointerFocus lookups with
those events, in order to ensure those events make it all the way to the
intended target.
This is fallout from adding GdkEventSequence information to touchpad
gestures.
This change is done for 2 reasons:
- The logic to request this phase when compressing scroll events is
slightly broken. If there are multiple scroll events that are
coalesced into one, the surface frame clock will not get this request.
The worst case is having >= 2 scroll events on every frame, as the
compressed event will be left in the queue, and be further compressed
on future events.
- Even scroll events aside, this phase is requested in oddly specific
places that are not enough to cover all events, others do rely on
unrelated GdkFrameClock activity that happens to flush the events
as well.
Unify this phase request so it explicitly happens on the arrival of any
event. This ensures that events (compressed or not) will be handled
promptly after arrival.
Currently when the widget is realized after the focus in event the input
method isn't activated as enable is never sent. The call trace is
gtk_text_focus_changed ->
gtk_im_context_focus_in ->
gtk_im_context_wayland_focus_in
which returns early as self->widget is NULL since it's set up in
gtk_text_realize() via gtk_im_context_set_client_widget(). Handle that
case by invoking gtk_im_context_focus_in() from gtk_text_realize() too.
A case where the above happens is a GtkSearchEntry in a GtkSearchBar.
E.g. in gtk4-demo when starting the demo and then hitting the search
button right away.
Remember the current context on focus-in even though the text-input
isn't set up yet. This helps in the case where the text-input is not yet
created but a widget already got focused. Without that the enable()
invocation in text_input_enter() woulnd't be invoked leaving the input
method disabled.
This fixes
gtk4-demo --run=search_entry
which would initially not show the on-screen keyboard when e.g using
phoc/sway as compositor.