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 <ppaalanen@gmail.com>
dev
Pekka Paalanen 13 years ago
parent 56cdea96f0
commit 57da4a822e
  1. 68
      compositor/shell.c

@ -58,8 +58,17 @@ struct wl_shell {
struct wl_list hidden_surface_list; 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 shell_surface {
struct wl_listener destroy_listener; struct wl_listener destroy_listener;
enum shell_surface_purpose purpose;
}; };
struct wlsc_move_grab { struct wlsc_move_grab {
@ -102,6 +111,8 @@ get_shell_surface(struct wlsc_surface *surface)
surface->shell_priv = priv; surface->shell_priv = priv;
priv->purpose = SHELL_SURFACE_NORMAL;
return priv; return priv;
} }
@ -823,12 +834,16 @@ desktop_shell_set_background(struct wl_client *client,
struct wlsc_output *output = struct wlsc_output *output =
container_of(shell->compositor->output_list.next, container_of(shell->compositor->output_list.next,
struct wlsc_output, link); struct wlsc_output, link);
struct shell_surface *priv;
shell->background = surface_resource->data; shell->background = surface_resource->data;
shell->background_listener.func = handle_background_surface_destroy; shell->background_listener.func = handle_background_surface_destroy;
wl_list_insert(&surface_resource->destroy_listener_list, wl_list_insert(&surface_resource->destroy_listener_list,
&shell->background_listener.link); &shell->background_listener.link);
priv = get_shell_surface(surface);
priv->purpose = SHELL_SURFACE_BACKGROUND;
wl_resource_post_event(resource, wl_resource_post_event(resource,
DESKTOP_SHELL_CONFIGURE, DESKTOP_SHELL_CONFIGURE,
wlsc_compositor_get_time(), 0, surface, wlsc_compositor_get_time(), 0, surface,
@ -856,6 +871,7 @@ desktop_shell_set_panel(struct wl_client *client,
struct wlsc_output *output = struct wlsc_output *output =
container_of(shell->compositor->output_list.next, container_of(shell->compositor->output_list.next,
struct wlsc_output, link); struct wlsc_output, link);
struct shell_surface *priv;
shell->panel = surface_resource->data; 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, wl_list_insert(&surface_resource->destroy_listener_list,
&shell->panel_listener.link); &shell->panel_listener.link);
priv = get_shell_surface(shell->panel);
priv->purpose = SHELL_SURFACE_PANEL;
wl_resource_post_event(resource, wl_resource_post_event(resource,
DESKTOP_SHELL_CONFIGURE, DESKTOP_SHELL_CONFIGURE,
wlsc_compositor_get_time(), 0, surface_resource, 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_resource *surface_resource)
{ {
struct wl_shell *shell = resource->data; struct wl_shell *shell = resource->data;
struct shell_surface *priv;
shell->prepare_event_sent = false; 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; shell->lock_surface_listener.func = handle_lock_surface_destroy;
wl_list_insert(&surface_resource->destroy_listener_list, wl_list_insert(&surface_resource->destroy_listener_list,
&shell->lock_surface_listener.link); &shell->lock_surface_listener.link);
priv = get_shell_surface(shell->lock_surface);
priv->purpose = SHELL_SURFACE_LOCK;
} }
static void 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 wl_shell *shell = container_of(base, struct wl_shell, shell);
struct wlsc_compositor *compositor = shell->compositor; struct wlsc_compositor *compositor = shell->compositor;
struct shell_surface *priv;
priv = get_shell_surface(es);
wlsc_surface_activate(es, device, time); wlsc_surface_activate(es, device, time);
if (compositor->wxs) if (compositor->wxs)
wlsc_xserver_surface_activate(es); 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_remove(&es->link);
wl_list_insert(compositor->surface_list.prev, &es->link); wl_list_insert(compositor->surface_list.prev, &es->link);
} else if (shell->panel && !shell->locked) { 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_remove(&shell->panel->link);
wl_list_insert(&compositor->surface_list, &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 wl_list *surface_list = &shell->compositor->surface_list;
struct wlsc_surface *cur; struct wlsc_surface *cur;
struct wlsc_surface *tmp; struct wlsc_surface *tmp;
struct shell_surface *priv;
struct wlsc_input_device *device; struct wlsc_input_device *device;
uint32_t time; uint32_t time;
@ -1050,7 +1087,8 @@ lock(struct wlsc_shell *base)
if (cur->surface.resource.client == NULL) if (cur->surface.resource.client == NULL)
continue; continue;
if (cur == shell->background) priv = get_shell_surface(cur);
if (priv->purpose == SHELL_SURFACE_BACKGROUND)
continue; continue;
cur->output = NULL; cur->output = NULL;
@ -1104,6 +1142,9 @@ map(struct wlsc_shell *base,
struct wl_shell *shell = container_of(base, struct wl_shell, shell); struct wl_shell *shell = container_of(base, struct wl_shell, shell);
struct wlsc_compositor *compositor = shell->compositor; struct wlsc_compositor *compositor = shell->compositor;
struct wl_list *list; struct wl_list *list;
struct shell_surface *priv;
priv = get_shell_surface(surface);
if (shell->locked) if (shell->locked)
list = &shell->hidden_surface_list; list = &shell->hidden_surface_list;
@ -1111,23 +1152,28 @@ map(struct wlsc_shell *base,
list = &compositor->surface_list; list = &compositor->surface_list;
/* surface stacking order, see also activate() */ /* surface stacking order, see also activate() */
if (surface == shell->background) { switch (priv->purpose) {
case SHELL_SURFACE_BACKGROUND:
/* background always visible, at the bottom */ /* background always visible, at the bottom */
wl_list_insert(compositor->surface_list.prev, &surface->link); wl_list_insert(compositor->surface_list.prev, &surface->link);
break;
} else if (surface == shell->panel) { case SHELL_SURFACE_PANEL:
/* panel always on top, hidden while locked */ /* panel always on top, hidden while locked */
wl_list_insert(list, &surface->link); wl_list_insert(list, &surface->link);
break;
} else if (surface == shell->lock_surface) { case SHELL_SURFACE_LOCK:
/* lock surface always visible, on top */ /* lock surface always visible, on top */
wl_list_insert(&compositor->surface_list, &surface->link); wl_list_insert(&compositor->surface_list, &surface->link);
wlsc_compositor_repick(compositor); wlsc_compositor_repick(compositor);
wlsc_compositor_wake(compositor); wlsc_compositor_wake(compositor);
} else { break;
default:
/* everything else just below the panel */ /* everything else just below the panel */
if (shell->panel)
wl_list_insert(&shell->panel->link, &surface->link); wl_list_insert(&shell->panel->link, &surface->link);
else
wl_list_insert(list, &surface->link);
} }
if (surface->map_type == WLSC_SURFACE_MAP_TOPLEVEL) { if (surface->map_type == WLSC_SURFACE_MAP_TOPLEVEL) {
@ -1137,7 +1183,7 @@ map(struct wlsc_shell *base,
surface->width = width; surface->width = width;
surface->height = height; surface->height = height;
if (!shell->locked || surface == shell->lock_surface) if (!shell->locked || priv->purpose == SHELL_SURFACE_LOCK)
wlsc_surface_configure(surface, wlsc_surface_configure(surface,
surface->x, surface->y, width, height); surface->x, surface->y, width, height);
} }

Loading…
Cancel
Save