[PATCH weston v2] libweston: Position layers in an absolute way

Quentin Glidic sardemff7+wayland at sardemff7.net
Mon Jul 11 09:16:56 UTC 2016


On 11/07/2016 10:23, Giulio Camuffo wrote:
> 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.

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


More information about the wayland-devel mailing list