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);
}
}