Add focus surface setting of keyboard for copy and paste between clients
authorMinJeong Kim <minjjj.kim@samsung.com>
Wed, 9 Jul 2014 15:06:25 +0000 (11:06 -0400)
committerChris Michael <cp.michael@samsung.com>
Tue, 26 Aug 2014 14:10:37 +0000 (10:10 -0400)
Summary:
To enable copy and paste between clients,
wayland data device requires to know what surface is focused.
So this revision have make keyboard get focused surface when client is focused or unfocused,
and create data_offer for new focused surface in order to let new focused surface be able to get data from current selection data_source.

Test Plan:
1. Run wayland server
2. Run elementary_test -to entry5 on wayland server.
3. Run elementary_test -to entry5 on wayland server again. (preparing two clients)
4. Copy text on one of clients, and paste to the other.

Reviewers: devilhorns

CC: gwanglim, cedric
Differential Revision: https://phab.enlightenment.org/D1157

src/bin/e_comp_wl.c
src/bin/e_comp_wl.h
src/bin/e_comp_wl_data.c
src/bin/e_comp_wl_data.h

index 641a14a..83614c8 100644 (file)
@@ -2482,6 +2482,12 @@ _e_comp_wl_cb_hook_client_focus_set(void *data EINA_UNUSED, E_Client *ec)
                        E_FOCUS_METHOD_GLOBALLY_ACTIVE);
    else if (!ec->icccm.take_focus)
      e_grabinput_focus(e_client_util_win_get(ec), E_FOCUS_METHOD_PASSIVE);
+
+   if (ec->comp->wl_comp_data->kbd.focus != ec->wl_comp_data->surface)
+     {
+        ec->comp->wl_comp_data->kbd.focus = ec->wl_comp_data->surface;
+        e_comp_wl_data_device_keyboard_focus_set(ec->comp->wl_comp_data);
+     }
 }
 
 static void 
@@ -2498,6 +2504,9 @@ _e_comp_wl_cb_hook_client_focus_unset(void *data EINA_UNUSED, E_Client *ec)
      }
 
    _e_comp_wl_focus_check(ec->comp);
+
+   if (ec->comp->wl_comp_data->kbd.focus == ec->wl_comp_data->surface)
+     ec->comp->wl_comp_data->kbd.focus = NULL;
 }
 
 EAPI Eina_Bool 
index 74b4968..21043c9 100644 (file)
@@ -79,6 +79,7 @@ struct _E_Comp_Wl_Data
         xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
         xkb_layout_index_t mod_group;
         struct wl_array keys;
+        struct wl_resource *focus;
      } kbd;
 
    struct 
index 643da73..0f931c3 100644 (file)
@@ -155,7 +155,7 @@ _e_comp_wl_data_device_destroy_selection_data_source(struct wl_listener *listene
 {
    E_Comp_Wl_Data *cdata;
    E_Comp_Wl_Data_Source *source;
-   struct wl_resource *data_device_res;
+   struct wl_resource *data_device_res, *focus = NULL;
 
    if (!(source = (E_Comp_Wl_Data_Source*)data))
      return;
@@ -166,13 +166,18 @@ _e_comp_wl_data_device_destroy_selection_data_source(struct wl_listener *listene
 
    cdata->selection.data_source = NULL;
 
-   /* TODO: get data device from a focused surface */
-   data_device_res = 
-     _e_comp_wl_data_find_for_client(cdata->mgr.data_resources, 
-                                     wl_resource_get_client(source->resource));
+   if (cdata->kbd.enabled)
+     focus = cdata->kbd.focus;
 
-   if (data_device_res)
-     wl_data_device_send_selection(data_device_res, NULL);
+   if (focus)
+     {
+        data_device_res = 
+           _e_comp_wl_data_find_for_client(cdata->mgr.data_resources, 
+                                           wl_resource_get_client(source->resource));
+
+        if (data_device_res)
+          wl_data_device_send_selection(data_device_res, NULL);
+     }
 
    wl_signal_emit(&cdata->selection.signal, cdata);
 }
@@ -221,7 +226,7 @@ _e_comp_wl_data_device_cb_selection_set(struct wl_client *client EINA_UNUSED, st
 {
    E_Comp_Wl_Data *cdata;
    E_Comp_Wl_Data_Source *source, *sel_source;
-   struct wl_resource *offer_res, *data_device_res;
+   struct wl_resource *offer_res, *data_device_res, *focus = NULL;
 
    if (!source_resource) return;
    if (!(cdata = wl_resource_get_user_data(resource))) return;
@@ -244,20 +249,26 @@ _e_comp_wl_data_device_cb_selection_set(struct wl_client *client EINA_UNUSED, st
    cdata->selection.data_source = sel_source = source;
    cdata->selection.serial = serial;
 
-   /* TODO: get data device from a focused surface */
-   data_device_res = 
-     _e_comp_wl_data_find_for_client(cdata->mgr.data_resources, 
-                                     wl_resource_get_client(source->resource));
+   if (cdata->kbd.enabled)
+     focus = cdata->kbd.focus;
 
-   if ((data_device_res) && (source))
+   if (focus)
      {
-        offer_res = 
-          _e_comp_wl_data_device_data_offer_create(source, data_device_res);
-        wl_data_device_send_selection(data_device_res, offer_res);
-     }
-   else if (data_device_res)
-     {
-        wl_data_device_send_selection(data_device_res, NULL);
+        data_device_res =
+           _e_comp_wl_data_find_for_client(cdata->mgr.data_resources,
+                                           wl_resource_get_client(focus));
+        if ((data_device_res) && (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);
+
+          }
+        else if (data_device_res)
+          {
+             wl_data_device_send_selection(data_device_res, NULL);
+          }
      }
 
    wl_signal_emit(&cdata->selection.signal, cdata);
@@ -387,7 +398,32 @@ _e_comp_wl_data_cb_bind_manager(struct wl_client *client, void *data, uint32_t v
    wl_resource_set_implementation(res, &_e_manager_interface, cdata, NULL);
 }
 
-EINTERN Eina_Bool 
+EINTERN void
+e_comp_wl_data_device_keyboard_focus_set(E_Comp_Wl_Data *cdata)
+{
+   struct wl_resource *data_device_res, *offer_res, *focus;
+   E_Comp_Wl_Data_Source *source;
+
+   if (!cdata->kbd.enabled) return;
+
+   focus = cdata->kbd.focus;
+   if (!focus) return;
+
+   data_device_res =
+      _e_comp_wl_data_find_for_client(cdata->mgr.data_resources,
+                                      wl_resource_get_client(focus));
+   if (!data_device_res) return;
+
+   source = (E_Comp_Wl_Data_Source*)cdata->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);
+     }
+}
+
+EINTERN Eina_Bool
 e_comp_wl_data_manager_init(E_Comp_Wl_Data *cdata)
 {
    /* check for valid compositor data */
index 23d2362..e2ae0a7 100644 (file)
@@ -26,6 +26,7 @@ struct _E_Comp_Wl_Data_Offer
    struct wl_listener source_destroy_listener; //listener for destroy of source
 };
 
+EINTERN void e_comp_wl_data_device_keyboard_focus_set(E_Comp_Wl_Data *cdata);
 EINTERN Eina_Bool e_comp_wl_data_manager_init(E_Comp_Wl_Data *cdata);
 EINTERN void e_comp_wl_data_manager_shutdown(E_Comp_Wl_Data *cdata);