From 56cdea96f067782b69e90573c7ec0dec3a9eb166 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Wed, 23 Nov 2011 16:14:12 +0200 Subject: [PATCH 1/2] shell: add private surface struct Add a pointer to wlsc_surface for shell-private data. This is a temporary solution. Add struct shell_surface, where you can add any shell-private data members related to a wlsc_surface. The getter function takes care of creating the private data if it does not exist yet. Not used anywhere yet. Signed-off-by: Pekka Paalanen --- compositor/compositor.c | 2 +- compositor/compositor.h | 2 ++ compositor/shell.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/compositor/compositor.c b/compositor/compositor.c index fe123f8c..0ae71b6c 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -248,7 +248,7 @@ wlsc_surface_create(struct wlsc_compositor *compositor, { struct wlsc_surface *surface; - surface = malloc(sizeof *surface); + surface = calloc(1, sizeof *surface); if (surface == NULL) return NULL; diff --git a/compositor/compositor.h b/compositor/compositor.h index b66903ae..4163d04d 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -276,6 +276,8 @@ struct wlsc_surface { struct wl_buffer *buffer; struct wl_listener buffer_destroy_listener; + + void *shell_priv; }; void diff --git a/compositor/shell.c b/compositor/shell.c index f8305dbe..edef868b 100644 --- a/compositor/shell.c +++ b/compositor/shell.c @@ -58,12 +58,53 @@ struct wl_shell { struct wl_list hidden_surface_list; }; +struct shell_surface { + struct wl_listener destroy_listener; +}; + struct wlsc_move_grab { struct wl_grab grab; struct wlsc_surface *surface; int32_t dx, dy; }; +static void +destroy_shell_surface(struct shell_surface *priv) +{ + wl_list_remove(&priv->destroy_listener.link); + free(priv); +} + +static void +handle_shell_surface_destroy(struct wl_listener *listener, + struct wl_resource *resource, uint32_t time) +{ + struct shell_surface *priv = + container_of(listener, struct shell_surface, destroy_listener); + destroy_shell_surface(priv); +} + +static struct shell_surface * +get_shell_surface(struct wlsc_surface *surface) +{ + struct shell_surface *priv; + + if (surface->shell_priv) + return surface->shell_priv; + + priv = calloc(1, sizeof *priv); + if (!priv) + return NULL; + + priv->destroy_listener.func = handle_shell_surface_destroy; + wl_list_insert(surface->surface.resource.destroy_listener_list.prev, + &priv->destroy_listener.link); + + surface->shell_priv = priv; + + return priv; +} + static void move_grab_motion(struct wl_grab *grab, uint32_t time, int32_t x, int32_t y) From 57da4a822e4ae2b498c1e6915a9f5def04af84ea Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Wed, 23 Nov 2011 16:42:16 +0200 Subject: [PATCH 2/2] shell: introduce shell_surface_purpose Enumerate the different surface purposes for the shell: background, panel, lock surface, and normal (other) surfaces. Instead of testing wlsc_surface pointers against known pointers, check the purpose field. This change will ease implementing per-output background, panel, etc. when the number of "known" surface pointers grows dynamically. Signed-off-by: Pekka Paalanen --- compositor/shell.c | 74 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/compositor/shell.c b/compositor/shell.c index edef868b..034db553 100644 --- a/compositor/shell.c +++ b/compositor/shell.c @@ -58,8 +58,17 @@ struct wl_shell { struct wl_list hidden_surface_list; }; +enum shell_surface_purpose { + SHELL_SURFACE_NORMAL, + SHELL_SURFACE_PANEL, + SHELL_SURFACE_BACKGROUND, + SHELL_SURFACE_LOCK, +}; + struct shell_surface { struct wl_listener destroy_listener; + + enum shell_surface_purpose purpose; }; struct wlsc_move_grab { @@ -102,6 +111,8 @@ get_shell_surface(struct wlsc_surface *surface) surface->shell_priv = priv; + priv->purpose = SHELL_SURFACE_NORMAL; + return priv; } @@ -823,12 +834,16 @@ desktop_shell_set_background(struct wl_client *client, struct wlsc_output *output = container_of(shell->compositor->output_list.next, struct wlsc_output, link); + struct shell_surface *priv; shell->background = surface_resource->data; shell->background_listener.func = handle_background_surface_destroy; wl_list_insert(&surface_resource->destroy_listener_list, &shell->background_listener.link); + priv = get_shell_surface(surface); + priv->purpose = SHELL_SURFACE_BACKGROUND; + wl_resource_post_event(resource, DESKTOP_SHELL_CONFIGURE, wlsc_compositor_get_time(), 0, surface, @@ -856,6 +871,7 @@ desktop_shell_set_panel(struct wl_client *client, struct wlsc_output *output = container_of(shell->compositor->output_list.next, struct wlsc_output, link); + struct shell_surface *priv; shell->panel = surface_resource->data; @@ -863,6 +879,9 @@ desktop_shell_set_panel(struct wl_client *client, wl_list_insert(&surface_resource->destroy_listener_list, &shell->panel_listener.link); + priv = get_shell_surface(shell->panel); + priv->purpose = SHELL_SURFACE_PANEL; + wl_resource_post_event(resource, DESKTOP_SHELL_CONFIGURE, wlsc_compositor_get_time(), 0, surface_resource, @@ -887,6 +906,7 @@ desktop_shell_set_lock_surface(struct wl_client *client, struct wl_resource *surface_resource) { struct wl_shell *shell = resource->data; + struct shell_surface *priv; shell->prepare_event_sent = false; @@ -898,6 +918,9 @@ desktop_shell_set_lock_surface(struct wl_client *client, shell->lock_surface_listener.func = handle_lock_surface_destroy; wl_list_insert(&surface_resource->destroy_listener_list, &shell->lock_surface_listener.link); + + priv = get_shell_surface(shell->lock_surface); + priv->purpose = SHELL_SURFACE_LOCK; } static void @@ -1005,18 +1028,31 @@ activate(struct wlsc_shell *base, struct wlsc_surface *es, { struct wl_shell *shell = container_of(base, struct wl_shell, shell); struct wlsc_compositor *compositor = shell->compositor; + struct shell_surface *priv; + + priv = get_shell_surface(es); wlsc_surface_activate(es, device, time); if (compositor->wxs) wlsc_xserver_surface_activate(es); - if (es == shell->background) { + switch (priv->purpose) { + case SHELL_SURFACE_BACKGROUND: + /* put background back to bottom */ wl_list_remove(&es->link); wl_list_insert(compositor->surface_list.prev, &es->link); - } else if (shell->panel && !shell->locked) { - wl_list_remove(&shell->panel->link); - wl_list_insert(&compositor->surface_list, &shell->panel->link); + break; + case SHELL_SURFACE_PANEL: + /* already put on top */ + break; + default: + if (shell->panel && !shell->locked) { + /* bring panel back to top */ + wl_list_remove(&shell->panel->link); + wl_list_insert(&compositor->surface_list, + &shell->panel->link); + } } } @@ -1027,6 +1063,7 @@ lock(struct wlsc_shell *base) struct wl_list *surface_list = &shell->compositor->surface_list; struct wlsc_surface *cur; struct wlsc_surface *tmp; + struct shell_surface *priv; struct wlsc_input_device *device; uint32_t time; @@ -1050,7 +1087,8 @@ lock(struct wlsc_shell *base) if (cur->surface.resource.client == NULL) continue; - if (cur == shell->background) + priv = get_shell_surface(cur); + if (priv->purpose == SHELL_SURFACE_BACKGROUND) continue; cur->output = NULL; @@ -1104,6 +1142,9 @@ map(struct wlsc_shell *base, struct wl_shell *shell = container_of(base, struct wl_shell, shell); struct wlsc_compositor *compositor = shell->compositor; struct wl_list *list; + struct shell_surface *priv; + + priv = get_shell_surface(surface); if (shell->locked) list = &shell->hidden_surface_list; @@ -1111,23 +1152,28 @@ map(struct wlsc_shell *base, list = &compositor->surface_list; /* surface stacking order, see also activate() */ - if (surface == shell->background) { + switch (priv->purpose) { + case SHELL_SURFACE_BACKGROUND: /* background always visible, at the bottom */ wl_list_insert(compositor->surface_list.prev, &surface->link); - - } else if (surface == shell->panel) { + break; + case SHELL_SURFACE_PANEL: /* panel always on top, hidden while locked */ wl_list_insert(list, &surface->link); - - } else if (surface == shell->lock_surface) { + break; + case SHELL_SURFACE_LOCK: /* lock surface always visible, on top */ wl_list_insert(&compositor->surface_list, &surface->link); wlsc_compositor_repick(compositor); - wlsc_compositor_wake(compositor); - } else { + wlsc_compositor_wake(compositor); + break; + default: /* everything else just below the panel */ - wl_list_insert(&shell->panel->link, &surface->link); + if (shell->panel) + wl_list_insert(&shell->panel->link, &surface->link); + else + wl_list_insert(list, &surface->link); } if (surface->map_type == WLSC_SURFACE_MAP_TOPLEVEL) { @@ -1137,7 +1183,7 @@ map(struct wlsc_shell *base, surface->width = width; surface->height = height; - if (!shell->locked || surface == shell->lock_surface) + if (!shell->locked || priv->purpose == SHELL_SURFACE_LOCK) wlsc_surface_configure(surface, surface->x, surface->y, width, height); }