[PATCH weston v3 06/13] shell: account for the subsurfaces when going fullscreen or maximizing
Pekka Paalanen
ppaalanen at gmail.com
Mon Apr 29 00:19:20 PDT 2013
On Sun, 28 Apr 2013 20:14:50 +0200
Jonas Ådahl <jadahl at gmail.com> wrote:
> On Thu, Apr 25, 2013 at 12:57 PM, Pekka Paalanen
> <ppaalanen at gmail.com> wrote:
> > From: Giulio Camuffo <giuliocamuffo at gmail.com>
> >
> > We must calculate the bounding box of the surface + subsurfaces set
> > and use that when maximizing the window or going fullscreen.
> >
> > Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
> > ---
> > src/shell.c | 89
> > ++++++++++++++++++++++++++++++++++++++++++++++--------------- 1
> > file changed, 68 insertions(+), 21 deletions(-)
> >
> > diff --git a/src/shell.c b/src/shell.c
> > index 86bdd84..39df27a 100644
> > --- a/src/shell.c
> > +++ b/src/shell.c
> > @@ -1203,6 +1203,41 @@ static const struct
> > wl_pointer_grab_interface resize_grab_interface =
> > { resize_grab_button, };
> >
> > +/*
> > + * Returns the bounding box of a surface and all its sub-surfaces,
> > + * in the surface coordinates system. */
> > +static void
> > +surface_subsurfaces_boundingbox(struct weston_surface *surface,
> > int32_t *x,
> > + int32_t *y, int32_t *w, int32_t *h)
> > {
>
> Wouldn't it be better if we left sub-compositor details to the
> compositor and instead use a generic "weston_surface_get_bounds()"
> function to get the collective bounding box of the given surface and
> associated sub-surfaces?
Yeah, that's a good point. Another thing is, should this be computed
from the surface sizes like here, or from input regions, or from ...
regions?
We had some talk about adding a "window region" or something in the
past, that would be used for edge snapping and stuff, or was it deemed
that input region was enough; I can't recall.
If this should be computed from core features like the input region,
then we could indeed make this a Weston core function.
Oh and I just realized, this code does not recurse, so it does not
handle nested sub-surfaces.
Thanks,
pq
> > + pixman_region32_t region;
> > + pixman_box32_t *box;
> > + struct weston_subsurface *subsurface;
> > +
> > + pixman_region32_init_rect(®ion, 0, 0,
> > + surface->geometry.width,
> > + surface->geometry.height);
> > +
> > + wl_list_for_each(subsurface, &surface->subsurface_list,
> > parent_link) {
> > + pixman_region32_union_rect(®ion, ®ion,
> > + subsurface->position.x,
> > + subsurface->position.y,
> > +
> > subsurface->surface->geometry.width,
> > +
> > subsurface->surface->geometry.height);
> > + }
> > +
> > + box = pixman_region32_extents(®ion);
> > + if (x)
> > + *x = box->x1;
> > + if (y)
> > + *y = box->y1;
> > + if (w)
> > + *w = box->x2 - box->x1;
> > + if (h)
> > + *h = box->y2 - box->y1;
> > +
> > + pixman_region32_fini(®ion);
> > +}
> > +
> > static int
> > surface_resize(struct shell_surface *shsurf,
> > struct weston_seat *ws, uint32_t edges)
> > @@ -1222,8 +1257,8 @@ surface_resize(struct shell_surface *shsurf,
> > return -1;
> >
> > resize->edges = edges;
> > - resize->width = shsurf->surface->geometry.width;
> > - resize->height = shsurf->surface->geometry.height;
> > + surface_subsurfaces_boundingbox(shsurf->surface, NULL, NULL,
> > + &resize->width,
> > &resize->height);
> >
> > shell_grab_start(&resize->base, &resize_grab_interface,
> > shsurf, ws->seat.pointer, edges);
> > @@ -1726,6 +1761,7 @@ shell_configure_fullscreen(struct
> > shell_surface *shsurf) struct weston_surface *surface =
> > shsurf->surface; struct weston_matrix *matrix;
> > float scale, output_aspect, surface_aspect, x, y;
> > + int32_t surf_x, surf_y, surf_width, surf_height;
> >
> > if (!shsurf->fullscreen.black_surface)
> > shsurf->fullscreen.black_surface =
> > @@ -1740,6 +1776,9 @@ shell_configure_fullscreen(struct
> > shell_surface *shsurf)
> > &shsurf->fullscreen.black_surface->layer_link);
> > shsurf->fullscreen.black_surface->output = output;
> >
> > + surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y,
> > + &surf_width, &surf_height);
> > +
> > switch (shsurf->fullscreen.type) {
> > case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT:
> > if (surface->buffer_ref.buffer)
> > @@ -1747,9 +1786,10 @@ shell_configure_fullscreen(struct
> > shell_surface *shsurf) break;
> > case WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE:
> > /* 1:1 mapping between surface and output
> > dimensions */
> > - if (output->width == surface->geometry.width &&
> > - output->height == surface->geometry.height) {
> > - weston_surface_set_position(surface,
> > output->x, output->y);
> > + if (output->width == surf_width &&
> > + output->height == surf_height) {
> > + weston_surface_set_position(surface,
> > output->x - surf_x,
> > +
> > output->y - surf_y); break;
> > }
> >
> > @@ -1762,33 +1802,33 @@ shell_configure_fullscreen(struct
> > shell_surface *shsurf) (float) surface->geometry.height;
> > if (output_aspect < surface_aspect)
> > scale = (float) output->width /
> > - (float) surface->geometry.width;
> > + (float) surf_width;
> > else
> > scale = (float) output->height /
> > - (float) surface->geometry.height;
> > + (float) surf_height;
> >
> > weston_matrix_scale(matrix, scale, scale, 1);
> > wl_list_remove(&shsurf->fullscreen.transform.link);
> > wl_list_insert(&surface->geometry.transformation_list,
> > &shsurf->fullscreen.transform.link);
> > - x = output->x + (output->width -
> > surface->geometry.width * scale) / 2;
> > - y = output->y + (output->height -
> > surface->geometry.height * scale) / 2;
> > + x = output->x + (output->width - surf_width *
> > scale) / 2 - surf_x;
> > + y = output->y + (output->height - surf_height *
> > scale) / 2 - surf_y; weston_surface_set_position(surface, x, y);
> >
> > break;
> > case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER:
> > if (shell_surface_is_top_fullscreen(shsurf)) {
> > struct weston_mode mode = {0,
> > - surface->geometry.width,
> > - surface->geometry.height,
> > + surf_width,
> > + surf_height,
> > shsurf->fullscreen.framerate};
> >
> > if (weston_output_switch_mode(output,
> > &mode) == 0)
> > { weston_surface_configure(shsurf->fullscreen.black_surface,
> > - output->x,
> > output->y,
> > + output->x
> > - surf_x,
> > + output->y
> > - surf_y, output->width,
> > output->height);
> > -
> > weston_surface_set_position(surface, output->x, output->y); break;
> > }
> > }
> > @@ -3122,12 +3162,13 @@ hide_input_panels(struct wl_listener
> > *listener, void *data) static void
> > center_on_output(struct weston_surface *surface, struct
> > weston_output *output) {
> > - int32_t width = weston_surface_buffer_width(surface);
> > - int32_t height = weston_surface_buffer_height(surface);
> > + int32_t surf_x, surf_y, width, height;
> > float x, y;
> >
> > - x = output->x + (output->width - width) / 2;
> > - y = output->y + (output->height - height) / 2;
> > + surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y,
> > &width, &height); +
> > + x = output->x + (output->width - width) / 2 - surf_x / 2;
> > + y = output->y + (output->height - height) / 2 - surf_y / 2;
> >
> > weston_surface_configure(surface, x, y, width, height);
> > }
> > @@ -3205,6 +3246,7 @@ map(struct desktop_shell *shell, struct
> > weston_surface *surface, struct weston_seat *seat;
> > struct workspace *ws;
> > int panel_height = 0;
> > + int32_t surf_x, surf_y;
> >
> > surface->geometry.width = width;
> > surface->geometry.height = height;
> > @@ -3222,8 +3264,10 @@ map(struct desktop_shell *shell, struct
> > weston_surface *surface, case SHELL_SURFACE_MAXIMIZED:
> > /* use surface configure to set the geometry */
> > panel_height =
> > get_output_panel_height(shell,surface->output);
> > - weston_surface_set_position(surface,
> > shsurf->output->x,
> > - shsurf->output->y +
> > panel_height);
> > + surface_subsurfaces_boundingbox(shsurf->surface,
> > &surf_x, &surf_y,
> > +
> > NULL, NULL);
> > + weston_surface_set_position(surface,
> > shsurf->output->x - surf_x,
> > + shsurf->output->y +
> > panel_height - surf_y); break;
> > case SHELL_SURFACE_POPUP:
> > shell_map_popup(shsurf);
> > @@ -3297,6 +3341,7 @@ configure(struct desktop_shell *shell, struct
> > weston_surface *surface, {
> > enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
> > struct shell_surface *shsurf;
> > + int32_t surf_x, surf_y;
> >
> > shsurf = get_shell_surface(surface);
> > if (shsurf)
> > @@ -3311,9 +3356,11 @@ configure(struct desktop_shell *shell,
> > struct weston_surface *surface, break;
> > case SHELL_SURFACE_MAXIMIZED:
> > /* setting x, y and using configure to change that
> > geometry */
> > - surface->geometry.x = surface->output->x;
> > + surface_subsurfaces_boundingbox(shsurf->surface,
> > &surf_x, &surf_y,
> > +
> > NULL, NULL);
> > + surface->geometry.x = surface->output->x - surf_x;
> > surface->geometry.y = surface->output->y +
> > -
> > get_output_panel_height(shell,surface->output);
> > + get_output_panel_height(shell,surface->output) -
> > surf_y; break;
> > case SHELL_SURFACE_TOPLEVEL:
> > break;
> > --
> > 1.8.1.5
> >
>
> Jonas
More information about the wayland-devel
mailing list