wayland: Pass shadow width to the compositor

Use xdg_surface_set_window_geometry() to tell the compositor about the
shadow widths, this makes some gnome-shell/mutter features (edge resistance,
frames around windows in the overview, side maximization, ...) work alright
with GTK+.

In order to add this, some other places in gdkwindow-wayland had to gain
some knowledge about margins:

- xdg_surface_configure() now syncs the shadow after applying the state,
  and gdk_wayland_window_set_shadow_width() possibly reconfigures the
  window in order to preserve window geometry. This is necessary to keep
  shadows in sync with state/geometry changes, as this does not happen
  all at once.
- xdg_popups relative to an xdg_surface are shown relative to buffer
  coordinates, so the left/top margins must be added there.

https://bugzilla.gnome.org/show_bug.cgi?id=736742
This commit is contained in:
Carlos Garnacho 2014-11-11 12:07:24 +01:00
parent 6b95810aae
commit 44c412ecc7

View File

@ -683,23 +683,17 @@ static void
gdk_wayland_window_sync_margin (GdkWindow *window)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
gint x, y, width, height;
if (!impl->xdg_surface)
return;
/* XXX: xdg_surface now has xdg_surface_set_window_geometry.
*
* We need to have a GdkToplevel or some other class in order
* to make this work correctly. For now, don't do anything with
* the shadow widths.
*/
#if 0
xdg_surface_set_margin (impl->xdg_surface,
impl->margin_left,
impl->margin_right,
impl->margin_top,
impl->margin_bottom);
#endif
x = impl->margin_left;
y = impl->margin_top;
width = window->width - (impl->margin_left + impl->margin_right);
height = window->height - (impl->margin_top + impl->margin_bottom);
xdg_surface_set_window_geometry (impl->xdg_surface, x, y, width, height);
}
static struct wl_region *
@ -858,8 +852,8 @@ xdg_surface_configure (void *data,
{
gdk_window_constrain_size (&impl->geometry_hints,
impl->geometry_mask,
width,
height,
width + impl->margin_left + impl->margin_right,
height + impl->margin_top + impl->margin_bottom,
&width,
&height);
@ -889,6 +883,7 @@ xdg_surface_configure (void *data,
}
_gdk_set_window_state (window, new_state);
gdk_wayland_window_sync_margin (window);
xdg_surface_ack_configure (xdg_surface, serial);
}
@ -1025,6 +1020,12 @@ gdk_wayland_window_create_xdg_popup (GdkWindow *window,
x = window->x - parent_x;
y = window->y - parent_y;
if (parent_impl->xdg_surface)
{
x -= parent_impl->margin_left;
y -= parent_impl->margin_top;
}
impl->xdg_popup = xdg_shell_get_xdg_popup (display_wayland->xdg_shell,
impl->surface,
parent_impl->surface,
@ -2047,10 +2048,22 @@ gdk_wayland_window_set_shadow_width (GdkWindow *window,
int bottom)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
gint new_width, new_height;
if (GDK_WINDOW_DESTROYED (window))
return;
if (left == impl->margin_left && right == impl->margin_right &&
top == impl->margin_top && bottom == impl->margin_bottom)
return;
/* Reconfigure window to keep the same window geometry */
new_width = window->width -
(impl->margin_left + impl->margin_right) + (left + right);
new_height = window->height -
(impl->margin_top + impl->margin_bottom) + (top + bottom);
gdk_wayland_window_configure (window, new_width, new_height);
impl->margin_left = left;
impl->margin_right = right;
impl->margin_top = top;