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. + + + + + + +