Wayland clipboard selection cancellation events only sent to version 3 sources
Affected version
I'm testing Mutter 3.36.1 (F32), but I'm told this is also reproducible on 3.34.5 (F31).
This is a Wayland-only issue for obvious reasons.
Bug summary
Mutter doesn't send wl_data_source.cancelled
events to data sources of versions 1 and 2. This includes selection sources that are not involved in drag-n-drop.
Steps to reproduce
Run a client that uses v1 or v2 sources and copies something to the clipboard. Copy something else from another client. Observe wl_data_source.cancelled
not getting emitted for the original client.
To make this more straightforward to reproduce & test, I've written a small test client that reproduces this issue.
Compile it like this:
$ gcc reproducer.c -o reproducer -lwayland-client
Run it with Wayland debug logging enabled:
$ WAYLAND_DEBUG=1 ./reproducer |& grep data
It should display a square. Click the square to perform a copy. Copy something else from some other client. Observe that no wl_data_source.cancelled
is emitted:
[3829698.173] wl_registry@2.global(7, "wl_data_device_manager", 3)
[3829698.195] -> wl_registry@2.bind(7, "wl_data_device_manager", 1, new id [unknown]@6)
[3830406.780] -> wl_data_device_manager@6.create_data_source(new id wl_data_source@13)
[3830406.792] -> wl_data_source@13.offer("text/plain")
[3830406.802] -> wl_data_device_manager@6.get_data_device(new id wl_data_device@14, wl_seat@8)
[3830406.814] -> wl_data_device@14.set_selection(wl_data_source@13, 11110)
[3830407.310] wl_data_source@13.send("text/plain", fd 5)
Now, run it again, passing 3
(the data source version to use):
$ WAYLAND_DEBUG=1 ./reproducer 3 |& grep data
Perform the same actions, observe wl_data_source.cancelled
getting emitted as expected:
[3850677.612] wl_registry@2.global(7, "wl_data_device_manager", 3)
[3850677.622] -> wl_registry@2.bind(7, "wl_data_device_manager", 3, new id [unknown]@6)
[3851733.011] -> wl_data_device_manager@6.create_data_source(new id wl_data_source@13)
[3851733.025] -> wl_data_source@13.offer("text/plain")
[3851733.033] -> wl_data_device_manager@6.get_data_device(new id wl_data_device@14, wl_seat@8)
[3851733.044] -> wl_data_device@14.set_selection(wl_data_source@13, 11209)
[3851733.452] wl_data_source@13.send("text/plain", fd 5)
[3854655.414] wl_data_source@13.cancelled()
[3854655.443] wl_data_source@13.cancelled()
It's actually getting emitted twice, which a bug on its own; but that's at least less wrong than not emitting it at all.
What happened
- For version 1 and 2 sources,
wl_data_source.cancelled
is not emitted. - For version 3 sources,
wl_data_source.cancelled
is emitted twice.
What did you expect to happen
wl_data_source.cancelled
is emitted once no matter the data source version.
The protocol says,
For objects of version 2 or older,
wl_data_source.cancelled
will only be emitted if the data source was replaced by another data source.
Relevant logs, screenshots, screencasts etc.
See above.
Additional information
This used to work before, and was apparently broken just recently. Relevant commits: