From 335f9c43241444d5f73e7acdbafb59b09ba0797f Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 10 Aug 2015 18:52:22 -0400 Subject: [PATCH] finish off x11<->wl clipboard support a lot of this functionality is reused from dnd. basic selection owner management in x11 and slapping bytes down a pipe to the wl client; a bit laggy when pasting to wl clients sometimes, need to spend more time debugging that... #Kansas --- src/bin/e_comp_wl_data.c | 19 +++++++++++- src/modules/xwayland/dnd.c | 63 +++++++++++++++++++++++++++++++++----- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/bin/e_comp_wl_data.c b/src/bin/e_comp_wl_data.c index ea01be0eb..f483abd80 100644 --- a/src/bin/e_comp_wl_data.c +++ b/src/bin/e_comp_wl_data.c @@ -764,12 +764,29 @@ e_comp_wl_data_device_keyboard_focus_set(void) ERR("No focused resource"); return; } + source = (E_Comp_Wl_Data_Source*)e_comp->wl_comp_data->selection.data_source; +#ifndef HAVE_WAYLAND_ONLY + do + { + if (!e_comp_util_has_xwayland()) break; + if (e_comp->wl_comp_data->clipboard.xwl_owner) + { + if (e_client_has_xwindow(e_client_focused_get())) return; + break; + } + else if (source && e_client_has_xwindow(e_client_focused_get())) + { + /* wl -> x11 */ + ecore_x_selection_owner_set(e_comp->cm_selection, ECORE_X_ATOM_SELECTION_CLIPBOARD, ecore_x_current_time_get()); + return; + } + } while (0); +#endif data_device_res = e_comp_wl_data_find_for_client(wl_resource_get_client(focus)); if (!data_device_res) return; - source = (E_Comp_Wl_Data_Source*)e_comp->wl_comp_data->selection.data_source; if (source) offer_res = _e_comp_wl_data_device_data_offer_create(source, data_device_res); wl_data_device_send_selection(data_device_res, offer_res); diff --git a/src/modules/xwayland/dnd.c b/src/modules/xwayland/dnd.c index ca8fb7df4..5cc6f2477 100644 --- a/src/modules/xwayland/dnd.c +++ b/src/modules/xwayland/dnd.c @@ -107,11 +107,15 @@ _xwayland_target_send(E_Comp_Wl_Data_Source *source, uint32_t serial EINA_UNUSED static void _xwayland_send_send(E_Comp_Wl_Data_Source *source, const char* mime_type, int32_t fd) { - Ecore_X_Atom type; + Ecore_X_Atom type, sel = ECORE_X_ATOM_SELECTION_CLIPBOARD; DBG("XWL Data Source Source Send"); - _xdnd_finish(0); + if (e_comp->wl_comp_data->drag_client) + { + _xdnd_finish(0); + sel = ECORE_X_ATOM_SELECTION_XDND; + } if (eina_streq(mime_type, WL_TEXT_STR)) type = string_atom; @@ -119,7 +123,7 @@ _xwayland_send_send(E_Comp_Wl_Data_Source *source, const char* mime_type, int32_ type = ecore_x_atom_get(mime_type); cur_fd = fd; - xconvertselection(ecore_x_display_get(), ECORE_X_ATOM_SELECTION_XDND, type, xwl_dnd_atom, e_comp->cm_selection, 0); + xconvertselection(ecore_x_display_get(), sel, type, xwl_dnd_atom, e_comp->cm_selection, 0); } static void @@ -208,7 +212,17 @@ _xwl_fixes_selection_notify(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Even } if (ev->atom == ECORE_X_ATOM_SELECTION_CLIPBOARD) { - e_comp->wl_comp_data->clipboard.xwl_owner = ev->owner ? e_pixmap_find_client(E_PIXMAP_TYPE_X, ev->owner) : NULL; + if (ev->owner) + { + if (e_comp->wl_comp_data->clipboard.source) + e_comp_wl_clipboard_source_unref(e_comp->wl_comp_data->clipboard.source); + e_comp->wl_comp_data->clipboard.source = NULL; + e_comp->wl_comp_data->clipboard.xwl_owner = ev->owner ? e_pixmap_find_client(E_PIXMAP_TYPE_X, ev->owner) : NULL; + xconvertselection(ecore_x_display_get(), ECORE_X_ATOM_SELECTION_CLIPBOARD, + ECORE_X_ATOM_SELECTION_TARGETS, xwl_dnd_atom, e_comp->cm_selection, 0); + } + else + e_comp->wl_comp_data->clipboard.xwl_owner = NULL; } return ECORE_CALLBACK_RENEW; } @@ -220,11 +234,38 @@ _xwl_selection_notify(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Sele int wrote = 0; DBG("XWL SELECTION NOTIFY"); - if ((ev->selection != ECORE_X_SELECTION_XDND) && (ev->selection == ECORE_X_SELECTION_CLIPBOARD)) + if ((ev->selection != ECORE_X_SELECTION_XDND) && (ev->selection != ECORE_X_SELECTION_CLIPBOARD)) { e_object_del(E_OBJECT(e_comp->wl_comp_data->drag)); return ECORE_CALLBACK_RENEW; } + if (ev->selection == ECORE_X_SELECTION_CLIPBOARD) + { + if (eina_streq(ev->target, "TARGETS")) + { + Ecore_X_Selection_Data_Targets *tgs = ev->data; + E_Comp_Wl_Clipboard_Source *source; + E_Comp_Wl_Data_Source *dsource; + int i, p[2]; + + if (pipe2(p, O_CLOEXEC) == -1) + return ECORE_CALLBACK_RENEW; + source = e_comp_wl_clipboard_source_create(NULL, 0, p[0]); + dsource = e_comp_wl_data_manager_source_create(e_comp->wl_comp_data->xwl_client, + e_comp->wl_comp_data->mgr.resource, 1); + for (i = 0; i < tgs->num_targets; i++) + if (tgs->targets[i]) + source->data_source.mime_types = eina_list_append(source->data_source.mime_types, eina_stringshare_add(tgs->targets[i])); + e_comp->wl_comp_data->clipboard.source = source; + e_comp->wl_comp_data->selection.data_source = &source->data_source; + source->data_source.resource = dsource->resource; + source->data_source.send = _xwayland_send_send; + free(dsource); + if (e_client_has_xwindow(e_client_focused_get())) + e_comp_wl_data_device_keyboard_focus_set(); + return ECORE_CALLBACK_RENEW; + } + } /* FIXME: ecore-x events are fucked */ //if (ecore_x_atom_get(ev->target) != xwl_dnd_atom) return ECORE_CALLBACK_RENEW; sd = ev->data; @@ -233,8 +274,10 @@ _xwl_selection_notify(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Sele { wrote += write(cur_fd, sd->data, sd->length); } while (wrote < sd->length); - _xdnd_finish(1); + if (ev->selection == ECORE_X_SELECTION_XDND) + _xdnd_finish(1); close(cur_fd); + cur_fd = -1; _xwayland_dnd_finish(); return ECORE_CALLBACK_RENEW; } @@ -289,9 +332,13 @@ _xwl_selection_request(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Sel const char *type; Eina_List *l; - if (!e_comp->wl_comp_data->drag_source) return ECORE_CALLBACK_RENEW; + if (e_comp->wl_comp_data->drag_source) + source = e_comp->wl_comp_data->drag_source; + else if (e_comp->wl_comp_data->selection.data_source) + source = e_comp->wl_comp_data->selection.data_source; + else + return ECORE_CALLBACK_RENEW; - source = e_comp->wl_comp_data->drag_source; if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS) { Ecore_X_Atom *atoms;