On 11/07/2016 10:23, Giulio Camuffo wrote:
2016-07-09 20:45 GMT+02:00 Quentin Glidic <[email protected]>:
From: Quentin Glidic <[email protected]>

Currently, layers’ order depends on the module loading order and it does
not survive runtime modifications (like shell locking/unlocking).
With this patch, modules can safely add their own layer at the expected
position in the stack, with runtime persistence.

Signed-off-by: Quentin Glidic <[email protected]>
---


v2:
 - Tiny commit message addition: added runtime behaviour comment.
 - Reworked (a lot) the enum comment to explain further the position
   values and their actual expected scope. I hope their are clear enough.
   Here are the biggest changes:
     - Added a BOTTOM_UI value for widgets and conky-like applications.
     - Changed BACKGROUND to be 1, as nothing should be under it
     - Added a comment about mandatory background

As a side question: if this semantic regarding background surface is
accepted, would that be relevant for libweston to provide a “real” fallback
black surface if no BACKGROUND layer is found?

 desktop-shell/input-panel.c         |  9 +++--
 desktop-shell/shell.c               | 80 +++++++++++++++++++++++--------------
 fullscreen-shell/fullscreen-shell.c |  3 +-
 ivi-shell/input-panel-ivi.c         |  9 +++--
 ivi-shell/ivi-layout.c              |  3 +-
 ivi-shell/ivi-shell.c               |  3 +-
 libweston/compositor.c              | 34 +++++++++++++---
 libweston/compositor.h              | 59 ++++++++++++++++++++++++++-
 tests/weston-test.c                 |  2 +-
 9 files changed, 156 insertions(+), 46 deletions(-)

diff --git a/desktop-shell/input-panel.c b/desktop-shell/input-panel.c
index 0d003b1..f712289 100644
--- a/desktop-shell/input-panel.c
+++ b/desktop-shell/input-panel.c
@@ -114,8 +114,9 @@ show_input_panels(struct wl_listener *listener, void *data)
        shell->showing_input_panels = true;

        if (!shell->locked)
-               wl_list_insert(&shell->compositor->cursor_layer.link,
-                              &shell->input_panel_layer.link);
+               weston_layer_set_position(shell->compositor,
+                                         &shell->input_panel_layer,
+                                         WESTON_LAYER_POSITION_TOP_UI);

        wl_list_for_each_safe(ipsurf, next,
                              &shell->input_panel.surfaces, link) {
@@ -140,7 +141,9 @@ hide_input_panels(struct wl_listener *listener, void *data)
        shell->showing_input_panels = false;

        if (!shell->locked)
-               wl_list_remove(&shell->input_panel_layer.link);
+               weston_layer_set_position(shell->compositor,
+                                         &shell->input_panel_layer,
+                                         WESTON_LAYER_POSITION_HIDDEN);

        wl_list_for_each_safe(view, next,
                              &shell->input_panel_layer.view_list.link,
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index c72f801..803ff33 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -1079,13 +1079,14 @@ seat_destroyed(struct wl_listener *listener, void *data)
 }

 static struct workspace *
-workspace_create(void)
+workspace_create(struct desktop_shell *shell)
 {
        struct workspace *ws = malloc(sizeof *ws);
        if (ws == NULL)
                return NULL;

-       weston_layer_init(&ws->layer, NULL);
+       weston_layer_init(shell->compositor, &ws->layer,
+                         WESTON_LAYER_POSITION_HIDDEN);

        wl_list_init(&ws->focus_list);
        wl_list_init(&ws->seat_destroyed_listener.link);
@@ -1124,7 +1125,9 @@ activate_workspace(struct desktop_shell *shell, unsigned 
int index)
        struct workspace *ws;

        ws = get_workspace(shell, index);
-       wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
+       weston_layer_set_position(shell->compositor,
+                                 &ws->layer,
+                                 WESTON_LAYER_POSITION_NORMAL);

        shell->workspaces.current = index;
 }
@@ -4596,20 +4599,22 @@ resume_desktop(struct desktop_shell *shell)
 {
        struct workspace *ws = get_current_workspace(shell);

-       wl_list_remove(&shell->lock_layer.link);
-       if (shell->showing_input_panels) {
-               wl_list_insert(&shell->compositor->cursor_layer.link,
-                              &shell->input_panel_layer.link);
-               wl_list_insert(&shell->input_panel_layer.link,
-                              &shell->fullscreen_layer.link);
-       } else {
-               wl_list_insert(&shell->compositor->cursor_layer.link,
-                              &shell->fullscreen_layer.link);
-       }
-       wl_list_insert(&shell->fullscreen_layer.link,
-                      &shell->panel_layer.link);
-       wl_list_insert(&shell->panel_layer.link,
-                      &ws->layer.link),
+       weston_layer_set_position(shell->compositor,
+                                 &shell->lock_layer,
+                                 WESTON_LAYER_POSITION_HIDDEN);
+       if (shell->showing_input_panels)
+               weston_layer_set_position(shell->compositor,
+                                         &shell->input_panel_layer,
+                                         WESTON_LAYER_POSITION_TOP_UI);
+       weston_layer_set_position(shell->compositor,
+                                 &shell->fullscreen_layer,
+                                 WESTON_LAYER_POSITION_FULLSCREEN);
+       weston_layer_set_position(shell->compositor,
+                                 &shell->panel_layer,
+                                 WESTON_LAYER_POSITION_UI);
+       weston_layer_set_position(shell->compositor,
+                                 &ws->layer,
+                                 WESTON_LAYER_POSITION_NORMAL);

        restore_focus_state(shell, get_current_workspace(shell));

@@ -5302,13 +5307,22 @@ lock(struct desktop_shell *shell)
         * toplevel layers.  This way nothing else can show or receive
         * input events while we are locked. */

-       wl_list_remove(&shell->panel_layer.link);
-       wl_list_remove(&shell->fullscreen_layer.link);
+       weston_layer_set_position(shell->compositor,
+                                 &shell->panel_layer,
+                                 WESTON_LAYER_POSITION_HIDDEN);
+       weston_layer_set_position(shell->compositor,
+                                 &shell->fullscreen_layer,
+                                 WESTON_LAYER_POSITION_HIDDEN);
        if (shell->showing_input_panels)
-               wl_list_remove(&shell->input_panel_layer.link);
-       wl_list_remove(&ws->layer.link);
-       wl_list_insert(&shell->compositor->cursor_layer.link,
-                      &shell->lock_layer.link);
+               weston_layer_set_position(shell->compositor,
+                                         &shell->input_panel_layer,
+                                         WESTON_LAYER_POSITION_HIDDEN);
+       weston_layer_set_position(shell->compositor,
+                                 &ws->layer,
+                                 WESTON_LAYER_POSITION_HIDDEN);
+       weston_layer_set_position(shell->compositor,
+                                 &shell->lock_layer,
+                                 WESTON_LAYER_POSITION_LOCK);

        weston_compositor_sleep(shell->compositor);

@@ -6732,11 +6746,16 @@ module_init(struct weston_compositor *ec,
        ec->shell_interface.set_pid = set_pid;
        ec->shell_interface.get_output_work_area = get_output_work_area;

-       weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
-       weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
-       weston_layer_init(&shell->background_layer, &shell->panel_layer.link);
-       weston_layer_init(&shell->lock_layer, NULL);
-       weston_layer_init(&shell->input_panel_layer, NULL);
+       weston_layer_init(ec, &shell->fullscreen_layer,
+                         WESTON_LAYER_POSITION_FULLSCREEN);
+       weston_layer_init(ec, &shell->panel_layer,
+                         WESTON_LAYER_POSITION_UI);
+       weston_layer_init(ec, &shell->background_layer,
+                         WESTON_LAYER_POSITION_BACKGROUND);
+       weston_layer_init(ec, &shell->lock_layer,
+                         WESTON_LAYER_POSITION_HIDDEN);
+       weston_layer_init(ec, &shell->input_panel_layer,
+                         WESTON_LAYER_POSITION_HIDDEN);

        wl_array_init(&shell->workspaces.array);
        wl_list_init(&shell->workspaces.client_list);
@@ -6758,13 +6777,14 @@ module_init(struct weston_compositor *ec,
                if (pws == NULL)
                        return -1;

-               *pws = workspace_create();
+               *pws = workspace_create(shell);
                if (*pws == NULL)
                        return -1;
        }
        activate_workspace(shell, 0);

-       weston_layer_init(&shell->minimized_layer, NULL);
+       weston_layer_init(ec, &shell->minimized_layer,
+                         WESTON_LAYER_POSITION_HIDDEN);

        wl_list_init(&shell->workspaces.anim_sticky_list);
        wl_list_init(&shell->workspaces.animation.link);
diff --git a/fullscreen-shell/fullscreen-shell.c 
b/fullscreen-shell/fullscreen-shell.c
index 2ec2d02..65f75bb 100644
--- a/fullscreen-shell/fullscreen-shell.c
+++ b/fullscreen-shell/fullscreen-shell.c
@@ -834,7 +834,8 @@ module_init(struct weston_compositor *compositor,

        shell->client_destroyed.notify = client_destroyed;

-       weston_layer_init(&shell->layer, &compositor->cursor_layer.link);
+       weston_layer_init(compositor, &shell->layer,
+                         WESTON_LAYER_POSITION_FULLSCREEN);

        wl_list_init(&shell->output_list);
        shell->output_created_listener.notify = output_created;
diff --git a/ivi-shell/input-panel-ivi.c b/ivi-shell/input-panel-ivi.c
index 954d4ef..bd685d5 100644
--- a/ivi-shell/input-panel-ivi.c
+++ b/ivi-shell/input-panel-ivi.c
@@ -115,8 +115,9 @@ show_input_panels(struct wl_listener *listener, void *data)
        shell->showing_input_panels = true;

        if (!shell->locked)
-               wl_list_insert(&shell->compositor->cursor_layer.link,
-                              &shell->input_panel_layer.link);
+               weston_layer_set_position(shell->compositor,
+                                         &shell->input_panel_layer,
+                                         WESTON_LAYER_POSITION_TOP_UI);

        wl_list_for_each_safe(ipsurf, next,
                              &shell->input_panel.surfaces, link) {
@@ -141,7 +142,9 @@ hide_input_panels(struct wl_listener *listener, void *data)
        shell->showing_input_panels = false;

        if (!shell->locked)
-               wl_list_remove(&shell->input_panel_layer.link);
+               weston_layer_set_position(shell->compositor,
+                                         &shell->input_panel_layer,
+                                         WESTON_LAYER_POSITION_HIDDEN);

        wl_list_for_each_safe(view, next,
                              &shell->input_panel_layer.view_list.link,
diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
index dec4936..ea297db 100644
--- a/ivi-shell/ivi-layout.c
+++ b/ivi-shell/ivi-layout.c
@@ -2028,7 +2028,8 @@ ivi_layout_init_with_compositor(struct weston_compositor 
*ec)
        wl_signal_init(&layout->surface_notification.configure_changed);

        /* Add layout_layer at the last of weston_compositor.layer_list */
-       weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
+       weston_layer_init(ec, &layout->layout_layer,
+                         WESTON_LAYER_POSITION_NORMAL);

        create_screen(ec);

diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c
index 090ee4d..ef665b3 100644
--- a/ivi-shell/ivi-shell.c
+++ b/ivi-shell/ivi-shell.c
@@ -391,7 +391,8 @@ init_ivi_shell(struct weston_compositor *compositor, struct 
ivi_shell *shell,

        wl_list_init(&shell->ivi_surface_list);

-       weston_layer_init(&shell->input_panel_layer, NULL);
+       weston_layer_init(compositor, &shell->input_panel_layer,
+                         WESTON_LAYER_POSITION_HIDDEN);

        if (setting->developermode) {
                weston_install_debug_key_binding(compositor, MODIFIER_SUPER);
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 771f1c9..459e775 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -2402,14 +2402,38 @@ weston_layer_entry_remove(struct weston_layer_entry 
*entry)
        entry->layer = NULL;
 }

+
 WL_EXPORT void
-weston_layer_init(struct weston_layer *layer, struct wl_list *below)
+weston_layer_init(struct weston_compositor *compositor,
+                 struct weston_layer *layer,
+                 enum weston_layer_position position)
 {
+       wl_list_init(&layer->link);
        wl_list_init(&layer->view_list.link);
        layer->view_list.layer = layer;
        weston_layer_set_mask_infinite(layer);
-       if (below != NULL)
-               wl_list_insert(below, &layer->link);
+       weston_layer_set_position(compositor, layer, position);
+}
+
+WL_EXPORT void
+weston_layer_set_position(struct weston_compositor *compositor,
+                         struct weston_layer *layer,
+                         enum weston_layer_position position)
+{

Can you add some documentation for this function?

+       struct weston_layer *below;
+
+       layer->position = position;
+       if (layer->position == WESTON_LAYER_POSITION_HIDDEN) {
+               wl_list_remove(&layer->link);
+       } else {
+               wl_list_for_each_reverse(below, &compositor->layer_list, link) {
+                       if (below->position >= layer->position) {
+                               wl_list_insert(&below->link, &layer->link);
+                               return;
+                       }
+               }
+               wl_list_insert(compositor->layer_list.next, &layer->link);
+       }
 }

 WL_EXPORT void
@@ -4725,8 +4749,8 @@ weston_compositor_create(struct wl_display *display, void 
*user_data)
        loop = wl_display_get_event_loop(ec->wl_display);
        ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);

-       weston_layer_init(&ec->fade_layer, &ec->layer_list);
-       weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
+       weston_layer_init(ec, &ec->fade_layer, WESTON_LAYER_POSITION_FADE);
+       weston_layer_init(ec, &ec->cursor_layer, WESTON_LAYER_POSITION_CURSOR);

        weston_compositor_add_debug_binding(ec, KEY_T,
                                            timeline_key_binding_handler, ec);
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 557d2f5..eedc12f 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -605,10 +605,61 @@ struct weston_layer_entry {
        struct weston_layer *layer;
 };

+/*
+ * Higher value means higher in the stack.
+ *
+ * These values are based on well-known concepts in a classic desktop
+ * environment. Third-party modules based on libweston are encouraged to use
+ * them to integrate better with other projects.
+ *
+ * A fully integrated environment can use any value, based on these or not,
+ * at their discretion.
+ */
+enum weston_layer_position {
+       /* Special value to remove a layer from the rendering list. */
+       WESTON_LAYER_POSITION_HIDDEN     = 0x00000000,

I find this value slightly surprising, as it actually unsets the
position. In orbital, i have a "hidden" layer but that's behind the
background, and the purpose is to keep sending the frame callbacks for
the views in it (for e.g. minimized views). Using this would instead
stop sending them. I think it would be clearer to have a
weston_layer_unset_position(), and have this value be behind the
background, or remove it at all.

I didn’t think about that kind of use case; a bit odd but I guess it has its uses.

Added unset_position.


+
+       /*
+        * This value is for the mandatory background,
+        * reserved for the compositor.
+        *
+        * If the compositor supports runtime-loadable modules to set the
+        * background, they must use (BACKGROUND + 1) and let the compositor
+        * put a fallback a solid color surface on BACKGROUND.
+        */
+       WESTON_LAYER_POSITION_BACKGROUND = 0x00000001,
+
+       /* For "desktop widgets" and applications like conky. */
+       WESTON_LAYER_POSITION_BOTTOM_UI  = 0x30000000,
+
+       /* For regular applications, only one layer should have this value
+        * to ensure proper stacking control. */
+       WESTON_LAYER_POSITION_NORMAL     = 0x50000000,
+
+       /* For desktop UI, like panels. */
+       WESTON_LAYER_POSITION_UI         = 0x80000000,
+
+       /* For fullscreen applications that should cover UI. */
+       WESTON_LAYER_POSITION_FULLSCREEN = 0xb0000000,
+
+       /* For special UI like on-screen keyboard that fullscreen applications
+        * will need. */
+       WESTON_LAYER_POSITION_TOP_UI     = 0xe0000000,
+
+       /* For the lock surface. */
+       WESTON_LAYER_POSITION_LOCK       = 0xffff0000,
+
+       /* Values reserved for libweston internal usage */
+       WESTON_LAYER_POSITION_CURSOR     = 0xfffffffe,
+       WESTON_LAYER_POSITION_FADE       = 0xffffffff,
+};
+
 struct weston_layer {
        struct weston_layer_entry view_list;
        struct wl_list link;
        pixman_box32_t mask;
+       enum weston_layer_position position;
+       const char *name;

What is this name for?

Leftover from my tests. Removed.

Will send a v3.

Cheers,

 };

 struct weston_plane {
@@ -1222,7 +1273,13 @@ weston_layer_entry_insert(struct weston_layer_entry 
*list,
 void
 weston_layer_entry_remove(struct weston_layer_entry *entry);
 void
-weston_layer_init(struct weston_layer *layer, struct wl_list *below);
+weston_layer_init(struct weston_compositor *compositor,
+                 struct weston_layer *layer,
+                 enum weston_layer_position position);
+void
+weston_layer_set_position(struct weston_compositor *compositor,
+                         struct weston_layer *layer,
+                         enum weston_layer_position position);

 void
 weston_layer_set_mask(struct weston_layer *layer, int x, int y, int width, int 
height);
diff --git a/tests/weston-test.c b/tests/weston-test.c
index 09d8b5e..2425776 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -595,7 +595,7 @@ module_init(struct weston_compositor *ec,
                return -1;

        test->compositor = ec;
-       weston_layer_init(&test->layer, &ec->cursor_layer.link);
+       weston_layer_init(ec, &test->layer, WESTON_LAYER_POSITION_NORMAL);

        if (wl_global_create(ec->wl_display, &weston_test_interface, 1,
                             test, bind_test) == NULL)
--
2.9.0

--

Quentin “Sardem FF7” Glidic
_______________________________________________
wayland-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to