desktop_shell: Nullify `E_Client` reference on surface destruction 22/324822/2
authorSeunghun Lee <shiin.lee@samsung.com>
Tue, 27 May 2025 08:00:59 +0000 (17:00 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 27 May 2025 09:35:57 +0000 (09:35 +0000)
The `E_Client` instance may be deallocated when the associated
surface is destroyed. This patch sets the `E_Client` reference to `null`
during surface destruction and adds checks to ensure the reference is
valid before using the `E_Client` instance in related functions.

Change-Id: Ifeeb437dd85cb2e8d5bd667d50b307b3f47ea79b

src/bin/server/e_desktop_shell.c

index 82d116c42fc8afa5292b2c058aad41622098968d..0fa1a86f1c2ca4ce744d0b080fe6e92c57ef45c7 100644 (file)
@@ -191,6 +191,7 @@ _surface_finish(E_Desktop_Surface *surface)
    surface->iface = NULL;
    surface->surface = NULL;
    e_shell_e_client_destroy(surface->ec);
+   surface->ec = NULL;
 }
 
 static E_Desktop_Surface *
@@ -311,6 +312,9 @@ e_desktop_toplevel_destroy_listener_add(E_Desktop_Toplevel *toplevel, struct wl_
 EINTERN void
 e_desktop_toplevel_title_set(E_Desktop_Toplevel *toplevel, const char *title)
 {
+   if (!toplevel->surface.ec)
+     return;
+
    ELOGF("TOPLEVEL", "Set title: %s", toplevel->surface.ec, title ?: "(null)");
    e_shell_e_client_name_title_set(toplevel->surface.ec, title, title);
 }
@@ -318,6 +322,9 @@ e_desktop_toplevel_title_set(E_Desktop_Toplevel *toplevel, const char *title)
 EINTERN void
 e_desktop_toplevel_app_id_set(E_Desktop_Toplevel *toplevel, const char *app_id)
 {
+   if (!toplevel->surface.ec)
+     return;
+
    ELOGF("TOPLEVEL", "Set app_id: %s", toplevel->surface.ec, app_id ?: "(null)");
    e_shell_e_client_app_id_set(toplevel->surface.ec, app_id);
 }
@@ -327,6 +334,9 @@ e_desktop_toplevel_parent_set(E_Desktop_Toplevel *toplevel, E_Desktop_Toplevel *
 {
    E_Client *epc = NULL;
 
+   if (!toplevel->surface.ec)
+     return;
+
    if (parent)
      epc = parent->surface.ec;
 
@@ -338,6 +348,9 @@ e_desktop_toplevel_parent_set(E_Desktop_Toplevel *toplevel, E_Desktop_Toplevel *
 EINTERN void
 e_desktop_toplevel_interactive_move_begin(E_Desktop_Toplevel *toplevel, struct wl_resource *seat_resource)
 {
+   if (!toplevel->surface.ec)
+     return;
+
    ELOGF("TOPLEVEL", "Begin interactive move: seat_resource(%p)", toplevel->surface.ec, seat_resource);
    e_shell_e_client_interactive_move(toplevel->surface.ec, seat_resource);
 }
@@ -345,6 +358,9 @@ e_desktop_toplevel_interactive_move_begin(E_Desktop_Toplevel *toplevel, struct w
 EINTERN void
 e_desktop_toplevel_interactive_resize_begin(E_Desktop_Toplevel *toplevel, struct wl_resource *toplevel_resource, struct wl_resource *seat_resource, int32_t edges)
 {
+   if (!toplevel->surface.ec)
+     return;
+
    ELOGF("TOPLEVEL", "Begin interactive resize: seat_resource(%p), edges(%d)", toplevel->surface.ec, seat_resource, edges);
    e_shell_e_client_interactive_resize(toplevel->surface.ec, toplevel_resource, seat_resource, edges);
 }
@@ -354,6 +370,9 @@ e_desktop_toplevel_fullscreen_request(E_Desktop_Toplevel *toplevel)
 {
    E_Client *ec = toplevel->surface.ec;
 
+   if (!ec)
+     return;
+
    ELOGF("TOPLEVEL", "Request fullscreen: lock_user_fullscreen(%d)", ec, ec->lock_user_fullscreen);
 
    if (ec->lock_user_fullscreen)
@@ -367,6 +386,9 @@ e_desktop_toplevel_unfullscreen_request(E_Desktop_Toplevel *toplevel)
 {
    E_Client *ec = toplevel->surface.ec;
 
+   if (!ec)
+     return;
+
    ELOGF("TOPLEVEL", "Request unfullscreen: lock_user_fullscreen(%d)", ec, ec->lock_user_fullscreen);
 
    if (ec->lock_user_fullscreen)
@@ -379,7 +401,9 @@ EINTERN void
 e_desktop_toplevel_maximize_request(E_Desktop_Toplevel *toplevel)
 {
    E_Client *ec = toplevel->surface.ec;
-   E_Maximize max = ec->maximize_type | E_MAXIMIZE_BOTH;
+
+   if (!ec)
+     return;
 
    ELOGF("TOPLEVEL", "Request maximize: lock_user_maximize(%d)", ec, ec->lock_user_maximize);
 
@@ -391,7 +415,7 @@ e_desktop_toplevel_maximize_request(E_Desktop_Toplevel *toplevel)
      return;
 
    e_client_layout_apply(ec, EINA_FALSE);
-   e_client_maximize(ec, max);
+   e_client_maximize(ec, (ec->maximize_type | E_MAXIMIZE_BOTH));
 }
 
 EINTERN void
@@ -399,6 +423,9 @@ e_desktop_toplevel_unmaximize_request(E_Desktop_Toplevel *toplevel)
 {
    E_Client *ec = toplevel->surface.ec;
 
+   if (!ec)
+     return;
+
    ELOGF("TOPLEVEL", "Request unmaximize", ec);
 
    e_client_layout_apply(ec, EINA_FALSE);
@@ -413,6 +440,9 @@ e_desktop_toplevel_minimize_request(E_Desktop_Toplevel *toplevel)
 {
    E_Client *ec = toplevel->surface.ec;
 
+   if (!ec)
+     return;
+
    ELOGF("TOPLEVEL", "Request minimize: lock_client_iconify(%d)", ec, ec->lock_client_iconify);
 
    if (ec->lock_client_iconify)
@@ -426,6 +456,9 @@ e_desktop_toplevel_window_geometry_set(E_Desktop_Toplevel *toplevel, int x, int
 {
    E_Client *ec = toplevel->surface.ec;
 
+   if (!ec)
+     return;
+
    if ((ec->comp_data->shell.window.x == x) &&
        (ec->comp_data->shell.window.y == y) &&
        (ec->comp_data->shell.window.w == width) &&
@@ -442,6 +475,9 @@ e_desktop_toplevel_min_size_set(E_Desktop_Toplevel *toplevel, int width, int hei
 {
    E_Client *ec = toplevel->surface.ec;
 
+   if (!ec)
+     return;
+
    if ((ec->icccm.min_w == width) &&
        (ec->icccm.min_h == height))
      return;
@@ -461,6 +497,9 @@ e_desktop_toplevel_max_size_set(E_Desktop_Toplevel *toplevel, int width, int hei
 {
    E_Client *ec = toplevel->surface.ec;
 
+   if (!ec)
+     return;
+
    if ((ec->icccm.max_w == width) &&
        (ec->icccm.max_h == height))
      return;
@@ -478,30 +517,45 @@ e_desktop_toplevel_max_size_set(E_Desktop_Toplevel *toplevel, int width, int hei
 EINTERN bool
 e_desktop_toplevel_is_fullscreen(E_Desktop_Toplevel *toplevel)
 {
+   if (!toplevel->surface.ec)
+     return false;
+
    return toplevel->surface.ec->fullscreen;
 }
 
 EINTERN bool
 e_desktop_toplevel_is_maximized(E_Desktop_Toplevel *toplevel)
 {
+   if (!toplevel->surface.ec)
+     return false;
+
    return !!toplevel->surface.ec->maximized;
 }
 
 EINTERN bool
 e_desktop_toplevel_is_activated(E_Desktop_Toplevel *toplevel)
 {
+   if (!toplevel->surface.ec)
+     return false;
+
    return toplevel->surface.ec == e_client_focused_get();
 }
 
 EINTERN void
 e_desktop_toplevel_fullscreen_size_get(E_Desktop_Toplevel *toplevel, int32_t *width, int32_t *height)
 {
+   if (!toplevel->surface.ec)
+     return;
+
    e_client_base_output_resolution_useful_geometry_get(toplevel->surface.ec, NULL, NULL, width, height);
 }
 
 EINTERN void
 e_desktop_toplevel_maximized_size_get(E_Desktop_Toplevel *toplevel, int32_t *width, int32_t *height)
 {
+   if (!toplevel->surface.ec)
+     return;
+
    e_client_maximized_geometry_get(toplevel->surface.ec, NULL, NULL, width, height);
 }