xdg_shell_v6: Use ds_xdg_shell_v6 90/300790/2
authorSeunghun Lee <shiin.lee@samsung.com>
Wed, 1 Nov 2023 11:24:08 +0000 (20:24 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Thu, 2 Nov 2023 08:38:56 +0000 (08:38 +0000)
Replaces xdg_shell_v6 implementation with ds_xdg_shell_v6.

Change-Id: I1a88cc361d10763c88cff43c032fd397ff541cf4

configure.ac
packaging/enlightenment.spec
src/bin/e_comp_wl_shell.c
src/bin/e_xdg_shell_v6.c

index 943840f..f9cdf97 100755 (executable)
@@ -291,6 +291,7 @@ e_requires="\
   libds \
   libds-tizen-tbm-server \
   libds-tizen-scaler \
+  libds-xdg-shell-v6 \
   "
 
 PKG_CHECK_MODULES(E_INFO, [
index d0b07fc..c30ede1 100644 (file)
@@ -79,6 +79,7 @@ BuildRequires:  pkgconfig(wayland-client)
 BuildRequires:  pkgconfig(capi-media-streamrecorder)
 
 BuildRequires:  pkgconfig(libds)
+BuildRequires:  pkgconfig(libds-xdg-shell-v6)
 BuildRequires:  pkgconfig(libds-tizen-tbm-server)
 BuildRequires:  pkgconfig(libds-tizen-scaler)
 
index 8e2240c..19fbb9f 100644 (file)
@@ -98,6 +98,24 @@ e_shell_e_client_shsurface_api_set(E_Client *ec, E_Shell_Surface_Api *api)
    cdata->shell.unmap = api->unmap;
 }
 
+static void
+_e_shell_e_client_shsurface_api_reset(E_Client *ec)
+{
+   E_Comp_Wl_Client_Data *cdata;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   cdata = ec->comp_data;
+   if (!cdata)
+     return;
+
+   cdata->shell.configure_send = NULL;
+   cdata->shell.configure = NULL;
+   cdata->shell.ping = NULL;
+   cdata->shell.map = NULL;
+   cdata->shell.unmap = NULL;
+}
+
 EINTERN void
 e_shell_e_client_toplevel_set(E_Client *ec)
 {
@@ -360,6 +378,8 @@ e_shell_e_client_destroy(E_Client *ec)
 
    ELOGF("SHELL", "Destroy shell surface", ec);
 
+   _e_shell_e_client_shsurface_api_reset(ec);
+
    if (e_policy_visibility_client_grab_cancel(ec))
      {
         ELOGF("POL_VIS", "CLIENT VIS ON(temp).", ec);
index 9c21489..e8cc105 100644 (file)
@@ -1,5 +1,7 @@
 #include "e.h"
-#include <xdg-shell-unstable-v6-server-protocol.h>
+
+#include <libds/surface.h>
+#include <libds/types/ds_xdg_shell_v6.h>
 
 #ifdef LOG
 #undef LOG
 #define LOG(f, e, x...)  ELOGF("XDG6 <LOG>", f, e, ##x)
 #define ERR(f, e, x...)  ELOGF("XDG6 <ERR>", f, e, ##x)
 
-#define e_xdg_surface_role_biggest_struct E_Xdg_Toplevel
-#define E_XDG_SURFACE_V6_TYPE (int)0xE0b06000
-
-const int WAIT_ACK_COUNT_MAX = 16;
-
-typedef enum   _E_Xdg_Surface_Role        E_Xdg_Surface_Role;
-typedef struct _E_Xdg_Size                E_Xdg_Size;
-typedef struct _E_Xdg_Shell               E_Xdg_Shell;
-typedef struct _E_Xdg_Surface             E_Xdg_Surface;
-typedef struct _E_Xdg_Toplevel            E_Xdg_Toplevel;
-typedef struct _E_Xdg_Popup               E_Xdg_Popup;
-typedef struct _E_Xdg_Positioner          E_Xdg_Positioner;
-typedef struct _E_Xdg_Toplevel_State      E_Xdg_Toplevel_State;
-typedef struct _E_Xdg_Surface_Configure   E_Xdg_Surface_Configure;
-
-enum _E_Xdg_Surface_Role
-{
-   E_XDG_SURFACE_ROLE_NONE,
-   E_XDG_SURFACE_ROLE_TOPLEVEL,
-   E_XDG_SURFACE_ROLE_POPUP,
-};
-
-struct _E_Xdg_Size
-{
-   int w, h;
-};
-
-struct _E_Xdg_Shell
-{
-   struct wl_client     *wclient;
-   struct wl_resource   *resource;     /* xdg_shell resource */
-   Eina_List            *surfaces;     /* list of all E_Xdg_Surface belonging to shell */
-   Eina_List            *positioners;  /* list of E_Xdg_Positioner */
-   uint32_t              ping_serial;
-};
-
-struct _E_Xdg_Toplevel_State
-{
-   Eina_Bool maximized;
-   Eina_Bool fullscreen;
-   Eina_Bool resizing;
-   Eina_Bool activated;
-};
+typedef struct _E_Xdg_Shell_V6 E_Xdg_Shell_V6;
+typedef struct _E_Xdg_Toplevel_V6 E_Xdg_Toplevel_V6;
 
-struct _E_Xdg_Surface
+struct _E_Xdg_Shell_V6
 {
-   E_Object e_obj_inherit;
-   struct wl_resource   *resource;        /* wl_resource for Zxdg_Surface_V6 */
-   E_Client             *ec;              /* E_Client corresponding Xdg_Surface */
-   E_Xdg_Shell          *shell;           /* Xdg_Shell created Xdg_Surface */
-   Eina_List            *configure_list;  /* list of data being appended whenever configure send and remove by ack_configure */
-
-   Ecore_Idle_Enterer   *configure_idle;  /* Idle_Enterer for sending configure */
-   E_Comp_Wl_Hook       *commit_hook;  /* Handler raised when wl_surface is committed. */
-
-   E_Xdg_Surface_Role    role;
-   Eina_Rectangle        configured_geometry;   /* configured geometry by compositor */
-   Eina_Rectangle        window_geometry;       /* window geometry set by client */
-
-   Eina_Bool             configured :1;
-   Eina_Bool             has_window_geometry: 1;
-   Eina_Bool             wait_next_commit;
-};
+   struct ds_xdg_shell_v6 *ds_xdg_shell;
 
-struct _E_Xdg_Toplevel
-{
-   E_Xdg_Surface         base;
-   struct wl_resource   *resource;
-
-   struct
-   {
-      E_Xdg_Toplevel_State state;
-      E_Xdg_Size           size;
-      uint32_t             edges;
-   } pending;
-   struct
-   {
-      E_Xdg_Toplevel_State state;
-      E_Xdg_Size           size;
-      E_Xdg_Size           min_size, max_size;
-   } next;
-   struct
-   {
-      E_Xdg_Toplevel_State state;
-      E_Xdg_Size           min_size, max_size;
-   } current;
+   struct wl_listener destroy;
+   struct wl_listener new_surface;
 };
 
-struct _E_Xdg_Popup
+struct _E_Xdg_Toplevel_V6
 {
-   E_Xdg_Surface         base;
-
-   struct wl_resource   *resource;
-   E_Xdg_Surface        *parent;
+   struct ds_xdg_toplevel_v6 *ds_toplevel;
+   E_Client *ec;
 
-   Eina_Rectangle        geometry;
-   Eina_Bool             committed;
+   struct wl_listener set_parent;
+   struct wl_listener set_title;
+   struct wl_listener set_app_id;
+   struct wl_listener request_move;
+   struct wl_listener request_resize;
+   struct wl_listener request_maximize;
+   struct wl_listener request_fullscreen;
+   struct wl_listener request_minimize;
+   struct wl_listener destroy;
+   struct wl_listener configure;
+   struct wl_listener ping_timeout;
+   struct wl_listener surface_commit;
 };
 
-struct _E_Xdg_Surface_Configure
-{
-   uint32_t serial;
-   E_Xdg_Toplevel_State state;
-   E_Xdg_Size size;
-};
+static void _e_xdg_shell_v6_cb_destroy(struct wl_listener *listener, void *data);
+static void _e_xdg_shell_v6_cb_new_surface(struct wl_listener *listener, void *data);
+static void _e_xdg_toplevel_v6_add(struct ds_xdg_surface_v6 *ds_xdg_surface);
+static void _e_xdg_toplevel_v6_cb_xdg_surface_destroy(struct wl_listener *listener, void *data);
+static E_Xdg_Toplevel_V6 *_e_xdg_toplevel_v6_from_shell_surface_resource(struct wl_resource *shsurface_resource);
 
-struct _E_Xdg_Positioner
+EINTERN Eina_Bool
+e_xdg_shell_v6_init(void)
 {
-   E_Xdg_Shell          *shell;
-   struct wl_resource   *resource;     /* xdg_positioner_v6 resources */
-   E_Xdg_Size            size;
-   Eina_Rectangle        anchor_rect;
-   enum zxdg_positioner_v6_anchor                  anchor;
-   enum zxdg_positioner_v6_gravity                 gravity;
-   enum zxdg_positioner_v6_constraint_adjustment   constraint_adjustment;
-   struct
-   {
-      int x, y;
-   } offset;
-};
+   static E_Xdg_Shell_V6 shell = { .ds_xdg_shell = NULL };
 
-static struct wl_global *global_resource = NULL;
+   LOG("Initializing Xdg_Shell_V6", NULL);
 
-static void             _e_xdg_shell_surface_add(E_Xdg_Shell *shell, E_Xdg_Surface *exsurf);
-static void             _e_xdg_shell_surface_remove(E_Xdg_Shell *shell, E_Xdg_Surface *exsurf);
-static void             _e_xdg_shell_ping(E_Xdg_Shell *shell);
-static Eina_Bool        _e_xdg_surface_cb_configure_send(void *data);
-static Eina_Rectangle   _e_xdg_positioner_geometry_get(E_Xdg_Positioner *p);
+   if (shell.ds_xdg_shell)
+     {
+        LOG("Xdg_Shell_V6 already initialized", NULL);
+        return EINA_TRUE;
+     }
 
-/**********************************************************
- * Implementation for Utility
- **********************************************************/
-static Eina_Bool
-_e_client_shsurface_assignable_check(E_Client *ec)
-{
-   E_Comp_Wl_Client_Data *cdata;
 
-   if (!e_shell_e_client_shell_assignable_check(ec))
+   shell.ds_xdg_shell = ds_xdg_shell_v6_create(e_comp_wl->wl.disp);
+   if (!shell.ds_xdg_shell)
      {
-        ERR("Could not assign shell", ec);
-        cdata = e_client_cdata_get(ec);
-        wl_resource_post_error(cdata->surface,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Could not assign shell surface to wl_surface");
+        ERR("Could not create ds_xdg_shell_v6", NULL);
         return EINA_FALSE;
      }
 
-   return EINA_TRUE;
-}
-
-static Eina_Bool
-_e_client_xdg_shell_v6_assigned_check(E_Client *ec)
-{
-   E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
-   return !!cdata->sh_v6.res_role;
-}
-
-static void
-_e_client_xdg_shell_v6_assign(E_Client *ec,
-                              struct wl_resource *resource,
-                              E_Comp_Wl_Sh_Surf_Role role)
-{
-   E_Comp_Wl_Client_Data *cdata;
-
-   if (!ec) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
-   cdata = e_client_cdata_get(ec);
-   if (!cdata) return;
+   shell.destroy.notify = _e_xdg_shell_v6_cb_destroy;
+   ds_xdg_shell_v6_add_destroy_listener(shell.ds_xdg_shell, &shell.destroy);
+   shell.new_surface.notify = _e_xdg_shell_v6_cb_new_surface;
+   ds_xdg_shell_v6_add_new_surface_listener(shell.ds_xdg_shell, &shell.new_surface);
 
-   cdata->sh_v6.res_role = resource;
-   cdata->sh_v6.role = role;
+   return EINA_TRUE;
 }
 
-static void
-_e_client_xdg_shell_v6_role_assingment_unset(E_Client *ec)
+EINTERN E_Client *
+e_xdg_shell_v6_xdg_surface_ec_get(struct wl_resource *resource)
 {
-   E_Comp_Wl_Client_Data *cdata;
-
-   if (!ec) return;
-   if (e_object_is_del(E_OBJECT(ec))) return;
-   cdata = e_client_cdata_get(ec);
-   if (!cdata) return;
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   _e_client_xdg_shell_v6_assign(ec, NULL, E_COMP_WL_SH_SURF_ROLE_NONE);
-}
+   toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(resource);
+   if (!toplevel)
+     {
+        ERR("No E_Xdg_Toplevel_V6 in wl_resource", NULL);
+        return NULL;
+     }
 
-static void
-_validate_size(struct wl_resource *resource, int32_t value)
-{
-   if (value <= 0)
-     wl_resource_post_error(resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, "Invalid size passed");
+   return toplevel->ec;
 }
-/* End of utility */
 
-/**********************************************************
- * Implementation for Xdg_popup
- **********************************************************/
 static void
-_e_xdg_popup_positioner_apply(E_Xdg_Popup *popup, E_Xdg_Positioner *pos)
+_e_xdg_shell_v6_cb_destroy(struct wl_listener *listener, void *data)
 {
-   popup->geometry = _e_xdg_positioner_geometry_get(pos);
+   E_Xdg_Shell_V6 *shell;
 
-   /* TODO apply geometry to popup */
+   LOG("Destroy Xdg_Shell_V6", NULL);
 
+   shell = wl_container_of(listener, shell, destroy);
+   wl_list_remove(&shell->destroy.link);
+   wl_list_remove(&shell->new_surface.link);
+   shell->ds_xdg_shell = NULL;
 }
 
 static void
-_e_xdg_popup_parent_set(E_Xdg_Popup *popup, E_Xdg_Surface *parent)
+_e_xdg_shell_v6_cb_new_surface(struct wl_listener *listener, void *data)
 {
-   E_Comp_Wl_Client_Data *parent_cdata;
-
-   popup->parent = parent;
-   parent_cdata = e_client_cdata_get(parent->ec);
+   struct ds_xdg_surface_v6 *ds_xdg_surface = data;
 
-   /* set this client as a transient for parent */
-   e_shell_e_client_parent_set(popup->base.ec, parent_cdata->surface);
+   if (ds_xdg_surface->role == DS_XDG_SURFACE_V6_ROLE_TOPLEVEL)
+     _e_xdg_toplevel_v6_add(ds_xdg_surface);
+   else
+     ERR("Not implemented: xdg_surface_v6(role:%d)", NULL, ds_xdg_surface->role);
 }
 
-static void
-_e_xdg_popup_set(E_Xdg_Popup *popup, struct wl_resource *resource)
+static E_Xdg_Toplevel_V6 *
+_e_xdg_toplevel_v6_from_shell_surface_resource(struct wl_resource *shsurface_resource)
 {
-   popup->resource = resource;
-   _e_client_xdg_shell_v6_assign(popup->base.ec, resource, E_COMP_WL_SH_SURF_ROLE_POPUP);
-   e_shell_e_client_popup_set(popup->base.ec);
-}
+   E_Xdg_Toplevel_V6 *toplevel;
+   struct ds_xdg_surface_v6 *ds_xdg_surface;
+   struct wl_listener *listener;
 
-static void
-_e_xdg_popup_committed(E_Xdg_Popup *popup)
-{
-   if (!popup->committed)
-     {
-        if (!popup->base.configure_idle)
-          {
-             popup->base.configure_idle =
-                ecore_idle_enterer_add(_e_xdg_surface_cb_configure_send, popup);
-          }
-     }
+   ds_xdg_surface = ds_xdg_surface_v6_from_resource(shsurface_resource);
+   if (!ds_xdg_surface)
+     return NULL;
 
-   popup->committed = EINA_TRUE;
+   listener = wl_signal_get(&ds_xdg_surface->events.destroy,
+                            _e_xdg_toplevel_v6_cb_xdg_surface_destroy);
+   if (listener)
+     return wl_container_of(listener, toplevel, destroy);
 
-   /* TODO: Weston does update the position of popup here */
+   return NULL;
 }
 
 static void
-_e_xdg_popup_configure_send(E_Xdg_Popup *popup)
+_e_xdg_toplevel_v6_fullscreen_send(E_Xdg_Toplevel_V6 *toplevel)
 {
-   if (!popup) return;
-   if (!popup->resource) return;
-
-   zxdg_popup_v6_send_configure(popup->resource,
-                                popup->geometry.x,
-                                popup->geometry.y,
-                                popup->geometry.w,
-                                popup->geometry.h);
-}
+   struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
+   E_Client *ec = toplevel->ec;
 
-static void
-_e_xdg_popup_cb_resource_destroy(struct wl_resource *resource)
-{
-   E_Xdg_Popup *popup;
+   if (ds_toplevel->scheduled.fullscreen == ec->fullscreen)
+     return;
 
-   popup = wl_resource_get_user_data(resource);
-   popup->resource = NULL;
-   _e_client_xdg_shell_v6_role_assingment_unset(popup->base.ec);
-   e_object_unref(E_OBJECT(popup));
-}
+   LOG("Send fullscreen(%d)", ec, ec->fullscreen);
 
-static void
-_e_xdg_popup_cb_destroy(struct wl_client *client, struct wl_resource *resource)
-{
-   wl_resource_destroy(resource);
+   ds_xdg_toplevel_v6_set_fullscreen(ds_toplevel, ec->fullscreen);
 }
 
 static void
-_e_xdg_popup_cb_grab(struct wl_client *client,
-                     struct wl_resource *resource,
-                     struct wl_resource *res_seat,
-                     uint32_t serial)
+_e_xdg_toplevel_v6_maximized_send(E_Xdg_Toplevel_V6 *toplevel)
 {
-   /* TODO no op */
-}
+   struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
+   E_Client *ec = toplevel->ec;
 
-static const struct zxdg_popup_v6_interface _e_xdg_popup_interface =
-{
-   _e_xdg_popup_cb_destroy,
-   _e_xdg_popup_cb_grab
-};
+   if (ds_toplevel->scheduled.maximized == !!ec->maximized)
+     return;
 
-/* End of Xdg_Popup */
+   LOG("Send maximized(%d)", ec, ec->maximized);
 
-/**********************************************************
- * Implementation for Xdg_toplevel
- ***********************************************************/
-static void
-_e_xdg_toplevel_set(E_Xdg_Toplevel *toplevel, struct wl_resource *resource)
-{
-   toplevel->resource = resource;
-   _e_client_xdg_shell_v6_assign(toplevel->base.ec, resource, E_COMP_WL_SH_SURF_ROLE_TOPLV);
-   e_shell_e_client_toplevel_set(toplevel->base.ec);
-   e_comp_wl_shell_surface_ready(toplevel->base.ec);
+   ds_xdg_toplevel_v6_set_maximized(ds_toplevel, ec->maximized);
 }
 
 static void
-_e_xdg_toplevel_committed(E_Xdg_Toplevel *toplevel)
+_e_xdg_toplevel_v6_resizing_send(E_Xdg_Toplevel_V6 *toplevel, Eina_Bool resizing)
 {
-   E_Client *ec;
-   E_Comp_Wl_Client_Data *cdata;
-   int pw, ph;
-
-   ec = toplevel->base.ec;
-   if (!ec)
-     {
-        ERR("E_Xdg_Toplevel must have E_Client", NULL);
-        return;
-     }
-
-   cdata = e_client_cdata_get(ec);
-   if (!cdata)
-     {
-        ERR("E_Client must have E_Comp_Wl_Client_Data", ec);
-        return;
-     }
-
-   if (!toplevel->resource)
-     {
-        ERR("E_Client must have xdg_toplevel instance", ec);
-        return;
-     }
-
-   if (!e_pixmap_usable_get(ec->pixmap))
-     {
-        ERR("E_Pixmap should be valid here", ec);
-        return;
-     }
-
-   e_pixmap_size_get(ec->pixmap, &pw, &ph);
+   struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
 
-   if ((toplevel->next.state.maximized || toplevel->next.state.fullscreen) &&
-        (toplevel->next.size.w != cdata->shell.window.w ||
-        toplevel->next.size.h != cdata->shell.window.h ||
-        toplevel->next.size.w != pw ||
-        toplevel->next.size.h != ph))
-     {
-        ERR("Xdg_surface buffer does not match the configured state\nmaximized: "
-            "%d fullscreen: %d, size:expected(%d %d) shell.request(%d %d) pixmap(%d %d)",
-            ec,
-            toplevel->next.state.maximized,
-            toplevel->next.state.fullscreen,
-            toplevel->next.size.w, toplevel->next.size.h,
-            cdata->shell.window.w, cdata->shell.window.h,
-            pw, ph);
-        /* TODO Disable this part for now, but need to consider enabling it later.
-         * To enable this part, we first need to ensure that do not send configure
-         * with argument of size as 0, and make client ensure that set
-         * window geometry correctly so that match its commit buffer size, if
-         * its state is maximize or fullscreen.
-         */
-        /*
-           wl_resource_post_error(toplevel->base.shell->resource,
-           ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
-           "xdg_surface buffer does not match the configured state");
-           return;
-           */
-     }
-   toplevel->current.state = toplevel->next.state;
-   toplevel->current.min_size = toplevel->next.min_size;
-   toplevel->current.max_size = toplevel->next.max_size;
+   if (ds_toplevel->scheduled.resizing == resizing)
+     return;
 
-   /* Now we can adjust size of its composite object corresponding client */
-   if (!ec->lock_client_size)
-      {
-         ec->icccm.min_w = toplevel->current.min_size.w;
-         ec->icccm.min_h = toplevel->current.min_size.h;
-         ec->icccm.max_w = toplevel->current.max_size.w;
-         ec->icccm.max_h = toplevel->current.max_size.h;
-      }
-}
+   LOG("Send resizing(%d)", toplevel->ec, resizing);
 
-static void
-_e_xdg_toplevel_configure_ack(E_Xdg_Toplevel *toplevel,
-                              E_Xdg_Surface_Configure *configure)
-{
-   LOG("Ack configure TOPLEVEL size (%d %d) "
-       "state (f %d m %d r %d a %d)",
-       toplevel->base.ec,
-       configure->size.w, configure->size.h,
-       configure->state.fullscreen, configure->state.maximized,
-       configure->state.resizing, configure->state.activated);
-
-   toplevel->next.state = configure->state;
-   toplevel->next.size = configure->size;
-   toplevel->base.wait_next_commit = EINA_TRUE;
+   ds_xdg_toplevel_v6_set_resizing(ds_toplevel, resizing);
 }
 
 static void
-_e_xdg_toplevel_configure_send(E_Xdg_Toplevel *toplevel,
-                               E_Xdg_Surface_Configure *configure)
+_e_xdg_toplevel_v6_activated_send(E_Xdg_Toplevel_V6 *toplevel)
 {
-   uint32_t *s;
-   struct wl_array states;
-   Eina_Bool array_added = EINA_FALSE;
-
-   if (!toplevel->resource) return;
-
-   configure->state = toplevel->pending.state;
-   configure->size = toplevel->pending.size;
-
-   wl_array_init(&states);
-   if (toplevel->pending.state.maximized)
-     {
-        s = wl_array_add(&states, sizeof(uint32_t));
-        if (!s) goto err;
-        array_added = EINA_TRUE;
-        *s = ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED;
-     }
-   if (toplevel->pending.state.fullscreen)
-     {
-        s = wl_array_add(&states, sizeof(uint32_t));
-        if (!s) goto err;
-        array_added = EINA_TRUE;
-        *s = ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN;
-     }
-   if (toplevel->pending.state.resizing)
-     {
-        s = wl_array_add(&states, sizeof(uint32_t));
-        if (!s) goto err;
-        array_added = EINA_TRUE;
-        *s = ZXDG_TOPLEVEL_V6_STATE_RESIZING;
-     }
-   if (toplevel->pending.state.activated)
-     {
-        s = wl_array_add(&states, sizeof(uint32_t));
-        if (!s) goto err;
-        *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED;
-     }
-
-   LOG("Send configure: Topevel size (%d %d) "
-       "state (f %d m %d r %d a %d)",
-       toplevel->base.ec,
-       toplevel->pending.size.w, toplevel->pending.size.h,
-       toplevel->pending.state.fullscreen, toplevel->pending.state.maximized,
-       toplevel->pending.state.resizing, toplevel->pending.state.activated);
-
-   zxdg_toplevel_v6_send_configure(toplevel->resource,
-                                   toplevel->pending.size.w,
-                                   toplevel->pending.size.h,
-                                   &states);
+   struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
+   E_Client *ec = toplevel->ec, *focused_ec;
+   Eina_Bool activated;
 
-   wl_array_release(&states);
+   focused_ec = e_client_focused_get();
+   activated = (focused_ec == ec);
 
-   // clear toplevel's pending size
-   toplevel->pending.size.w = 0;
-   toplevel->pending.size.h = 0;
+   if (ds_toplevel->scheduled.activated == activated)
+     return;
 
-   return;
+   LOG("Send activated(%d)", ec, activated);
 
-err:
-   ERR("Failed on adding item to states !",  toplevel->base.ec);
-   if (array_added) wl_array_release(&states);
-   return;
+   ds_xdg_toplevel_v6_set_activated(ds_toplevel, activated);
 }
 
 static void
-_e_xdg_toplevel_configure_pending_set(E_Xdg_Toplevel *toplevel,
-                                      uint32_t edges,
-                                      int32_t width,
-                                      int32_t height)
+_e_xdg_toplevel_v6_size_send(E_Xdg_Toplevel_V6 *toplevel, int32_t width, int32_t height)
 {
-   E_Client *ec, *focused;
+   E_Client *ec = toplevel->ec;
+   struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
+   int32_t configure_width = 0, configure_height = 0;
    int mw, mh;
 
-   ec = toplevel->base.ec;
-
-   toplevel->pending.state.fullscreen = ec->fullscreen;
-   toplevel->pending.state.maximized = !!ec->maximized;
-   toplevel->pending.state.resizing = !!edges;
-   toplevel->pending.edges = edges;
-   if ((width != -1) && (height != -1))
-     {
-        /* NOTE:
-         * Width and Height are -1 means that the configure event doesn't consider size value.
-         * So, we update pending size if the size are not -1.
-         */
-        toplevel->pending.size.w = width;
-        toplevel->pending.size.h = height;
-     }
-
    if (ec->fullscreen)
      {
         e_client_base_output_resolution_useful_geometry_get(ec, NULL, NULL, &mw, &mh);
         LOG("FORCELY STAY current fullscreen size (%d %d) of E_Client, requested size "
             "is (%d %d), the state (maximize %d, fullscreen %d)",
             ec, mw, mh, width, height, ec->maximized, ec->fullscreen);
-        toplevel->pending.size.w = mw;
-        toplevel->pending.size.h = mh;
+        configure_width = mw;
+        configure_height = mh;
      }
    else if (ec->maximized)
      {
-        /* NOTE
-         * DO NOT configure maximized or fullscreen surface to (0x0) size.
-         * If the width or height arguments are zero, it means the client should
-         * decide its own window dimension. See xdg-shell-v6.xml
-         */
         e_client_maximized_geometry_get(ec, NULL, NULL, &mw, &mh);
         LOG("FORCELY STAY current maximized size (%d %d) of E_Client, requested size "
             "is (%d %d), the state (maximize %d, fullscreen %d)",
-            ec, mw, mh, width, height,
-            toplevel->pending.state.maximized,
-            toplevel->pending.state.fullscreen);
-        toplevel->pending.size.w = mw;
-        toplevel->pending.size.h = mh;
-     }
-
-   focused = e_client_focused_get();
-   toplevel->pending.state.activated = (ec == focused);
-
-   LOG("Set pending state: edges %d size (%d %d) "
-       "state (f %d m %d r %d a %d)",
-       ec,
-       toplevel->pending.edges,
-       toplevel->pending.size.w, toplevel->pending.size.h,
-       toplevel->pending.state.fullscreen, toplevel->pending.state.maximized,
-       toplevel->pending.state.resizing, toplevel->pending.state.activated);
-}
-
-static Eina_Bool
-_e_xdg_toplevel_pending_state_compare(E_Xdg_Toplevel *toplevel)
-{
-   E_Xdg_Surface_Configure *configure;
-   int pw, ph;
-   int cw, ch;
-
-   struct {
-        E_Xdg_Toplevel_State state;
-        E_Xdg_Size size;
-   } configured;
-
-   /* must send configure at least once */
-   if (!toplevel->base.configured)
-     return EINA_FALSE;
-
-   if (!toplevel->base.configure_list)
-     {
-        /* if configure_list is empty, last configure is actually the current
-         * state */
-        e_pixmap_size_get(toplevel->base.ec->pixmap, &pw, &ph);
-        e_client_geometry_get(toplevel->base.ec, NULL, NULL, &cw, &ch);
-
-        if ((pw != cw) || (ph != ch))
-          {
-             ERR("The size of buffer is different with expected "
-                 "client size. So, here, let it compare with buffer size.",
-                 toplevel->base.ec);
-          }
-
-        configured.state = toplevel->current.state;
-        configured.size.w = pw;
-        configured.size.h = ph;
-     }
-   else
-     {
-        configure = eina_list_last_data_get(toplevel->base.configure_list);
-        configured.state = configure->state;
-        configured.size = configure->size;
+            ec, mw, mh, width, height, ec->maximized, ec->fullscreen);
+        configure_width = mw;
+        configure_height = mh;
      }
-
-   if (toplevel->pending.state.activated != configured.state.activated)
-     return EINA_FALSE;
-   if (toplevel->pending.state.fullscreen != configured.state.fullscreen)
-     return EINA_FALSE;
-   if (toplevel->pending.state.maximized != configured.state.maximized)
-     return EINA_FALSE;
-   if (toplevel->pending.state.resizing != configured.state.resizing)
-     return EINA_FALSE;
-
-   if ((toplevel->pending.size.w == configured.size.w) &&
-       (toplevel->pending.size.h == configured.size.h))
+   else if ((width != -1) && (height != -1))
      {
-        if (!toplevel->base.ec->changes.size)
-          return EINA_TRUE;
+        configure_width = width;
+        configure_height = height;
      }
 
-   if ((toplevel->pending.size.w == 0) &&
-       (toplevel->pending.size.h == 0))
-     return EINA_TRUE;
+   LOG("Send size(%dx%d)", ec, configure_width, configure_height);
 
-   return EINA_FALSE;
+   ds_xdg_toplevel_v6_set_size(ds_toplevel, configure_width, configure_height);
 }
 
 static void
-_e_xdg_toplevel_cb_resource_destroy(struct wl_resource *resource)
+_e_xdg_toplevel_v6_configure_send(struct wl_resource *shsurface_resource,
+                                  uint32_t edges, int32_t width, int32_t height)
 {
-   E_Xdg_Toplevel *toplevel;
+   E_Xdg_Toplevel_V6 *toplevel;
+
+   toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(shsurface_resource);
+   if (!toplevel)
+     return;
 
-   toplevel = wl_resource_get_user_data(resource);
-   toplevel->resource = NULL;
-   _e_client_xdg_shell_v6_role_assingment_unset(toplevel->base.ec);
-   e_object_unref(E_OBJECT(toplevel));
+   _e_xdg_toplevel_v6_fullscreen_send(toplevel);
+   _e_xdg_toplevel_v6_maximized_send(toplevel);
+   _e_xdg_toplevel_v6_resizing_send(toplevel, !!edges);
+   _e_xdg_toplevel_v6_size_send(toplevel, width, height);
+   _e_xdg_toplevel_v6_activated_send(toplevel);
 }
 
 static void
-_e_xdg_toplevel_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+_e_xdg_toplevel_v6_configure(struct wl_resource *shsurface_resource,
+                             Evas_Coord x, Evas_Coord y,
+                             Evas_Coord w, Evas_Coord h)
 {
-   wl_resource_destroy(resource);
+   E_Xdg_Toplevel_V6 *toplevel;
+
+   toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(shsurface_resource);
+   if (!toplevel)
+     return;
+
+   e_client_util_move_resize_without_frame(toplevel->ec, x, y, w, h);
 }
 
 static void
-_e_xdg_toplevel_cb_parent_set(struct wl_client *client,
-                              struct wl_resource *resource,
-                              struct wl_resource *res_parent)
+_e_xdg_toplevel_v6_ping(struct wl_resource *shsurface_resource)
 {
-   E_Xdg_Toplevel *toplevel, *parent;
-   E_Client *pc;
-   E_Comp_Wl_Client_Data *pc_cdata;
-   struct wl_resource *parent_wsurface = NULL;
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   toplevel = wl_resource_get_user_data(resource);
+   toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(shsurface_resource);
    if (!toplevel)
      return;
 
-   if (res_parent)
-     {
-        parent = wl_resource_get_user_data(res_parent);
-        if (!parent)
-          {
-             ERR("No E_Xdg_Toplevel data in wl_resource", NULL);
-             wl_resource_post_error(res_parent,
-                                    WL_DISPLAY_ERROR_INVALID_OBJECT,
-                                    "No E_Xdg_Toplevel data in wl_resource");
-
-             return;
-          }
-
-        pc = parent->base.ec;
-        if (!pc)
-          {
-             ERR("Toplevel must have E_Client", NULL);
-             wl_resource_post_error(res_parent,
-                                    WL_DISPLAY_ERROR_INVALID_OBJECT,
-                                    "No E_Client data in wl_resource");
-             return;
-          }
-
-        pc_cdata = e_client_cdata_get(pc);
-        if (!pc_cdata) return;
-
-        parent_wsurface = pc_cdata->surface;
-     }
-
-   /* set this client as a transient for parent */
-   e_shell_e_client_parent_set(toplevel->base.ec, parent_wsurface);
+   LOG("Ping", toplevel->ec);
 
-   EC_CHANGED(toplevel->base.ec);
+   ds_xdg_surface_v6_ping(toplevel->ds_toplevel->base);
 }
 
 static void
-_e_xdg_toplevel_cb_title_set(struct wl_client *client,
-                             struct wl_resource *resource,
-                             const char *title)
+_e_xdg_surface_v6_map(struct wl_resource *shsurface_resource)
 {
-   E_Xdg_Toplevel *toplevel;
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   toplevel = wl_resource_get_user_data(resource);
+   toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(shsurface_resource);
    if (!toplevel)
      return;
 
-   e_shell_e_client_name_title_set(toplevel->base.ec, title, title);
+   LOG("Map", toplevel->ec);
+
+   toplevel->ds_toplevel->base->mapped = true;
+   e_shell_e_client_map(toplevel->ec);
 }
 
 static void
-_e_xdg_toplevel_cb_app_id_set(struct wl_client *client,
-                              struct wl_resource *resource,
-                              const char *app_id)
+_e_xdg_toplevel_v6_unmap(struct wl_resource *shsurface_resource)
 {
-   E_Xdg_Toplevel *toplevel;
-   E_Client *ec;
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   toplevel = wl_resource_get_user_data(resource);
+   toplevel = _e_xdg_toplevel_v6_from_shell_surface_resource(shsurface_resource);
    if (!toplevel)
      return;
 
-   ec = toplevel->base.ec;
-   if (!ec)
-     {
-        ERR("Toplevel must have E_Client", NULL);
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Client data in wl_resource");
-        return;
-     }
-
-   /* use the wl_client to get the pid * and set it in the netwm props */
-   wl_client_get_credentials(client, &ec->netwm.pid, NULL, NULL);
+   LOG("Unmap", toplevel->ec);
 
-   e_shell_e_client_app_id_set(ec, app_id);
+   toplevel->ds_toplevel->base->mapped = false;
+   e_shell_e_client_unmap(toplevel->ec);
 }
 
-static void
-_e_xdg_toplevel_cb_win_menu_show(struct wl_client *client,
-                                 struct wl_resource *resource,
-                                 struct wl_resource *res_seat,
-                                 uint32_t serial,
-                                 int32_t x,
-                                 int32_t y)
-{
-   /* TODO no op */
-}
+static E_Shell_Surface_Api shell_xdg_toplevel_v6_api = {
+     .configure_send = _e_xdg_toplevel_v6_configure_send,
+     .configure = _e_xdg_toplevel_v6_configure,
+     .ping = _e_xdg_toplevel_v6_ping,
+     .map = _e_xdg_surface_v6_map,
+     .unmap = _e_xdg_toplevel_v6_unmap,
+};
 
 static void
-_e_xdg_toplevel_cb_move(struct wl_client *client,
-                        struct wl_resource *resource,
-                        struct wl_resource *res_seat,
-                        uint32_t serial)
+_e_xdg_toplevel_v6_role_init(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Toplevel *toplevel;
+   E_Client *ec = toplevel->ec;
+   struct ds_xdg_surface_v6 *ds_xdg_surface = toplevel->ds_toplevel->base;
+   E_Comp_Wl_Client_Data *cdata;
 
-   toplevel = wl_resource_get_user_data(resource);
-   if (!toplevel)
-     return;
+   e_shell_e_client_shsurface_assign(ec,
+                                     ds_xdg_surface->resource,
+                                     &shell_xdg_toplevel_v6_api);
 
-   if (!e_shell_e_client_interactive_move(toplevel->base.ec, res_seat))
+   cdata = e_client_cdata_get(ec);
+   if (cdata)
      {
-        ERR("Failed to move this Toplevel", NULL);
-        return;
+        cdata->sh_v6.res_role = toplevel->ds_toplevel->resource;
+        cdata->sh_v6.role = E_COMP_WL_SH_SURF_ROLE_TOPLV;
      }
+
+   e_shell_e_client_toplevel_set(ec);
+   e_comp_wl_shell_surface_ready(toplevel->ec);
 }
 
 static void
-_e_xdg_toplevel_cb_resize(struct wl_client *client,
-                          struct wl_resource *resource,
-                          struct wl_resource *res_seat,
-                          uint32_t serial,
-                          uint32_t edges)
+_e_xdg_toplevel_v6_client_parent_update(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Toplevel *toplevel;
-
-   toplevel = wl_resource_get_user_data(resource);
-   if (!toplevel)
-     return;
+   E_Client *ec = toplevel->ec;
+   struct ds_xdg_toplevel_v6 *parent = toplevel->ds_toplevel->parent;
+   struct wl_resource *parent_surface_resource = NULL;
 
-   if (!e_shell_e_client_interactive_resize(toplevel->base.ec, resource, res_seat, edges))
+   if (parent)
      {
-        ERR("Failed to resize this Toplevel", NULL);
-        return;
+        parent_surface_resource =
+           ds_surface_get_wl_resource(parent->base->ds_surface);
      }
+
+   LOG("Set parent: resource(%p)", ec, parent_surface_resource);
+
+   e_shell_e_client_parent_set(ec, parent_surface_resource);
+   EC_CHANGED(ec);
 }
 
 static void
-_e_xdg_toplevel_cb_max_size_set(struct wl_client *client,
-                                struct wl_resource *resource,
-                                int32_t w,
-                                int32_t h)
+_e_xdg_toplevel_v6_title_update(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Toplevel *toplevel;
+   E_Client *ec = toplevel->ec;
+   char *title = toplevel->ds_toplevel->title;
 
-   toplevel = wl_resource_get_user_data(resource);
-   if (!toplevel)
-     return;
+   LOG("Set title: %s", ec, title ? title : "(null)");
 
-   toplevel->next.max_size.w = w;
-   toplevel->next.max_size.h = h;
-   toplevel->base.wait_next_commit = EINA_TRUE;
+   e_shell_e_client_name_title_set(ec, title, title);
 }
 
 static void
-_e_xdg_toplevel_cb_min_size_set(struct wl_client *client,
-                                struct wl_resource *resource,
-                                int32_t w,
-                                int32_t h)
+_e_xdg_toplevel_v6_app_id_update(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Toplevel *toplevel;
+   E_Client *ec = toplevel->ec;
+   char *app_id = toplevel->ds_toplevel->app_id;
+   struct wl_client *client;
 
-   toplevel = wl_resource_get_user_data(resource);
-   if (!toplevel)
-     return;
+   client = wl_resource_get_client(toplevel->ds_toplevel->resource);
+   wl_client_get_credentials(client, &ec->netwm.pid, NULL, NULL);
 
-   toplevel->next.min_size.w = w;
-   toplevel->next.min_size.h = h;
-   toplevel->base.wait_next_commit = EINA_TRUE;
+   LOG("Set app_id: %s, PID(%d)", ec, app_id ? app_id : "(null)", ec->netwm.pid);
+
+   e_shell_e_client_app_id_set(ec, app_id);
 }
 
 static void
-_e_xdg_toplevel_cb_maximized_set(struct wl_client *client, struct wl_resource *resource)
+_e_xdg_toplevel_v6_move_begin(E_Xdg_Toplevel_V6 *toplevel, struct wl_resource *seat_resource)
 {
-   E_Xdg_Toplevel *toplevel;
-   E_Client *ec;
-   E_Maximize max;
+   E_Client *ec = toplevel->ec;
 
-   toplevel = wl_resource_get_user_data(resource);
-   if (!toplevel)
-     return;
+   LOG("Begin interactive move", ec);
 
-   ec = toplevel->base.ec;
-   if (!ec)
-     {
-        ERR("Toplevel must have E_Client", NULL);
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Client data in wl_resource");
-        return;
-     }
+   if (!e_shell_e_client_interactive_move(ec, seat_resource))
+     ERR("Failed to move this Toplevel(%p)", ec, toplevel);
+}
 
-   ELOGF("XDG6", "Toplevel Maximized Set. res:%p, lock_user_maximize:%d, dir:%d", ec, resource, ec->lock_user_maximize, ec->maximize_dir);
-   if (!ec->lock_user_maximize)
-     {
-        if ((ec->maximize_dir == E_MAXIMIZE_DIRECTION_ALL) || (ec->maximize_dir == E_MAXIMIZE_DIRECTION_NONE))
-          {
-             e_client_layout_apply(ec, EINA_FALSE);
+static void
+_e_xdg_toplevel_v6_resize_begin(E_Xdg_Toplevel_V6 *toplevel, struct wl_resource *seat_resource, uint32_t edges)
+{
+   E_Client *ec = toplevel->ec;
+   struct wl_resource *toplevel_resource = toplevel->ds_toplevel->resource;
 
-             max = ec->maximize_type | E_MAXIMIZE_BOTH;
-             e_client_maximize(ec, max);
-          }
-     }
+   LOG("Begin interactive resize", ec);
+
+   if (!e_shell_e_client_interactive_resize(ec, toplevel_resource, seat_resource, edges))
+     ERR("Failed to move this Toplevel(%p)", ec, toplevel);
 }
 
 static void
-_e_xdg_toplevel_cb_maximized_unset(struct wl_client *client, struct wl_resource *resource)
+_e_xdg_toplevel_v6_maximize_set(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Toplevel *toplevel;
-   E_Client *ec;
+   E_Client *ec = toplevel->ec;
+   E_Maximize max = ec->maximize_type | E_MAXIMIZE_BOTH;
 
-   toplevel = wl_resource_get_user_data(resource);
-   if (!toplevel)
+   LOG("Set maximize. lock_user_maximize:%d, dir:%d",
+       ec, ec->lock_user_maximize, ec->maximize_dir);
+
+   if (ec->lock_user_maximize)
      return;
 
-   ec = toplevel->base.ec;
-   if (!ec)
-     {
-        ERR("Toplevel must have E_Client", NULL);
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Client data in wl_resource");
-        return;
-     }
+   if ((ec->maximize_dir != E_MAXIMIZE_DIRECTION_ALL) &&
+       (ec->maximize_dir != E_MAXIMIZE_DIRECTION_NONE))
+     return;
 
    e_client_layout_apply(ec, EINA_FALSE);
+   e_client_maximize(ec, max);
+}
 
-   ELOGF("XDG6", "Toplevel Maximized Unset. res:%p, lock_user_maximize:%d", ec, resource, ec->lock_user_maximize);
+static void
+_e_xdg_toplevel_v6_maximize_unset(E_Xdg_Toplevel_V6 *toplevel)
+{
+   E_Client *ec = toplevel->ec;
+
+   LOG("Unset maximize. lock_user_maximize:%d", ec, ec->lock_user_maximize);
+
+   e_client_layout_apply(ec, EINA_FALSE);
 
    ec->maximize_dir = E_MAXIMIZE_DIRECTION_NONE;
    /* it's doubtful */
@@ -856,1250 +440,324 @@ _e_xdg_toplevel_cb_maximized_unset(struct wl_client *client, struct wl_resource
 }
 
 static void
-_e_xdg_toplevel_cb_fullscreen_set(struct wl_client *client,
-                                  struct wl_resource *resource,
-                                  struct wl_resource *res_output)
+_e_xdg_toplevel_v6_fullscreen_set(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Toplevel *toplevel;
-   E_Client *ec;
+   E_Client *ec = toplevel->ec;
 
-   toplevel = wl_resource_get_user_data(resource);
-   if (!toplevel)
-     return;
+   LOG("Set fullscreen. lock_user_fullscreen:%d", ec, ec->lock_user_fullscreen);
 
-   ec = toplevel->base.ec;
-   if (!ec)
-     {
-        ERR("Toplevel must have E_Client", NULL);
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Client data in wl_resource");
-        return;
-     }
+   if (ec->lock_user_fullscreen)
+     return;
 
-   ELOGF("XDG6", "Toplevel Fullscreen Set. res:%p, lock_user_fullscreen:%d", ec, resource, ec->lock_user_fullscreen);
-   if (!ec->lock_user_fullscreen)
-     e_client_fullscreen(ec, e_config->fullscreen_policy);
+   e_client_fullscreen(ec, e_config->fullscreen_policy);
 }
 
 static void
-_e_xdg_toplevel_cb_fullscreen_unset(struct wl_client *client, struct wl_resource *resource)
+_e_xdg_toplevel_v6_fullscreen_unset(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Toplevel *toplevel;
-   E_Client *ec;
+   E_Client *ec = toplevel->ec;
 
-   toplevel = wl_resource_get_user_data(resource);
-   if (!toplevel)
-     return;
+   LOG("Unset fullscreen. lock_user_fullscreen:%d", ec, ec->lock_user_fullscreen);
 
-   ec = toplevel->base.ec;
-   if (!ec)
-     {
-        ERR("Toplevel must have E_Client", NULL);
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Client data in wl_resource");
-        return;
-     }
+   if (ec->lock_user_fullscreen)
+     return;
 
-   ELOGF("XDG6", "Toplevel Fullscreen Unset. res:%p, lock_user_fullscreen:%d", ec, resource, ec->lock_user_fullscreen);
-   if (!ec->lock_user_fullscreen)
-     e_client_unfullscreen(ec);
+   e_client_unfullscreen(ec);
 }
 
 static void
-_e_xdg_toplevel_cb_minimized_set(struct wl_client *client, struct wl_resource *resource)
+_e_xdg_toplevel_v6_minimize_set(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Toplevel *toplevel;
-   E_Client *ec;
+   E_Client *ec = toplevel->ec;
 
-   toplevel = wl_resource_get_user_data(resource);
-   if (!toplevel)
-     return;
+   LOG("Set minimize. lock_client_iconify:%d", ec, ec->lock_client_iconify);
 
-   ec = toplevel->base.ec;
-   if (!ec)
-     {
-        ERR("Toplevel must have E_Client", NULL);
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Client data in wl_resource");
-        return;
-     }
+   if (ec->lock_client_iconify)
+     return;
 
-   ELOGF("XDG6", "Toplevel Minimized Set. res:%p, lock_client_iconify:%d", ec, resource, ec->lock_client_iconify);
-   if (!ec->lock_client_iconify)
-     e_client_iconify(ec);
+   e_client_iconify(ec);
 }
 
-static const struct zxdg_toplevel_v6_interface _e_xdg_toplevel_interface =
-{
-   _e_xdg_toplevel_cb_destroy,
-   _e_xdg_toplevel_cb_parent_set,
-   _e_xdg_toplevel_cb_title_set,
-   _e_xdg_toplevel_cb_app_id_set,
-   _e_xdg_toplevel_cb_win_menu_show,
-   _e_xdg_toplevel_cb_move,
-   _e_xdg_toplevel_cb_resize,
-   _e_xdg_toplevel_cb_max_size_set,
-   _e_xdg_toplevel_cb_min_size_set,
-   _e_xdg_toplevel_cb_maximized_set,
-   _e_xdg_toplevel_cb_maximized_unset,
-   _e_xdg_toplevel_cb_fullscreen_set,
-   _e_xdg_toplevel_cb_fullscreen_unset,
-   _e_xdg_toplevel_cb_minimized_set
-};
-
-/* End of Xdg_toplevel */
-
-/**********************************************************
- * Implementation for Xdg_Positioner
- **********************************************************/
-static Eina_Rectangle
-_e_xdg_positioner_geometry_get(E_Xdg_Positioner *p)
+static void
+_e_xdg_toplevel_v6_oldest_configure_remove(E_Xdg_Toplevel_V6 *toplevel)
 {
-   Eina_Rectangle geometry = {
-        .x = p->offset.x,
-        .y = p->offset.y,
-        .w = p->size.w,
-        .h = p->size.h,
-   };
-
-   if (p->anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP)
-     geometry.y += p->anchor_rect.y;
-   else if (p->anchor & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM)
-     geometry.y += p->anchor_rect.y + p->anchor_rect.h;
-   else
-     geometry.y += p->anchor_rect.y + p->anchor_rect.h / 2;
+   struct ds_xdg_surface_v6 *ds_xdg_surface;
+   struct ds_xdg_surface_v6_configure *oldest_configure;
+   const int WAIT_ACK_COUNT_MAX = 16;
 
-   if (p->anchor & ZXDG_POSITIONER_V6_ANCHOR_LEFT)
-     geometry.x += p->anchor_rect.x;
-   else if (p->anchor & ZXDG_POSITIONER_V6_ANCHOR_RIGHT)
-     geometry.x += p->anchor_rect.x + p->anchor_rect.w;
-   else
-     geometry.x += p->anchor_rect.x + p->anchor_rect.w / 2;
-
-   if (p->gravity & ZXDG_POSITIONER_V6_GRAVITY_TOP)
-     geometry.y -= geometry.h;
-   else if (!(p->gravity & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM))
-     geometry.y = geometry.h / 2;
-
-   if (p->gravity & ZXDG_POSITIONER_V6_GRAVITY_LEFT)
-     geometry.x -= geometry.w;
-   else if (!(p->gravity & ZXDG_POSITIONER_V6_GRAVITY_RIGHT))
-     geometry.x = geometry.w / 2;
+   ds_xdg_surface = toplevel->ds_toplevel->base;
+   if (wl_list_length(&ds_xdg_surface->configure_list) <= WAIT_ACK_COUNT_MAX)
+     return;
 
-   if (p->constraint_adjustment == ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_NONE)
-     return geometry;
+   oldest_configure = wl_container_of(ds_xdg_surface->configure_list.next,
+                                      oldest_configure,
+                                      link);
 
-   /* TODO: According to weston, add compositor policy configuration and the
-    * code here
-    */
+   LOG("Don't rececive Configure Ack. Remove oldest configure:%p, serial:%d",
+       toplevel->ec, oldest_configure, oldest_configure->serial);
 
-   return geometry;
+   wl_list_remove(&oldest_configure->link);
+   free(oldest_configure);
 }
 
-static Eina_Bool
-_e_xdg_positioner_validation_check(E_Xdg_Positioner *p)
+static void
+_e_xdg_toplevel_v6_window_geometry_update(E_Xdg_Toplevel_V6 *toplevel)
 {
-   return ((p->size.w != 0) && (p->anchor_rect.w != 0));
+   struct ds_xdg_surface_v6 *ds_xdg_surface = toplevel->ds_toplevel->base;
+   E_Comp_Wl_Client_Data *cdata;
+
+   cdata = e_client_cdata_get(toplevel->ec);
+   if (!cdata)
+     return;
+
+   EINA_RECTANGLE_SET(&cdata->shell.window,
+                      ds_xdg_surface->current.geometry.x,
+                      ds_xdg_surface->current.geometry.y,
+                      ds_xdg_surface->current.geometry.width,
+                      ds_xdg_surface->current.geometry.height);
 }
 
 static void
-_e_xdg_positioner_cb_resource_destroy(struct wl_resource *resource)
+_e_xdg_toplevel_v6_min_max_size_update(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Positioner *p;
-
-   p = wl_resource_get_user_data(resource);
-   EINA_SAFETY_ON_NULL_RETURN(p);
-
-   if (!p->shell)
-     goto finish;
+   E_Client *ec = toplevel->ec;
+   struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
 
-   p->shell->positioners = eina_list_remove(p->shell->positioners, p);
+   if (!ec->lock_client_size)
+     return;
 
-finish:
-   free(p);
+   ec->icccm.min_w = ds_toplevel->current.min_width;
+   ec->icccm.min_h = ds_toplevel->current.min_height;
+   ec->icccm.max_w = ds_toplevel->current.max_width;
+   ec->icccm.max_h = ds_toplevel->current.max_height;
 }
 
 static void
-_e_xdg_positioner_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+_e_xdg_toplevel_v6_cb_set_parent(struct wl_listener *listener, void *data)
 {
-   wl_resource_destroy(resource);
+   E_Xdg_Toplevel_V6 *toplevel;
+
+   toplevel = wl_container_of(listener, toplevel, set_parent);
+   _e_xdg_toplevel_v6_client_parent_update(toplevel);
 }
 
 static void
-_e_xdg_positioner_cb_size_set(struct wl_client *client,
-                              struct wl_resource *resource,
-                              int32_t w, int32_t h)
+_e_xdg_toplevel_v6_cb_set_title(struct wl_listener *listener, void *data)
 {
-   E_Xdg_Positioner *p;
-
-   _validate_size(resource, w);
-   _validate_size(resource, h);
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   p = wl_resource_get_user_data(resource);
-   p->size.w = w;
-   p->size.h = h;
+   toplevel = wl_container_of(listener, toplevel, set_title);
+   _e_xdg_toplevel_v6_title_update(toplevel);
 }
 
 static void
-_e_xdg_positioner_cb_anchor_rect_set(struct wl_client *client,
-                                     struct wl_resource *resource,
-                                     int32_t x, int32_t y, int32_t w, int32_t h)
+_e_xdg_toplevel_v6_cb_set_app_id(struct wl_listener *listener, void *data)
 {
-   E_Xdg_Positioner *p;
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   _validate_size(resource, w);
-   _validate_size(resource, h);
-
-   p = wl_resource_get_user_data(resource);
-   EINA_RECTANGLE_SET(&p->anchor_rect, x, y, w, h);
+   toplevel = wl_container_of(listener, toplevel, set_app_id);
+   _e_xdg_toplevel_v6_app_id_update(toplevel);
 }
 
 static void
-_e_xdg_positioner_cb_anchor_set(struct wl_client *client,
-                                struct wl_resource *resource,
-                                enum zxdg_positioner_v6_anchor anchor)
+_e_xdg_toplevel_v6_cb_request_move(struct wl_listener *listener, void *data)
 {
-   E_Xdg_Positioner *p;
+   E_Xdg_Toplevel_V6 *toplevel;
+   struct ds_xdg_toplevel_v6_event_request_move *event = data;
 
-   if ((anchor & (ZXDG_POSITIONER_V6_ANCHOR_TOP | ZXDG_POSITIONER_V6_ANCHOR_BOTTOM)) ==
-       (ZXDG_POSITIONER_V6_ANCHOR_TOP | ZXDG_POSITIONER_V6_ANCHOR_BOTTOM))
-     {
-        wl_resource_post_error(resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT,
-                               "Invalid anchor values passed");
-     }
-   else if ((anchor & (ZXDG_POSITIONER_V6_ANCHOR_LEFT | ZXDG_POSITIONER_V6_ANCHOR_RIGHT)) ==
-            (ZXDG_POSITIONER_V6_ANCHOR_LEFT | ZXDG_POSITIONER_V6_ANCHOR_RIGHT))
-     {
-        wl_resource_post_error(resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT,
-                               "Invalid anchor values passed");
-     }
-   else
-     {
-        p = wl_resource_get_user_data(resource);
-        p->anchor = anchor;
-     }
+   toplevel = wl_container_of(listener, toplevel, request_move);
+   _e_xdg_toplevel_v6_move_begin(toplevel, event->seat_resource);
 }
 
 static void
-_e_xdg_positioner_cb_gravity_set(struct wl_client *client,
-                                 struct wl_resource *resource,
-                                 enum zxdg_positioner_v6_gravity gravity)
+_e_xdg_toplevel_v6_cb_request_resize(struct wl_listener *listener, void *data)
 {
-   E_Xdg_Positioner *p;
+   E_Xdg_Toplevel_V6 *toplevel;
+   struct ds_xdg_toplevel_v6_event_request_resize *event = data;
 
-   if ((gravity & (ZXDG_POSITIONER_V6_GRAVITY_TOP | ZXDG_POSITIONER_V6_GRAVITY_BOTTOM)) ==
-       (ZXDG_POSITIONER_V6_GRAVITY_TOP | ZXDG_POSITIONER_V6_GRAVITY_BOTTOM))
-     {
-        wl_resource_post_error(resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT,
-                               "Invalid gravity values passed");
-     }
-   else if ((gravity & (ZXDG_POSITIONER_V6_GRAVITY_LEFT | ZXDG_POSITIONER_V6_GRAVITY_RIGHT)) ==
-            (ZXDG_POSITIONER_V6_GRAVITY_LEFT | ZXDG_POSITIONER_V6_GRAVITY_RIGHT))
-     {
-        wl_resource_post_error(resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT,
-                               "Invalid gravity values passed");
-     }
-   else
-     {
-        p = wl_resource_get_user_data(resource);
-        p->gravity = gravity;
-     }
-}
-
-static void
-_e_xdg_positioner_cb_constraint_adjustment_set(struct wl_client *client,
-                                               struct wl_resource *resource,
-                                               enum zxdg_positioner_v6_constraint_adjustment constraint_adjustment)
-{
-   E_Xdg_Positioner *p;
-
-   p = wl_resource_get_user_data(resource);
-   p->constraint_adjustment = constraint_adjustment;
+   toplevel = wl_container_of(listener, toplevel, request_resize);
+   _e_xdg_toplevel_v6_resize_begin(toplevel, event->seat_resource, event->edges);
 }
 
 static void
-_e_xdg_positioner_cb_offset_set(struct wl_client *client,
-                                struct wl_resource *resource,
-                                int32_t x, int32_t y)
-{
-   E_Xdg_Positioner *p;
-
-   p = wl_resource_get_user_data(resource);
-   p->offset.x = x;
-   p->offset.y = y;
-}
-
-static const struct zxdg_positioner_v6_interface _e_xdg_positioner_interface =
-{
-   _e_xdg_positioner_cb_destroy,
-   _e_xdg_positioner_cb_size_set,
-   _e_xdg_positioner_cb_anchor_rect_set,
-   _e_xdg_positioner_cb_anchor_set,
-   _e_xdg_positioner_cb_gravity_set,
-   _e_xdg_positioner_cb_constraint_adjustment_set,
-   _e_xdg_positioner_cb_offset_set,
-};
-
-/* End of Xdg_positioner */
-
-/**********************************************************
- * Implementation for Xdg_Surface
- **********************************************************/
-static const char *
-_e_xdg_surface_util_role_string_get(E_Xdg_Surface *exsurf)
-{
-   switch (exsurf->role)
-     {
-      case E_XDG_SURFACE_ROLE_TOPLEVEL:
-         return "TOPLEVEL";
-      case E_XDG_SURFACE_ROLE_POPUP:
-         return "POPUP";
-      default:
-      case E_XDG_SURFACE_ROLE_NONE:
-         return "NONE";
-     }
-}
-
-static Eina_Bool
-_e_xdg_surface_cb_configure_send(void *data)
+_e_xdg_toplevel_v6_cb_request_maximize(struct wl_listener *listener, void *data)
 {
-   E_Xdg_Surface *exsurf;
-   E_Xdg_Surface_Configure *configure;
-   Eina_Bool wait_ack = EINA_FALSE;
-
-   exsurf = data;
-
-   EINA_SAFETY_ON_NULL_GOTO(exsurf, end);
-   EINA_SAFETY_ON_NULL_GOTO(exsurf->ec, end);
-   EINA_SAFETY_ON_NULL_GOTO(e_client_cdata_get(exsurf->ec), end);
-   EINA_SAFETY_ON_NULL_GOTO(exsurf->resource, end);
-
-   if (e_object_is_del(E_OBJECT(exsurf->ec)))
-     goto end;
-
-   /* Make configure */
-   configure = E_NEW(E_Xdg_Surface_Configure, 1);
-   if (!configure)
-     {
-        ERR("Failed to allocate memory: E_Xdg_Surface_Configure", NULL);
-        goto end;
-     }
-
-   configure->serial = wl_display_next_serial(e_comp_wl->wl.disp);
-
-   switch (exsurf->role)
-     {
-      case E_XDG_SURFACE_ROLE_NONE:
-         ERR("Cannot reach here", NULL);
-         break;
-      case E_XDG_SURFACE_ROLE_POPUP:
-         _e_xdg_popup_configure_send((E_Xdg_Popup *)exsurf);
-         wait_ack = EINA_TRUE;
-         break;
-      case E_XDG_SURFACE_ROLE_TOPLEVEL:
-         _e_xdg_toplevel_configure_send((E_Xdg_Toplevel *)exsurf, configure);
-         wait_ack = EINA_TRUE;
-         break;
-     }
-
-   zxdg_surface_v6_send_configure(exsurf->resource, configure->serial);
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   LOG("Send configure: %s serial %d", exsurf->ec,
-       _e_xdg_surface_util_role_string_get(exsurf), configure->serial);
-
-   if (wait_ack)
-     {
-        if (eina_list_count(exsurf->configure_list) > WAIT_ACK_COUNT_MAX)
-          {
-             E_Xdg_Surface_Configure *oldest_configure = NULL;
-             oldest_configure = eina_list_nth(exsurf->configure_list, 0);
-             if (oldest_configure)
-               {
-                  ELOGF("XDG6", "Don't receive Configure Ack. Remove oldest configure:%p, serial:%d",
-                        exsurf->ec, oldest_configure, oldest_configure->serial);
-                  exsurf->configure_list = eina_list_remove(exsurf->configure_list, oldest_configure);
-                  E_FREE(oldest_configure);
-               }
-          }
-        exsurf->configure_list = eina_list_append(exsurf->configure_list, configure);
-     }
+   toplevel = wl_container_of(listener, toplevel, request_maximize);
+   if (toplevel->ds_toplevel->requested.maximized)
+     _e_xdg_toplevel_v6_maximize_set(toplevel);
    else
-     E_FREE(configure);
-
-end:
-   if (exsurf)
-     exsurf->configure_idle = NULL;
-
-   return ECORE_CALLBACK_DONE;
+     _e_xdg_toplevel_v6_maximize_unset(toplevel);
 }
 
 static void
-_e_xdg_surface_configure_send(struct wl_resource *resource,
-                              uint32_t edges,
-                              int32_t width,
-                              int32_t height)
+_e_xdg_toplevel_v6_cb_request_fullscreen(struct wl_listener *listener, void *data)
 {
-   E_Xdg_Surface *exsurf;
-   Eina_Bool pending_same = EINA_FALSE;
-
-   EINA_SAFETY_ON_NULL_RETURN(resource);
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        ERR("Invalid wl_resource", NULL);
-        return;
-     }
-
-   LOG("Scheduling task to send configure %s edges %d w %d h %d",
-       exsurf->ec,
-       _e_xdg_surface_util_role_string_get(exsurf), edges, width, height);
-
-   switch (exsurf->role)
-     {
-      case E_XDG_SURFACE_ROLE_NONE:
-      default:
-         ERR("Cannot reach here", exsurf->ec);
-         break;
-      case E_XDG_SURFACE_ROLE_TOPLEVEL:
-         _e_xdg_toplevel_configure_pending_set((E_Xdg_Toplevel *)exsurf,
-                                               edges, width, height);
-
-         pending_same = _e_xdg_toplevel_pending_state_compare((E_Xdg_Toplevel *)exsurf);
-         if (pending_same)
-           {
-              LOG("\tSKIP Configuring state is same with current state",
-                  exsurf->ec);
-           }
-         break;
-      case E_XDG_SURFACE_ROLE_POPUP:
-         break;
-     }
-
-   if (exsurf->configure_idle)
-     {
-        if (!pending_same)
-          return;
-
-        LOG("\tRemove configure idler", exsurf->ec);
-
-        E_FREE_FUNC(exsurf->configure_idle, ecore_idle_enterer_del);
-     }
+   toplevel = wl_container_of(listener, toplevel, request_fullscreen);
+   if (toplevel->ds_toplevel->requested.fullscreen)
+     _e_xdg_toplevel_v6_fullscreen_set(toplevel);
    else
-     {
-        if (pending_same)
-          return;
-
-        exsurf->configure_idle =
-           ecore_idle_enterer_add(_e_xdg_surface_cb_configure_send, exsurf);
-
-        LOG("\tAdd configure idler %p",
-            exsurf->ec, exsurf->configure_idle);
-     }
-}
-
-static void
-_e_xdg_surface_configure(struct wl_resource *resource,
-                         Evas_Coord x, Evas_Coord y,
-                         Evas_Coord w, Evas_Coord h)
-{
-   E_Xdg_Surface *exsurf;
-
-   EINA_SAFETY_ON_NULL_RETURN(resource);
-
-   /* get the client for this resource */
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        ERR("No E_Xdg_Surface data in wl_resource", NULL);
-        return;
-     }
-
-   if (!exsurf->configured)
-     {
-        // any attempts by a client to attach or manipulate a buffer prior to the first xdg_surface.configure call must
-        // be treated as errors.
-        ERR("Could not handle %s prior to the first xdg_surface.configure",
-            exsurf->ec,
-            _e_xdg_surface_util_role_string_get(exsurf));
-
-        E_Client *provider_ec = NULL;
-        provider_ec = e_comp_wl_remote_surface_bound_provider_ec_get(exsurf->ec);
-        if (!provider_ec)
-          return;
-
-        ERR("This is bound the remote surface provider. So, set configure_ack by force", exsurf->ec);
-        exsurf->configured = EINA_TRUE;
-     }
-
-   EINA_RECTANGLE_SET(&exsurf->configured_geometry, x, y, w, h);
-
-   e_client_util_move_resize_without_frame(exsurf->ec, x, y, w, h);
-}
-
-static void
-_e_xdg_surface_ping(struct wl_resource *resource)
-{
-   E_Xdg_Surface *exsurf;
-
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        ERR("No E_Xdg_Surface data in wl_resource", NULL);
-        return;
-     }
-
-   if (e_object_is_del(E_OBJECT(exsurf->ec)))
-     return;
-
-   _e_xdg_shell_ping(exsurf->shell);
-}
-
-static void
-_e_xdg_surface_map(struct wl_resource *resource)
-{
-   E_Xdg_Surface *exsurf;
-
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        ERR("No E_Xdg_Surface in wl_resource", NULL);
-        return;
-     }
-
-   e_shell_e_client_map(exsurf->ec);
-}
-
-static void
-_e_xdg_surface_unmap(struct wl_resource *resource)
-{
-   E_Xdg_Surface *exsurf;
-
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        ERR("No E_Xdg_Surface in wl_resource", NULL);
-        return;
-     }
-
-   e_shell_e_client_unmap(exsurf->ec);
-}
-
-static Eina_Bool
-_e_xdg_surface_role_assign(E_Xdg_Surface *exsurf,
-                           struct wl_resource *resource,
-                           E_Xdg_Surface_Role role)
-{
-   E_Shell_Surface_Api api = {
-        .configure_send = _e_xdg_surface_configure_send,
-        .configure = _e_xdg_surface_configure,
-        .ping = _e_xdg_surface_ping,
-        .map = _e_xdg_surface_map,
-        .unmap = _e_xdg_surface_unmap,
-   };
-
-   if (_e_client_xdg_shell_v6_assigned_check(exsurf->ec))
-     {
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Client already has shell resource");
-        return EINA_FALSE;
-     }
-
-   exsurf->role = role;
-
-   e_shell_e_client_shsurface_api_set(exsurf->ec, &api);
-
-   switch (role)
-     {
-      case E_XDG_SURFACE_ROLE_NONE:
-      default:
-         ERR("Cannot reach here", exsurf->ec);
-         return EINA_FALSE;
-
-      case E_XDG_SURFACE_ROLE_TOPLEVEL:
-         _e_xdg_toplevel_set((E_Xdg_Toplevel *)exsurf, resource);
-         break;
-
-      case E_XDG_SURFACE_ROLE_POPUP:
-         _e_xdg_popup_set((E_Xdg_Popup *)exsurf, resource);
-         break;
-     }
-
-   return EINA_TRUE;
-}
-
-static void
-_e_xdg_surface_cb_destroy(struct wl_client *client, struct wl_resource *resource)
-{
-   wl_resource_destroy(resource);
-}
-
-static void
-_e_xdg_surface_cb_toplevel_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
-{
-   E_Xdg_Surface *exsurf;
-   struct wl_resource *toplevel_resource;
-
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Xdg_Surface data in wl_resource");
-        return;
-     }
-
-   toplevel_resource = wl_resource_create(client, &zxdg_toplevel_v6_interface, 1, id);
-   if (!toplevel_resource)
-     {
-        ERR("Could not create xdg toplevel resource", NULL);
-        wl_resource_post_no_memory(resource);
-        return;
-     }
-
-   wl_resource_set_implementation(toplevel_resource,
-                                  &_e_xdg_toplevel_interface,
-                                  exsurf,
-                                  _e_xdg_toplevel_cb_resource_destroy);
-
-   if (!_e_xdg_surface_role_assign(exsurf, toplevel_resource, E_XDG_SURFACE_ROLE_TOPLEVEL))
-     {
-        ERR("Failed to assign TOPLEVEL role", exsurf->ec);
-        wl_resource_destroy(toplevel_resource);
-        return;
-     }
-
-   e_object_ref(E_OBJECT(exsurf));
-}
-
-static void
-_e_xdg_surface_cb_popup_get(struct wl_client *client,
-                            struct wl_resource *resource,
-                            uint32_t id,
-                            struct wl_resource *res_parent,
-                            struct wl_resource *res_pos)
-{
-   struct wl_resource *popup_resource;
-   E_Xdg_Surface *exsurf, *parent;
-   E_Xdg_Positioner *p;
-
-   if (!res_parent)
-     {
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "Popup requires a parent shell surface");
-        return;
-     }
-
-   parent = wl_resource_get_user_data(res_parent);
-   if (!parent)
-     {
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "xdg_popup must have parent");
-        return;
-     }
-
-   p = wl_resource_get_user_data(res_pos);
-   if (!p)
-     {
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "invalid positioner");
-        return;
-     }
-
-   if (!_e_xdg_positioner_validation_check(p))
-     {
-        wl_resource_post_error(resource,
-                               ZXDG_SHELL_V6_ERROR_INVALID_POSITIONER,
-                               "invalid positioner");
-        return;
-     }
-
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Xdg_Popup data in wl_resource");
-        return;
-     }
-
-   popup_resource = wl_resource_create(client, &zxdg_popup_v6_interface, 1, id);
-   if (!popup_resource)
-     {
-        ERR("Could not create xdg popup resource", NULL);
-        wl_resource_post_no_memory(resource);
-        return;
-     }
-
-   wl_resource_set_implementation(popup_resource,
-                                  &_e_xdg_popup_interface,
-                                  exsurf,
-                                  _e_xdg_popup_cb_resource_destroy);
-
-
-   if (!_e_xdg_surface_role_assign(exsurf, popup_resource, E_XDG_SURFACE_ROLE_POPUP))
-     {
-        ERR("Failed to assign role to surface", exsurf->ec);
-        wl_resource_destroy(popup_resource);
-        return;
-     }
-
-   _e_xdg_popup_parent_set((E_Xdg_Popup *)exsurf, parent);
-   _e_xdg_popup_positioner_apply((E_Xdg_Popup *)exsurf, p);
-
-   e_object_ref(E_OBJECT(exsurf));
-}
-
-static void
-_e_xdg_surface_cb_win_geometry_set(struct wl_client *client,
-                                   struct wl_resource *resource,
-                                   int32_t x,
-                                   int32_t y,
-                                   int32_t w,
-                                   int32_t h)
-{
-   E_Xdg_Surface *exsurf;
-
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Xdg_Surface data in wl_resource");
-        return;
-     }
-
-   LOG("Set window geometry: geometry(%d %d %d %d)",
-       exsurf->ec, x, y, w, h);
-
-   exsurf->has_window_geometry = EINA_TRUE;
-   EINA_RECTANGLE_SET(&exsurf->window_geometry, x, y, w, h);
-
-   exsurf->wait_next_commit = EINA_TRUE;
+     _e_xdg_toplevel_v6_fullscreen_unset(toplevel);
 }
 
 static void
-_e_xdg_surface_cb_configure_ack(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
+_e_xdg_toplevel_v6_cb_request_minimize(struct wl_listener *listener, void *data)
 {
-   E_Xdg_Surface *exsurf;
-   E_Xdg_Surface_Configure *configure;
-   Eina_List *l, *ll;
-   Eina_Bool found = EINA_FALSE;
-
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Xdg_Surface data in wl_surface");
-        return;
-     }
-
-   LOG("Ack configure", exsurf->ec);
-
-   if ((exsurf->role != E_XDG_SURFACE_ROLE_TOPLEVEL) &&
-       (exsurf->role != E_XDG_SURFACE_ROLE_POPUP))
-     {
-        wl_resource_post_error(resource,
-                               ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
-                               "xdg_surface must have a role");
-        return;
-     }
-
-   EINA_LIST_FOREACH_SAFE(exsurf->configure_list, l, ll, configure)
-     {
-        if (configure->serial < serial)
-          {
-             exsurf->configure_list =
-                eina_list_remove_list(exsurf->configure_list, l);
-             free(configure);
-          }
-        else if (configure->serial == serial)
-          {
-             exsurf->configure_list =
-                eina_list_remove_list(exsurf->configure_list, l);
-             found = EINA_TRUE;
-             break;
-          }
-        else
-          break;
-     }
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   LOG("Ack configure %s first %d serial %d found %d",
-       exsurf->ec,
-       _e_xdg_surface_util_role_string_get(exsurf),
-       !exsurf->configured,
-       serial, found);
-
-   if (!found)
-     {
-        wl_resource_post_error(exsurf->shell->resource,
-                               ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
-                               "Wrong configure serial: %u", serial);
-        return;
-     }
-
-   exsurf->configured = EINA_TRUE;
-
-   switch (exsurf->role)
-     {
-      case E_XDG_SURFACE_ROLE_NONE:
-         ERR("Cannot reach here", exsurf->ec);
-         break;
-      case E_XDG_SURFACE_ROLE_TOPLEVEL:
-         _e_xdg_toplevel_configure_ack((E_Xdg_Toplevel *)exsurf, configure);
-         break;
-      case E_XDG_SURFACE_ROLE_POPUP:
-         break;
-     }
-
-   E_FREE_FUNC(configure, free);
+   toplevel = wl_container_of(listener, toplevel, request_minimize);
+   _e_xdg_toplevel_v6_minimize_set(toplevel);
 }
 
-static const struct zxdg_surface_v6_interface _e_xdg_surface_interface =
-{
-   _e_xdg_surface_cb_destroy,
-   _e_xdg_surface_cb_toplevel_get,
-   _e_xdg_surface_cb_popup_get,
-   _e_xdg_surface_cb_win_geometry_set,
-   _e_xdg_surface_cb_configure_ack
-};
-
 static void
-_e_xdg_surface_cb_commit(void *data, E_Client *ec)
+_e_xdg_toplevel_v6_cb_xdg_surface_configure(struct wl_listener *listener, void *data)
 {
-   E_Xdg_Surface *exsurf;
-   E_Comp_Wl_Client_Data *exsurf_cdata;
-
-   exsurf = (E_Xdg_Surface *)data;
-
-   if (exsurf->ec != ec)
-     return;
-
-   if (!exsurf->wait_next_commit)
-     return;
-
-   LOG("Wl_Surface Commit, Update Xdg_Surface state %s",
-       exsurf->ec,
-       _e_xdg_surface_util_role_string_get(exsurf));
-
-   exsurf->wait_next_commit = EINA_FALSE;
-
-   if (exsurf->has_window_geometry)
-     {
-        exsurf->has_window_geometry = EINA_FALSE;
-        exsurf_cdata = e_client_cdata_get(exsurf->ec);
-        EINA_RECTANGLE_SET(&exsurf_cdata->shell.window,
-                           exsurf->window_geometry.x,
-                           exsurf->window_geometry.y,
-                           exsurf->window_geometry.w,
-                           exsurf->window_geometry.h);
-     }
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   switch (exsurf->role)
-     {
-      case E_XDG_SURFACE_ROLE_NONE:
-         wl_resource_post_error(exsurf->resource,
-                                ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
-                                "xdg_surface must have a role");
-         break;
-      case E_XDG_SURFACE_ROLE_TOPLEVEL:
-         _e_xdg_toplevel_committed((E_Xdg_Toplevel *)exsurf);
-         break;
-      case E_XDG_SURFACE_ROLE_POPUP:
-         _e_xdg_popup_committed((E_Xdg_Popup *)exsurf);
-         break;
-     }
+   toplevel = wl_container_of(listener, toplevel, configure);
+   _e_xdg_toplevel_v6_oldest_configure_remove(toplevel);
 }
 
 static void
-_e_xdg_surface_free(E_Xdg_Surface *exsurf)
+_e_xdg_toplevel_v6_cb_ping_timeout(struct wl_listener *listener, void *data)
 {
-   free(exsurf);
+   // This is intentionally left blank.
 }
 
 static void
-_e_xdg_surface_del(E_Xdg_Surface *exsurf)
+_e_xdg_toplevel_v6_cb_surface_commit(struct wl_listener *listener, void *data)
 {
-   _e_xdg_shell_surface_remove(exsurf->shell, exsurf);
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   E_FREE_LIST(exsurf->configure_list, free);
-   if (exsurf->configure_idle)
-     ecore_idle_enterer_del(exsurf->configure_idle);
-   if (exsurf->commit_hook)
-     e_comp_wl_hook_del(exsurf->commit_hook);
+   toplevel = wl_container_of(listener, toplevel, surface_commit);
+   _e_xdg_toplevel_v6_window_geometry_update(toplevel);
+   _e_xdg_toplevel_v6_min_max_size_update(toplevel);
 }
 
 static void
-_e_xdg_surface_cb_resource_destroy(struct wl_resource *resource)
+_e_xdg_toplevel_v6_listener_init(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Surface *exsurf;
-
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        ERR("No E_Xdg_Surface data in wl_resource", NULL);
-        return;
+   struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
+   struct ds_xdg_surface_v6 *ds_xdg_surface = toplevel->ds_toplevel->base;
+   struct ds_surface *ds_surface = ds_xdg_surface->ds_surface;
 
-     }
-
-   LOG("Destroy resource of Xdg_Surface %s",
-       exsurf->ec,
-       _e_xdg_surface_util_role_string_get(exsurf));
-
-   /* Although zxdg_toplevel_v6 or zxdg_popup_v6 are still existed, unset
-    * assignment at here anyway. once zxdg_surface_v6 is destroyed, the
-    * attribute 'toplevel and popup' is no longer meaningful. */
-   _e_client_xdg_shell_v6_role_assingment_unset(exsurf->ec);
-
-   e_shell_e_client_destroy(exsurf->ec);
-   /* set null after destroying shell of e_client, ec will be freed */
-   exsurf->ec = NULL;
-
-   e_object_del(E_OBJECT(exsurf));
+   toplevel->set_parent.notify = _e_xdg_toplevel_v6_cb_set_parent;
+   ds_xdg_toplevel_v6_add_set_parent_listener(ds_toplevel, &toplevel->set_parent);
+   toplevel->set_title.notify = _e_xdg_toplevel_v6_cb_set_title;
+   ds_xdg_toplevel_v6_add_set_title_listener(ds_toplevel, &toplevel->set_title);
+   toplevel->set_app_id.notify = _e_xdg_toplevel_v6_cb_set_app_id;
+   ds_xdg_toplevel_v6_add_set_app_id_listener(ds_toplevel, &toplevel->set_app_id);
+   toplevel->request_move.notify = _e_xdg_toplevel_v6_cb_request_move;
+   ds_xdg_toplevel_v6_add_request_move_listener(ds_toplevel, &toplevel->request_move);
+   toplevel->request_resize.notify = _e_xdg_toplevel_v6_cb_request_resize;
+   ds_xdg_toplevel_v6_add_request_resize_listener(ds_toplevel, &toplevel->request_resize);
+   toplevel->request_maximize.notify = _e_xdg_toplevel_v6_cb_request_maximize;
+   ds_xdg_toplevel_v6_add_request_maximize_listener(ds_toplevel, &toplevel->request_maximize);
+   toplevel->request_fullscreen.notify = _e_xdg_toplevel_v6_cb_request_fullscreen;
+   ds_xdg_toplevel_v6_add_request_fullscreen_listener(ds_toplevel, &toplevel->request_fullscreen);
+   toplevel->request_minimize.notify = _e_xdg_toplevel_v6_cb_request_minimize;
+   ds_xdg_toplevel_v6_add_request_minimize_listener(ds_toplevel, &toplevel->request_minimize);
+   toplevel->destroy.notify = _e_xdg_toplevel_v6_cb_xdg_surface_destroy;
+   ds_xdg_surface_v6_add_destroy_listener(ds_xdg_surface, &toplevel->destroy);
+   toplevel->configure.notify = _e_xdg_toplevel_v6_cb_xdg_surface_configure;
+   ds_xdg_surface_v6_add_configure_listener(ds_xdg_surface, &toplevel->configure);
+   toplevel->ping_timeout.notify = _e_xdg_toplevel_v6_cb_ping_timeout;
+   ds_xdg_surface_v6_add_ping_timeout_listener(ds_xdg_surface, &toplevel->ping_timeout);
+   toplevel->surface_commit.notify = _e_xdg_toplevel_v6_cb_surface_commit;
+   ds_surface_add_commit_listener(ds_surface, &toplevel->surface_commit);
 }
 
-static E_Xdg_Surface *
-_e_xdg_surface_create(E_Xdg_Shell *shell,
-                      struct wl_resource *wsurface,
-                      uint32_t id)
-{
-   E_Xdg_Surface *exsurf;
-   E_Client *ec;
-
-   ec = e_client_from_surface_resource(wsurface);
-   if (!ec)
-     {
-        ERR("No E_Client data in wl_resource", NULL);
-        wl_resource_post_error(wsurface,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No data in wl_resource");
-        return NULL;
-     }
-
-   LOG("Create Xdg_Surface", ec);
-
-   if (!_e_client_shsurface_assignable_check(ec))
-     {
-        ERR("Cannot get xdg_surface with this wl_surface", ec);
-        return NULL;
-     }
-
-   exsurf = E_OBJECT_ALLOC(e_xdg_surface_role_biggest_struct,
-                           E_XDG_SURFACE_V6_TYPE,
-                           _e_xdg_surface_free);
-   if (!exsurf)
-     {
-        wl_client_post_no_memory(shell->wclient);
-        return NULL;
-     }
-   e_object_del_func_set(E_OBJECT(exsurf), E_OBJECT_CLEANUP_FUNC(_e_xdg_surface_del));
-
-   exsurf->resource = wl_resource_create(shell->wclient,
-                                         &zxdg_surface_v6_interface,
-                                         1,
-                                         id);
-   if (!exsurf->resource)
-     {
-        ERR("Could not create wl_resource for xdg surface", ec);
-        wl_client_post_no_memory(shell->wclient);
-        e_object_del(E_OBJECT(exsurf));
-        return NULL;
-     }
-
-   wl_resource_set_implementation(exsurf->resource,
-                                  &_e_xdg_surface_interface,
-                                  exsurf,
-                                  _e_xdg_surface_cb_resource_destroy);
-
-   e_shell_e_client_shsurface_assign(ec, exsurf->resource, NULL);
-
-   exsurf->shell = shell;
-   exsurf->ec = ec;
-   exsurf->configured = EINA_FALSE;
-   exsurf->commit_hook =
-      e_comp_wl_hook_add(E_COMP_WL_HOOK_CLIENT_SURFACE_COMMIT,
-                         _e_xdg_surface_cb_commit,
-                         exsurf);
-
-   _e_xdg_shell_surface_add(shell, exsurf);
-
-   // base_output_resolution.
-   e_client_base_output_resolution_update(ec);
-
-   return exsurf;
-}
-/* End of Xdg_surface */
-
-/**********************************************************
- * Implementation for Xdg_Shell
- **********************************************************/
 static void
-_e_xdg_shell_surface_add(E_Xdg_Shell *shell, E_Xdg_Surface *exsurf)
+_e_xdg_toplevel_v6_listener_finish(E_Xdg_Toplevel_V6 *toplevel)
 {
-   if (!shell) return;
-   shell->surfaces = eina_list_append(shell->surfaces, exsurf);
+   wl_list_remove(&toplevel->set_parent.link);
+   wl_list_remove(&toplevel->set_title.link);
+   wl_list_remove(&toplevel->set_app_id.link);
+   wl_list_remove(&toplevel->request_move.link);
+   wl_list_remove(&toplevel->request_resize.link);
+   wl_list_remove(&toplevel->request_maximize.link);
+   wl_list_remove(&toplevel->request_fullscreen.link);
+   wl_list_remove(&toplevel->request_minimize.link);
+   wl_list_remove(&toplevel->destroy.link);
+   wl_list_remove(&toplevel->configure.link);
+   wl_list_remove(&toplevel->ping_timeout.link);
+   wl_list_remove(&toplevel->surface_commit.link);
 }
 
 static void
-_e_xdg_shell_surface_remove(E_Xdg_Shell *shell, E_Xdg_Surface *exsurf)
+_e_xdg_toplevel_v6_init(E_Xdg_Toplevel_V6 *toplevel)
 {
-   if (!shell) return;
-   shell->surfaces = eina_list_remove(shell->surfaces, exsurf);
-}
+   struct ds_xdg_toplevel_v6 *ds_toplevel = toplevel->ds_toplevel;
 
-static void
-_e_xdg_shell_ping(E_Xdg_Shell *shell)
-{
-   EINA_SAFETY_ON_NULL_RETURN(shell);
-   EINA_SAFETY_ON_NULL_RETURN(shell->resource);
+   _e_xdg_toplevel_v6_title_update(toplevel);
+   _e_xdg_toplevel_v6_app_id_update(toplevel);
 
-   if (shell->ping_serial != 0)
-     return;
+   if (ds_toplevel->requested.maximized)
+     _e_xdg_toplevel_v6_maximize_set(toplevel);
 
-   ELOGF("XDG6", "Ping. res:%p", NULL, shell->resource);
-   shell->ping_serial = wl_display_next_serial(e_comp_wl->wl.disp);
-   zxdg_shell_v6_send_ping(shell->resource, shell->ping_serial);
-}
+   if (ds_toplevel->requested.fullscreen)
+     _e_xdg_toplevel_v6_fullscreen_set(toplevel);
 
-static void
-_e_xdg_shell_cb_destroy(struct wl_client *client, struct wl_resource *resource)
-{
-   LOG("Destroy Xdg_Shell", NULL);
-
-   wl_resource_destroy(resource);
-}
-
-static void
-_e_xdg_shell_cb_positioner_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
-{
-   E_Xdg_Shell *shell;
-   E_Xdg_Positioner *p;
-   struct wl_resource *new_res;
-
-   LOG("Create Positioner", NULL);
-
-   shell = wl_resource_get_user_data(resource);
-   if (!shell)
-     {
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No resource for xdg_shell_v6");
-        return;
-     }
-
-   new_res = wl_resource_create(client, &zxdg_positioner_v6_interface, 1, id);
-   if (!new_res)
-     {
-        wl_resource_post_no_memory(resource);
-        return;
-     }
-
-   p = E_NEW(E_Xdg_Positioner, 1);
-   if (!p)
-     {
-        wl_resource_destroy(new_res);
-        wl_resource_post_no_memory(resource);
-        return;
-     }
-   p->shell = shell;
-   p->resource = new_res;
-
-   shell->positioners = eina_list_append(shell->positioners, p);
-
-   wl_resource_set_implementation(new_res,
-                                  &_e_xdg_positioner_interface,
-                                  p,
-                                  _e_xdg_positioner_cb_resource_destroy);
+   _e_xdg_toplevel_v6_role_init(toplevel);
 }
 
 static void
-_e_xdg_shell_cb_surface_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *wsurface)
+_e_xdg_toplevel_v6_finish(E_Xdg_Toplevel_V6 *toplevel)
 {
-   E_Xdg_Shell *shell;
-   E_Xdg_Surface *exsurf;
+   E_Client *ec = toplevel->ec;
+   E_Comp_Wl_Client_Data *cdata;
 
-   shell = wl_resource_get_user_data(resource);
-   if (!shell)
+   cdata = e_client_cdata_get(ec);
+   if (cdata)
      {
-        ERR("No E_Xdg_Shell data in wl_resource", NULL);
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No shell data in wl_resource");
-        return;
+        cdata->sh_v6.res_role = toplevel->ds_toplevel->resource;
+        cdata->sh_v6.role = E_COMP_WL_SH_SURF_ROLE_NONE;
      }
 
-   exsurf = _e_xdg_surface_create(shell, wsurface, id);
-   if (!exsurf)
-     {
-        ERR("Failed to create E_Xdg_Surface", NULL);
-        return;
-     }
+   e_shell_e_client_destroy(ec);
 }
 
 static void
-_e_xdg_shell_cb_pong(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
+_e_xdg_toplevel_v6_add(struct ds_xdg_surface_v6 *ds_xdg_surface)
 {
-   E_Xdg_Shell *shell;
-   E_Xdg_Surface *exsurf;
-   Eina_List *l;
-
-   ELOGF("XDG6", "Pong. res:%p", NULL, resource);
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   shell = wl_resource_get_user_data(resource);
-   if (!shell)
+   toplevel = E_NEW(E_Xdg_Toplevel_V6, 1);
+   if (!toplevel)
      {
-        ERR("No E_Xdg_Shell data in wl_resource", NULL);
-        wl_resource_post_error(resource,
-                               WL_DISPLAY_ERROR_INVALID_OBJECT,
-                               "No E_Xdg_Shell data in wl_resource");
+        ERR("Could not create E_Xdg_Toplevel_V6", NULL);
         return;
      }
 
-   EINA_LIST_FOREACH(shell->surfaces, l, exsurf)
-      e_shell_e_client_pong(exsurf->ec);
-
-   shell->ping_serial = 0;
-}
-
-static const struct zxdg_shell_v6_interface _e_xdg_shell_interface =
-{
-   _e_xdg_shell_cb_destroy,
-   _e_xdg_shell_cb_positioner_create,
-   _e_xdg_shell_cb_surface_get,
-   _e_xdg_shell_cb_pong
-};
-
-static E_Xdg_Shell *
-_e_xdg_shell_create(struct wl_client *client, struct wl_resource *resource)
-{
-   E_Xdg_Shell *shell;
-
-   shell = E_NEW(E_Xdg_Shell, 1);
-   if (!shell)
-     return NULL;
-
-   shell->wclient = client;
-   shell->resource = resource;
-
-   return shell;
-}
-
-static void
-_e_xdg_shell_destroy(E_Xdg_Shell *shell)
-{
-   E_Xdg_Surface *exsurf;
-   E_Xdg_Positioner *p;
-
-   EINA_LIST_FREE(shell->surfaces, exsurf)
-     {
-        /* Do we need to do it even though shell is just about to be destroyed? */
-        e_shell_e_client_pong(exsurf->ec);
-        exsurf->shell = NULL;
-     }
-
-   EINA_LIST_FREE(shell->positioners, p)
-      p->shell = NULL;
+   toplevel->ds_toplevel = ds_xdg_surface->toplevel;
+   toplevel->ec = e_client_from_surface_resource(
+      ds_surface_get_wl_resource(ds_xdg_surface->ds_surface));
 
-   free(shell);
-}
+   _e_xdg_toplevel_v6_listener_init(toplevel);
+   _e_xdg_toplevel_v6_init(toplevel);
 
-static void
-_e_xdg_shell_cb_unbind(struct wl_resource *resource)
-{
-   E_Xdg_Shell *shell;
-
-   LOG("Unbind Xdg_Shell", NULL);
-
-   shell = wl_resource_get_user_data(resource);
-   if (!shell)
-     {
-        ERR("No E_Xdg_Shell in wl_resource", NULL);
-        return;
-     }
+   // FIXME HACK
+   // For wayland clients which don't follow the rule of
+   // xdg_shell_v6.configure, this sets `configured` variable as true to work
+   // with libds which does follow the rule of xdg_shell_v6 spec.
+   ds_xdg_surface->configured = EINA_TRUE;
 
-   _e_xdg_shell_destroy(shell);
+   LOG("Created E_Xdg_Toplevel_V6(%p)", toplevel->ec, toplevel);
 }
 
 static void
-_e_xdg_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
+_e_xdg_toplevel_v6_cb_xdg_surface_destroy(struct wl_listener *listener, void *data)
 {
-   E_Xdg_Shell *shell;
-   struct wl_resource *resource;
-
-   LOG("Bind Xdg_Shell", NULL);
+   E_Xdg_Toplevel_V6 *toplevel;
 
-   /* Create resource for zxdg_shell_v6 */
-   resource = wl_resource_create(client,
-                                 &zxdg_shell_v6_interface,
-                                 version,
-                                 id);
-   if (!resource)
-     goto err_res;
+   toplevel = wl_container_of(listener, toplevel, destroy);
 
+   LOG("Destroy E_Xdg_Toplevel_V6(%p)", toplevel->ec, toplevel);
 
-   shell = _e_xdg_shell_create(client, resource);
-   if (!shell)
-     {
-        ERR("Failed to create E_Xdg_Shell", NULL);
-        goto err_shell;
-     }
-
-   wl_resource_set_implementation(resource, &_e_xdg_shell_interface,
-                                  shell, _e_xdg_shell_cb_unbind);
-
-   return;
-err_shell:
-   wl_resource_destroy(resource);
-err_res:
-   wl_client_post_no_memory(client);
-}
-
-EINTERN Eina_Bool
-e_xdg_shell_v6_init(void)
-{
-   LOG("Initializing Xdg_Shell_V6", NULL);
-
-   /* try to create global xdg_shell interface */
-   global_resource = wl_global_create(e_comp_wl->wl.disp,
-                                      &zxdg_shell_v6_interface,
-                                      1,
-                                      e_comp->wl_comp_data,
-                                      _e_xdg_shell_cb_bind);
-   if (!global_resource)
-     {
-        ERR("Could not create zxdg_shell_v6 global: %m", NULL);
-        return EINA_FALSE;
-     }
-
-   return EINA_TRUE;
-}
-
-EINTERN void
-e_xdg_shell_v6_shutdown(void)
-{
-   E_FREE_FUNC(global_resource, wl_global_destroy);
-}
-
-EINTERN E_Client *
-e_xdg_shell_v6_xdg_surface_ec_get(struct wl_resource *resource)
-{
-   E_Xdg_Surface *exsurf = NULL;
-
-   exsurf = wl_resource_get_user_data(resource);
-   if (!exsurf)
-     {
-        ERR("No E_Xdg_Shell in wl_resource", NULL);
-        return NULL;
-     }
-
-   return exsurf->ec;
+   _e_xdg_toplevel_v6_listener_finish(toplevel);
+   _e_xdg_toplevel_v6_finish(toplevel);
+   free(toplevel);
 }
-/* End of Xdg_shell */