From e445671a546481de90e63cd10e91a5974ad8411d Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 21 Sep 2023 09:15:39 +0900 Subject: [PATCH] e_client: Introduce E_Client_Private This commit introduces an E_Client_Private within the E_Client. It's designed to store private data related to E_Client. This approach prevents us from breaking ABI when adding or removing fields from the E_Client structure. Instead, we can modify the E_Client_Private structure as needed. A pointer to E_Client_Private will be assigned to e_object's data and accessed through e_object's data using e_object_data_{set,get}. So it's crucial to ensure that no one overwrites it with different data using e_object_data_set. Change-Id: I4dff782d2d661f6eb0007253484640ebc9e3c2c4 --- src/bin/e_client.c | 71 +++++++++++++++++++++++++++++++++++++++ src/bin/e_client_intern.h | 11 ++++++ 2 files changed, 82 insertions(+) create mode 100644 src/bin/e_client_intern.h diff --git a/src/bin/e_client.c b/src/bin/e_client.c index 10f4097552..b89d32caaa 100644 --- a/src/bin/e_client.c +++ b/src/bin/e_client.c @@ -1,4 +1,25 @@ #include "e.h" +#include "e_client_intern.h" + +#define PRI(ec) ((E_Client_Private *)e_object_data_get(E_OBJECT(ec))) + +#define API_ENTRY \ + EINA_SAFETY_ON_NULL_RETURN(ec); \ + E_Client_Private *priv = PRI(ec) + +#define API_ENTRY_VAL(ret) \ + EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ret); \ + E_Client_Private *priv = PRI(ec) + +typedef struct _E_Client_Private E_Client_Private; + +struct _E_Client_Private +{ + struct + { + struct wl_signal destroy; + } events; +}; static int _e_client_hooks_delete = 0; static int _e_client_hooks_walking = 0; @@ -1052,6 +1073,33 @@ e_client_check_above_focused(E_Client *ec) return EINA_FALSE; } +static Eina_Bool +_e_client_private_init(E_Client *ec) +{ + E_Client_Private *priv; + + priv = E_NEW(E_Client_Private, 1); + if (!priv) + return EINA_FALSE; + + wl_signal_init(&priv->events.destroy); + + e_object_data_set(E_OBJECT(ec), priv); + + return EINA_TRUE; +} + +static void +_e_client_private_finish(E_Client *ec) +{ + E_Client_Private *priv; + + priv = PRI(ec); + e_object_data_set(E_OBJECT(ec), NULL); + + free(priv); +} + static void _e_client_free(E_Client *ec) { @@ -1152,6 +1200,8 @@ _e_client_free(E_Client *ec) #else e_desk_client_del(ec->desk, ec); #endif + + _e_client_private_finish(ec); free(ec); } @@ -1202,6 +1252,8 @@ _e_client_del(E_Client *ec) /* must be called before parent/child clear */ _e_client_hook_call(E_CLIENT_HOOK_DEL, ec); + wl_signal_emit_mutable(&PRI(ec)->events.destroy, ec); + _e_client_event_remove(ec); ELOGF("COMP", "CLIENT DEL", ec); @@ -4079,6 +4131,12 @@ e_client_new(E_Pixmap *cp, int first_map, int internal) if (!ec) return NULL; e_object_del_func_set(E_OBJECT(ec), E_OBJECT_CLEANUP_FUNC(_e_client_del)); + if (!_e_client_private_init(ec)) + { + e_object_del(E_OBJECT(ec)); + return NULL; + } + uuid_generate(ec->uuid); ec->focus_policy_override = E_FOCUS_LAST; @@ -8780,3 +8838,16 @@ e_client_uniconify_event_send(E_Client *ec) } #endif +EINTERN void +e_client_destroy_listener_add(E_Client *ec, struct wl_listener *listener) +{ + API_ENTRY; + wl_signal_add(&priv->events.destroy, listener); +} + +EINTERN struct wl_listener * +e_client_destroy_listener_get(E_Client *ec, wl_notify_func_t notify) +{ + API_ENTRY_VAL(NULL); + return wl_signal_get(&priv->events.destroy, notify); +} \ No newline at end of file diff --git a/src/bin/e_client_intern.h b/src/bin/e_client_intern.h new file mode 100644 index 0000000000..d2aea094e2 --- /dev/null +++ b/src/bin/e_client_intern.h @@ -0,0 +1,11 @@ +#ifndef E_CLIENT_INTERN_H +#define E_CLIENT_INTERN_H + +#include + +typedef struct E_Client E_Client; + +void e_client_destroy_listener_add(E_Client *ec, struct wl_listener *listener); +struct wl_listener *e_client_destroy_listener_get(E_Client *ec, wl_notify_func_t notify); + +#endif -- 2.34.1