[PATCH weston v2] libweston: Position layers in an absolute way
Giulio Camuffo
giuliocamuffo at gmail.com
Mon Jul 11 08:23:22 UTC 2016
2016-07-09 20:45 GMT+02:00 Quentin Glidic <sardemff7+wayland at sardemff7.net>:
> From: Quentin Glidic <sardemff7+git at sardemff7.net>
>
> 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 <sardemff7+git at sardemff7.net>
> ---
>
>
> 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.
> +
> + /*
> + * 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?
> };
>
> 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
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list