}
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
if (!window->custom) {
if (window->xdg_surface) {
window_sync_parent(window);
- window_sync_margin(window);
+ window_sync_geometry(window);
}
}
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;
};
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;
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);
}
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
}
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,
const char *app_id)
}
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)
{
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,
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) {
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);
<arg name="parent" type="object" interface="wl_surface" allow-null="true"/>
</request>
- <request name="set_margin">
- <description summary="set the visible frame boundaries">
- 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.
- </description>
- <arg name="left_margin" type="int"/>
- <arg name="right_margin" type="int"/>
- <arg name="top_margin" type="int"/>
- <arg name="bottom_margin" type="int"/>
- </request>
-
<request name="set_title">
<description summary="set surface title">
Set a short title for the surface.
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.
<arg name="serial" type="uint" summary="a serial to configure for"/>
</request>
+ <request name="set_window_geometry">
+ <description summary="set the new window geometry">
+ 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.
+ </description>
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </request>
+
<request name="set_maximized" />
<request name="unset_maximized" />