We want all pointer events to be passed through the pointer a11y
processing before going through event filters: Once we go through event
filters, events might be dispatched to Wayland and get filtered out.
With the changes to immediately dispatch events to wayland, this changed
and the pointer a11y is now no longer seeing any events going to wayland
clients. Fix it by shuffling things around a bit and letting pointer
a11y take a peek at events earlier.
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5192
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2332>
There's a bunch of crashes right now where the assertions in
clutter_actor_set_mapped() after calling the map/unmap() vfuncs are
failing. The only way this can happen is by re-entering
clutter_actor_set_mapped() during the map/unmap recursion.
The reason for those crashes is that the shell hides/shows some actors
in response to crossing events and key-focus changes. These in turn get
triggered by the newly introduced ungrabbing of ClutterGrabs when an
actor gets unmapped, which triggers GRAB_NOTIFY crossing events and
key-focus changes.
Since these situations are hardly avoidable (it's a valid use-case to
hide/show something in response to a crossing/key-focus event), catch
the set_mapped() call early while we reenter the mapping machinery and
log a warning instead of crashing.
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3165
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2299>
With the introduction of untrottled event delivery to wayland clients,
we moved the _clutter_event_process_filters() call outside of
_clutter_process_event(). This also moved the processing of event
filters outside of the timespan where the event is added to Clutters
current_event stack, making Clutter.get_current_event() no longer
available to anything happening inside mutters event filter.
One thing that happens in mutters event filter is detecting and
triggering keybindings like the alt-tab switcher. Now the alt-tab
switcher has a special case where it finishes and activates a window
right when the keybinding gets activated, relying on the current event
time as the timestamp to activate the window.
Now since the current event time is no longer available from inside
mutters event filter, we'd pass 0 to meta_window_activate(), causing
mutter to send a notification instead of actually activating the window.
To fix this, also set a current_event for the ClutterContext when going
through event filters, this makes sure Clutter.get_current_event_time()
works when called inside keybinding handlers.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2327>
In the right combination of circumstances, and given 2 actors (parent
actor P with an offscreen effect and child actor C), we may have the
following situation happening:
- A redraw is queued on the actor C, actors C and P are marked as
priv->is_dirty and priv->propagated_one_redraw.
- During paint() handling we paint actor P, priv->propagated_one_redraw
is turned off.
- We recurse into child actor C, priv->propagated_one_redraw is turned
off.
- A new redraw is queued on actor C, actors C and P are marked as
priv->is_dirty and priv->propagated_one_redraw.
- The paint() method recurses back, actors C and P get priv->is_dirty
disabled, priv->propagated_one_redraw remains set.
- At this point queueing up more redraws on actor C will not propagate
up, because actor C has priv->propagated_one_redraw set, but the
parent actor P has priv->is_dirty unset, so the offscreen effect will
not get CLUTTER_EFFECT_PAINT_ACTOR_DIRTY and will avoid repainting
actor C.
The end result is that actor C does not redraw again, despite requesting
redraws. This situation eventually resolves itself through e.g. relayouts
on actor P, but may take some time to happen.
In order to fix this, consider actors that did get a further redraw
request still dirty after paint().
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2188
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2353>
Simplify the function arguments (the origin is just the actor that
the function is originally called from), and make it also handle
marking as dirty the actor that got the redraw queued up explicitly.
This makes it a single place where priv->is_dirty is being enabled.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2353>
We not just have X11 devices, but also virtual devices on both backends.
In the mean time, keep these working on top of a ClutterInputDeviceType,
but transform that into capabilities on device construction so users can
rely on the new flagset.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2331>
This fixes instances of:
```
*** BUG ***
In pixman_region32_init_rect: Invalid rectangle passed
Set a breakpoint on '_pixman_log_error' to debug
```
seen when navigating the overview and launching apps.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2349>
The ClutterGestureAction base code would correctly try to cancel a
gesture if it would receive GRAB_NOTIFY leave events (that would indicate
other portions of the actor tree stole input away from the gesture actor),
but it would mistakenly do so only if the gesture was already initiated,
possibly leaving stale point information if the gesture collected input
but didn't initiate yet.
This could be indirectly seen clicking with the mouse on OSK keys with
no motions in between, clicks would accumulate on the swipeTracker
gestures until the trigger point, so the third click could drag the
workspaces.
We do always want to unregister the related device/sequence here, do that
while still cancelling any already initiated gesture.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1907
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4987
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2334>
We'll need the additional context of which actor the event will be
emitted to in mutters event filter (see next commit), so pass that
target actor to the event filters that are installed.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2321>
It does not make sense that the event "source" (aka the target) is
both content and recipient of a message. Not doing so, events become
largely independent of the actor that is receiving/handling an
event. This is small step toward making events opaque and immutable.
Every user of these API calls in our code have ported away from
them, but other users may remain in extensions, so make these
functions work on top of the alternative API without accessing the
soon to be removed event field.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2311>
This is just "necessary" for --nested stages, since the pointer is
allowed to leave the stage in that case. Since the only side effect
is that there is still a pointer focus somewhere inside the stage,
simply drop this.
This is a small leftover of commit b8f92a6ce4, since we stopped
handling the double ENTER event there.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2311>
In addition to the presented callback time, it shows the time to the
reported presentation time (which can be earlier or later than the
presented callback), as well as the GPU rendering duration.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1928>
The distribute_natural_allocation() function was copied over from Gtk to
Clutter 11 years ago with commit e636a0bbce.
Gtk only supports integers sizes in its layout machinery, while Clutter
does everything using floats.
Since this function sets the minimum_size (the size we allocate the
children in the end) to an integer, this means we're implicitly
typecasting floats to integers here, effectively floor()'ing all sizes
that we allocate the box children.
A bug this caused in gnome-shell was that a scrollView (like the one in
the endSessionDialog) was showing scrollbars even though the content
perfectly fit inside the view: Say the content and its scrollView parent
request a size of 63.9 px, but get allocated a size of 63 px by a box
layout. Now the scrollView notices that its allocated size is smaller
than the requested size and thus shows a scrollbar.
So fix that and use floats in distribute_natural_allocation() instead of
integers, as we do everywhere else in the layout machinery.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2284>
Without input device grabs in play, all functions that emit
pointer/key/crossing/touch events are pretty much the same. Remove this
duplication and use a common emit_event() function.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2100>
In case of misuse (e.g. passing NULL stage) this might result in crashes
before the precondition checks managed to kick in. Move this priv variable
initialization after these checks.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2099>
Wayland event processing and WM operations are themselves outside the
ClutterGrab loop so far. Until this is sorted out, these pieces of
event handling have got to learn to stay aside while there is a
ClutterGrab going on.
So, synchronize foci and other state when grabs come in or out, and
make it sure that Wayland event processing does not happen while
grabs happen.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2099>
Since we want these accessed from bindings this must be a boxed
type. This has the side effect of making ClutterGrab a refcounted
object, since we want to avoid JS from pointing to freed memory
and maybe causing crashes if misusing the object after dismiss.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2099>
Toggling the click action on when leaving the actor/action sounds weird,
this was presumably meant to toggle it off on leave, and back to in_held
on enter. This way, the CLUTTER_LEAVE handling also matches what we want
to do in case of grabs.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2099>
The lack of handling of regular crossing events here is dubious, perhaps
to be fixed later on. So far, ensure gestures are cancelled whenever
a grab-inducted crossing event would leave this action in the blue.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2099>
This is (luckily!) unused, and it's inconvenient to have a toggle to
break the input model we are striving towards. Drop this function
and stick to the default behavior.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2099>
This looks like a relic of glReadPixels-based picking, the pointer
might well be outside redrawn areas, yet still require a device
update (e.g. in order to reflect the actor layout changes in the
"clear area" info).
Instead, always update all devices that are inside the view after
relayouts, the tracking on the need for that update is now done
on each ClutterStageView, instead of globally in the ClutterStage.
This theoretically fixes situations where pointers might miss
updating their "clear area" after the actor tree changed.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2117
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2257>
The stage window is an interface, that added properties, that were only
then actually managed by MetaStageImpl. Shuffle things slightly, and let
the MetaStageImpl object deal with these things itself.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2014>
As ClutterGrab is a stack, the backend only cares about some grab
existing currently or not. Make it sure that we grab whenever we
go to >=1 grabs, and ungrab whenever we go to <1.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2068>