On X11, the stage itself is backed by an XWindow, and moving the
input focus elsewhere will bypass any Clutter-level grabs.
This effectively allows newly opened windows to steal the focus
from gnome-shell itself, which is clearly undesirable. To prevent
that, only allow moving the X11 focus to a Window when no grab is
in place, just like commit 50e89e376 did for the stage focus.
But particularly the updating of x11_display->focus_xwindow is not
prevented. Since it's more consistent to the MetaDisplay/MetaX11Display
dual focus tracking and across Wayland/X11 backends, ensure the X11
input focus is actually set on the last focus Window after the
grabs are gone and windows became interactable again.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2832>
This patch unfortunately results in situations where it is intended
that the focus change happens while a grab is present (e.g. Alt+tab
popup), resulting in confused focus state.
This commit is reverted in order to try a similar approach at a
different level.
This reverts commit 7531669b4f.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2832>
ClutterActions now no longer receive their events via
clutter_actor_event(), instead they get special treatment by the stage
now. Make the MetaGestureTracker work with this and stop emitting events
directly to Clutter via clutter_actor_event(), but instead let them get
through to Clutter (but still not to Wayland).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2342>
The previous logic tried to keep the position of the top left corner of
the window relative to the top left corner of the monitor. This allowed
the window to move out of the target monitor. This change keeps the
proportions of the distance between the window and the monitor borders
instead if possible. Otherwise it keeps the relative position of the
center of the window clamped to [0,1] to make sure the window lands on
the right output.
This also slightly changes what monitor is considered to be on: the
monitor which contains the center of the window and, if the center is on
no monitor, the monitor wich overlaps the most with the window.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2591>
At least indirectly, this is set as object qdata while the
window drag is ongoing, and reset/reconstructed if needed.
Consequently, this edge data does not need to be stored in
the MetaDisplay struct anymore.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
Even though the data is still stored in the display, add a "high
level" meta_window_drag_update_edges() call, so that the cached
edges may be updated while a window drag operation is ongoing.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
This is a public API change. Add device/sequence parameters to this
operation, so that window dragging and resizing can stick to one
set of pointing events of them all.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
Since MetaWindowDrag took a lot of this code to handle window drags
internally with less interactions with the rest of the stack, this
code in display/window/keybindings is unused.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
Flip the switch in using MetaWindowDrag, leaving display grab
ops and a bunch other code unused. Some places checked the grab op
and/or window in complex ways, others just checked for grab existence
and should now look for clutter ones, and others already were already
doing this in addition.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
We only allow partial grabs in the case of a keyboard-type MetaGrabOp
happening while the pointer cannot be grabbed. In that case, it's not
a big stretch to unconditionally ungrab the pointer device at the time
of undoing the grab, as it will be always ineffective (not even implicit
grabs on frame windows can happen now, inside Mutter).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
This is no longer necessary, since the SSD frames are no longer
part of Mutter process, so it is not the MetaX11Display connection
which holds the implicit grab when a mouse button is pressed over
a window frame (say, to start a drag).
As the SSD frames client communicates the same way than CSD windows
for window operations, it is also expected to undo its implicit
grab before requesting a window move/resize operation.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
The final effect of this boolean can now be expressed through the
META_GRAB_OP_WINDOW_FLAG_UNCONSTRAINED flag to MetaGrabOp. Use that
in the relevant places, and drop the argument.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
Now that it is called from a single place, there's a few arguments
that are unnecessary:
- button and modifiers are unused
- already_grabbed was originally added to handle grab transitions between
window menus (GtkMenus, back in the day) with display grabs. It's no
longer necessary now
- frame_action can be passed through the META_GRAB_OP_WINDOW_FLAG UNCONSTRAINED
flag
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
Leave meta_window_begin_grab_op() as the only public API to initiate
a display grab. There's no longer grab operations that don't attain
windows, and ending these grabs usually happen through user interaction
when the right circumstances happen.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
There is no longer reason to call meta_display_begin_grab_op() except
for window grab operations, and meta_window_begin_grab_op() is a
perfectly fine entry point for all window grab operations.
Move away from meta_display_begin_grab_op().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
Currently, it is thought out to be called with META_GRAB_OP_KEYBOARD*
grab op parameters. Make it more generic so it can also be called for
pointer operations (avoiding pointer warping in that situation).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
Unlike the comment suggests, this piece of event handling manages
the ungrabbing of a window on button press in the following 2
conditions:
- If a keyboard grab operation was triggered, the window does
additionally follow the pointer, and first button press ends
the grab.
- If a button-press grab is ongoing on the window, but more buttons
are pressed.
We can simplify this to just happen every time a button press event
is received while a window grab op is ongoing. The only case where
this might diverge a bit is same button presses from different
pointer devices, and it's not a big stretch to also undo the grab
in that situation.
This also happens to make the "button" argument in
meta_display_begin_grab_op() completely unused.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
The frame_action boolean is only used by constraints.c code, in order to
determine whether a moving window should be able to move past the top
bar or not.
We can avoid the special casing by passing this information as a
META_GRAB_OP_WINDOW_FLAG_UNCONSTRAINED flag passed with the grab op.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
The whole reason for META_GRAB_OP_WAYLAND_POPUP to exist is to
avoid windows from being activatable/movable/resizable when a
grabbing xdg_popup is active.
Use the meta_display_is_grabbed() method which can tell this
from existing MetaWaylandCompositor grabs, so that this remains
true after dropping META_GRAB_OP_WAYLAND_POPUP.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
Make this public API check just return a boolean about whether
there is an existing grab, instead of exposing MetaGrabOp.
It is desirable to avoid exposing details like
META_GRAB_OP_WAYLAND_POPUP, so that MetaDisplay and wayland
grabs can port to ClutterGrab at their own pace, but also
this further information is unused.
This is likely to be temporary API anyways, after both
MetaDisplay and wayland grabs port to Clutter, it will be
possible to check the ClutterStage for all of them.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
Rewrite this codepath so it handles the grab ops that it cares
about, and ignores the rest. This way the code works despite
possible future modifications to MetaGrabOp (e.g.
META_GRAB_OP_WAYLAND_POPUP removal).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
This piece of event handling only applies on windows receiving events while
the display is ungrabbed (i.e. for raising it, or beginning a move/resize
operation).
Move the checks on the current grab operation outside of window.c and into
events.c, so all checks about the current grab operation move closer to the
main event handler.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
Some tests expect warnings to be logged, and handle that using
g_test_expect_message(). However, if debug topics are enabled, this
causes g_logv() to expect expected messages to also contain entries with
the debug level 'message' or higher to be listed in the expected message
list. Since meta_topic() always logged using g_message(), enabling debug
topics caused any test that used g_test_expect_message() and had debug
logging somewhere along the code path to fail.
Fix this by changing the log level of meta_topic() to 'debug' if we're
in a test. This doesn't mean they won't be visible, they still will
since debug log entries are printed by default during testing.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2800>
These frames client will use a visual with alpha information, and
report the opaque frame shapes through the _NET_WM_OPAQUE_REGION
window property. We can use this information in the Mutter side
for accurate opaque shapes, despite X11 windows with frames now
being seen as possibly transparent.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2758>
If the window is unmapped or otherwise unmanaged while still existing,
we would fail to let the frames client follow up in destroying the
frame for the window.
Delete the _MUTTER_NEEDS_FRAME property, so that the frames client
can react to meta_window_destroy_frame(), this avoids stale invisible
frame windows for clients that simply unmap windows to reuse them
later.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2791>
This XChangeWindowAttributes call was never surrounded by an error trap
and was not really expected to fail with BadWindow since the frame window
would be owned by Mutter itself.
This however is no longer true, and we might be getting a BadWindow from
the frame window given the right timing.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2745>
Quoting Carlos:
The META_PRIORITY_EVENTS ± 1 happening below are in order to set these idles
and timeouts in a priority that is relative to the literal GDK event priority,
making those diverge is a likely way to sneakily break things.
But that's unlikely to happen, and decoupling mutter from GTK further
should make it moot, so perhaps it's alright after all.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2407>
Clutter has an API to get the text direction but used to depend
on gtk3's translation domain. In order to avoid broken i18n
in case gtk3 is not installed, move the transtalable string to
clutter itself.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2407>
Things like meta_compositor_destroy() and meta_compositor_add_window()
isn't intended to be used externally, and if they was, things would
probably fall apart rather quickly.
MetaCompositor also isn't introspected, meaning things that technically
belong to the compositing parts isn't easily available via some object,
but much take detours via other objects like MetaDisplay.
So move the API intended for internal usage to compositor-private.h, and
leave API that is meant to be expose in the public compositor.h.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2718>
The "later" API is used to queue actions in relation to compositing,
thus is owned by the MetaCompositor instance. Make users of this
functionality get MetaLaters instance from the compositor, and stop
using the global meta_later() API.
display: Use non-singleton MetaLater API
tests: Use non-singleton MetaLater API
meta/common: Make docs refer to context aware MetaLater API
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2718>
The API has no concept of user data, and requires the user to some how
get an instance without context, i.e. via static globals. Limit this to
the file where this is needed.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2718>
As elsewhere, make sure objects that need to have a ownership up to the
context, and use this ownership chain to find relevant components, such
as the backend or the Wayland compositor object instance.
wayland/data-device: Hook up data devices to seats
They are tied to a seat - make that connection in struct fields too, so
that related objects can get to the context via it.
wayland: Don't get Wayland compositor via singleton getter
This means via the ownership chain or equivalent.
xwayland: Hook up manager to Wayland compositor
Same applies to the drag-n-drop struct.
xwayland: Make X11 event handling compositor instance aware
This avoids finding it via singletons in the callee.
xwayland: Don't get Wayland compositor from singleton
xwayland: Pass manager when handling dnd event
window/xwayland: Don't get Wayland compositor from singleton
xwayland/grab-keyboard: Don't get backend from singleton
xwayland: Don't get backend from singleton
wayland: Always get the backend from the context
This means traveling up the ownership chain or equivalent when
necessary.
wayland: Hook up data devices, offers and sources to the compositor
This allows tying them to a context without going through any
singletons.
wayland: Don't get display from singleton
xwayland: Don't get display from singleton
tablet: Don't get display from singleton
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2718>
As with other parts, make objects have the ability to walk up the
ownership chain to the context, to get things like the Wayland
compositor or backend instances.
Contains these squashed commits:
display: Don't get backend from singleton
window: Don't get backend from singleton
keybindings: Don't get backend from singleton
workspace: Don't get backend from singleton
display: Don't get Wayland compositor from singleton
selection: Add display getter
context/main: Get backend directly from the context
clipboard-manager: Don't get display from singleton
stack-tracker: Don't use singleton MetaLater API
startup-notification: Hook up sequences and activations to display
This allows using context aware API directly.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2718>
This might happen when the workspace is not switched and
focus_default_window is called or when 'workspace on primary display
only' is enabled, a secondary display exists and the workspace is
switched.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2747>
There's 2 users of this, meta_display_sync_wayland_input_focus() which
does already perform these checks on its own, and MetaCursorTracker's
update_displayed_cursor() to determine whether it should go with the
Wayland client's cursor.
This second check should also consider the existing ClutterGrabs, so
make meta_display_windows_are_interactable() handle them for both
callers.
Fixes the cursor shown over windows while e.g. there are menus opened.
Close: https://gitlab.gnome.org/GNOME/mutter/-/issues/2553
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2754>
Let the frames client render its own shadow. In order to do that,
avoid double painting a shadow on the compositor side, and extend
the mask area of the frame, so it does unveil the (so far)
hidden frames-client-side shadows.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
There's two meanings of "frame" there! Since SSD frames are now
rendered by an external client, and there are no actual mechanism
that ensures the frame did already get painted when the client did
respond to its NET_WM_FRAME_SYNC_REQUEST request, there may be
artifacts when resizing windows.
In order to get always the best visual result, we should actually
synchronize rendering with both the client window and the window
frame window.
This commit adds these mechanisms, so a sync alarm update is
expected on both windows until further resizes are allowed, this
ensures window and frame stay in sync, even after moving rendering
elsewhere.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
Replace the in-process implementation of frames with the external
frames client.
When a client window is created and managed by Mutter, Mutter will
determine whether it is a window that requires decorations and
hint the creation of a frame for it by setting the _MUTTER_NEEDS_FRAME
property on the client window.
After the frames client created a window that has the _MUTTER_FRAME_FOR
property, Mutter will proceed to reparent the client window on the
frame window, and show them as a single unit.
Rendering and event handling on the frame window will be performed by
the external client, Mutter is still responsible for everything else,
namely resizing client and frame window in synchronization, and
managing updates on the MetaWindowActor.
In order to let the frame be managed by the external client, Mutter
needs to change the way some properties are forwarded to the client
and/or frame windows. Some properties are necessary to keep propagating
to the client window only, some others need to happen on the frame
window now, and some others needs to be propagated on both so they
are synchronized about the behavior.
Also, some events that were previously totally unexpected in frame
windows are now susceptible to happen, so must be allowed now.
MetaFrame in src/core/frame.c now acts as the wrapper of foreign
windows created by the frames client, from the Mutter side. Location,
size, and lifetime are still largely in control of Mutter, some
details like visible/invisible borders are obtained from the client
instead (through the _MUTTER_FRAME_EXTENTS and _GTK_FRAME_EXTENTS
properties, respectively).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
Put the helper to use, in order to lift MetaWindow itself from this
accounting. As a bonus, the data itself now moved to the MetaWindowX11
private struct, since this may only happen with X11 windows (or its
Xwayland subclass).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
This may result in a view of the stack in MetaStackManager that does not correspond
to reality, since the window is already being unmanaged, there is no point either in
notifying the stack manager about it.
This slight divergence with reality in the MetaStackManager may produce a non-accurate
view if querying its state has to go through the predicted branches. Later synchronization
with the X11 stack may even this out, but the result really depends on when it is asked.
Fixes some intermittent failures in the stacking/closed-transient-only-take-focus-parents
unit test.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
The meta_window_show() method internally relies on window->mapped being
up-to-date, or attempting to focus it may fail since the window is not
mapped yet, resulting on the window being mapped, but not focused as
it would be expected.
This is moot so far, since windows with frames are created sort-of
synchronously and showing them will result in the focus attempt happening
when the window is already mapped, but things will break when this
becomes an asynchronous step.
Ensure to synchronize client state before showing, so any attempts to
focus the window are able to succeed despite the initial state when
calling meta_window_update_visibility().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2175>
We can land inside meta_window_focus() in the middle of changing the
window workspace, because some signal handler of MetaWorkspace's
"window-removed" signal triggers a focus. This can cause a crash in
`g_assert (link)` when updating the MRU list because we still think
we're on the old workspace when actually we are already removed from
this workspaces MRU list.
To avoid crashes like this, bail out of meta_window_focus() when we're
in the middle of a workspace change.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5368
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2691>
It's a bad idea to have data like this in the middle of a struct, as it
will easily cause everything behind it to be badly aligned and thus
increase memory access times.
So move all those bitfield booleans to the end of the struct.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2691>
Currently, we will notify the display about a new window being created
during the constructed phase of the GObject. During this time,
property-change notifications are frozen by GObject, so we'll emit a few
::notify signals only after the window-created signal, although
the actual property change happened before that.
This caused confusion in gnome-shell code where a notify::skip-taskbar =
true emission was seen when the property already was true inside a
window-created handler before.
In order to fix that that, we notify the window creation
post-construction
of the GObject on GInitable.init vfunc
Details
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6119#note_1598983
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6119
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2703>
If two X11 windows were the last two, we'd remove them from the stack
while unmanaging them. That'd hit an assert in
meta_stack_tracker_restack_managed(), resulting in the following crash
when Xwayland exited unexpectedly with two or more X11 windows being the
only windows on the stack:
#1 g_assertion_message() at ../glib/gtestutils.c:3256
#2 g_assertion_message_expr() at ../glib/gtestutils.c:3282
#3 meta_stack_tracker_restack_managed() at ../src/core/stack-tracker.c:1210
#4 on_stack_changed() at ../src/core/stack.c:142
#5 _g_closure_invoke_va() at ../gobject/gclosure.c:895
#6 g_signal_emit_valist() at ../gobject/gsignal.c:3456
#7 g_signal_emit() at ../gobject/gsignal.c:3606
#8 meta_stack_changed() at ../src/core/stack.c:265
#9 meta_stack_remove() at ../src/core/stack.c:324
#10 meta_window_unmanage() at ../src/core/window.c:1542
#11 meta_x11_display_unmanage_windows() at ../src/x11/meta-x11-display.c:111
#12 meta_x11_display_dispose() at ../src/x11/meta-x11-display.c:141
#13 g_object_run_dispose() at ../gobject/gobject.c:1448
#14 meta_display_shutdown_x11() at ../src/core/display.c:831
The added test specifically checks that this scenario is handled
gracefully.
Related: https://bugzilla.redhat.com/show_bug.cgi?id=2143637
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2704>
In constrast to x11, Wayland has sane handling for touch events and
allows the compositor to handle a touch event while the clients are
already seeing it. This means we don't need the REJECTED state on
Wayland, since we can also grab sequences after the client has seen
them.
So disallow moving sequences to the REJECTED state on Wayland.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2508>
It's not really a backend thing, and we'll want to profile e.g. loading
the backend too, so create it very early and destroy it very late and
let MetaContextMain own it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2678>