[PATCH v2 1/4] shell: add fullscreen path for activate() and switcher
Kristian Hoegsberg
hoegsberg at gmail.com
Thu Mar 29 08:37:42 PDT 2012
On Tue, Mar 13, 2012 at 11:18:23PM +0800, zhiwen.wu at linux.intel.com wrote:
> From: Alex Wu <zhiwen.wu at linux.intel.com>
>
> For activate(), stack the surface atop fullscreen layer instead of
> toplevel layer.
> For switcher, involve the fullscreen surfaces into surface iteration,
> and make fullscreen surface and its black surface transparent if
> necessary.
Sorry for the long delay in reviewing this. Comments below.
Kristian
> ---
> src/shell.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++---------
> 1 files changed, 59 insertions(+), 11 deletions(-)
>
> diff --git a/src/shell.c b/src/shell.c
> index 765b0a4..984c75d 100644
> --- a/src/shell.c
> +++ b/src/shell.c
> @@ -144,6 +144,9 @@ struct rotate_grab {
> } center;
> };
>
> +static struct shell_surface *
> +get_shell_surface(struct weston_surface *surface);
> +
> static void
> center_on_output(struct weston_surface *surface,
> struct weston_output *output);
> @@ -1344,6 +1347,7 @@ activate(struct weston_shell *base, struct weston_surface *es,
> {
> struct wl_shell *shell = container_of(base, struct wl_shell, shell);
> struct weston_compositor *compositor = shell->compositor;
> + struct wl_list *lst;
>
> weston_surface_activate(es, device, time);
>
> @@ -1364,14 +1368,48 @@ activate(struct weston_shell *base, struct weston_surface *es,
> break;
> case SHELL_SURFACE_FULLSCREEN:
> /* should on top of panels */
> + shell_stack_fullscreen(get_shell_surface(es));
> break;
> default:
> - weston_surface_restack(es,
> - &shell->toplevel_layer.surface_list);
> + if (wl_list_empty(&shell->fullscreen_layer.surface_list))
> + lst = &shell->toplevel_layer.surface_list;
> + else
> + lst = &shell->fullscreen_layer.surface_list;
> + weston_surface_restack(es, lst);
Isn't this putting the surface (which could be a regular toplevel)
into the fullscreen layer? What we need instead is to move the
fullscreen surface down into the toplevel layer if another surface is
activated.
> break;
> }
> }
>
> +
> +static struct weston_surface *
> +get_upper_surface(struct weston_surface *es)
> +{
> + if (es->link.prev == &es->compositor->surface_list)
> + return NULL;
> +
> + return container_of(es->link.prev, struct weston_surface, link);
> +}
> +
> +static struct weston_surface *
> +get_lower_surface(struct weston_surface *es)
> +{
> + if (es->link.next == &es->compositor->surface_list)
> + return NULL;
> +
> + return container_of(es->link.next, struct weston_surface, link);
> +}
> +
> +static bool
> +is_black_surface(struct weston_surface *es)
> +{
> + struct weston_surface *upper;
> +
> + if ((upper = get_upper_surface(es)) &&
> + get_shell_surface_type(upper) == SHELL_SURFACE_FULLSCREEN)
> + return true;
> + return false;
> +}
Instead of this fragile get_upper/get_lower stuff, I think we just
need to set a destroy listener on the black surface so we can
recognize it like we recognize shell surfaces in get_shell_surface.
The destroy function shouldn't do anything, but we'll be able to
recognize the black surface by it. Embed the wl_listener as
shell_surface.fullscreen.destroy_listener, and that way
we can get the associated fullscreen surface as
shsurf = container_of(listener, struct shell_surface, fullscreen.destroy_listener);
then we could do something like
is_black_surface(surface, &upper);
which does all this and returns the upper surface if it's a black
surface.
> static void
> click_to_activate_binding(struct wl_input_device *device,
> uint32_t time, uint32_t key,
> @@ -1380,19 +1418,13 @@ click_to_activate_binding(struct wl_input_device *device,
> struct weston_input_device *wd = (struct weston_input_device *) device;
> struct weston_compositor *compositor = data;
> struct weston_surface *focus;
> - struct weston_surface *upper;
>
> focus = (struct weston_surface *) device->pointer_focus;
> if (!focus)
> return;
>
> - upper = container_of(focus->link.prev, struct weston_surface, link);
> - if (focus->link.prev != &compositor->surface_list &&
> - get_shell_surface_type(upper) == SHELL_SURFACE_FULLSCREEN) {
> - printf("%s: focus is black surface, raise its fullscreen surface\n", __func__);
> - shell_stack_fullscreen(get_shell_surface(upper));
> - focus = upper;
> - }
> + if (is_black_surface(focus))
> + focus = get_upper_surface(focus);
>
> if (state && device->pointer_grab == &device->default_pointer_grab)
> activate(compositor->shell, focus, wd, time);
> @@ -1833,6 +1865,12 @@ switcher_next(struct switcher *switcher)
> weston_surface_damage(surface);
> break;
> default:
> + if (is_black_surface(surface)) {
> + weston_surface_set_color(surface,
> + 0.0, 0.0, 0.0, (GLfloat)64/(GLfloat)255);
We should just set the alpha for solid color surfaces here... which I
just added support for in master :) Also, I would put the if statement
outside the switch, which is just for shell surface types.
> + surface->geometry.dirty = 1;
> + weston_surface_damage(surface);
> + }
> break;
> }
> }
> @@ -1840,12 +1878,19 @@ switcher_next(struct switcher *switcher)
> if (next == NULL)
> next = first;
>
> + if (next == NULL)
> + return;
> +
> wl_list_remove(&switcher->listener.link);
> wl_list_insert(next->surface.resource.destroy_listener_list.prev,
> &switcher->listener.link);
>
> switcher->current = next;
> next->alpha = 255;
> +
> + if (get_shell_surface_type(next) == SHELL_SURFACE_FULLSCREEN) {
> + weston_surface_set_color(get_lower_surface(next), 0.0, 0.0, 0.0, 1.0);
This shouldn't be nececssary now.
> + }
> }
>
> static void
> @@ -1867,11 +1912,14 @@ switcher_destroy(struct switcher *switcher, uint32_t time)
> (struct weston_input_device *) switcher->grab.input_device;
>
> wl_list_for_each(surface, &compositor->surface_list, link) {
> + if (is_black_surface(surface))
> + weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
This shouldn't be nececssary now.
> surface->alpha = 255;
> weston_surface_damage(surface);
> }
>
> - activate(compositor->shell, switcher->current, device, time);
> + if (switcher->current)
> + activate(compositor->shell, switcher->current, device, time);
> wl_list_remove(&switcher->listener.link);
> wl_input_device_end_keyboard_grab(&device->input_device, time);
> free(switcher);
> --
> 1.7.5.4
>
More information about the wayland-devel
mailing list