diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index f01a42886..3dce723c6 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -209,16 +209,40 @@ toplevel_surface_commit (MetaWaylandSurface *surface,
return;
}
- if (pending->frame_extents_changed)
- meta_window_set_custom_frame_extents (surface->window, &pending->frame_extents);
-
/* We resize X based surfaces according to X events */
if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
{
MetaRectangle geom;
- calculate_surface_window_geometry (surface, &geom, 0, 0);
- meta_window_client_rect_to_frame_rect (window, &geom, &geom);
+ if (pending->has_new_geometry)
+ {
+ /* If we have new geometry, use it. */
+ geom = pending->new_geometry;
+ surface->has_set_geometry = TRUE;
+ }
+ else if (!surface->has_set_geometry)
+ {
+ /* If the surface has never set any geometry, calculate
+ * a default one unioning the surface and all subsurfaces together. */
+ calculate_surface_window_geometry (surface, &geom, 0, 0);
+ }
+ else
+ {
+ /* Otherwise, keep the geometry the same. */
+
+ /* XXX: We don't store the geometry in any consistent place
+ * right now, so we can't re-fetch it. We should change
+ * meta_window_wayland_move_resize. */
+
+ /* XXX: This is the common case. Recognize it to prevent
+ * a warning. */
+ if (pending->dx == 0 && pending->dy == 0)
+ return;
+
+ g_warning ("XXX: Attach-initiated move without a new geometry. This is unimplemented right now.");
+ return;
+ }
+
meta_window_wayland_move_resize (window, geom, pending->dx, pending->dy);
}
}
@@ -247,7 +271,7 @@ pending_state_init (MetaWaylandPendingState *state)
state->buffer_destroy_listener.notify = surface_handle_pending_buffer_destroy;
wl_list_init (&state->frame_callback_list);
- state->frame_extents_changed = FALSE;
+ state->has_new_geometry = FALSE;
}
static void
@@ -756,23 +780,6 @@ xdg_surface_set_parent (struct wl_client *client,
meta_window_set_transient_for (surface->window, transient_for);
}
-static void
-xdg_surface_set_margin (struct wl_client *client,
- struct wl_resource *resource,
- int32_t left_margin,
- int32_t right_margin,
- int32_t top_margin,
- int32_t bottom_margin)
-{
- MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
-
- surface->pending.frame_extents_changed = TRUE;
- surface->pending.frame_extents.left = left_margin;
- surface->pending.frame_extents.right = right_margin;
- surface->pending.frame_extents.top = top_margin;
- surface->pending.frame_extents.bottom = bottom_margin;
-}
-
static void
xdg_surface_set_title (struct wl_client *client,
struct wl_resource *resource,
@@ -903,6 +910,20 @@ xdg_surface_ack_configure (struct wl_client *client,
* client gets the new state. */
}
+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)
+{
+ MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
+
+ surface->pending.has_new_geometry = TRUE;
+ surface->pending.new_geometry.x = x;
+ surface->pending.new_geometry.y = y;
+ surface->pending.new_geometry.width = width;
+ surface->pending.new_geometry.height = height;
+}
+
static void
xdg_surface_set_maximized (struct wl_client *client,
struct wl_resource *resource)
@@ -947,13 +968,13 @@ xdg_surface_set_minimized (struct wl_client *client,
static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = {
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,
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index c808e6dc6..582d07d4e 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -61,8 +61,8 @@ typedef struct
/* wl_surface.frame */
struct wl_list frame_callback_list;
- gboolean frame_extents_changed;
- GtkBorder frame_extents;
+ MetaRectangle new_geometry;
+ gboolean has_new_geometry;
} MetaWaylandPendingState;
typedef struct
@@ -109,6 +109,8 @@ struct _MetaWaylandSurface
GSList *pending_placement_ops;
} sub;
+ gboolean has_set_geometry;
+
/* All the pending state that wl_surface.commit will apply. */
MetaWaylandPendingState pending;
};
diff --git a/src/wayland/protocol/xdg-shell.xml b/src/wayland/protocol/xdg-shell.xml
index 0327f40ab..9532644ca 100644
--- a/src/wayland/protocol/xdg-shell.xml
+++ b/src/wayland/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.
+
+
+
+
+
+
+