shell: introduce shell_surface_purpose
authorPekka Paalanen <ppaalanen@gmail.com>
Wed, 23 Nov 2011 14:42:16 +0000 (16:42 +0200)
committerPekka Paalanen <ppaalanen@gmail.com>
Wed, 23 Nov 2011 14:43:43 +0000 (16:43 +0200)
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>
compositor/shell.c

index edef868..034db55 100644 (file)
@@ -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);
 }