e_comp_wl_data: Support multiple secondary selection 85/300185/1
authorJunkyeong Kim <jk0430.kim@samsung.com>
Wed, 18 Oct 2023 05:26:50 +0000 (14:26 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Wed, 18 Oct 2023 05:54:18 +0000 (14:54 +0900)
Send copied data to secondary_list members.

Change-Id: Ie08a988ab2d8bb12675675eda48b23ffd7d08b11

src/bin/e_comp_wl.h
src/bin/e_comp_wl_data.c
src/bin/e_compositor.c
src/bin/services/e_service_kvm.c

index 78b12e3..038db85 100644 (file)
@@ -307,10 +307,9 @@ struct _E_Comp_Wl_Data
         E_Client *target;
 
         struct wl_resource *cbhm;
-        struct wl_resource *secondary;
         Eina_List *secondary_list;
         Eina_List *data_only_list;
-        Eina_Bool secondary_selection_sent;
+        struct wl_resource *secondary_sent;
      } selection;
 
    struct
index 79242f2..3424112 100644 (file)
@@ -525,12 +525,79 @@ _e_comp_wl_data_device_data_offer_create(E_Comp_Wl_Data_Source *source, struct w
    return offer->resource;
 }
 
+static Eina_Bool
+_e_comp_wl_data_secondary_res_check(struct wl_resource *resource)
+{
+   struct wl_resource *surface;
+   E_Client *ec;
+   Eina_List *l;
+
+   if (resource == NULL)
+     return EINA_FALSE;
+
+   if (e_comp_wl->selection.secondary_list == NULL)
+     return EINA_FALSE;
+
+   EINA_LIST_FOREACH(e_comp_wl->selection.secondary_list, l, ec)
+     {
+        surface = e_comp_wl_client_surface_get(ec);
+        if (!surface) continue;
+
+        if (wl_resource_get_client(surface) == wl_resource_get_client(resource))
+          return EINA_TRUE;
+     }
+
+   return EINA_FALSE;
+}
+
+static void
+_e_comp_wl_data_secondary_send(E_Comp_Wl_Data_Source *source)
+{
+   struct wl_client *secondary_client;
+   struct wl_resource *surface, *offer_res, *data_device_res;
+   E_Client *ec;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(e_comp_wl->selection.secondary_list, l, ec)
+     {
+        surface = e_comp_wl_client_surface_get(ec);
+        if (!surface) continue;
+
+        if ((e_comp_wl->selection.secondary_sent != NULL) &&
+            (wl_resource_get_client(surface) == wl_resource_get_client(e_comp_wl->selection.secondary_sent)))
+          continue;
+
+        secondary_client = wl_resource_get_client(surface);
+        if (secondary_client == NULL)
+          {
+             ERR("error get client resource");
+             continue;
+          }
+        data_device_res = e_comp_wl_data_find_for_client(secondary_client);
+        if (data_device_res == NULL)
+          {
+             ERR("error get device resource");
+             continue;
+          }
+
+        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);
+          }
+        else
+          wl_data_device_send_selection(data_device_res, NULL);
+     }
+
+   e_comp_wl->selection.secondary_sent = NULL;
+}
+
 static void
 _e_comp_wl_data_device_selection_set(void *data EINA_UNUSED, E_Comp_Wl_Data_Source *source, uint32_t serial)
 {
    E_Comp_Wl_Data_Source *sel_source;
    struct wl_resource *offer_res, *data_device_res, *focus = NULL;
-   struct wl_client *source_client = NULL, *sel_client = NULL, *cbhm_client = NULL, *secondary_selection_client = NULL;
+   struct wl_client *source_client = NULL, *sel_client = NULL, *cbhm_client = NULL;
 
    sel_source = (E_Comp_Wl_Data_Source*)e_comp_wl->selection.data_source;
 
@@ -540,8 +607,6 @@ _e_comp_wl_data_device_selection_set(void *data EINA_UNUSED, E_Comp_Wl_Data_Sour
      sel_client = wl_resource_get_client(sel_source->resource);
    if (e_comp_wl->selection.cbhm)
      cbhm_client = wl_resource_get_client(e_comp_wl->selection.cbhm);
-   if (e_comp_wl->selection.secondary)
-     secondary_selection_client = wl_resource_get_client(e_comp_wl->selection.secondary);
 
    if ((sel_source) &&
        (sel_client == source_client) &&
@@ -583,33 +648,15 @@ _e_comp_wl_data_device_selection_set(void *data EINA_UNUSED, E_Comp_Wl_Data_Sour
              offer_res = _e_comp_wl_data_device_data_offer_create(source, data_device_res);
              wl_data_device_send_selection(data_device_res, offer_res);
 
-             if ((secondary_selection_client) && (secondary_selection_client == source_client))
-               e_comp_wl->selection.secondary_selection_sent = EINA_TRUE;
+             if (_e_comp_wl_data_secondary_res_check(source->resource) == EINA_TRUE)
+               e_comp_wl->selection.secondary_sent = source->resource;
           }
      }
    else
      {
         /* send wl_data_device@selection to secondary selection client */
-        if (secondary_selection_client)
-          {
-             if ((e_comp_wl->selection.secondary_selection_sent != EINA_TRUE) &&
-                 (secondary_selection_client != source_client))
-               {
-                  data_device_res = e_comp_wl_data_find_for_client(secondary_selection_client);
-                  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);
-               }
-             else
-               {
-                  e_comp_wl->selection.secondary_selection_sent = EINA_FALSE;
-               }
-          }
+        if (e_comp_wl->selection.secondary_list != NULL)
+          _e_comp_wl_data_secondary_send(source);
 
         /* send wl_data_device@selection to focused client */
         if (focus)
@@ -1676,6 +1723,8 @@ e_comp_wl_data_secondary_remove(E_Client *ec)
    DBG("remove secondary %s(%p). listcount(%d)",
        e_client_util_name_get(ec), ec, eina_list_count(e_comp_wl->selection.secondary_list));
 
+   if (e_comp_wl->selection.secondary_sent == e_comp_wl_client_surface_get(ec))
+     e_comp_wl->selection.secondary_sent = NULL;
 
    if (eina_list_count(e_comp_wl->selection.secondary_list) == 0)
      {
index bdf7090..6ce5e0d 100644 (file)
@@ -537,11 +537,7 @@ _e_surface_destroy(E_Surface *surface)
    if (e_comp_wl->selection.cbhm == surface->base.surface)
      e_comp_wl->selection.cbhm = NULL;
 
-   if (e_comp_wl->selection.secondary == surface->base.surface)
-     {
-        e_comp_wl->selection.secondary = NULL;
-        e_comp_wl->selection.secondary_selection_sent = EINA_FALSE;
-     }
+   e_comp_wl_data_secondary_remove(surface->ec);
 
    if (surface->base.viewport_transform)
      {
index fcc4ad3..35267f8 100644 (file)
@@ -32,9 +32,9 @@ _kvm_service_del(E_Service_Kvm *esk)
 
    eina_hash_del(_kvm_service_hash, &esk->ec, esk);
 
-   E_FREE(esk);
+   e_comp_wl_data_secondary_remove(esk->ec);
 
-   e_comp_wl->selection.secondary = NULL;
+   E_FREE(esk);
 
    if (eina_hash_population(_kvm_service_hash) == 0)
      {
@@ -321,7 +321,6 @@ e_service_kvm_perform_drag_leave(E_Client *ec)
 EINTERN Eina_Bool
 e_service_kvm_secondary_selection_set(E_Client *ec, Eina_Bool set)
 {
-   E_Comp_Wl_Client_Data *cdata;
    E_Service_Kvm *esk;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
@@ -337,19 +336,10 @@ e_service_kvm_secondary_selection_set(E_Client *ec, Eina_Bool set)
 
    ELOGF("KVM", "secondary selection set requested! service:%p, set:%d", ec, esk, set);
 
-   cdata = e_client_cdata_get(ec);
    if (set)
-     {
-        if (!cdata) return EINA_FALSE;
-        e_comp_wl->selection.secondary = cdata->surface;
-     }
+     e_comp_wl_data_secondary_add(ec);
    else
-     {
-        if (!cdata || e_comp_wl->selection.secondary == cdata->surface)
-          e_comp_wl->selection.secondary = NULL;
-        else
-          return EINA_FALSE;
-     }
+     e_comp_wl_data_secondary_remove(ec);
 
    return EINA_TRUE;
 }