aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/xwayland/xwm.h5
-rw-r--r--xwayland/selection/dnd.c12
-rw-r--r--xwayland/selection/selection.c61
-rw-r--r--xwayland/xwm.c61
4 files changed, 67 insertions, 72 deletions
diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h
index f467e107..d12eb681 100644
--- a/include/xwayland/xwm.h
+++ b/include/xwayland/xwm.h
@@ -103,13 +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;
-
- xcb_window_t dnd_window;
struct wlr_xwm_selection dnd_selection;
struct wlr_xwayland_surface *focus_surface;
diff --git a/xwayland/selection/dnd.c b/xwayland/selection/dnd.c
index 16941558..ee9a23a6 100644
--- a/xwayland/selection/dnd.c
+++ b/xwayland/selection/dnd.c
@@ -64,7 +64,7 @@ static void xwm_dnd_send_enter(struct wlr_xwm *xwm) {
struct wl_array *mime_types = &drag->source->mime_types;
xcb_client_message_data_t data = { 0 };
- data.data32[0] = xwm->dnd_window;
+ data.data32[0] = xwm->dnd_selection.window;
data.data32[1] = XDND_VERSION << 24;
// If we have 3 MIME types or less, we can send them directly in the
@@ -94,7 +94,7 @@ static void xwm_dnd_send_enter(struct wlr_xwm *xwm) {
xcb_change_property(xwm->xcb_conn,
XCB_PROP_MODE_REPLACE,
- xwm->dnd_window,
+ xwm->dnd_selection.window,
xwm->atoms[DND_TYPE_LIST],
XCB_ATOM_ATOM,
32, // format
@@ -110,7 +110,7 @@ static void xwm_dnd_send_position(struct wlr_xwm *xwm, uint32_t time, int16_t x,
assert(drag != NULL);
xcb_client_message_data_t data = { 0 };
- data.data32[0] = xwm->dnd_window;
+ data.data32[0] = xwm->dnd_selection.window;
data.data32[2] = (x << 16) | y;
data.data32[3] = time;
data.data32[4] =
@@ -126,7 +126,7 @@ static void xwm_dnd_send_drop(struct wlr_xwm *xwm, uint32_t time) {
assert(dest != NULL);
xcb_client_message_data_t data = { 0 };
- data.data32[0] = xwm->dnd_window;
+ data.data32[0] = xwm->dnd_selection.window;
data.data32[2] = time;
xwm_dnd_send_event(xwm, xwm->atoms[DND_DROP], &data);
@@ -139,7 +139,7 @@ static void xwm_dnd_send_leave(struct wlr_xwm *xwm) {
assert(dest != NULL);
xcb_client_message_data_t data = { 0 };
- data.data32[0] = xwm->dnd_window;
+ data.data32[0] = xwm->dnd_selection.window;
xwm_dnd_send_event(xwm, xwm->atoms[DND_LEAVE], &data);
}
@@ -151,7 +151,7 @@ static void xwm_dnd_send_leave(struct wlr_xwm *xwm) {
assert(dest != NULL);
xcb_client_message_data_t data = { 0 };
- data.data32[0] = xwm->dnd_window;
+ data.data32[0] = xwm->dnd_selection.window;
data.data32[1] = drag->source->accepted;
if (drag->source->accepted) {
diff --git a/xwayland/selection/selection.c b/xwayland/selection/selection.c
index 0996f94d..9cb8c455 100644
--- a/xwayland/selection/selection.c
+++ b/xwayland/selection/selection.c
@@ -174,12 +174,65 @@ int xwm_handle_selection_event(struct wlr_xwm *xwm,
void xwm_selection_init(struct wlr_xwm_selection *selection,
struct wlr_xwm *xwm, xcb_atom_t atom) {
- selection->xwm = xwm;
- selection->atom = atom;
- selection->window = xwm->selection_window;
wl_list_init(&selection->incoming);
wl_list_init(&selection->outgoing);
+ selection->xwm = xwm;
+ selection->atom = atom;
+ selection->window = xcb_generate_id(xwm->xcb_conn);
+
+ if (atom == xwm->atoms[DND_SELECTION]) {
+ xcb_create_window(
+ xwm->xcb_conn,
+ XCB_COPY_FROM_PARENT,
+ selection->window,
+ xwm->screen->root,
+ 0, 0,
+ 8192, 8192,
+ 0,
+ XCB_WINDOW_CLASS_INPUT_ONLY,
+ xwm->screen->root_visual,
+ XCB_CW_EVENT_MASK,
+ (uint32_t[]){
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE
+ }
+ );
+
+ xcb_change_property(
+ xwm->xcb_conn,
+ XCB_PROP_MODE_REPLACE,
+ selection->window,
+ xwm->atoms[DND_AWARE],
+ XCB_ATOM_ATOM,
+ 32, // format
+ 1,
+ &(uint32_t){XDND_VERSION}
+ );
+ } else {
+ xcb_create_window(
+ xwm->xcb_conn,
+ XCB_COPY_FROM_PARENT,
+ selection->window,
+ xwm->screen->root,
+ 0, 0,
+ 10, 10,
+ 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ xwm->screen->root_visual,
+ XCB_CW_EVENT_MASK,
+ (uint32_t[]){
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE
+ }
+ );
+
+ if (atom == xwm->atoms[CLIPBOARD]) {
+ xcb_set_selection_owner(xwm->xcb_conn, selection->window,
+ xwm->atoms[CLIPBOARD_MANAGER], XCB_TIME_CURRENT_TIME);
+ } else {
+ assert(atom == xwm->atoms[PRIMARY]);
+ }
+ }
+
uint32_t mask =
XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
@@ -203,6 +256,8 @@ void xwm_selection_finish(struct wlr_xwm_selection *selection) {
wl_list_for_each_safe(incoming, tmp, &selection->incoming, link) {
xwm_selection_transfer_destroy(incoming);
}
+
+ xcb_destroy_window(selection->xwm->xcb_conn, selection->window);
}
static void xwm_selection_set_owner(struct wlr_xwm_selection *selection,
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
index be1436a5..cfc192f5 100644
--- a/xwayland/xwm.c
+++ b/xwayland/xwm.c
@@ -864,8 +864,9 @@ static void xsurface_unmap(struct wlr_xwayland_surface *surface) {
static void xwm_handle_create_notify(struct wlr_xwm *xwm,
xcb_create_notify_event_t *ev) {
if (ev->window == xwm->window ||
- ev->window == xwm->selection_window ||
- ev->window == xwm->dnd_window) {
+ ev->window == xwm->primary_selection.window ||
+ ev->window == xwm->clipboard_selection.window ||
+ ev->window == xwm->dnd_selection.window) {
return;
}
@@ -1588,14 +1589,6 @@ void xwm_destroy(struct wlr_xwm *xwm) {
xwm_selection_finish(&xwm->primary_selection);
xwm_selection_finish(&xwm->dnd_selection);
- if (xwm->selection_window) {
- xcb_destroy_window(xwm->xcb_conn, xwm->selection_window);
- }
-
- if (xwm->dnd_window) {
- xcb_destroy_window(xwm->xcb_conn, xwm->dnd_window);
- }
-
if (xwm->seat) {
if (xwm->seat->selection_source &&
data_source_is_xwayland(xwm->seat->selection_source)) {
@@ -1927,56 +1920,8 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
xwm_set_net_active_window(xwm, XCB_WINDOW_NONE);
- // Clipboard and primary selection
- xwm->selection_window = xcb_generate_id(xwm->xcb_conn);
- xcb_create_window(
- xwm->xcb_conn,
- XCB_COPY_FROM_PARENT,
- xwm->selection_window,
- xwm->screen->root,
- 0, 0,
- 10, 10,
- 0,
- XCB_WINDOW_CLASS_INPUT_OUTPUT,
- xwm->screen->root_visual,
- XCB_CW_EVENT_MASK, (uint32_t[]){
- XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE
- }
- );
-
- xcb_set_selection_owner(xwm->xcb_conn, xwm->selection_window,
- xwm->atoms[CLIPBOARD_MANAGER], XCB_TIME_CURRENT_TIME);
-
xwm_selection_init(&xwm->clipboard_selection, xwm, xwm->atoms[CLIPBOARD]);
xwm_selection_init(&xwm->primary_selection, xwm, xwm->atoms[PRIMARY]);
-
- // Drag'n'drop
- xwm->dnd_window = xcb_generate_id(xwm->xcb_conn);
- xcb_create_window(
- xwm->xcb_conn,
- XCB_COPY_FROM_PARENT,
- xwm->dnd_window,
- xwm->screen->root,
- 0, 0,
- 8192, 8192,
- 0,
- XCB_WINDOW_CLASS_INPUT_ONLY,
- xwm->screen->root_visual,
- XCB_CW_EVENT_MASK, (uint32_t[]){
- XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE
- }
- );
-
- xcb_change_property(
- xwm->xcb_conn,
- XCB_PROP_MODE_REPLACE,
- xwm->dnd_window,
- xwm->atoms[DND_AWARE],
- XCB_ATOM_ATOM,
- 32, // format
- 1, &(uint32_t){XDND_VERSION}
- );
-
xwm_selection_init(&xwm->dnd_selection, xwm, xwm->atoms[DND_SELECTION]);
xwm->compositor_new_surface.notify = handle_compositor_new_surface;