According to the XSetSelectionOwner libX11 documentation:
[...] If the owner window it has specified in the request is later
destroyed, the owner of the selection automatically reverts to None,
but the last-change time is not affected.
This is indeed visible through the selection_timestamp field in
XFixesSelectionNotify events.
Use this to check whether the selection time is recent-ish (thus
likely coming from an explicit XSetSelectionOwner request) and honor
the client intent by setting a "NULL" owner. If the selection time
is too old, it's definitely an indication of the owner client being
closed, the scenario where we do want the clipboard manager to take
over.
This fixes two usecases:
- X11 LibreOffice / WPS clear the selection each time before copying
its own content. Mutter's clipboard manager would see each of those
as a hint to take over, competing with the client over selection
ownership. This would simply no longer happen
- Password managers may want to clear the selection, which would be
frustrated by our clipboard manager.
There's a slight window of opportunity for the heuristics to fail
though, if a X11 client sets the selection and closes within 50ms, we
would miss the clipboard manager taking over.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1206
(cherry picked from commit 5671f0a284a5875f7d964a4d368470c33581ba80)
The X11 selection source was being preserved after unsetting its
ownership. This is no leak as it would be eventually replaced by
another source, or destroyed on finalize. But it's pointless to
keep it.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1206
(cherry picked from commit 94b3c334e5a141f68911c6e69fa2dab49ff260b7)
Most visible with xwayland-on-demand, at the time of setting things up
for X11 selections, we don't forward the current state. This makes the
first started X11 app oblivious to eg. the current clipboard.
Syncing selections up at the time of initializing the X11 selection
stuff ensures that doesn't happen.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1186
(cherry picked from commit 167fd07e010e25feb7ff195706bf91d7c70d1273)
We already have a signal callback that translates selection ownership changes to
data_device/primary .selection events. Given both will be run when a data source
is being replaced, and this event emission being deleted is kinda short sighted
in that in only knows about Wayland, rely entirely on MetaSelection::owner-changed
emission.
Fixes spurious .selection(null) events being sent when a compositor-local source
takes over the selection without the focus changing (eg. screenshot to clipboard).
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1160https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1204
(cherry picked from commit 1363246d4452c0eebf404f2668df9931d06eae92)
This is taken care already by the MetaSelection machinery, by
deactivating the previous selection source when setting a new one.
That works across X11 and internal selection sources. This
only works when replacing one wayland source with another, and
actually results in doubly .cancelled events due to the other
paths.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1177https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1203
(cherry picked from commit 0b6560fac41beaf08d89d30b4450dc7318c5a740)
We are meant to send a .cancelled event after the drop is performed
in certain situations, but only for version>3 clients. Since this is
all version 3 business, only set the drop_performed flag for v3
clients. This drops the need to perform version checks at the time
of cancelling (which is present for other usecases in v1).
Fixes emission of wl_data_source.cancelled for v1 clients.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1177https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1203
(cherry picked from commit d4c3870286353e58d7e4c95111f1cdd354ba17ce)
For the cases where we read a fixed size from the selection (eg. imposing
limits for the clipboard manager), g_input_stream_read_bytes_async() might
not read up to this given size if the other side is spoonfeeding it content.
Cater for multiple read/write cycles here, until (maximum) transfer size is
reached.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit 4bdf9a1e70e8aef0066fb3af72ad580069b02fa1)
Flushing the X11 selection output stream may happen synchronously or
implicitly, in which case there is not a task to complete. Check there
is actually a task before returning errors. We additionally set the
pipe_error flag, so future operations will fail with an error, albeit
with a more generic message.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit 1909977a6787d6e06d4931df158b821f6fb35ad1)
If a write_async() comes up while we are flushing on the background,
the task will be queued, but not deemed a reason on itself to keep
flushing (and finish the task) after a property delete event.
To fix this, do not ever queue up write_async tasks (this leaves
priv->pending_task only used for flush(), so the "flush to end"
behavior in the background is consistent). We only start a
background flush if there's reasons to do it, but the tasks are
immediately finished.
All data will still be ensured to be transfered on flush/close,
this makes the caller in this situation still able to reach to it.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit 655a783891ac38c01834cb6d9631aa5834666892)
It does not make sense to check for the stream not being closed,
this might happen multiple times during the lifetime of the stream
for a single transfer. We want to notify the INCR transfer just
once.
Check for the explicit conditions that we want, that the remaining
data is bigger than we can transfer at once, and that we are not
yet within the INCR transfer.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit a4596becc43959c3cd049fd49a236a9920fd9f24)
The stream automatically flushes after data size exceeds the
size we deem for INCR chunks, but we still try to copy it all.
Actually limit the data we copy, and leave the rest for future
INCR chunks.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit 7015bb3efd5e588e50be9948f32ee04fa4bd8319)
INCR transfers are mandated to finish with a final 0-size XChangeProperty
roundtrip after the final data chunk. Actually honor this and ensure we
iterate just once more for this.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit 04d429b743a641c81e2fd8b683a8ec40775b3213)
It does not make sense to notify flushes mid-transfer. We should wait
till the data is actually finished before notifying on the pending
task.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit 0b21dcfe08c9a3ac137da518d6ef5f3a80528883)
This should only be sent if the selection can be sent at once, or
if we are right about to notify on the first chunk of an INCR
transfer.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit 7c939d78c2b20989412a710665cbbea6b12ff8dd)
This seemed to work under the assumption that a flush() call can
only result in one INCR roundtrip. This is evidently not true, so
we should hold things off until all pending data is actually flushed.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit 8a2b82897db66b3edbe985a370429b4f36b9918c)
Together with some other state. We can do this altogether on task
notification, instead of lost somewhere in this function flow.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit e95c365cf01837862f87dea90190b47392ee7f67)
If say we want 32bit data, but have 2 bytes stored, we would simply
ignore flush requests. Allow (and don't clear) the needs_flush flag
if we have less than the element size accumulated.
Instead handle this in can_flush(), so it's triggered whenever we
have enough data to fill 1 element, or if the stream is closing
(seems a broken situation, but triggered by the caller).
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit 967966cdee13306501eacd3f25791f56d1fc8249)
XMaxRequestSize/XMaxExtendedRequestSize are documented to return
the maximum size in 4-byte units, whereas we are comparing this
to byte lenghts. We can afford 4x the data here.
Since I don't know the payload size of the XChangeProperty request,
be generous and allot 400 bytes for it, we have some to spare.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1198
(cherry picked from commit 06d67b6abfd4d5ed8ceecd998b08cd1103946f26)
Commit cda9579034b fixed a corner case when setting the initial workspace
state of transient windows, but it still missed a case:
should_be_on_all_workspaces() returns whether the window should be on all
workspaces according to its properties/placement, but it doesn't take
transient relations into account.
That means in case of nested transients, we can still fail the assert:
1. on-all-workspaces toplevel
2. should_be_on_all_workspaces() is TRUE for the first transient's parent,
as the window from (1) has on_all_workspaces_requested == TRUE
3. should_be_on_all_workspaces() is FALSE for the second transient's
parent, as the window from (2) is only on-all-workspace because
of its parent
We can fix this by either using the state from the root ancestor
instead of the direct transient parent, or by using the parent's
on_all_workspaces_state.
The latter is simpler, so go with that.
https://gitlab.gnome.org/GNOME/mutter/issues/1083
This error was just logged but not raised. Do as the code comment said
and raise a pipe error at that moment, and for subsequent operations
on the output stream (although none besides close() should be expected
after propagating the error properly).
Related: https://gitlab.gnome.org/GNOME/mutter/issues/1065
(cherry picked from commit 2ecbf6d74637508203290c0e324d736de10a9174)
Support for them appears to be way less common than e.g. png, which is
currently the preferred format from Firefox, Chromium, Libreoffice and others.
Adopt to that fact.
As a side effect, this works around a bug observed when copying images in
Firefox on Wayland.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1141
(cherry picked from commit 6aa546145fe614d15f23f2a022637fa72bb50149)
There is a race where an output can be used as a fullscreen target, but
it has already been removed due to a hotplug. Handle this gracefully by
ignoring said output in such situations.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1120
(cherry picked from commit 512bb7d1cd0836e6d110609a16fdbf9f9f5b30df)
It may happen that drmModeGetResources() starts returning NULL. Handle
this gracefully by removing all connectors, CRTCs and planes making the
device in practice defunct.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1121
(cherry picked from commit 5319949a45bb22f5c998b485e955c1ddd13810f3)
Listen for GPU hotplug events to initialize their cursor support.
This fixes one reason for why DisplayLink devices may not be using a hardware
cursor. Particularly, when a DisplayLink device is hotplugged for the first
time such that EVDI creates a new DRM device node after gnome-shell has already
started, we used to forget to initialize the cursor support.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1097
(cherry picked from commit 8abdf16a3992e3332f2378ea7c65e6e251e418e0)
Extract the code to initialize a single GPU cursor support into its own
function. The new function will be used by GPU hotplug in the future.
This is a pure refactoring without any behavioral changes.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1097
Backported from 4cc29cfb619102a8e7cd32731205c8018d83544e.
If a data offer comes from an X11 client, the Wayland resource would be
NULL, causing a crash in `data_offer_choose_action()` trying to get the
resource version.
So instead of doing the version check in `data_offer_choose_action()`,
do it early when creating the data source.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1057https://gitlab.gnome.org/GNOME/mutter/merge_requests/1073
(cherry picked from commit f9326cfa3d5f0fd9f63f561d6dfbb92a8f6fb34a)
For clarity, check the resource version needs the "cancelled" message in
the actual vmethod rather than from the caller function.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1073
(cherry picked from commit 963108a9a6a0a3a811945da5354eafe0b86ffde2)
By default clutter will show an actor as it is added to a parent. This
means that after we create the window actor, when it's added to the
window group, we implicitly show it. What we really want is to not show
it until the window is supposed to be shown, which happens when
meta_window_actor_show() is called, as showing prior to that, could
cause issues.
Avoid the implicit show by setting the "show-on-set-parent" property on
the window actor to `FALSE` on window actor construction.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1066
When an X11 window requests an initial workspace, we currently trust
it that the workspace actually exists. However dynamic workspaces
make this easy to get wrong for applications: They make it likely
for the number of workspaces to change between application starts,
and if the app blindly applies its saved state on startup, it will
trigger an assertion.
Make sure that we pass valid parameters to set_workspace_state(),
and simply let the workspace assignment fall through to the default
handling otherwise.
https://gitlab.gnome.org/GNOME/mutter/issues/1029
The actors of Wayland subsurfaces are set to be reactive on creation,
when receiving the `wl_subcompositor.get_subsurface` request.
However, if a client creates several subsurfaces and then creates the
xdg_toplevel object after, the previous subsurface actors are reset.
As a result, Clutter picking will skip and ignore those actors in
`clutter_actor_should_pick_paint()` because they aren't marked as
reactive anymore.
An example of such a client being affected by this issue is SCTK, the
Rust library implementing client side decorations for Wayland used
internally by winit and alacritty.
Move the `set_reactive()` call from `get_subsurface()` to the subsurface
`sync_actor_subsurface_state()` vfunc to make sure those remain reactive
even after `xdg_surface.get_toplevel` is invoked.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1024https://gitlab.gnome.org/GNOME/mutter/merge_requests/1040
(cherry picked from commit 934a829a57d0b00c5eef8d405473e8a56923cd22)
And order those preferences in order of lossiness (jpeg < png < bmp). This
avoids us from prefering other formats that are not useful or widely
recognized.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/939
(cherry picked from commit 832c0fb0ea79d4cf904b1519b11ef0b11cbbfbdc)
Most usually, applications either expose clipboard content either as text
or as images, so the prioritization here is pointless. However there's some
outliers like LibreOffice Calc which exports content as both image and text
formats (besides other internal ones).
In that mixed case, we probably prefer to keep text formats, rather than
image based ones.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/919
(cherry picked from commit 2fbbf657d51f14bdcb75c045637e6ebf4df10063)
Interoperation between wl_data_device_manager v1 and v3 got broken
at some point. Ensure that we resort to the "copy" action if either
the drop site or the drag source are from a client that requested v1.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/965
(cherry picked from commit ffad55c66f5b131cdaa92ef61c44d99b7c7312b5)
Similar to our handling in set_primary(), ignore set_selection() requests
that come from unfocused clients.
https://gitlab.gnome.org/GNOME/mutter/issues/878
(cherry picked from commit e865fcc460d7666873475f7bb9efc7fd4b336ab8)
This function is already checking for the focus surface client
matching the requestor. The type check was slightly bogus though
as it'd be an screwup in our code, make it an assert instead.
Also, move the check for the client having the focus into the
upper call, so this and wl_data_device.set_selection code can
get more in line.
https://gitlab.gnome.org/GNOME/mutter/issues/878
(cherry picked from commit 16eb46105425a9a677c408f5a19e1bebae88a602)
We have an abstract MetaWaylandDataSource and 2 subclasses for
clipboard/primary data sources. Since the abstraction provided
by the additional sublevel is arguable, push the wl_resource
field up, and leave us with just 2 objects to think about, all
of them containing a wl_resource.
https://gitlab.gnome.org/GNOME/mutter/issues/878
(cherry picked from commit c11ef6ef079eeaa8024c8703bbe432356d06388a)
This check was added on commit 48639ac5 as a means to disregard
DnD drops where the offer would disappear beforehand. However since
that commit was all about wl_data_device_manager version < 3,
forgetting about the selected mimetype seems a behavior more inline
with those versions.
Since no current drop is something expected on X11 drop sites, fixes
DnD over those, while keeping the original bug fixed.
Found by Robert Mader (https://gitlab.gnome.org/GNOME/mutter/issues/974#note_688144)
https://gitlab.gnome.org/GNOME/mutter/issues/974https://gitlab.gnome.org/GNOME/mutter/merge_requests/1005
(cherry picked from commit 30bf588a38c326897efb8637aad5dfeb0cafe5c9)
In XDND, we just get a hint on XdndPosition about what's the action
chosen by the user. Make the data source actions the full set on
XdndEnter (as we can't know better), and pass the hint in XdndPosition
as the user chosen action as it should be.
Makes Wayland drop sites aware of the user action as per XDND with X11
drag sources, and still makes modifiers during DnD work.
https://gitlab.gnome.org/GNOME/mutter/issues/974https://gitlab.gnome.org/GNOME/mutter/merge_requests/1005
(cherry picked from commit 090a6ad409ce0ea0bcf30b66cb1048dfdb86ab9e)
Leaking a texture object and a framebuffer object every time you update
the secondary GPU is perhaps not the best plan.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1011
(cherry picked from commit 545fcb3dbff00adf1899012524926730a8c23572)