On Sun, 28 Apr 2013 20:14:50 +0200 Jonas Ådahl <[email protected]> wrote:
> On Thu, Apr 25, 2013 at 12:57 PM, Pekka Paalanen > <[email protected]> wrote: > > From: Giulio Camuffo <[email protected]> > > > > 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 <[email protected]> > > --- > > 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 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
