[PATCH weston 2/3] desktop-shell: use panel location to calculate correct sizes and ranges
Pekka Paalanen
ppaalanen at gmail.com
Wed Aug 20 07:08:05 PDT 2014
On Wed, 20 Aug 2014 15:53:20 +0200
Jonny Lamb <jonny.lamb at collabora.co.uk> wrote:
> Now the client can let us know where the panel is using
> desktop_shell.set_panel_position, we can correctly calculate where to
> put new views and how big maximized views should be.
> ---
> desktop-shell/shell.c | 173 ++++++++++++++++++++++++++++++++++----------------
> 1 file changed, 120 insertions(+), 53 deletions(-)
>
> diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
> index d307e48..e3abaad 100644
> --- a/desktop-shell/shell.c
> +++ b/desktop-shell/shell.c
> @@ -251,9 +251,10 @@ shell_fade_startup(struct desktop_shell *shell);
> static struct shell_seat *
> get_shell_seat(struct weston_seat *seat);
>
> -static int
> -get_output_panel_height(struct desktop_shell *shell,
> - struct weston_output *output);
> +static void
> +get_output_panel_size(struct desktop_shell *shell,
> + struct weston_output *output,
> + int *width, int *height);
>
> static void
> shell_surface_update_child_surface_layers(struct shell_surface *shsurf);
> @@ -351,24 +352,85 @@ shell_grab_start(struct shell_grab *grab,
> }
> }
>
> -static int
> -get_output_panel_height(struct desktop_shell *shell,
> - struct weston_output *output)
> +static void
> +get_output_panel_size(struct desktop_shell *shell,
> + struct weston_output *output,
> + int *width,
> + int *height)
> {
> struct weston_view *view;
> - int panel_height = 0;
> +
> + *width = 0;
> + *height = 0;
>
> if (!output)
> - return 0;
> + return;
>
> wl_list_for_each(view, &shell->panel_layer.view_list.link, layer_link.link) {
> - if (view->surface->output == output) {
> - panel_height = view->surface->height;
> + float x, y;
> +
> + if (view->surface->output != output)
> + continue;
> +
> + switch (shell->panel_position) {
> + case DESKTOP_SHELL_PANEL_POSITION_TOP:
> + case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
> +
> + weston_view_to_global_float(view,
> + view->surface->width, 0,
> + &x, &y);
> +
> + *width = (int) x;
> + *height = view->surface->height + (int) y;
> + return;
> +
> + case DESKTOP_SHELL_PANEL_POSITION_LEFT:
> + case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
> + weston_view_to_global_float(view,
> + 0, view->surface->height,
> + &x, &y);
> +
> + *width = view->surface->width + (int) x;
> + *height = (int) y;
> + return;
> +
> + default:
> + /* we've already set width and height to
> + * fallback values. */
> break;
> }
> }
>
> - return panel_height;
> + /* the correct view wasn't found */
> +}
> +
> +static void
> +get_output_work_area(struct desktop_shell *shell,
> + struct weston_output *output,
> + pixman_rectangle32_t *area)
> +{
> + int32_t panel_width = 0, panel_height = 0;
> +
> + area->x = 0;
> + area->y = 0;
> +
> + get_output_panel_size(shell, output, &panel_width, &panel_height);
> +
> + switch (shell->panel_position) {
> + case DESKTOP_SHELL_PANEL_POSITION_TOP:
> + default:
> + area->y = panel_height;
> + case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
> + area->width = output->width;
> + area->height = output->height - panel_height;
> + break;
> + case DESKTOP_SHELL_PANEL_POSITION_LEFT:
> + area->x = panel_width;
> + case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
> + area->width = output->width - panel_width;
> + area->height = output->height;
> + break;
> + }
> }
>
> static void
> @@ -389,13 +451,13 @@ send_configure_for_surface(struct shell_surface *shsurf)
> height = shsurf->output->height;
> } else if (state->maximized) {
> struct desktop_shell *shell;
> - uint32_t panel_height = 0;
> + pixman_rectangle32_t area;
>
> shell = shell_surface_get_shell(shsurf);
> - panel_height = get_output_panel_height(shell, shsurf->output);
> + get_output_work_area(shell, shsurf->output, &area);
>
> - width = shsurf->output->width;
> - height = shsurf->output->height - panel_height;
> + width = area.width;
> + height = area.height;
> } else {
> width = 0;
> height = 0;
> @@ -1550,20 +1612,25 @@ constrain_position(struct weston_move_grab *move, int *cx, int *cy)
> {
> struct shell_surface *shsurf = move->base.shsurf;
> struct weston_pointer *pointer = move->base.grab.pointer;
> - int x, y, panel_height, bottom;
> + int x, y, panel_width, panel_height, bottom;
> const int safety = 50;
>
> x = wl_fixed_to_int(pointer->x + move->dx);
> y = wl_fixed_to_int(pointer->y + move->dy);
>
> - panel_height = get_output_panel_height(shsurf->shell,
> - shsurf->surface->output);
> - bottom = y + shsurf->geometry.height;
> - if (bottom - panel_height < safety)
> - y = panel_height + safety - shsurf->geometry.height;
> + if (shsurf->shell->panel_position == DESKTOP_SHELL_PANEL_POSITION_TOP) {
> + get_output_panel_size(shsurf->shell, shsurf->surface->output,
> + &panel_width, &panel_height);
>
> - if (move->client_initiated && y + shsurf->geometry.y < panel_height)
> - y = panel_height - shsurf->geometry.y;
> + bottom = y + shsurf->geometry.height;
> + if (bottom - panel_height < safety)
> + y = panel_height + safety -
> + shsurf->geometry.height;
> +
> + if (move->client_initiated &&
> + y + shsurf->geometry.y < panel_height)
> + y = panel_height - shsurf->geometry.y;
> + }
>
> *cx = x;
> *cy = y;
> @@ -4974,10 +5041,11 @@ weston_view_set_initial_position(struct weston_view *view,
> {
> struct weston_compositor *compositor = shell->compositor;
> int ix = 0, iy = 0;
> - int range_x, range_y;
> - int dx, dy, x, y, panel_height;
> + int32_t range_x, range_y;
> + int32_t dx, dy, x, y;
> struct weston_output *output, *target_output = NULL;
> struct weston_seat *seat;
> + pixman_rectangle32_t area;
>
> /* As a heuristic place the new window on the same output as the
> * pointer. Falling back to the output containing 0, 0.
> @@ -5009,20 +5077,18 @@ weston_view_set_initial_position(struct weston_view *view,
> * If this is negative it means that the surface is bigger than
> * output.
> */
> - panel_height = get_output_panel_height(shell, target_output);
> - range_x = target_output->width - view->surface->width;
> - range_y = (target_output->height - panel_height) -
> - view->surface->height;
> + get_output_work_area(shell, target_output, &area);
> +
> + dx = area.x;
> + dy = area.y;
> + range_x = area.width - view->surface->width;
> + range_y = area.height - view->surface->height;
>
> if (range_x > 0)
> - dx = random() % range_x;
> - else
> - dx = 0;
> + dx += random() % range_x;
>
> if (range_y > 0)
> - dy = panel_height + random() % range_y;
> - else
> - dy = panel_height;
> + dy += random() % range_y;
>
> x = target_output->x + dx;
> y = target_output->y + dy;
> @@ -5031,13 +5097,28 @@ weston_view_set_initial_position(struct weston_view *view,
> }
>
> static void
> +set_maximized_position(struct desktop_shell *shell,
> + struct shell_surface *shsurf)
> +{
> + int32_t surf_x, surf_y;
> + pixman_rectangle32_t area;
> +
> + /* use surface configure to set the geometry */
> + get_output_work_area(shell, shsurf->output, &area);
> + surface_subsurfaces_boundingbox(shsurf->surface,
> + &surf_x, &surf_y, NULL, NULL);
> +
> + weston_view_set_position(shsurf->view,
> + area.x - surf_x,
> + area.y - surf_y);
> +}
> +
> +static void
> map(struct desktop_shell *shell, struct shell_surface *shsurf,
> int32_t sx, int32_t sy)
> {
> struct weston_compositor *compositor = shell->compositor;
> struct weston_seat *seat;
> - int panel_height = 0;
> - int32_t surf_x, surf_y;
>
> /* initial positioning, see also configure() */
> switch (shsurf->type) {
> @@ -5046,14 +5127,7 @@ map(struct desktop_shell *shell, struct shell_surface *shsurf,
> center_on_output(shsurf->view, shsurf->fullscreen_output);
> shell_map_fullscreen(shsurf);
> } else if (shsurf->state.maximized) {
> - /* use surface configure to set the geometry */
> - panel_height = get_output_panel_height(shell, shsurf->output);
> - surface_subsurfaces_boundingbox(shsurf->surface,
> - &surf_x, &surf_y, NULL, NULL);
> - weston_view_set_position(shsurf->view,
> - shsurf->output->x - surf_x,
> - shsurf->output->y +
> - panel_height - surf_y);
> + set_maximized_position(shell, shsurf);
> } else if (!shsurf->state.relative) {
> weston_view_set_initial_position(shsurf->view, shell);
> }
> @@ -5126,7 +5200,6 @@ configure(struct desktop_shell *shell, struct weston_surface *surface,
> {
> struct shell_surface *shsurf;
> struct weston_view *view;
> - int32_t mx, my, surf_x, surf_y;
>
> shsurf = get_shell_surface(surface);
>
> @@ -5135,13 +5208,7 @@ configure(struct desktop_shell *shell, struct weston_surface *surface,
> if (shsurf->state.fullscreen)
> shell_configure_fullscreen(shsurf);
> else if (shsurf->state.maximized) {
> - /* setting x, y and using configure to change that geometry */
> - surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y,
> - NULL, NULL);
> - mx = shsurf->output->x - surf_x;
> - my = shsurf->output->y +
> - get_output_panel_height(shell,shsurf->output) - surf_y;
> - weston_view_set_position(shsurf->view, mx, my);
> + set_maximized_position(shell, shsurf);
> } else {
> weston_view_set_position(shsurf->view, x, y);
> }
Hi,
these 2 patches pushed, but I am still looking at 3/3.
Thanks,
pq
More information about the wayland-devel
mailing list