Mainly doing s/TARGET/BUBBLE/ on the fully ported widgets, but GtkTreeView
where the double click handler has moved to GTK_PHASE_TARGET so it runs
parallelly to the still existing event handlers.
Previously, there would be globally just a capture and a bubble phase,
with the event just going down the hierarchy once, and the up once.
GTK_PHASE_TARGET actually meaning "run within event handlers", so in
a hierarchy of 3 widgets, emission would be:
Capture(C)
Capture(B)
Capture(A)
Target(A) (if event handlers allow)
Bubble(A)
Target(B) (if event handlers allow)
Bubble(B)
Target(C) (if event handlers allow)
Bubble(C)
This commit changes this behavior and uses GTK_PHASE_TARGET in a less
misleading way, running only on the widget that was meant to receive
the event. And GTK_PHASE_BUBBLE has taken over the execution place of
GTK_PHASE_TARGET, so the emission remains:
Capture(C)
Capture(B)
Capture(A)
Target(A)
Bubble(A) (if event handlers allow)
Bubble(B) (...)
Bubble(C) (...)
As it was, GTK_PHASE_BUBBLE was useful for running event controllers
paralelly to event handlers, without modifying a single line in those.
For those mixed scenarios, Any of the other phases will have to be
used at discretion, or the event handlers eventually changed to chain
up and let the default event handlers in GtkWidget to be run.
The events to those are fed outside the regular event propagation scheme,
through _gtk_window_check_handle_wm_event(), so set the controller to
GTK_PHASE_NONE so events aren't processed first manually, and then
automatically.
Event controllers now auto-attach, and the GtkCapturePhase only determines
when are events dispatched, but all controllers are managed by the widget wrt
grabs.
All callers have been updated.
Go back to respecting GtkMisc::xpad/ypad. Not doing so breaks
the misc-alignment reftest. As long as we still derive from
GtkMisc, we may as well do this.
The icontheme lookup code has a special-case that prefers builtin icons
if the theme name is "hicolor". This is problematic for our reftests,
which run in a barebones environment with not settings.
Drop the ref on the action muxer in finalize, and also make sure
shutdown() tears down the muxer setup done in startup().
When GtkApplication adds itself to a muxer, it causes the muxer to take
a ref on the GtkApplication. This has to be undone in shutdown() to make
sure the GtkApplication doesn't end up holding a ref on itself.
https://bugzilla.gnome.org/show_bug.cgi?id=730383
And handle the fact that drawing bounds are now handled by this API and
the corresponding gtk_widget_get_clip().
Also add _gtk_widget_supports_clip() function to check if a widget has
been ported to the new world.
Now that labels and images no longer use x/yalign in their code,
we need to make gtk_misc_set_alignment set the h/valign for these
widgets, to keep it stumbling along until its final demise.
https://bugzilla.gnome.org/show_bug.cgi?id=730613
Those get in the middle more than help on these widgets, the widget
is already packed with clickable areas and having handles (and their
invisible clickable area around) hovering above don't help, plus the
purpose in most likely numeric values is a bit doubtful.
All touch events are either consumed by the up/down panels, or
the swipe gesture, all GtkEntry handling of touch events on the text
window is avoided, so handles to not appear anymore.
the "bubble" phase used to run before event handlers before GTK_PHASE_TARGET
was added, in order to keep phases in the expected order, move GTK_PHASE_BUBBLE
to be run (still invariably) after event handlers.
The only behavioral change should be wrt widgets wanting mixed event handler/
gesture handling, they could previously attach the gesture to the bubble phase
and check for gtk_gesture_is_active() in the event handler to bail out, they'll
have to use GTK_PHASE_CAPTURE for that purpose from now on.
The handle is still centered horizontally, but the extra vertical
space wasn't taken into account, leading to misplacing the dragging
point (and the handle) during motion events.
GtkPaned may just capture pointer events because the child widget
doesn't happen to have GDK_TOUCH_MASK set, resort to checking the
device in that case.
Dragging is all handled by a GtkGesturePan now, matching the
paned orientation.
On touch events, a wider area is listened for, so touch events
don't need to be as accurate to initiate dragging, if no dragging
is truly initiated in this case, events are just forwarded for
child widgets to handle.
A pan gesture is used to handle switch dragging, which is only triggered
by horizontal panning movements. A multipress gesture handles the cases
where clicking without dragging happens, just toggling the switch.
A pan gesture is optionally attached if there is only one scrolling direction, the pan
gesture orientation is changed so movements tangential to the scroll direction get
scrolling cancelled (The pan gesture is automatically denied when that happens, and
that state change spreads to the others gestures in the group). If the pan direction
happens in the expected directions, no cancellation happens, and scrolling eventually
takes place.
Multiple calls are supposedly allowed to change the phase (although
unlikely to happen), so remove the g_return_if_fail() checking whether
the controller was already added.
Presses alternatively show and dismiss the popover, the popover is still
always shown invariably after any dragging happens (either text selection,
or dragging a text handle)
Presses alternatively show and dismiss the popover, the popover is still
always shown invariably after any dragging happens (either text selection,
or dragging a text handle)
Similarly to GtkTextView, a GtkGestureMultiPress gesture handles
button/touch presses to initiate one selection mode or other, and
a GtkGestureDrag is used to handle text selection and DnD checks.
The code from button press/release, motion, and grab_notify handlers
has been shuffled into the actions triggered by those gestures.
A GtkGestureDrag is used for color selection, removing also the
need to track the pointer state in widget data. The GDK grab performed
just to set the crosshair cursor has been replaced by a call
to gdk_window_set_device_cursor(), which will be unset if the
drag operation is finished, or cancelled due to the implicit grab
being broken.
All "exclusive" gestures listen for either pointer events, or
"pointer emulating" touch events, so only a single sequence at
a time can make these run.
This signal will always be paired with a ::pressed signal, unless
the sequence is cancelled, or the controller is reset. the n_press
argument in the signal always matches the ::press signal one, even
if GtkGestureMultiPress::stopped was emitted in between.
The current sequence (as per gtk_gesture_single_get_current_sequence)
is used to find out the coordinates. And only emit ::pressed if the
gesture began through a GDK_BUTTON_PRESS/TOUCH_BEGIN (eg. not due to
an extra touch being lifted)
Just call the controllers on that phase if the default widget handlers
are run.
For compatibility reasons, in the touch event handler, let the pointer
emulating touch be transformed to a pointer event as usual, in order to
have widget handlers a chance to run at all. If they have to be managed
by a controller in that phase, it'll have to be through the default pointer
event handlers.
This phase is meant to run in the default widget handlers, as opposed
to externally as in the bubble/capture phase. This will be most usually
the expected phase for every controller replacing code in event handlers
in GTK+, just so invocation and triggering order is kept unaltered.
That may happen separately from grab-notify, and also due to external
reasons, so ensure all sequences are cancelled if a grab is taken
in some GdkWindows that would obscure events on the controller.
We can end up with _gtk_widget_remove_controller getting called
while we are iterating over the list in _gtk_widget_run_controllers.
To avoid trouble, only mark the event controller as dead by
setting data->controller to NULL, and defer the actual freeing
and list manipulation to the loop in _gtk_widget_run_controllers.
Update other places that operate on controllers to handle
data->controller being NULL.
Make it really sure that the event is only emitted after every gesture
that consumed the button press is done with the sequence.
The event must only be emulated if a gesture in the capture phase happened
to consume the event, be cancelled, and
Sequences may be cancelled within the ::sequence-state-changed handler, which
would change the points hashtable as it's being iterated in this function. So
iterate over a list of sequences and let the hashtable change freely.
The propagation phase property/methods in GtkEventController are gone,
This is now set directly on the GtkWidget add/remove controller API,
which has been made private.
The only public bit now are the new functions gtk_gesture_attach() and
gtk_gesture_detach() that will use the private API underneath.
All callers have been updated.
Within a widget, if a gesture accepts a sequence, it would previously
cancel every other gesture that not in the same group. Change this to
only cancelling gestures that previously claimed the gesture, and let
gestures with state=NONE for that sequence remain like that.
This enables late recognition of gestures, even on the presence of
another gesture group that was more eager at claiming the gesture.
One usecase is user-defined panning gestures on scrolledwindows,
if ::capture-button-press is TRUE (eg. the default), the gesture is
claimed early in order to consume the button press, but that would
tipically make every other gesture group deny the sequence. With
this change, the pan gesture can keep state=NONE, and later claim
the sequence for itself if the panning gesture is recognized.
Also, do not propagate state=DENIED to every gesture in the widget,
that was unintended.
If no match is found with the gesture widget when poking the event
window parents, bail out safely instead of falling in an infinite
loop. This was seen on Mutter.
The utility of those signals is somewhat dubious now that there is
gtk_gesture_group(), so make that the only way to coordinate gestures.
The cooperation model offered by gtk_gesture_group() is flexible
enough,
Listen for notify::sequence-state-changed on the controller, so the
only way to manipulate a sequence state are gtk_gesture_set_sequence_state()
and gtk_gesture_set_state().
Also, make use of gesture groups, so the sequence state is set at once
on all gestures pertaining to a single group. Within a widget, if a sequence
is claimed on one group, it is made to be denied on every other group.
This API eliminates the need for overriding
GtkWidget::sequence-state-changed virtually everywhere. Grouped
gestures share common states for a same GdkEventSequence, so the
state of sequences stay in sync across those.
A multipress gesture is used to control all this, replacing
single/double click custom code, and triggering window dragging
when the multipress is stopped, yet active (ie. the sequence remains
pressed).
This gesture is used by gtk_drag_source_set() to determine
whether dragging moved past the threshold. The gesture events
are handled via the usual ::event callbacks, so we don't mess
up with callers expecting that to happen in a signal handler.
If the sequence gets claimed somewhere else in the event widget
stack, the DnD gesture will be cancelled.
With gtk_gesture_get_point() returning events in
gtk_event_controller_get_widget() coordinates, we no longer need
to compensate for the overshoot here.