Remove surfaces linked to the current resource when unbinding 78/137678/1
authorJi-hoon Lee <dalton.lee@samsung.com>
Wed, 5 Jul 2017 11:01:40 +0000 (20:01 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Fri, 7 Jul 2017 05:14:11 +0000 (14:14 +0900)
Since the current implementation of unbind() frees the
entire surfaces list when unbinding, if the unbind is
executed after a new bind/get_surface request, this would
erase surfaces that should not be deleted.
Thus, store the resource pointer when acquiring surfaces,
and when unbinding remove the surfaces that are linked to
the currently unbinding resource to ensure the surfaces
that are currently in use, are not being lost.

Change-Id: I3e43ca7f991e9d09f78b11fc5c3e9be3e196ef22

src/e_mod_input_panel.c

index f17a01e..82e9997 100644 (file)
@@ -67,11 +67,13 @@ _e_input_panel_is_effect_running(E_Client *ec)
 }
 
 static void
-_e_input_panel_surface_append(E_Input_Panel *input_panel, E_Input_Panel_Surface *ips)
+_e_input_panel_surface_append(E_Input_Panel *input_panel, E_Input_Panel_Surface *ips, struct wl_resource *resource)
 {
    if (!input_panel || !ips) return;
 
+   ips->resource = resource;
    input_panel->surfaces = eina_list_append(input_panel->surfaces, ips);
+   LOGD("input_panel %p ips %p resource %p", input_panel, ips, resource);
 
    /* When a new input panel surface is created and if we have failed
     * showing input panel previously, try to show it again here */
@@ -99,7 +101,7 @@ _e_input_panel_surface_cb_toplevel_set(struct wl_client *client EINA_UNUSED, str
     * since the newly created surface is already being appended at function _e_input_panel_cb_surface_get() */
    if (eina_list_data_find(input_panel->surfaces, ips) != ips)
      {
-        _e_input_panel_surface_append(input_panel, ips);
+        _e_input_panel_surface_append(input_panel, ips, resource);
      }
    ips->panel = EINA_FALSE;
 }
@@ -124,7 +126,7 @@ _e_input_panel_surface_cb_overlay_panel_set(struct wl_client *client EINA_UNUSED
    * since the newly created surface is already being appended at function _e_input_panel_cb_surface_get() */
    if (eina_list_data_find(input_panel->surfaces, ips) != ips)
      {
-        _e_input_panel_surface_append(input_panel, ips);
+        _e_input_panel_surface_append(input_panel, ips, resource);
      }
    ips->panel = EINA_TRUE;
 }
@@ -215,6 +217,7 @@ _e_input_panel_surface_resource_destroy(struct wl_resource *resource)
           }
      }
 
+   LOGD("Removing ips %p from input panel %p", ips, input_panel);
    input_panel->surfaces = eina_list_remove(input_panel->surfaces, ips);
    E_FREE_FUNC(ips->eh.rot_change_end, ecore_event_handler_del);
    E_FREE_FUNC(ips->eh.buf_change, ecore_event_handler_del);
@@ -455,6 +458,9 @@ _e_input_panel_cb_surface_get(struct wl_client *client, struct wl_resource *reso
    E_Input_Panel_Surface *ips = NULL;
    E_Comp_Client_Data *cdata = NULL;
 
+   LOGD("client %p input_panel %p ec %p resource %p surface_resource %p",
+           client, input_panel, ec, resource, surface_resource);
+
    if (!input_panel)
      {
         WTI_WARNING(resource,
@@ -536,7 +542,7 @@ _e_input_panel_cb_surface_get(struct wl_client *client, struct wl_resource *reso
    ips->ec = ec;
    ips->input_panel = input_panel;
 
-   _e_input_panel_surface_append(input_panel, ips);
+   _e_input_panel_surface_append(input_panel, ips, resource);
 
    wl_resource_set_implementation(cdata->shell.surface,
                                   &_e_input_panel_surface_implementation,
@@ -556,9 +562,12 @@ static void
 _e_input_panel_unbind(struct wl_resource *resource)
 {
    Eina_List *l;
+   Eina_List *l_next;
    E_Input_Panel_Surface *ips;
    E_Input_Panel *input_panel = wl_resource_get_user_data(resource);
 
+   LOGD("resource %p input_panel %p", resource, input_panel);
+
    if (!input_panel)
      {
         WTI_WARNING(resource,
@@ -569,20 +578,24 @@ _e_input_panel_unbind(struct wl_resource *resource)
 
    input_panel->resource = NULL;
 
-   l = eina_list_clone(input_panel->surfaces);
-   EINA_LIST_FREE(l, ips)
+   EINA_LIST_FOREACH_SAFE(input_panel->surfaces, l, l_next, ips)
      {
-        E_Client *ec;
-        E_Comp_Wl_Client_Data *cdata;
+        LOGD("foreach ips %p resource %p l %p", ips, resource, l);
+        if (ips && ips->resource == resource)
+          {
+             E_Client *ec;
+             E_Comp_Wl_Client_Data *cdata;
 
-        if (!(ec = ips->ec)) continue;
-        if (e_object_is_del(E_OBJECT(ec))) continue;
-        if (!(cdata = ec->comp_data)) continue;
+             input_panel->surfaces = eina_list_remove_list(input_panel->surfaces, l);
+             LOGD("Removed surface %p from list %p", l, input_panel->surfaces);
 
-        cdata->shell.surface = NULL;
-     }
+             if (!(ec = ips->ec)) continue;
+             if (e_object_is_del(E_OBJECT(ec))) continue;
+             if (!(cdata = ec->comp_data)) continue;
 
-   E_FREE_FUNC(input_panel->surfaces, eina_list_free);
+             cdata->shell.surface = NULL;
+          }
+     }
 }
 
 static void
@@ -599,6 +612,8 @@ _e_input_panel_bind(struct wl_client *client, void *data, uint32_t version EINA_
    resource = wl_resource_create(client, &wl_input_panel_interface, 1, id);
    if (!resource) return;
 
+   LOGD("client %p input_panel %p resource %p", client, input_panel, resource);
+
    if (input_panel->resource == NULL)
      {
         wl_resource_set_implementation(resource,
@@ -628,7 +643,7 @@ e_input_panel_visibility_change(Eina_Bool visible)
 
    if (!g_input_panel) return;
 
-   LOGD("e_input_panel_visibility_change : %d\n", visible);
+   LOGD("e_input_panel_visibility_change : %d", visible);
 
    EINA_LIST_FOREACH(g_input_panel->surfaces, l, ips)
      {