aboutsummaryrefslogtreecommitdiff
path: root/xwayland/selection
AgeCommit message (Collapse)Author
2021-04-08gtk-primary-selection: drop supportIsaac Freund
The standard primary-selection protocol is now widely supported.
2021-02-15xwayland/selection: flush connection after changing xwm selection ownerTudor Brindus
This was the actual underlying cause of #2192; we were not getting the XFIXES_SELECTION_NOTIFY event in time.
2021-02-15xwayland/selection: log when proxy window loses ownershipTudor Brindus
2021-02-15xwayland/selection: ignore requests for anything but the newest dataTudor Brindus
Our internal state machine gets screwed up if selection events are not monotonically increasing in time, and we can enter a self-copy loop from the proxy window that exhausts all pipes. Snippet of logs when this occurs: 00:00:46.238 [wlr] [xwayland/selection/incoming.c:487] XCB_XFIXES_SELECTION_NOTIFY (selection=277, owner=4194626) 00:00:46.238 [wlr] [xwayland/selection/incoming.c:487] XCB_XFIXES_SELECTION_NOTIFY (selection=277, owner=2097153) 00:00:46.238 [wlr] [xwayland/selection/outgoing.c:378] XCB_SELECTION_REQUEST (time=58979563 owner=2097153, requestor=2097153 selection=277, target=279, property=278) 00:00:46.238 [wlr] [xwayland/selection/outgoing.c:397] ignoring old request from timestamp 58979563; expecting > 58979563 00:00:46.238 [wlr] [xwayland/selection/outgoing.c:29] SendEvent destination=2097153 SelectionNotify(31) time=58979563 requestor=2097153 selection=277 target=279 property=0 00:00:46.238 [wlr] [xwayland/selection/incoming.c:453] XCB_SELECTION_NOTIFY (selection=277, property=0, target=279) Note that 2097153 is `selection->window`, and 4194626 is Emacs. The race occurs if the selection owner changes back to our proxy window between when we get `XCB_XFIXES_SELECTION_NOTIFY` for Emacs and when we call `xcb_convert_selection` in `incoming.c:source_send` -- the ConvertSelection request can end up hitting our proxy window, but the timestamp will be rejected. Fixes #2192.
2021-02-04xwayland/selection: allow simultaneous Wayland-to-X11 transfersTudor Brindus
There seems to be no reason why we can't service multiple Wayland-to-X11 transfers concurrently, so long as they are to different windows (or possibly, same windows but different target properties?) This commit removes the queuing logic, but retains the request de-duplication from #2428.
2021-02-04xwayland/selection: use one target window per selectionTudor Brindus
Previously, the clipboard and primary selections shared the same window. This was racey, and could have led to pasting failures. On xfixes selection owner change notification, the logic for requesting the supported mimetypes of the new owner's selection looks like: xcb_convert_selection( xwm->xcb_conn, selection->window, selection->atom, xwm->atoms[TARGETS], xwm->atoms[WL_SELECTION], selection->timestamp ); This means ask the selection owner to write its TARGETS for the `selection->atom` selection (one of PRIMARY, CLIPBOARD, DND_SELECTION) to `selection->window`'s WL_SELECTION atom. However, `selection->window` is shared for both PRIMARY and CLIPBOARD selections, and WL_SELECTION is used as the target atom in both cases. So, there's a race when both selections change at the same time. The CLIPBOARD selection might support mimetypes {A, B, C}, and the PRIMARY only {A, B}. If the ConvertSelection requests/responses "cross on the wire", so to speak, wlroots can end up believing that the PRIMARY selection also supports C. A Wayland client may then ask for the PRIMARY selection in C format, which will fail with "convert selection failed". This commit fixes this by using a separate window for PRIMARY and CLIPBOARD target requests, so that WL_SELECTION can be used as the target atom in both cases.
2021-02-04xwayland/selection: use one X11 window per incoming transferTudor Brindus
This commit introduces logic for using a new X11 window for each incoming transfer, rather than having a global window for each selection source. This eliminates a whole class of bugs involving multiple concurrent incoming transfers. For now, we retain the outgoing transfer queue, and the selection source-specific windows to support it. Source-specific windows are no longer used in the incoming path, and will be removed in a future PR. Refs #1497.
2021-01-31xwayland/selection: make xwm_selection_init take a wlr_xwm_selection *Tudor Brindus
This makes it consistent with xwm_selection_finish.
2021-01-31xwayland/selection: introduce `xwm_selection_transfer_init`Tudor Brindus
Currently, all this does is initialize `wl_client_fd` to -1, so that comparisons with 0 are meaningful.
2021-01-31xwayland/selection: make xwm_selection_finish take a wlr_xwm_selection *Tudor Brindus
Previously it took a wlr_xwm *, which was a bit surprising in that it freed members of wlr_xwm *, not just its respective selections.
2021-01-31xwayland/selection: destroy all selections on Xwayland restartTudor Brindus
Previously, Xwayland could restart, and we'd get events for transfers pointing to the previous (now freed) xwm instance. This led to use-after-free segfaults. Closes #2565.
2021-01-31xwayland/selection: don't leak Wayland fd if ConvertSelection failsTudor Brindus
If our ConvertSelection failed, we would previously leak the pending Wayland client fd. Refs swaywm/sway#5946.
2021-01-31xwayland/selection: don't request another selection while one is pendingTudor Brindus
This will hopefully be fixed in the future by having separate windows for each X11-to-Wayland transfer, but until then, let's avoid a compositor crash.
2021-01-29xwayland/selection: end incr transfer on empty prop, not next selectionTudor Brindus
Previously, `transfer->incr` was being cleared on the next selection. However, if the next selection was *also* incremental, it's possible that `xwm_handle_selection_property_notify` would route us to `xwm_get_incr_chunk` instead of `xwm_selection_get_data`.
2021-01-29xwayland/selection: refactor remaining incremental transfer codeTudor Brindus
2021-01-29xwayland/selection: extract out property requestsTudor Brindus
Apart from reducing duplication, this has the positive side-effect of allowing all deallocs to use `xwm_selection_transfer_destroy_property_reply`, as opposed to the latter and a mix of ad-hoc `free`s.
2021-01-29xwayland/selection: simplify incremental transfer control flowTudor Brindus
Previously, if the Wayland client died before an incremental transfer was complete, the logs would be spammed by "write error to target fd" as wlroots entered some control flow wherein it'd continually try scheduling further writes to the already-dead pipe. This commit contains no behavioral changes, but introduces explicit handling for draining the X11 selection in case of Wayland client death.
2021-01-29xwayland/selection: explicitly bail if first write to Wayland fd failsTudor Brindus
If `xwm_data_source_write` failed, it's failed permanently. In fact, a failing `xwm_data_source_write` sets `transfer->property_reply` to null as part of its error handling. Instead of relying on an indirect check (whether `transfer->property_reply` is still non-null), explicitly use the return value from `xwm_data_source_write`.
2021-01-29xwayland/selection: make `xwm_data_source_write` return 0 on failureTudor Brindus
The `fd` is marked `O_NONBLOCK`, so `write` will never spuriously return `EINTR`. Therefore, `write` failing is permanent, and we can return 0 to make the return value meaningful.
2021-01-25xwayland/selection: rename Wayland-facing data and helpersTudor Brindus
Previously, wlr_xwm_selection_transfer.source_fd meant: - the source of data in a Wayland -> X11 copy (good) - the destination of data in a X11 -> Wayland copy (confusing) This made reading through xwayland/selection/incoming.c difficult: in many places, "source" actually means "destination".
2021-01-25xwayland/selection: prevent fd leak on unsupported MIME typeTudor Brindus
Since we never end up calling xcb_convert_selection, the file descriptor ends up getting leaked (i.e., not cleaned up within xwm_data_source_write).
2021-01-25xwayland: use wlr_log_errno instead of %mTudor Brindus
Previously, any error would be masked by an internal isatty call: 24:31:48.174 [DEBUG] [wlr] [xwayland/selection/incoming.c:386] XCB_SELECTION_NOTIFY (selection=277, property=278, target=256) 24:31:48.174 [ERROR] [wlr] [xwayland/selection/incoming.c:30] write error to target fd: Inappropriate ioctl for device
2020-10-13xwayland: notify requestor when we fail to respond to their requestTudor Brindus
We already mostly did this, but there were a couple of branches (`calloc` failures) where we'd bail without letting the other side know. Refs swaywm/sway#4007. Likely not going to be a real improvement there (if `calloc` fails you're already pretty screwed), but it does address a theoretical possibility.
2020-10-12xwayland: remove stale transfers from the same requestorTudor Brindus
It seems that if we ever try to reply to a selection request after another has been sent by the same requestor (we reply in FIFO order), the requestor never reads from it, and we end up stalling forever on a transfer that will never complete. It appears that `XCB_SELECTION_REQUEST` has some sort of singleton semantics, and new requests for the same selection are meant to replace outstanding older ones. I couldn't find a reference for this, but empirically this does seem to be the case. Real (contrived) case where we don't currently do this, and things break: * run fcitx * run Slack * wl-copy < <(base64 /opt/firefox/libxul.so) # or some other large file * focus Slack (no need to paste) fcitx will send in an `XCB_SELECTION_REQUEST`, and we'll start processing it. Immediately after, Slack sends its own. fcitx hangs for a long, long time. In the meantime, Slack retries and sends another selection request. We now have two pending requests from Slack. Eventually fcitx gives up (or it can be `pkill`'d), and we start processing the first request Slack gave us (FIFO). Slack (Electron?) isn't listening on the other end anymore, and this transfer never completes. The X11 clipboard becomes unusable until Slack is killed. After this patch, the clipboard is immediately usable again after fcitx bails. Also added a bunch of debug-level logging that makes diagnosing this sort of issue easier. Refs swaywm/sway#4007.
2020-10-11xwayland: fix use-after-free in selection handlingTudor Brindus
Fixes #2425. wlroots can only handle one outgoing transfer at a time, so it keeps a list of pending selections. The head of the list is the currently-active selection, and when that transfer completes and is destroyed, the next one is started. The trouble is when you have a transfer to some app that is misbehaving. fcitx is one such application. With really large transfers, fcitx will hang and never wake up again. So, you can end up with a transfer list that looks like this: | T1: started | T2: pending | T3: pending | T4: pending | The file descriptor for transfer T1 is registered in libwayland's epoll loop. The rest are waiting in wlroots' list. As a user, you want your clipboard back, so you `pkill fcitx`. Now Xwayland sends `XCB_DESTROY_NOTIFY` to let us know to give up. We clean up T4 first. Due to a bug in wlroots code, we register the (fd, transfer data pointer) pair for T1 with libwayland *again*, despite it already being registered. We do this 2 more times as we remove T3 and T2. Finally, we remove T1 and `free` all the memory associated with it, before `close`-ing its transfer file descriptor. However, we still have 3 copies of T1's file descriptor left in the epoll loop, since we erroneously added them as part of removing T2/3/4. When we `close` the file descriptor as part of T1's teardown, we actually cause the epoll loop to wake up the next time around, saying "this file descriptor has activity!" (it was closed, so `read`-ing would normally return 0 to let us know of EOF). But instead of returning 0, it returns -1 with `EBADF`, because the file descriptor has already been closed. And finally, as part of error-handling this, we access the transfer pointer, which was `free`'d. And we crash.
2020-10-11xwayland: using %m in `wlr_log` is broken, use `wlr_log_errno` insteadTudor Brindus
This one was awful to track down, but calls to `wlr_log` with %m have the errno masked by the `isatty` call in `log_stderr`. Switch them to `wlr_log_errno` instead. Cue quality "how can read(2) POSSIBLY be returning ENOTTY?" moments.
2020-07-27Fix incorrect format parametersAntonin Décimo
2020-07-03xwm: end transfers when the requestor is destroyedJohn Chadwick
This improves the failure cases when incremental transfers fail to complete successfully for one reason or another.
2019-06-30Implement serial validation for selection requestsManuel Stoeckl
This change tracks, for each wlr_seat_client, the most recent serial numbers which were sent to the client. When the client makes a selection request, wlroots now verifies that the serial number associated with the selection request was actually provided to that specific client. This ensures that the client that was most recently interacted with always has priority for its copy selection requests, and that no other clients can incorrectly use a larger serial value and "steal" the role of having the copy selection. Also, the code used to determine when a given selection is superseded by a newer request uses < instead of <= to allow clients to make multiple selection requests with the same serial number and have the last one hold. To limit memory use, a ring buffer is used to store runs of sequential serial numbers, and all serial numbers earlier than the start of the ring buffer are assumed to be valid. Faking very old serials is unlikely to be disruptive. Assuming all clients are correctly written, the only additional constraint which this patch should impose is that serial numbers are now bound to seats: clients may not receive a serial number from an input event on one seat and then use that to request copy-selection on another seat.
2019-02-05data-device: destroy previous source when starting dragemersion
This supersedes f24e17259e49aef55b7ada54793a4cdb49ae94a1 and 04c9ca4198a729a95a6368bbbf0438d1ba3465fa. These commits were manually removing wlr_data_source destroy handlers when starting a new drag. This is error-prone. Instead, this commit destroys the previous source whenever we start a new drag.
2019-02-03Fix another instance of swaywm/sway#3545.John Chen
2019-01-24data-device: make sources inert, rename cancel to destroyemersion
2019-01-24data-device, primary-selection: add request_set_selectionemersion
This makes compositors able to block and/or customize set_selection requests coming from clients. For instance, it's possible for a compositor to disable rich selection content (by removing all MIME types except text/plain). This commit implements the design proposed in [1]. Two new events are added to wlr_seat: request_set_selection and request_set_primary_selection. Compositors need to listen to these events and either destroy the source or effectively set the selection. Fixes https://github.com/swaywm/wlroots/issues/1138 [1]: https://github.com/swaywm/wlroots/issues/1367#issuecomment-442403454
2019-01-21primary-selection: add a serial argumentemersion
The serial needs to be bumped when X11 clients set the selection, otherwise some Wayland clients (e.g. GTK) will overwrite it when they gain focus.
2018-11-29primary-selection: introduce wlr_primary_selection_sourceemersion
This is a common interface that can be used for all primary selection protocols, as discussed in [1]. A new function wlr_seat_set_primary_selection is added to set the primary selection for all protocols. The seat now owns again the source, and resets the selection to NULL when destroyed. [1]: https://github.com/swaywm/wlroots/issues/1367#issuecomment-442403454
2018-11-27gtk-primary-selection: use impl pattern for sourcesemersion
2018-11-27gtk-primary-selection: refactor everything, untie from seatemersion
This commits completely refactors wlr_gtk_primary_selection. The goal is to remove gtk-primary-selection state from the seat and better handle inert resources where it makes sense. wlr_seat_client.primary_selection_devices has been removed and replaced by wlr_gtk_primary_selection_device. This allows us to make offers inert when the current selection is replaced. wlr_seat_set_primary_selection has been removed because it relied on wlr_seat instead of wlr_gtk_primary_selection_device_manager. A new function, wlr_gtk_primary_selection_device_manager_set_selection (candidate for the longest function name in wlroots) has been added. It doesn't take a serial anymore as serial checking only makes sense for set_selection requests coming from Wayland clients (serial checking is now done in the Wayland interface implementation). Since wlr_gtk_primary_selection_device_manager is now required to set the selection, a new function wlr_xwayland_set_gtk_primary_selection_device_manager (candidate number two for longest function name) has been added. Devices are now made inert when the seat goes away. Future work includes removing the last primary selection bits from the seat, mainly wlr_seat.primary_selection_source and wlr_seat.events.primary_selection, replacing those with new fields in wlr_gtk_primary_selection_device. Or maybe we could keep those in the seat and replace them with a re-usable interface (for future zwp_primary_selection_v1 support). We need to think how we'll sync these three protocols (GTK, X11 and wayland-protocols). See https://github.com/swaywm/wlroots/issues/1388
2018-11-23Rename wlr_primary_selection to wlr_gtk_primary_selectionemersion
2018-11-06Use _POSIX_C_SOURCE, use shm_openemersion
2018-07-09util: add wlr_ prefix to log symbolsemersion
2018-04-26xwayland/selection: fix little memory leak on erroremersion
2018-04-26Merge pull request #882 from emersion/unprefix-local-symbolsDrew DeVault
Remove wlr_ prefix from local symbols
2018-04-26Use correct printf format specifiers for ssize_tGuido Guenther
This unbreaks the build on armhf that otherwise fails like ../xwayland/selection/incoming.c: In function 'xwm_data_source_write': ../include/wlr/util/log.h:34:17: error: format '%ld' expects argument of type 'long int', but argument 6 has type 'ssize_t {aka int}' [-Werror=format=] _wlr_log(verb, "[%s:%d] " fmt, wlr_strip_path(__FILE__), __LINE__, ##__VA_ARGS__) ^ ../xwayland/selection/incoming.c:34:2: note: in expansion of macro 'wlr_log' wlr_log(L_DEBUG, "wrote %zd (chunk size %ld) of %d bytes", ^~~~~~~ ../xwayland/selection/incoming.c:34:44: note: format string is defined here wlr_log(L_DEBUG, "wrote %zd (chunk size %ld) of %d bytes", ~~^ %d
2018-04-25Make sure we don't use others' prefixesemersion
2018-04-03xwayland: refactor selection codeemersion