diff --git a/clients/window.c b/clients/window.c index f44bf643..1700cf9e 100644 --- a/clients/window.c +++ b/clients/window.c @@ -3894,24 +3894,33 @@ window_sync_parent(struct window *window) } static void -window_sync_margin(struct window *window) +window_get_geometry(struct window *window, struct rectangle *geometry) { - int margin; + if (window->frame) + frame_input_rect(window->frame->frame, + &geometry->x, + &geometry->y, + &geometry->width, + &geometry->height); + else + window_get_allocation(window, geometry); +} - if (!window->xdg_surface) - return; +static void +window_sync_geometry(struct window *window) +{ + struct rectangle geometry; - if (!window->frame) + if (!window->xdg_surface) return; - margin = frame_get_shadow_margin(window->frame->frame); + window_get_geometry(window, &geometry); - /* Shadow size is the same on every side. */ - xdg_surface_set_margin(window->xdg_surface, - margin, - margin, - margin, - margin); + xdg_surface_set_window_geometry(window->xdg_surface, + geometry.x, + geometry.y, + geometry.width, + geometry.height); } static void @@ -3922,7 +3931,7 @@ window_flush(struct window *window) if (!window->custom) { if (window->xdg_surface) { window_sync_parent(window); - window_sync_margin(window); + window_sync_geometry(window); } } diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index fca1c007..593c7f3b 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -171,9 +171,9 @@ struct shell_surface { bool state_requested; struct { - int left, right, top, bottom; - } margin, next_margin; - bool has_next_margin; + int32_t x, y, width, height; + } geometry, next_geometry; + bool has_set_geometry, has_next_geometry; int focus_count; }; @@ -1554,14 +1554,12 @@ constrain_position(struct weston_move_grab *move, int *cx, int *cy) panel_height = get_output_panel_height(shsurf->shell, shsurf->surface->output); - bottom = y + shsurf->surface->height - shsurf->margin.bottom; + bottom = y + shsurf->geometry.height; if (bottom - panel_height < safety) - y = panel_height + safety - - shsurf->surface->height + shsurf->margin.bottom; + y = panel_height + safety - shsurf->geometry.height; - if (move->client_initiated && - y + shsurf->margin.top < panel_height) - y = panel_height - shsurf->margin.top; + if (move->client_initiated && y + shsurf->geometry.y < panel_height) + y = panel_height - shsurf->geometry.y; *cx = x; *cy = y; @@ -1829,13 +1827,9 @@ surface_resize(struct shell_surface *shsurf, return -1; resize->edges = edges; - surface_subsurfaces_boundingbox(shsurf->surface, NULL, NULL, - &resize->width, &resize->height); - resize->width -= shsurf->margin.left; - resize->width -= shsurf->margin.right; - resize->height -= shsurf->margin.top; - resize->height -= shsurf->margin.bottom; + resize->width = shsurf->geometry.width; + resize->height = shsurf->geometry.height; shsurf->resize_edges = edges; shell_surface_state_changed(shsurf); @@ -2130,14 +2124,14 @@ set_title(struct shell_surface *shsurf, const char *title) } static void -set_margin(struct shell_surface *shsurf, - int32_t left, int32_t right, int32_t top, int32_t bottom) +set_window_geometry(struct shell_surface *shsurf, + int32_t x, int32_t y, int32_t width, int32_t height) { - shsurf->next_margin.left = left; - shsurf->next_margin.right = right; - shsurf->next_margin.top = top; - shsurf->next_margin.bottom = bottom; - shsurf->has_next_margin = true; + shsurf->next_geometry.x = x; + shsurf->next_geometry.y = y; + shsurf->next_geometry.width = width; + shsurf->next_geometry.height = height; + shsurf->has_next_geometry = true; } static void @@ -3398,19 +3392,6 @@ xdg_surface_set_parent(struct wl_client *client, shell_surface_set_parent(shsurf, parent); } -static void -xdg_surface_set_margin(struct wl_client *client, - struct wl_resource *resource, - int32_t left, - int32_t right, - int32_t top, - int32_t bottom) -{ - struct shell_surface *shsurf = wl_resource_get_user_data(resource); - - set_margin(shsurf, left, right, top, bottom); -} - static void xdg_surface_set_app_id(struct wl_client *client, struct wl_resource *resource, @@ -3471,6 +3452,19 @@ xdg_surface_ack_configure(struct wl_client *client, } } +static void +xdg_surface_set_window_geometry(struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + struct shell_surface *shsurf = wl_resource_get_user_data(resource); + + set_window_geometry(shsurf, x, y, width, height); +} + static void xdg_surface_set_maximized(struct wl_client *client, struct wl_resource *resource) @@ -3542,13 +3536,13 @@ xdg_surface_set_minimized(struct wl_client *client, static const struct xdg_surface_interface xdg_surface_implementation = { xdg_surface_destroy, xdg_surface_set_parent, - xdg_surface_set_margin, xdg_surface_set_title, xdg_surface_set_app_id, xdg_surface_show_window_menu, xdg_surface_move, xdg_surface_resize, xdg_surface_ack_configure, + xdg_surface_set_window_geometry, xdg_surface_set_maximized, xdg_surface_unset_maximized, xdg_surface_set_fullscreen, @@ -5141,9 +5135,16 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy) if (es->width == 0) return; - if (shsurf->has_next_margin) { - shsurf->margin = shsurf->next_margin; - shsurf->has_next_margin = false; + if (shsurf->has_next_geometry) { + shsurf->geometry = shsurf->next_geometry; + shsurf->has_next_geometry = false; + shsurf->has_set_geometry = true; + } else if (!shsurf->has_set_geometry) { + surface_subsurfaces_boundingbox(shsurf->surface, + &shsurf->geometry.x, + &shsurf->geometry.y, + &shsurf->geometry.width, + &shsurf->geometry.height); } if (shsurf->state_changed) { @@ -6200,7 +6201,7 @@ module_init(struct weston_compositor *ec, ec->shell_interface.move = shell_interface_move; ec->shell_interface.resize = surface_resize; ec->shell_interface.set_title = set_title; - ec->shell_interface.set_margin = set_margin; + ec->shell_interface.set_window_geometry = set_window_geometry; weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link); weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link); diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml index 0327f40a..9532644c 100644 --- a/protocol/xdg-shell.xml +++ b/protocol/xdg-shell.xml @@ -146,32 +146,6 @@ - - - This tells the compositor what the visible size of the window - should be, so it can use it to determine what borders to use for - constrainment and alignment. - - CSD often has invisible areas for decoration purposes, like drop - shadows. These "shadow" drawings need to be subtracted out of the - normal boundaries of the window when computing where to place - windows (e.g. to set this window so it's centered on top of another, - or to put it to the left or right of the screen.) - - This value should change as little as possible at runtime, to - prevent flicker. - - This value is also ignored when the window is maximized or - fullscreen, and assumed to be 0. - - If never called, this value is assumed to be 0. - - - - - - - Set a short title for the surface. @@ -308,7 +282,7 @@ The configure event asks the client to resize its surface. The width and height arguments specify a hint to the window - about how its surface should be resized in surface local + about how its surface should be resized in window geometry coordinates. The states listed in the event specify how the width/height arguments should be interpreted. @@ -339,6 +313,29 @@ + + + The window geometry of a window is its "visible bounds" from the + user's perspective. Client-side decorations often have invisible + portions like drop-shadows which should be ignored for the + purposes of aligning, placing and constraining windows. + + The default value is the full bounds of the surface, including any + subsurfaces. Once the window geometry of the surface is set once, + it is not possible to unset it, and it will remain the same until + set_window_geometry is called again, even if a new subsurface or + buffer is attached. + + If responding to a configure event, the window geometry in here + must respect the sizing negotiations specified by the states in + the configure event. + + + + + + + diff --git a/src/compositor.h b/src/compositor.h index bef5e1d9..d4a2dbb7 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -110,9 +110,9 @@ struct weston_shell_interface { struct weston_seat *ws, uint32_t edges); void (*set_title)(struct shell_surface *shsurf, const char *title); - void (*set_margin)(struct shell_surface *shsurf, - int32_t left, int32_t right, - int32_t top, int32_t bottom); + void (*set_window_geometry)(struct shell_surface *shsurf, + int32_t x, int32_t y, + int32_t width, int32_t height); }; struct weston_animation { diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index 2fb65b1a..625a0e6b 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -1007,12 +1007,9 @@ weston_wm_window_draw_decoration(void *data) pixman_region32_init_rect(&window->surface->pending.input, input_x, input_y, input_w, input_h); - - shell_interface->set_margin(window->shsurf, - input_x, - width - input_w - input_x, - input_y, - height - input_h - input_y); + + shell_interface->set_window_geometry(window->shsurf, + input_x, input_y, input_w, input_h); } }