[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