[PATCH] [RFC]Shell: Hide panels when compositor has a top fullscreen surface.
wuzhiwen
zhiwen.wu at linux.intel.com
Sun Feb 19 18:21:17 PST 2012
Hi Krh,
Thanks for your feedback, my comments inlined.
>-----Original Message-----
>From:
>wayland-devel-bounces+zhiwen.wu=linux.intel.com at lists.freedesktop.org
>[mailto:wayland-devel-bounces+zhiwen.wu=linux.intel.com at lists.freedesktop.o
>rg] On Behalf Of Kristian H?gsberg
>Sent: Saturday, February 18, 2012 11:10 AM
>To: Wu, Zhiwen
>Cc: wayland-devel at lists.freedesktop.org
>Subject: Re: [PATCH] [RFC]Shell: Hide panels when compositor has a top
>fullscreen surface.
>
>On Tue, Feb 14, 2012 at 3:18 AM, <zhiwen.wu at intel.com> wrote:
>> From: Alex Wu <zhiwen.wu at intel.com>
>>
>> Hi krh
>
>Hi Alex,
>
>> This patch is the implementation of the method 3 of the
>> proposal(http://lists.freedesktop.org/archives/wayland-devel/2012-Febr
>> uary/002085.html)
>> for handling panels when compositor has a top fullscreen regular
>> surface, and rebases on commit
>> 8fb8d3b1b5b4ef7836a61f111aeb4aaa87ae89e4. Need your suggestion and
>ideas.
>> The main logic and modifications are as follows:
>>
>> 1.Add a struct wl_list wl_shell::hidden_panels to store the hidden panels.
>
>I think it's better to just raise the fullscreen surface above the panels. This is a
>little tricky right now because of the simplistic surface_list, but I'll try to fix that
[Wu, Zhiwen] All right, I will fix it at the next version of fullscreen patch.
>soon. I'm thinking we'll have a new struct wl_layer, which will be a list of
>surfaces. Then we'll have fade_layer, pointer_layer, fullscreen_layer,
>panels_layer, toplevel_layer and background_layer. Then it will be just a
>matter of pulling the surface out of toplevel_layer and putting it into
>fullscreen_layer.
>
[Wu, Zhiwen]Great to hear that, but do we need a popup/indicator_layer atop fullscreen_layer?
>> 2.Add a hook weston_shell:prepare_repaint to do the stacking adjustment
>before output repainting.
>
>Not sure about this part. Within shell.c, we should be able to know when we
>go from "fullscreen surface on top" to "something else on top"
>and vice versa. So lets handle the stack reordering there instead of checking it
>on every repaint.
[Wu, Zhiwen]The hook is a tricky way to unhide the panels when regular surfaces atop fullscreen one destroyed.
Since we decide not to hide/unhide panels, on need to add a hook there.
>
>Kristian
>
>> 3.In the hook, check if we had a top and fullscreen surface.
>> If yes, remove the panel surface from weston_compositor::surface_list and
>store them to wl_shell:hidden_panels.
>> If no, and we have hidden panels, unhide them.
>> 4.For now, popup surface is treated as regular surface, when popup
>> surface got on top of fullscreen surface,
>> panels will be unhidden.
>> PS: Just a RFC, coding style is not aligned.
>> ---
>> src/compositor.c | 2 +
>> src/compositor.h | 1 +
>> src/shell.c | 125
>> ++++++++++++++++++++++++++++++++++++++++++++++++------
>> 3 files changed, 115 insertions(+), 13 deletions(-)
>>
>> diff --git a/src/compositor.c b/src/compositor.c index
>> ab90ded..5ef830e 100644
>> --- a/src/compositor.c
>> +++ b/src/compositor.c
>> @@ -966,6 +966,8 @@ weston_output_repaint(struct weston_output
>> *output, int msecs)
>> overlap, surface_overlap;
>> int32_t width, height;
>>
>> + ec->shell->prepare_repaint (ec->shell, output);
>> +
>> width = output->current->width +
>> output->border.left + output->border.right;
>> height = output->current->height + diff --git
>> a/src/compositor.h b/src/compositor.h index 966d3f4..bc1f72b 100644
>> --- a/src/compositor.h
>> +++ b/src/compositor.h
>> @@ -135,6 +135,7 @@ struct weston_shell {
>> struct weston_surface *surface,
>> GLfloat x, GLfloat y, int32_t width, int32_t
>> height);
>> void (*destroy)(struct weston_shell *shell);
>> + void (*prepare_repaint)(struct weston_shell *shell, struct
>> + weston_output *output);
>> };
>>
>> enum {
>> diff --git a/src/shell.c b/src/shell.c index 66c4f01..85a487f 100644
>> --- a/src/shell.c
>> +++ b/src/shell.c
>> @@ -57,6 +57,7 @@ struct wl_shell {
>> struct shell_surface *lock_surface;
>> struct wl_listener lock_surface_listener;
>> struct wl_list hidden_surface_list;
>> + struct wl_list hidden_panels;
>>
>> struct wl_list backgrounds;
>> struct wl_list panels;
>> @@ -70,6 +71,7 @@ struct wl_shell {
>> } screensaver;
>> };
>>
>> +/*FIXME:Using bit flag for the type due to some surface may be both
>> +toplevel and fullscreen*/
>> enum shell_surface_type {
>> SHELL_SURFACE_NONE,
>>
>> @@ -600,7 +602,7 @@ get_shell_surface(struct weston_surface *surface)
>> struct wl_list *lst =
>> &surface->surface.resource.destroy_listener_list;
>> struct wl_listener *listener;
>>
>> - /* search the destroy listener list for our callback */
>> + /* search the destroy listener list for our callback */
>> wl_list_for_each(listener, lst, link) {
>> if (listener->func == shell_handle_surface_destroy) {
>> return container_of(listener, struct
>> shell_surface, @@ -1266,6 +1268,101 @@ center_on_output(struct
>> weston_surface *surface, struct weston_output *output)
>> weston_surface_set_position(surface, output->x + x, output->y +
>> y);
>> }
>>
>> +static struct weston_surface *
>> +top_regular_surface (struct weston_shell *base) {
>> + struct wl_shell *shell = container_of(base, struct wl_shell,
>> +shell);
>> + struct weston_compositor *compositor = shell->compositor;
>> + struct wl_list *list;
>> + struct weston_surface *surf;
>> + struct weston_surface *tmp;
>> + bool done = false;
>> +
>> + list = &compositor->surface_list;
>> +
>> + wl_list_for_each_safe(surf, tmp, list, link) {
>> + /*skip non-client surface*/
>> + if (surf->surface.resource.client == NULL)
>> + continue;
>> + if (get_shell_surface_type(surf) == SHELL_SURFACE_LOCK)
>> + continue;
>> + if (get_shell_surface_type(surf) == SHELL_SURFACE_SCREENSAVER)
>> + continue;
>> + if (get_shell_surface_type(surf) == SHELL_SURFACE_PANEL)
>> + continue;
>> + if (get_shell_surface_type(surf) == SHELL_SURFACE_BACKGROUND) {
>> + break;
>> + }
>> + /*got the top regular surface*/
>> + done = true;
>> + break;
>> + }
>> +
>> + if (!done) {
>> + printf ("no regular surface\n");
>> + surf = NULL;
>> + }
>> +
>> + return surf;
>> +}
>> +
>> +static bool
>> +is_fullscreen_surface (struct weston_surface *base) {
>> + struct shell_surface *shsurf;
>> + enum shell_surface_type surf_type;
>> +
>> + if (!base) {
>> + return false;
>> + }
>> +
>> + shsurf = get_shell_surface (base);
>> + surf_type = get_shell_surface_type (base);
>> +
>> + if (surf_type == SHELL_SURFACE_FULLSCREEN)
>> + return true;
>> + else
>> + return false;
>> +}
>> +
>> +static void
>> +prepare_repaint (struct weston_shell *base, struct weston_output
>> +*output) {
>> + struct wl_shell *shell = container_of(base, struct wl_shell,
>> +shell);
>> + struct weston_compositor *compositor = shell->compositor;
>> + struct weston_surface *top_regular_surf;
>> + struct weston_surface *tmp;
>> + struct shell_surface *panel;
>> + bool do_damage = false;
>> +
>> + top_regular_surf = top_regular_surface (base);
>> +
>> + if (is_fullscreen_surface (top_regular_surf)){
>> + if (wl_list_empty (&shell->hidden_panels) && !wl_list_empty
>> + (&shell->panels)) {
>> + /*hide panels*/
>> + wl_list_for_each(panel, &shell->panels, link) {
>> + panel->surface->output = NULL;
>> + wl_list_remove(&panel->surface->link);
>> + wl_list_insert(shell->hidden_panels.prev,
>> + &panel->surface->link);
>> + }
>> + do_damage = true;
>> + }
>> + } else {
>> + if (!wl_list_empty (&shell->hidden_panels)) {
>> + /*unhide panels*/
>> + struct wl_list *list = weston_compositor_top(compositor);
>> + wl_list_insert_list(list, &shell->hidden_panels);
>> + wl_list_init(&shell->hidden_panels);
>> + do_damage = true;
>> + }
>> + }
>> +
>> + if (do_damage) {
>> + weston_output_damage (output);
>> + }
>> + return;
>> +}
>> +
>> static void
>> map(struct weston_shell *base,
>> struct weston_surface *surface, int32_t width, int32_t height) @@
>> -1344,14 +1441,14 @@ map(struct weston_shell *base,
>> break;
>> default:
>> /* everything else just below the panel */
>> - if (!wl_list_empty(&shell->panels)) {
>> - struct shell_surface *panel =
>> - container_of(shell->panels.prev,
>> - struct
>shell_surface,
>> link);
>> - wl_list_insert(&panel->surface->link,
>> &surface->link);
>> - } else {
>> - wl_list_insert(list, &surface->link);
>> - }
>> + if (!wl_list_empty(&shell->panels) && wl_list_empty
>> + (&shell->hidden_panels)) {
>> + struct shell_surface *panel =
>> + container_of(shell->panels.prev,
>> + struct shell_surface, link);
>> + wl_list_insert(&panel->surface->link, &surface->link);
>> + } else {
>> + wl_list_insert(list, &surface->link);
>> + }
>> }
>>
>> if (do_configure) {
>> @@ -1399,10 +1496,10 @@ configure(struct weston_shell *base, struct
>> weston_surface *surface,
>> do_configure = !do_configure;
>> /* fall through */
>> case SHELL_SURFACE_FULLSCREEN:
>> - center_on_output(surface, surface->fullscreen_output);
>> - break;
>> - default:
>> - break;
>> + center_on_output(surface, surface->fullscreen_output);
>> + break;
>> + default:
>> + break;
>> }
>>
>> /* XXX: would a fullscreen surface need the same handling? */
>> @@ -1589,8 +1686,10 @@ shell_init(struct weston_compositor *ec)
>> shell->shell.map = map;
>> shell->shell.configure = configure;
>> shell->shell.destroy = shell_destroy;
>> + shell->shell.prepare_repaint = prepare_repaint;
>>
>> wl_list_init(&shell->hidden_surface_list);
>> + wl_list_init(&shell->hidden_panels);
>> wl_list_init(&shell->backgrounds);
>> wl_list_init(&shell->panels);
>> wl_list_init(&shell->screensaver.surfaces);
>> --
>> 1.7.5.4
>>
>> _______________________________________________
>> wayland-devel mailing list
>> wayland-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>_______________________________________________
>wayland-devel mailing list
>wayland-devel at lists.freedesktop.org
>http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list