#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 */
}
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 */