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>
Dissociate clutter_stage_set_key_focus() from the actors focused
state, so that it obeys stage grabs. The key focus actor state may
also change due to grab changes, add the code to notify about this.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2068>
Emit crossing events whenever a grab coming or going would cause a
pointer/touchpoint to become inactive on their position. Depending
on whether the pointer lies inside the old or new grab widgets,
enter or leave events would be generated.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2068>
We will want to be more specific about the portions of the actor
hierarchy that receive this event, separate creation and emission
so each place does what is relevant.
However, this commit brings no functional changes.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2068>
These events are not meant to be ever silenced away, every actor
that is meant to receive one should do so. Make it sure that those
events cannot be stopped, despite the event signal handlers return
values.
This opens the debate about whether crossing events should be
ClutterEvents, since they are more and more uncommon at being one,
maybe this notification mechanism should be taken away from the
event machinery, but that's something for future refactors.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2068>
Hopefully, the one to make them all converge. This new ClutterGrab
represents a handle on a created grab. These are stacked, so grabs
can be overridden and remain inactive until there is a time that
they become active again, although undoing these early is optional.
These grabs are global, they do apply to all pointer, touchpoint
and keyboard foci.
At the moment, only the API to create and stack those is added,
the actual functionality is added in future commits.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2068>
A property for reversing the visible order of children is a bit odd.
It has also been unused by actual gnome-shell code since 2010, and the
somewhat related pack_start()/pack_end() API in GtkBox(Layout) is gone
in GTK4.
With that in mind, turn the property into a no-op and deprecate it,
so that it can be dropped next cycle.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2206>
This ensures they remain perfectly smooth regardless of how the
dispatch time has been adjusted/optimized/delayed/jittered.
Idea by Ivan Molodetskikh <yalterz@gmail.com>
For example, dragging a window on a 60Hz monitor:
BEFORE
delta(time_us) = 17014μs
delta(time_us) = 15998μs
delta(time_us) = 17006μs
delta(time_us) = 16975μs
delta(time_us) = 16001μs
delta(time_us) = 17002μs
delta(time_us) = 17006μs
delta(time_us) = 16004μs
AFTER
delta(time_us) = 16667μs
delta(time_us) = 16667μs
delta(time_us) = 16670μs
delta(time_us) = 16667μs
delta(time_us) = 16669μs
delta(time_us) = 16668μs
delta(time_us) = 16664μs
delta(time_us) = 16674μs
Caveat 1: Because we don't know a "next presentation time" on the first
frame, the interval between the first and second frame will usually be
different to the subsequent steady interval. So this change increases the
jitter of just frame 2, but eliminates jitter thereafter.
Caveat 2: `clutter_frame_clock_schedule_update_now` schedules updates
earlier than `clutter_frame_clock_schedule_update`. This means potentially
you could get multiple frames targeting the same "next presentation time".
That doesn't really change here though - we're dispatching at the same
times as we used to and just giving timelines a better vsync-aligned
timestamp now.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/25
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2161>
This won't change anything for 60Hz displays but higher refresh rate
users will benefit.
Using Nvidia EGLStreams on a 240Hz monitor for example (refresh interval
~4.1ms), the maximum render time allowed before dropping to 120Hz is now
3.6ms whereas it was previously 2.1ms.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2158>
This is notably necessary with transformations, since these don't
trigger allocation machinery, but may affect the actor under the
pointer.
Visible e.g. with GNOME Shell's "Application does not respond"
dialogs.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1915>
With Wayland handling all events as they come, this code now just
performs motion compression for events that will be handled by Clutter
widgetry.
The intent to opt tablets and styli out of motion compression was
early and fast client handling, since that is now covered in a generic
manner, this code is superfluous. We don't really need the extra events
for these devices in compositor widgetry either.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1915>
We essentially create those at the time they need to be handled, and
use shortcuts that avoid the event from being queued up. It's too much
of a short cut though, these events are also of interest to the Wayland
event handlers, e.g. to handle pointer state changes (e.g. repicks due
to the pick actor being destroyed) immediately, instead of at the next
event.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1915>
If we are still under the "clear area" of the pick actor, we forget
to update the coordinates. This is usually not needed, unless we
need to repick again for non-event circumstances (e.g. pick actor
is destroyed). This will ensure the right pointer coordinates are
used afterwards in those situations.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1915>
Traditionally, the next repaint would also involve picking, which
would correct the actor under the pointer. This now does not happen
out of the box, so we really are waiting for the next pointer event
here.
To avoid the pointer/cursor to lag behind, trigger an immediate
repick here, that will look up the new actor under the pointer
coordinates.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1915>
And resort to it first, unless we are told to ignore the cache
(e.g. after relayouts). This avoids further pick context operations
while the pointer is on the current actor.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1915>
This safe area is the region (in stage coordinates) where the pointer
is ensured to stay within the current actor. This is not used yet, but
will be used for optimizations in pointer picking.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1915>
These may be used for optimizations once we find the pick actor,
so picking can be avoided in areas we know didn't cross into
other actors. Nothing makes use of it yet though, just log these
so far.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1915>
Add a clutter_stage_pick_and_update_device() method that is the only
single entry point for updating a device position as seen by the
stage.
Also, update all callers to use it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1915>
The clutter_stage_get_actor_at_pos() calls it almost 1:1 underneath
and is public API, we can have all callers use this, and stop using
this function outside of clutter-stage.c.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1915>