xwayland/selection: use one X11 window per incoming transfer

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.
This commit is contained in:
Tudor Brindus 2021-01-30 23:43:25 -05:00 committed by Simon Ser
parent 0977633457
commit 7964a313e8
5 changed files with 158 additions and 91 deletions

View file

@ -20,37 +20,43 @@ struct wlr_xwm_selection_transfer {
struct wl_array source_data;
int wl_client_fd;
struct wl_event_source *event_source;
struct wl_list link;
// when sending to x11
xcb_selection_request_event_t request;
struct wl_list outgoing_link;
// when receiving from x11
int property_start;
xcb_get_property_reply_t *property_reply;
xcb_window_t incoming_window;
};
struct wlr_xwm_selection {
struct wlr_xwm *xwm;
xcb_atom_t atom;
xcb_window_t window;
xcb_window_t owner;
xcb_timestamp_t timestamp;
struct wlr_xwm_selection_transfer incoming;
struct wl_list incoming;
struct wl_list outgoing;
};
struct wlr_xwm_selection_transfer *
xwm_selection_find_incoming_transfer_by_window(
struct wlr_xwm_selection *selection, xcb_window_t window);
void xwm_selection_transfer_remove_event_source(
struct wlr_xwm_selection_transfer *transfer);
void xwm_selection_transfer_close_wl_client_fd(
struct wlr_xwm_selection_transfer *transfer);
void xwm_selection_transfer_destroy_property_reply(
struct wlr_xwm_selection_transfer *transfer);
void xwm_selection_transfer_init(struct wlr_xwm_selection_transfer *transfer);
void xwm_selection_transfer_finish(struct wlr_xwm_selection_transfer *transfer);
bool xwm_selection_transfer_get_selection_property(
struct wlr_xwm_selection_transfer *transfer, bool delete);
void xwm_selection_transfer_init(struct wlr_xwm_selection_transfer *transfer,
struct wlr_xwm_selection *selection);
void xwm_selection_transfer_destroy(
struct wlr_xwm_selection_transfer *transfer);
void xwm_selection_transfer_destroy_outgoing(
struct wlr_xwm_selection_transfer *transfer);

View file

@ -103,6 +103,8 @@ struct wlr_xwm {
xcb_render_pictformat_t render_format_id;
xcb_cursor_t cursor;
// FIXME: need one per selection to simultaneously request both mimetypes,
// I think.
xcb_window_t selection_window;
struct wlr_xwm_selection clipboard_selection;
struct wlr_xwm_selection primary_selection;