Introduce E_Aux_Hint_Surface 25/325425/1
authorSeunghun Lee <shiin.lee@samsung.com>
Wed, 28 May 2025 07:46:55 +0000 (16:46 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 10 Jun 2025 09:08:58 +0000 (18:08 +0900)
This patch separates the responsibility of managing auxiliary hints out
from E_Comp_Wl_Client_Data to E_Aux_Hint_Surface.
The E_Aux_Hint_Surface is now responsible for managing auxiliary hints
for an E_Surface.

This separation of responsibility is aimed at decoupling these
functionalities from E_Comp_Wl_Client_Data, which currently handles many
mixed responsibilities.

Change-Id: Ibe991fa0fbb2ad704224290506c3b3368b84a21d

src/bin/core/e_client.c
src/bin/debug/e_info_server.c
src/bin/debug/e_test_helper.c
src/bin/server/e_comp_wl.c
src/bin/server/e_compositor.c
src/bin/server/e_policy_wl.c
src/bin/windowmgr/e_hints.c
src/bin/windowmgr/e_hints_intern.h
src/include/e_comp_wl.h

index 8e110501025c9bce9cd620a62180e3ef8a916fa4..c21baf9590ee30cb638467cad5f3e14a1e2a21e3 100644 (file)
@@ -29,6 +29,7 @@
 #include "e_policy_wl_intern.h"
 #include "e_desktop_shell_intern.h"
 #include "e_comp_cfdata_intern.h"
+#include "e_hints_intern.h"
 
 #define PRI(ec) ((E_Client_Private *)e_object_data_get(E_OBJECT(ec)))
 
@@ -1835,32 +1836,16 @@ _e_client_cb_view_restack(struct wl_listener *listener, void *data)
 EINTERN void
 e_client_aux_hint_eval(E_Client *ec)
 {
-   E_Comp_Wl_Client_Data *cdata;
-   Eina_List *l, *ll;
-   E_Comp_Wl_Aux_Hint *hint;
+   E_Aux_Hint_Surface *hsurface;
 
-   API_ENTRY;
+   hsurface = e_aux_hint_surface_try_from_ec(ec);
+   if (!hsurface || !e_aux_hint_surface_is_changed(hsurface))
+     return;
 
-   cdata = e_client_cdata_get(ec);
-   if (cdata && cdata->aux_hint.changed)
-     {
-        wl_signal_emit(&priv->events.aux_hint_change, NULL);
-        e_client_hook_call(E_CLIENT_HOOK_AUX_HINT_CHANGE, ec);
+   wl_signal_emit(&PRI(ec)->events.aux_hint_change, NULL);
+   e_client_hook_call(E_CLIENT_HOOK_AUX_HINT_CHANGE, ec);
 
-        EINA_LIST_FOREACH_SAFE(cdata->aux_hint.hints, l, ll, hint)
-          {
-             hint->changed = EINA_FALSE;
-             if (hint->deleted)
-               {
-                  ELOGF("COMP", "AUX_HINT |Del [%d:%s:%s]", ec, hint->id, hint->hint, hint->val);
-                  if (hint->hint) eina_stringshare_del(hint->hint);
-                  if (hint->val) eina_stringshare_del(hint->val);
-                  cdata->aux_hint.hints = eina_list_remove_list(cdata->aux_hint.hints, l);
-                  E_FREE(hint);
-               }
-          }
-        cdata->aux_hint.changed = 0;
-     }
+   e_aux_hint_surface_changed_clear(hsurface);
 }
 
 EINTERN void
index 5cba50f3ba992d90990711106ab89b69120a2b5f..03864f849618ed8d2936ca1de8d45e623d89cce6 100644 (file)
@@ -1581,25 +1581,26 @@ _get_win_prop_Subsurface_Parent(const Evas_Object *evas_obj)
 static const char*
 _get_win_prop_Aux_Hint(const Evas_Object *evas_obj)
 {
-   const E_Comp_Wl_Client_Data *cdata;
+   E_Aux_Hint_Surface *hsurface;
+   Eina_List *hints;
    const E_Comp_Wl_Aux_Hint *hint;
    const Eina_List *l;
 
-   const E_Client *ec;
+   E_Client *ec;
    char *str = NULL;
 
    ec = evas_object_data_get(evas_obj, "E_Client");
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
 
-   if (!ec->comp_data)
+   hsurface = e_aux_hint_surface_try_from_ec(ec);
+   if (!hsurface)
      return strdup("None");
 
-   cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
-
-   if (!cdata->aux_hint.hints)
+   hints = e_aux_hint_surface_hints_get(hsurface);
+   if (!hints)
      return strdup("None");
 
-   EINA_LIST_FOREACH(cdata->aux_hint.hints, l, hint)
+   EINA_LIST_FOREACH(hints, l, hint)
      astrcat_(&str, "[%d][%s][%s]\n", hint->id, hint->hint, hint->val);
 
    return str;
@@ -5922,14 +5923,16 @@ _e_info_server_cb_wininfo_size_hints_append(E_Client *ec, Eldbus_Message_Iter *a
 static void
 _e_info_server_cb_wininfo_wm_hints_append(E_Client *ec, Eldbus_Message_Iter *array_of_hints)
 {
+   E_Aux_Hint_Surface *hsurface;
    Eina_List *l;
    E_Comp_Wl_Aux_Hint *hint;
    char temp[512] = {0};
 
-   if (!ec->comp_data)
+   hsurface = e_aux_hint_surface_try_from_ec(ec);
+   if (!hsurface)
      return;
 
-   EINA_LIST_FOREACH(ec->comp_data->aux_hint.hints, l, hint)
+   EINA_LIST_FOREACH(e_aux_hint_surface_hints_get(hsurface), l, hint)
      {
         snprintf(temp, sizeof(temp), "%s: %s", hint->hint, hint->val);
         eldbus_message_iter_arguments_append(array_of_hints, "s", temp);
index baa08248437a34185aafe1869075b6894de300bf..5e634fc1c8395564b81ee9b1cf2788b17b803a51 100644 (file)
@@ -1632,6 +1632,7 @@ _e_test_helper_cb_get_aux_hint(const Eldbus_Service_Interface *iface, const Eldb
    Eldbus_Message *reply = eldbus_message_method_return_new(msg);
    Ecore_Window win = 0x0;
    Test_Helper_Reg_Win *reg_win = NULL;
+   E_Aux_Hint_Surface *hsurface;
    E_Comp_Wl_Aux_Hint *ecah;
    E_Client *ec;
    Eina_List *l;
@@ -1650,8 +1651,9 @@ _e_test_helper_cb_get_aux_hint(const Eldbus_Service_Interface *iface, const Eldb
    if (!th_data->reg_wins) goto fin;
    if (!(reg_win = _e_test_helper_find_win_on_reg_list(win))) goto fin;
    if (!(ec = reg_win->ec)) goto fin;
+   if (!(hsurface = e_aux_hint_surface_try_from_ec(ec))) goto fin;
 
-   EINA_LIST_REVERSE_FOREACH(ec->comp_data->aux_hint.hints, l, ecah)
+   EINA_LIST_REVERSE_FOREACH(e_aux_hint_surface_hints_get(hsurface), l, ecah)
      {
         if ((!ecah->deleted) &&
             (!e_util_strcmp(ecah->hint, hint)))
@@ -1844,7 +1846,7 @@ static void
 _e_test_helper_hook_cb_client_aux_hint_change(void *data EINA_UNUSED, E_Client *ec)
 {
    Ecore_Window win = 0;
-   E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
+   E_Aux_Hint_Surface *hsurface;
    Eina_List *l, *ll;
    E_Comp_Wl_Aux_Hint *hint;
 
@@ -1856,11 +1858,15 @@ _e_test_helper_hook_cb_client_aux_hint_change(void *data EINA_UNUSED, E_Client *
 
    if (win)
      {
-        EINA_LIST_FOREACH_SAFE(cdata->aux_hint.hints, l, ll, hint)
+        hsurface = e_aux_hint_surface_try_from_ec(ec);
+        if (hsurface)
           {
-             if (hint->changed)
+             EINA_LIST_FOREACH_SAFE(e_aux_hint_surface_hints_get(hsurface), l, ll, hint)
                {
-                  _e_test_helper_send_aux_hint_change(win, hint->id, hint->hint, hint->val);
+                  if (hint->changed)
+                    {
+                       _e_test_helper_send_aux_hint_change(win, hint->id, hint->hint, hint->val);
+                    }
                }
           }
      }
index 1bbd607b8be651a41abc01d7abebb5f508e67b16..4e7759a233c4645bfed2deb6eaa64e8e52fef8c5 100644 (file)
@@ -4108,19 +4108,29 @@ e_comp_wl_data_check(E_Client *ec)
 E_API Eina_Bool
 e_comp_wl_aux_hint_changed_get(E_Client *ec)
 {
+   E_Aux_Hint_Surface *hsurface;
+
    if (!ec) return EINA_FALSE;
-   if (!ec->comp_data) return EINA_FALSE;
 
-   return ec->comp_data->aux_hint.changed;
+   hsurface = e_aux_hint_surface_try_from_ec(ec);
+   if (!hsurface)
+     return EINA_FALSE;
+
+  return e_aux_hint_surface_is_changed(hsurface);
 }
 
 E_API Eina_List *
 e_comp_wl_aux_hint_hints_get(E_Client *ec)
 {
+   E_Aux_Hint_Surface *hsurface;
+
    if (!ec) return NULL;
-   if (!ec->comp_data) return NULL;
 
-  return ec->comp_data->aux_hint.hints;
+   hsurface = e_aux_hint_surface_try_from_ec(ec);
+   if (!hsurface)
+     return NULL;
+
+  return e_aux_hint_surface_hints_get(hsurface);
 }
 
 E_API E_Comp_Wl_Buffer *
index df0cebdcd47ba2b40ef1423c4eb27ecb4691b8d5..98ce7c555ea13bedcaafc648eac60379b3552a20 100644 (file)
@@ -1006,17 +1006,6 @@ _e_surface_base_finish(E_Comp_Wl_Client_Data *base)
 
    e_comp_wl_buffer_reference(&base->buffer_ref, NULL);
 
-   if (base->aux_hint.hints)
-     {
-        E_Comp_Wl_Aux_Hint *hint;
-        EINA_LIST_FREE(base->aux_hint.hints, hint)
-          {
-             eina_stringshare_del(hint->hint);
-             eina_stringshare_del(hint->val);
-             E_FREE(hint);
-          }
-     }
-
    if (e_comp_wl_get()->selection.cbhm == base->wl_surface)
      e_comp_wl_get()->selection.cbhm = NULL;
 
index 54eaed583a796e55a519e464a5bd806a3b8c448f..98171e9137b7278e8b17a1ec77c02ba1b43cdd88 100644 (file)
@@ -1780,19 +1780,23 @@ _e_policy_wl_allowed_aux_hint_send(struct wl_resource *res_tzpol, struct wl_reso
 }
 
 static void
-_e_policy_wl_aux_hint_apply(E_Client *ec)
+_e_policy_wl_aux_hint_apply(E_Aux_Hint_Surface *hsurface)
 {
-   E_Comp_Wl_Client_Data *cdata;
-   E_Comp_Wl_Aux_Hint *hint;
+   E_Client *ec;
    Eina_List *l;
+   E_Comp_Wl_Aux_Hint *hint;
 
-   cdata = e_client_cdata_get(ec);
-   if (!cdata) return;
-   if (!cdata->aux_hint.changed) return;
+   if (!e_aux_hint_surface_is_changed(hsurface))
+     return;
+
+   ec = e_aux_hint_surface_ec_try_get(hsurface);
+   if (!ec)
+     return;
 
-   EINA_LIST_FOREACH(cdata->aux_hint.hints, l, hint)
+   EINA_LIST_FOREACH(e_aux_hint_surface_hints_get(hsurface), l, hint)
      {
         if (!hint->changed) continue;
+
         EC_CHANGED(ec);
 
         if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_USER_GEOMETRY]))
@@ -1914,9 +1918,9 @@ _e_policy_wl_aux_hint_apply(E_Client *ec)
         else if (!strcmp(hint->hint, hint_names[E_POLICY_HINT_MSG_USE]))
           {
              if ((hint->deleted) || (!strcmp(hint->val, "0")))
-               cdata->aux_hint.use_msg = EINA_FALSE;
+               e_aux_hint_surface_use_msg_set(hsurface, false);
              else if (!strcmp(hint->val, "1"))
-               cdata->aux_hint.use_msg = EINA_TRUE;
+               e_aux_hint_surface_use_msg_set(hsurface, true);
           }
         else if (!strcmp(hint->hint, hint_names[E_COMP_HINT_ALWAYS_SELECTIVE]))
           {
@@ -2114,19 +2118,16 @@ _e_policy_wl_aux_hint_apply(E_Client *ec)
 static void
 _tzpol_iface_cb_aux_hint_add(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf, int32_t id, const char *name, const char *value)
 {
-   E_Client *ec;
-   Eina_Bool res = EINA_FALSE;
-
-   ec = e_client_from_surface_resource(surf);
-   EINA_SAFETY_ON_NULL_RETURN(ec);
+   E_Surface *surface = e_surface_from_resource(surf);
+   E_Aux_Hint_Surface *hsurface;
 
-   res = e_hints_aux_hint_add(ec, id, name, value);
-
-   ELOGF("TZPOL", "HINT_ADD |res_tzpol:%8p|id:%d, name:%s, val:%s, res:%d", ec, res_tzpol, id, name, value, res);
+   hsurface = e_aux_hint_surface_get_or_create(surface);
+   if (!hsurface)
+     return;
 
-   if (res)
+   if (e_aux_hint_surface_hint_add(hsurface, id, name, value))
      {
-        _e_policy_wl_aux_hint_apply(ec);
+        _e_policy_wl_aux_hint_apply(hsurface);
         _e_policy_wl_allowed_aux_hint_send(res_tzpol, surf, id);
      }
 }
@@ -2134,19 +2135,16 @@ _tzpol_iface_cb_aux_hint_add(struct wl_client *client EINA_UNUSED, struct wl_res
 static void
 _tzpol_iface_cb_aux_hint_change(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf, int32_t id, const char *value)
 {
-   E_Client *ec;
-   Eina_Bool res = EINA_FALSE;
-
-   ec = e_client_from_surface_resource(surf);
-   EINA_SAFETY_ON_NULL_RETURN(ec);
+   E_Surface *surface = e_surface_from_resource(surf);
+   E_Aux_Hint_Surface *hsurface;
 
-   res = e_hints_aux_hint_change(ec, id, value);
-
-   ELOGF("TZPOL", "HINT_CHD |res_tzpol:%8p|id:%d, val:%s, result:%d", ec, res_tzpol, id, value, res);
+   hsurface = e_aux_hint_surface_get_or_create(surface);
+   if (!hsurface)
+     return;
 
-   if (res)
+   if (e_aux_hint_surface_hint_change(hsurface, id, value))
      {
-        _e_policy_wl_aux_hint_apply(ec);
+        _e_policy_wl_aux_hint_apply(hsurface);
         _e_policy_wl_allowed_aux_hint_send(res_tzpol, surf, id);
      }
 }
@@ -2154,17 +2152,15 @@ _tzpol_iface_cb_aux_hint_change(struct wl_client *client EINA_UNUSED, struct wl_
 static void
 _tzpol_iface_cb_aux_hint_del(struct wl_client *client EINA_UNUSED, struct wl_resource *res_tzpol, struct wl_resource *surf, int32_t id)
 {
-   E_Client *ec;
-   unsigned int res = -1;
-
-   ec = e_client_from_surface_resource(surf);
-   EINA_SAFETY_ON_NULL_RETURN(ec);
+   E_Surface *surface = e_surface_from_resource(surf);
+   E_Aux_Hint_Surface *hsurface;
 
-   res = e_hints_aux_hint_del(ec, id);
-   ELOGF("TZPOL", "HINT_DEL |res_tzpol:%8p|id:%d, result:%d", ec, res_tzpol, id, res);
+   hsurface = e_aux_hint_surface_get_or_create(surface);
+   if (!hsurface)
+     return;
 
-   if (res)
-     _e_policy_wl_aux_hint_apply(ec);
+   if (e_aux_hint_surface_hint_del(hsurface, id))
+     _e_policy_wl_aux_hint_apply(hsurface);
 }
 
 static void
@@ -2881,7 +2877,11 @@ e_policy_wl_generate_request(E_Client *ec, E_Policy_Wl_Gen_Request type)
 EINTERN void
 e_policy_wl_aux_hint_apply(E_Client *ec)
 {
-   _e_policy_wl_aux_hint_apply(ec);
+   E_Aux_Hint_Surface *hsurface;
+
+   hsurface = e_aux_hint_surface_try_from_ec(ec);
+   if (hsurface)
+     _e_policy_wl_aux_hint_apply(hsurface);
 }
 
 // --------------------------------------------------------
@@ -2932,7 +2932,7 @@ e_policy_wl_aux_message_send(E_Client *ec,
                              const char *val,
                              Eina_List *options)
 {
-   E_Comp_Wl_Client_Data *cdata;
+   E_Aux_Hint_Surface *hsurface;
    E_Policy_Wl_Tzpol *tzpol;
    E_Policy_Wl_Surface *psurf;
    Eina_List *l;
@@ -2943,9 +2943,10 @@ e_policy_wl_aux_message_send(E_Client *ec,
    char *p;
 
    if (e_object_is_del(E_OBJECT(ec))) return;
-   cdata = e_client_cdata_get(ec);
-   if (!cdata) return;
-   if (!cdata->aux_hint.use_msg) return;
+
+   hsurface = e_aux_hint_surface_try_from_ec(ec);
+   if (!hsurface) return;
+   if (!e_aux_hint_surface_use_msg_get(hsurface)) return;
 
    wl_array_init(&opt_array);
    EINA_LIST_FOREACH(options, l, option)
index 84e6687b32a870eddf1902f2d1a0140e1b6f6263..d556419fc972ee99733271d9d2a04dfd2dd3a9ad 100644 (file)
 #include "e_scale_intern.h"
 #include "e_utils_intern.h"
 #include "e_comp_wl_intern.h"
+#include "e_compositor_intern.h"
 
+#include <stdbool.h>
 
-static Eina_List *aux_hints_supported = NULL;
-
-static Eina_Bool
-_e_hints_aux_hint_add(E_Client *ec, int32_t id, const char *name, const char *val)
+struct _E_Aux_Hint_Surface
 {
-   E_Comp_Wl_Client_Data *cdata;
-   Eina_Bool found = EINA_FALSE;
-   E_Comp_Wl_Aux_Hint *hint;
-   Eina_List *l;
-
-   cdata = e_client_cdata_get(ec);
-   if (!cdata) return EINA_FALSE;
-
-   EINA_LIST_FOREACH(cdata->aux_hint.hints, l, hint)
-     {
-        if (hint->id == id)
-          {
-             if (!e_util_strcmp(hint->hint, name))
-               {
-                  if (strcmp(hint->val, val) != 0)
-                    {
-                       ELOGF("COMP", "AUX_HINT |Change [%d:%s:%s -> %s]",
-                             ec, id, hint->hint, hint->val, val);
-                       eina_stringshare_del(hint->val);
+   E_Surface *surface;
+   E_Client *ec;
+   Eina_List *hints;
+   bool changed;
+   bool use_msg;
 
-                       hint->val = eina_stringshare_add(val);
-                       hint->changed = EINA_TRUE;
-                       hint->deleted = EINA_FALSE;
-                       cdata->aux_hint.changed = 1;
-                    }
-               }
-             else
-               {
-                  // hint's name is not same,
-                  // replace hint's name and value
+   struct wl_listener ec_destroy;
+   struct wl_listener surface_destroy;
+};
 
-                  ELOGF("COMP", "AUX_HINT |Replace [%d:%s:%s -> %s:%s]",
-                        ec, id, hint->hint, hint->val, name, val);
-                  eina_stringshare_del(hint->hint);
-                  eina_stringshare_del(hint->val);
-
-                  hint->hint = eina_stringshare_add(name);
-                  hint->val = eina_stringshare_add(val);
-                  hint->changed = EINA_TRUE;
-                  hint->deleted = EINA_FALSE;
-                  cdata->aux_hint.changed = 1;
-               }
-             found = EINA_TRUE;
-             break;
-          }
-     }
+static Eina_List *aux_hints_supported = NULL;
 
-   if (!found)
-     {
-        hint = E_NEW(E_Comp_Wl_Aux_Hint, 1);
-        EINA_SAFETY_ON_NULL_RETURN_VAL(hint, EINA_FALSE);
+static E_Aux_Hint_Surface *_surface_try_from_ec(E_Client *ec);
 
-        memset(hint, 0, sizeof(E_Comp_Wl_Aux_Hint));
+static Eina_Bool
+_e_hints_aux_hint_add(E_Client *ec, int32_t id, const char *name, const char *val)
+{
+   E_Aux_Hint_Surface *surface;
 
-        hint->id = id;
-        hint->hint = eina_stringshare_add(name);
-        hint->val = eina_stringshare_add(val);
-        hint->changed = EINA_TRUE;
-        hint->deleted = EINA_FALSE;
-        cdata->aux_hint.hints = eina_list_append(cdata->aux_hint.hints, hint);
-        cdata->aux_hint.changed = 1;
-        ELOGF("COMP", "AUX_HINT |Add [%d:%s:%s]", ec, id, hint->hint, hint->val);
-     }
+   surface = _surface_try_from_ec(ec);
+   if (!surface)
+     return EINA_FALSE;
 
-   return EINA_TRUE;
+   return e_aux_hint_surface_hint_add(surface, id, name, val);
 }
 
 static Eina_Bool
 _e_hints_aux_hint_change(E_Client *ec, int32_t id, const char *val)
 {
-   E_Comp_Wl_Client_Data *cdata;
-   Eina_List *l;
-   E_Comp_Wl_Aux_Hint *hint;
-   Eina_Bool found = EINA_FALSE;
-
-   cdata = e_client_cdata_get(ec);
-   if (!cdata) return EINA_FALSE;
+   E_Aux_Hint_Surface *surface;
 
-   EINA_LIST_FOREACH(cdata->aux_hint.hints, l, hint)
-     {
-        if (hint->id == id)
-          {
-             if ((hint->val) && (strcmp(hint->val, val) != 0))
-               {
-                  ELOGF("COMP", "AUX_HINT |Change [%d:%s:%s -> %s]", ec,
-                        id, hint->hint, hint->val, val);
-                  eina_stringshare_del(hint->val);
-                  hint->val = eina_stringshare_add(val);
-                  hint->changed = EINA_TRUE;
-                  cdata->aux_hint.changed = 1;
-               }
-
-             if (hint->deleted)
-               hint->deleted = EINA_FALSE;
-
-             found = EINA_TRUE;
-             break;
-          }
-     }
-
-   if (found)
-     return EINA_TRUE;
+   surface = _surface_try_from_ec(ec);
+   if (!surface)
+     return EINA_FALSE;
 
-   return EINA_FALSE;
+   return e_aux_hint_surface_hint_change(surface, id, val);
 }
 
 E_API Eina_Bool
@@ -131,45 +62,23 @@ e_hints_aux_hint_change_with_pixmap(E_Pixmap *cp, int32_t id, const char *val)
 static Eina_Bool
 _e_hints_aux_hint_del(E_Client *ec, int32_t id)
 {
-   E_Comp_Wl_Client_Data *cdata;
-   Eina_List *l, *ll;
-   E_Comp_Wl_Aux_Hint *hint;
-   int res = -1;
+   E_Aux_Hint_Surface *surface;
 
-   cdata = e_client_cdata_get(ec);
-   if (!cdata) return EINA_FALSE;
-
-   EINA_LIST_FOREACH_SAFE(cdata->aux_hint.hints, l, ll, hint)
-     {
-        if (hint->id == id)
-          {
-             ELOGF("COMP", "AUX_HINT |Del (pending) [%d:%s:%s]", ec, id, hint->hint, hint->val);
-             hint->changed = EINA_TRUE;
-             hint->deleted = EINA_TRUE;
-             cdata->aux_hint.changed = 1;
-             res = hint->id;
-             break;
-          }
-     }
-
-   if (res == -1)
+   surface = _surface_try_from_ec(ec);
+   if (!surface)
      return EINA_FALSE;
 
-   return EINA_TRUE;
+   return e_aux_hint_surface_hint_del(surface, id);
 }
 
 static const char *
-_e_hints_aux_hint_value_get(E_Client *ec, const char *name)
+_surface_hint_value_get(E_Aux_Hint_Surface *surface, const char *name)
 {
-   E_Comp_Wl_Client_Data *cdata;
-   Eina_List *l;
    E_Comp_Wl_Aux_Hint *hint;
+   Eina_List *l;
    const char *res = NULL;
 
-   cdata = e_client_cdata_get(ec);
-   if (!cdata) return NULL;
-
-   EINA_LIST_REVERSE_FOREACH(cdata->aux_hint.hints, l, hint)
+   EINA_LIST_REVERSE_FOREACH(surface->hints, l, hint)
      {
         if ((!hint->deleted) &&
             (!strcmp(hint->hint, name)))
@@ -182,6 +91,18 @@ _e_hints_aux_hint_value_get(E_Client *ec, const char *name)
    return res;
 }
 
+static const char *
+_e_hints_aux_hint_value_get(E_Client *ec, const char *name)
+{
+   E_Aux_Hint_Surface *surface;
+
+   surface = _surface_try_from_ec(ec);
+   if (!surface)
+     return NULL;
+
+   return _surface_hint_value_get(surface, name);
+}
+
 E_API void
 e_hints_window_visible_set(E_Client *ec)
 {
@@ -267,3 +188,288 @@ e_hints_aux_hint_value_get(E_Client *ec, const char *name)
    if (!ec) return NULL;
    return _e_hints_aux_hint_value_get(ec, name);
 }
+
+static void
+_surface_destroy(E_Aux_Hint_Surface *surface)
+{
+   E_Comp_Wl_Aux_Hint *hint;
+
+   ELOGF("HINTS", "Destroy E_Aux_Hint_Surface(%p)", surface->ec, surface);
+
+   EINA_LIST_FREE(surface->hints, hint)
+     {
+        eina_stringshare_del(hint->hint);
+        eina_stringshare_del(hint->val);
+        E_FREE(hint);
+     }
+
+   if (surface->ec)
+     wl_list_remove(&surface->ec_destroy.link);
+
+   wl_list_remove(&surface->surface_destroy.link);
+   free(surface);
+}
+
+static void
+_surface_cb_ec_destroy(struct wl_listener *listener, void *data)
+{
+   E_Aux_Hint_Surface *surface = wl_container_of(listener, surface, ec_destroy);
+
+   wl_list_remove(&surface->ec_destroy.link);
+   surface->ec = NULL;
+}
+
+static void
+_surface_cb_surface_destroy(struct wl_listener *listener, void *data)
+{
+   E_Aux_Hint_Surface *surface = wl_container_of(listener, surface, surface_destroy);
+
+   _surface_destroy(surface);
+}
+
+static E_Aux_Hint_Surface *
+_surface_create(E_Surface *e_surface)
+{
+   E_Aux_Hint_Surface *surface;
+
+   surface = calloc(1, sizeof(*surface));
+   if (!surface)
+     return NULL;
+
+   surface->ec = e_surface_ec_get(e_surface);
+   surface->ec_destroy.notify = _surface_cb_ec_destroy;
+   e_client_destroy_listener_add(surface->ec, &surface->ec_destroy);
+
+   surface->surface = e_surface;
+   surface->surface_destroy.notify = _surface_cb_surface_destroy;
+   e_surface_destroy_listener_add(e_surface, &surface->surface_destroy);
+
+   ELOGF("HINTS", "Create E_Aux_Hint_Surface(%p)", surface->ec, surface);
+
+   return surface;
+}
+
+static E_Aux_Hint_Surface *
+_surface_try_from_surface(E_Surface *e_surface)
+{
+   E_Aux_Hint_Surface *surface;
+   struct wl_listener *listener;
+
+   listener = e_surface_destroy_listener_get(e_surface, _surface_cb_surface_destroy);
+   if (!listener)
+     return NULL;
+
+   return wl_container_of(listener, surface, surface_destroy);
+}
+
+EINTERN E_Aux_Hint_Surface *
+e_aux_hint_surface_get_or_create(E_Surface *e_surface)
+{
+   E_Aux_Hint_Surface *surface;
+
+   surface = _surface_try_from_surface(e_surface);
+   if (surface)
+     return surface;
+
+   return _surface_create(e_surface);
+}
+
+static E_Aux_Hint_Surface *
+_surface_try_from_ec(E_Client *ec)
+{
+   E_Aux_Hint_Surface *surface;
+   struct wl_listener *listener;
+
+   listener = e_client_destroy_listener_get(ec, _surface_cb_ec_destroy);
+   if (!listener)
+     return NULL;
+
+   return wl_container_of(listener, surface, ec_destroy);
+}
+
+EINTERN E_Aux_Hint_Surface *
+e_aux_hint_surface_try_from_ec(E_Client *ec)
+{
+   return _surface_try_from_ec(ec);
+}
+
+EINTERN E_Client *
+e_aux_hint_surface_ec_try_get(E_Aux_Hint_Surface *surface)
+{
+   return surface->ec;
+}
+
+EINTERN bool
+e_aux_hint_surface_hint_add(E_Aux_Hint_Surface *surface, int32_t id, const char *name, const char *value)
+{
+   E_Comp_Wl_Aux_Hint *hint;
+   Eina_List *l;
+   bool found = false;
+
+   EINA_LIST_FOREACH(surface->hints, l, hint)
+     {
+        if (hint->id == id)
+          {
+             if (!e_util_strcmp(hint->hint, name))
+               {
+                  if (strcmp(hint->val, value) != 0)
+                    {
+                       ELOGF("HINTS", "AUX_HINT |Change [%d:%s:%s -> %s]",
+                             surface->ec, id, hint->hint, hint->val, value);
+                       eina_stringshare_del(hint->val);
+
+                       hint->val = eina_stringshare_add(value);
+                       hint->changed = true;
+                       hint->deleted = false;
+                       surface->changed = true;
+                    }
+               }
+             else
+               {
+                  // hint's name is not same,
+                  // replace hint's name and value
+
+                  ELOGF("HINTS", "AUX_HINT |Replace [%d:%s:%s -> %s:%s]",
+                        surface->ec, id, hint->hint, hint->val, name, value);
+                  eina_stringshare_del(hint->hint);
+                  eina_stringshare_del(hint->val);
+
+                  hint->hint = eina_stringshare_add(name);
+                  hint->val = eina_stringshare_add(value);
+                  hint->changed = true;
+                  hint->deleted = false;
+                  surface->changed = true;
+               }
+             found = true;
+             break;
+          }
+     }
+
+   if (!found)
+     {
+        hint = E_NEW(E_Comp_Wl_Aux_Hint, 1);
+        EINA_SAFETY_ON_NULL_RETURN_VAL(hint, false);
+
+        memset(hint, 0, sizeof(E_Comp_Wl_Aux_Hint));
+
+        hint->id = id;
+        hint->hint = eina_stringshare_add(name);
+        hint->val = eina_stringshare_add(value);
+        hint->changed = true;
+        hint->deleted = false;
+        surface->hints = eina_list_append(surface->hints, hint);
+        surface->changed = 1;
+        ELOGF("HINTS", "AUX_HINT |Add [%d:%s:%s]", surface->ec, id, hint->hint, hint->val);
+     }
+
+   return true;
+}
+
+EINTERN bool
+e_aux_hint_surface_hint_change(E_Aux_Hint_Surface *surface, int32_t id, const char *value)
+{
+   E_Comp_Wl_Aux_Hint *hint;
+   Eina_List *l;
+   bool found = false;
+
+   EINA_LIST_FOREACH(surface->hints, l, hint)
+     {
+        if (hint->id == id)
+          {
+             if ((hint->val) && (strcmp(hint->val, value) != 0))
+               {
+                  ELOGF("COMP", "AUX_HINT |Change [%d:%s:%s -> %s]", surface->ec,
+                        id, hint->hint, hint->val, value);
+                  eina_stringshare_del(hint->val);
+                  hint->val = eina_stringshare_add(value);
+                  hint->changed = true;
+                  surface->changed = true;
+               }
+
+             if (hint->deleted)
+               hint->deleted = false;
+
+             found = true;
+             break;
+          }
+     }
+
+   if (found)
+     return true;
+
+   return false;
+}
+
+EINTERN bool
+e_aux_hint_surface_hint_del(E_Aux_Hint_Surface *surface, int32_t id)
+{
+   E_Comp_Wl_Aux_Hint *hint;
+   Eina_List *l, *ll;
+   int res = -1;
+
+   EINA_LIST_FOREACH_SAFE(surface->hints, l, ll, hint)
+     {
+        if (hint->id == id)
+          {
+             ELOGF("HINTS", "AUX_HINT |Del (pending) [%d:%s:%s]", surface->ec, id, hint->hint, hint->val);
+             hint->changed = true;
+             hint->deleted = true;
+             surface->changed = true;
+             res = hint->id;
+             break;
+          }
+     }
+
+   if (res == -1)
+     return false;
+
+   return true;
+}
+
+EINTERN void
+e_aux_hint_surface_changed_clear(E_Aux_Hint_Surface *surface)
+{
+   E_Comp_Wl_Aux_Hint *hint;
+   Eina_List *l, *ll;
+
+   if (!surface->changed)
+     return;
+
+   EINA_LIST_FOREACH_SAFE(surface->hints, l, ll, hint)
+     {
+        hint->changed = EINA_FALSE;
+        if (hint->deleted)
+          {
+             ELOGF("HINTS", "AUX_HINT |Del [%d:%s:%s]", surface->ec, hint->id, hint->hint, hint->val);
+             if (hint->hint) eina_stringshare_del(hint->hint);
+             if (hint->val) eina_stringshare_del(hint->val);
+             surface->hints = eina_list_remove_list(surface->hints, l);
+             E_FREE(hint);
+          }
+     }
+   surface->changed = 0;
+}
+
+EINTERN bool
+e_aux_hint_surface_is_changed(E_Aux_Hint_Surface *surface)
+{
+   return surface->changed;
+}
+
+EINTERN Eina_List *
+e_aux_hint_surface_hints_get(E_Aux_Hint_Surface *surface)
+{
+   return surface->hints;
+}
+
+EINTERN void
+e_aux_hint_surface_use_msg_set(E_Aux_Hint_Surface *surface, bool val)
+{
+   surface->use_msg = val;
+}
+
+EINTERN bool
+e_aux_hint_surface_use_msg_get(E_Aux_Hint_Surface *surface)
+{
+   return surface->use_msg;
+}
index 5144f0c0236999c4a223857cd68efa6bf4e5014f..8f2ca4e1c450c1af2c6fa58c3badf3c5a0e8a1d8 100644 (file)
 #ifndef E_HINTS_INTERN_H
 #define E_HINTS_INTERN_H
 
+#include <stdbool.h>
+
 #include "e_intern.h"
 #include "e_hints.h"
+#include "e_compositor_intern.h"
+
+typedef struct _E_Aux_Hint_Surface E_Aux_Hint_Surface;
 
 EINTERN void             e_hints_scale_update(void);
 EINTERN const Eina_List *e_hints_aux_hint_supported_get(void);
 EINTERN Eina_Bool        e_hints_aux_hint_change(E_Client *ec, int32_t id, const char *val);
 
+/**
+ * Retrieve or create an E_Aux_Hint_Surface for a given E_Surface
+ *
+ * This function retrieves an existing E_Aux_Hint_Surface associated with the
+ * given E_Surface. If no such surface exists, it creates a new
+ * E_Aux_Hint_Surface and associates it with the given E_Surface.
+ */
+E_Aux_Hint_Surface *e_aux_hint_surface_get_or_create(E_Surface *e_surface);
+
+/**
+ * Retrieve an E_Aux_Hint_Surface from a given E_Client
+ *
+ * This function retrieves the E_Aux_Hint_Surface associated with the given
+ * E_Client. If no such surface exists, it returns NULL.
+ */
+E_Aux_Hint_Surface *e_aux_hint_surface_try_from_ec(E_Client *ec);
+
+/**
+ * Get an E_Client instance from E_Aux_Hint_Surface
+ */
+E_Client *e_aux_hint_surface_ec_try_get(E_Aux_Hint_Surface *surface);
+
+/**
+ * Add a new hint to E_Aux_Hint_Surface or change the value of hint if it
+ * already exists
+ *
+ * This function adds a new hint to the given E_Aux_Hint_Surface object if it
+ * does not already exist. If a hint with the same ID exists, it updates the
+ * value and name of the existing hint. It returns true if the hint was
+ * successfully added or updated, false otherwise.
+ */
+bool e_aux_hint_surface_hint_add(E_Aux_Hint_Surface *surface, int32_t id, const char *name, const char *value);
+
+/**
+ * Change the value of an existing hint in E_Aux_Hint_Surface
+ *
+ * It updates the value of the hint identified by the provided ID. If the hint
+ * does not exist, the function returns false.
+ */
+bool e_aux_hint_surface_hint_change(E_Aux_Hint_Surface *surface, int32_t id, const char *value);
+
+/**
+ * Delete a hint from E_Aux_Hint_Surface
+ *
+ * It removes the hint identified by the provided ID. If the hint does not
+ * exist, the function returns false.
+ */
+bool e_aux_hint_surface_hint_del(E_Aux_Hint_Surface *surface, int32_t id);
+
+/**
+ * Check if E_Aux_Hint_Surface has changed
+ *
+ * It returns true if any hints have been updated, false otherwise.
+ */
+bool e_aux_hint_surface_is_changed(E_Aux_Hint_Surface *surface);
+
+/**
+ * Get a list of hint from E_Aux_Hint_Surface
+ *
+ * This function retrieves a list of hint associated with the given
+ * E_Aux_Hint_Surface. The returned list contains all hints currently stored in
+ * the surface.
+ * It returns a list of hints if successful, NULL othersise.
+ */
+Eina_List *e_aux_hint_surface_hints_get(E_Aux_Hint_Surface *surface);
+
+/**
+ * Set use_msg to given value
+ */
+void e_aux_hint_surface_use_msg_set(E_Aux_Hint_Surface *surface, bool val);
+
+/**
+ * Get value of use_msg
+ */
+bool e_aux_hint_surface_use_msg_get(E_Aux_Hint_Surface *surface);
+
+/**
+ * Clear the changed state and deallocate hints to be deleted
+ *
+ * This function clears the changed state of the given E_Aux_Hint_Surface and
+ * deallocates any hints marked for deletion.
+ */
+void e_aux_hint_surface_changed_clear(E_Aux_Hint_Surface *surface);
+
 #endif
index 155b5d92d6b8e8ddc19b1b49f6e2d56e69a3bc6d..fffdd39ea2a0af9d617900125f2fd2839b193d9e 100644 (file)
@@ -454,7 +454,7 @@ struct _E_Comp_Wl_Client_Data
         Eina_Bool  changed : 1;
         Eina_List *hints;
         Eina_Bool  use_msg : 1;
-     } aux_hint;
+     } E_DEPRECATED aux_hint;
 
    /* before applying viewport */
    int width_from_buffer;