gdk: Always get shadow width via GdkToplevelSize

This removes the gdk_surface_set_shadow_width() function and related
vfuncs. The point here is that the shadow width and surface size can now
be communicated to GDK atomically, meaning it's possible to avoid
intermediate stages where the surface size includes the shadow, but
without the shadow width set, or the other way around.
This commit is contained in:
Jonas Ådahl 2020-12-02 14:58:45 +01:00
parent 0dcd4a5bdb
commit 3f96d4b6da
14 changed files with 77 additions and 103 deletions

View File

@ -203,7 +203,6 @@ gdk_surface_get_cursor
gdk_surface_set_input_region
gdk_surface_get_width
gdk_surface_get_height
gdk_surface_set_shadow_width
gdk_surface_get_device_position
GdkModifierType
GDK_MODIFIER_MASK

View File

@ -558,6 +558,7 @@ gdk_broadway_surface_layout_popup (GdkSurface *surface,
int height,
GdkPopupLayout *layout)
{
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkMonitor *monitor;
GdkRectangle bounds;
GdkRectangle final_rect;
@ -570,6 +571,10 @@ gdk_broadway_surface_layout_popup (GdkSurface *surface,
gdk_surface_layout_popup_helper (surface,
width,
height,
impl->shadow_left,
impl->shadow_right,
impl->shadow_top,
impl->shadow_bottom,
monitor,
&bounds,
layout,
@ -1529,6 +1534,7 @@ gdk_broadway_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor;
GdkToplevelSize size;
@ -1582,6 +1588,14 @@ gdk_broadway_toplevel_present (GdkToplevel *toplevel,
else
gdk_broadway_surface_unmaximize (surface);
if (size.margin.is_valid)
{
impl->shadow_left = size.margin.left;
impl->shadow_right = size.margin.right;
impl->shadow_top = size.margin.top;
impl->shadow_bottom = size.margin.bottom;
}
show_surface (surface);
}

View File

@ -64,6 +64,11 @@ struct _GdkBroadwaySurface
int root_x;
int root_y;
int shadow_left;
int shadow_right;
int shadow_top;
int shadow_bottom;
};
struct _GdkBroadwaySurfaceClass

View File

@ -285,6 +285,10 @@ void
gdk_surface_layout_popup_helper (GdkSurface *surface,
int width,
int height,
int shadow_left,
int shadow_right,
int shadow_top,
int shadow_bottom,
GdkMonitor *monitor,
GdkRectangle *bounds,
GdkPopupLayout *layout,
@ -315,8 +319,8 @@ gdk_surface_layout_popup_helper (GdkSurface *surface,
gdk_popup_layout_get_offset (layout, &rect_anchor_dx, &rect_anchor_dy);
anchor_hints = gdk_popup_layout_get_anchor_hints (layout);
final_rect.width = width - surface->shadow_left - surface->shadow_right;
final_rect.height = height - surface->shadow_top - surface->shadow_bottom;
final_rect.width = width - shadow_left - shadow_right;
final_rect.height = height - shadow_top - shadow_bottom;
final_rect.x = maybe_flip_position (bounds->x,
bounds->width,
root_rect.x,
@ -380,10 +384,10 @@ gdk_surface_layout_popup_helper (GdkSurface *surface,
final_rect.height = bounds->y + bounds->height - final_rect.y;
}
final_rect.x -= surface->shadow_left;
final_rect.y -= surface->shadow_top;
final_rect.width += surface->shadow_left + surface->shadow_right;
final_rect.height += surface->shadow_top + surface->shadow_bottom;
final_rect.x -= shadow_left;
final_rect.y -= shadow_top;
final_rect.width += shadow_left + shadow_right;
final_rect.height += shadow_top + shadow_bottom;
gdk_surface_get_origin (surface->parent, &x, &y);
final_rect.x -= x;
@ -2646,53 +2650,6 @@ gdk_surface_set_opaque_region (GdkSurface *surface,
class->set_opaque_region (surface, region);
}
/**
* gdk_surface_set_shadow_width:
* @surface: a #GdkSurface
* @left: The left extent
* @right: The right extent
* @top: The top extent
* @bottom: The bottom extent
*
* Newer GTK windows using client-side decorations use extra geometry
* around their frames for effects like shadows and invisible borders.
* Window managers that want to maximize windows or snap to edges need
* to know where the extents of the actual frame lie, so that users
* dont feel like windows are snapping against random invisible edges.
*
* Note that this property is automatically updated by GTK, so this
* function should only be used by applications which do not use GTK
* to create toplevel surfaces.
*/
void
gdk_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom)
{
GdkSurfaceClass *class;
g_return_if_fail (GDK_IS_SURFACE (surface));
g_return_if_fail (!GDK_SURFACE_DESTROYED (surface));
g_return_if_fail (left >= 0 && right >= 0 && top >= 0 && bottom >= 0);
if (surface->shadow_left == left &&
surface->shadow_right == right &&
surface->shadow_top == top &&
surface->shadow_bottom == bottom)
return;
surface->shadow_top = top;
surface->shadow_left = left;
surface->shadow_right = right;
surface->shadow_bottom = bottom;
class = GDK_SURFACE_GET_CLASS (surface);
if (class->set_shadow_width)
class->set_shadow_width (surface, left, right, top, bottom);
}
void
gdk_surface_set_state (GdkSurface *surface,
GdkToplevelState new_state)

View File

@ -128,13 +128,6 @@ GDK_AVAILABLE_IN_ALL
void gdk_surface_set_opaque_region (GdkSurface *surface,
cairo_region_t *region);
GDK_AVAILABLE_IN_ALL
void gdk_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom);
GDK_AVAILABLE_IN_ALL
GdkCairoContext *gdk_surface_create_cairo_context(GdkSurface *surface);
GDK_AVAILABLE_IN_ALL

View File

@ -84,10 +84,6 @@ struct _GdkSurface
guint update_and_descendants_freeze_count;
int width, height;
int shadow_top;
int shadow_left;
int shadow_right;
int shadow_bottom;
GdkCursor *cursor;
GHashTable *device_cursor;
@ -161,11 +157,6 @@ struct _GdkSurfaceClass
void (* set_opaque_region) (GdkSurface *surface,
cairo_region_t *region);
void (* set_shadow_width) (GdkSurface *surface,
int left,
int right,
int top,
int bottom);
GdkGLContext *(*create_gl_context) (GdkSurface *surface,
gboolean attached,
GdkGLContext *share,
@ -190,6 +181,10 @@ GdkMonitor * gdk_surface_get_layout_monitor (GdkSurface *surface,
void gdk_surface_layout_popup_helper (GdkSurface *surface,
int width,
int height,
int shadow_left,
int shadow_right,
int shadow_top,
int shadow_bottom,
GdkMonitor *monitor,
GdkRectangle *bounds,
GdkPopupLayout *layout,

View File

@ -69,6 +69,10 @@ gdk_macos_popup_surface_layout (GdkMacosPopupSurface *self,
gdk_surface_layout_popup_helper (GDK_SURFACE (self),
width,
height,
self->parent_instance.shadow_left,
self->parent_instance.shadow_right,
self->parent_instance.shadow_top,
self->parent_instance.shadow_bottom,
monitor,
&bounds,
self->layout,

View File

@ -125,6 +125,11 @@ void _gdk_macos_surface_set_opacity (GdkMacosSurface
void _gdk_macos_surface_get_root_coords (GdkMacosSurface *self,
int *x,
int *y);
void _gdk_macos_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom);
G_END_DECLS

View File

@ -139,7 +139,7 @@ gdk_macos_surface_get_scale_factor (GdkSurface *surface)
return [self->window backingScaleFactor];
}
static void
void
gdk_macos_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
@ -491,7 +491,6 @@ gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
surface_class->hide = gdk_macos_surface_hide;
surface_class->set_input_region = gdk_macos_surface_set_input_region;
surface_class->set_opaque_region = gdk_macos_surface_set_opaque_region;
surface_class->set_shadow_width = gdk_macos_surface_set_shadow_width;
properties [PROP_NATIVE] =
g_param_spec_pointer ("native",

View File

@ -155,6 +155,15 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
if (style_mask != [nswindow styleMask])
[nswindow setStyleMask:style_mask];
if (size.margin.is_valid)
{
_gdk_macos_surface_set_shadow_width (surface,
size.margin.left,
size.margin.right,
size.margin.top,
size.margin.bottom);
}
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
_gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);

View File

@ -1537,6 +1537,7 @@ static void
gdk_wayland_surface_configure_popup (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (surface->parent);
int x, y, width, height;
if (impl->display_server.xdg_popup)
@ -1576,8 +1577,8 @@ gdk_wayland_surface_configure_popup (GdkSurface *surface)
width = impl->pending.popup.width;
height = impl->pending.popup.height;
x += surface->parent->shadow_left;
y += surface->parent->shadow_top;
x += parent_impl->margin_left;
y += parent_impl->margin_top;
update_popup_layout_state (surface,
x, y,
@ -2449,6 +2450,7 @@ create_dynamic_positioner (GdkSurface *surface,
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkSurface *parent = surface->parent;
GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (parent);
GdkWaylandDisplay *display =
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkRectangle geometry;
@ -2470,8 +2472,8 @@ create_dynamic_positioner (GdkSurface *surface,
};
anchor_rect = gdk_popup_layout_get_anchor_rect (layout);
real_anchor_rect_x = anchor_rect->x - parent->shadow_left;
real_anchor_rect_y = anchor_rect->y - parent->shadow_top;
real_anchor_rect_x = anchor_rect->x - parent_impl->margin_left;
real_anchor_rect_y = anchor_rect->y - parent_impl->margin_top;
anchor_rect_width = MAX (anchor_rect->width, 1);
anchor_rect_height = MAX (anchor_rect->height, 1);
@ -2530,7 +2532,6 @@ create_dynamic_positioner (GdkSurface *surface,
xdg_positioner_get_version (positioner) >=
XDG_POSITIONER_SET_PARENT_CONFIGURE_SINCE_VERSION)
{
GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (parent);
int parent_width;
int parent_height;
@ -4068,15 +4069,6 @@ gdk_wayland_surface_set_opaque_region (GdkSurface *surface,
impl->opaque_region_dirty = TRUE;
}
static void
gdk_wayland_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom)
{
}
static gboolean
gdk_wayland_surface_show_window_menu (GdkSurface *surface,
GdkEvent *event)
@ -4161,7 +4153,6 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
impl_class->drag_begin = _gdk_wayland_surface_drag_begin;
impl_class->get_scale_factor = gdk_wayland_surface_get_scale_factor;
impl_class->set_opaque_region = gdk_wayland_surface_set_opaque_region;
impl_class->set_shadow_width = gdk_wayland_surface_set_shadow_width;
impl_class->create_gl_context = gdk_wayland_surface_create_gl_context;
impl_class->request_layout = gdk_wayland_surface_request_layout;
impl_class->compute_size = gdk_wayland_surface_compute_size;

View File

@ -1217,6 +1217,7 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
int height,
GdkPopupLayout *layout)
{
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
GdkMonitor *monitor;
GdkRectangle bounds;
GdkRectangle final_rect;
@ -1229,6 +1230,10 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
gdk_surface_layout_popup_helper (surface,
width,
height,
impl->margins.left,
impl->margins.right,
impl->margins.top,
impl->margins.bottom,
monitor,
&bounds,
layout,
@ -4615,8 +4620,6 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
//impl_class->beep = gdk_x11_surface_beep;
impl_class->set_shadow_width = gdk_win32_surface_set_shadow_width;
impl_class->destroy_notify = gdk_win32_surface_destroy_notify;
impl_class->drag_begin = _gdk_win32_surface_drag_begin;
impl_class->create_gl_context = _gdk_win32_surface_create_gl_context;
@ -4992,6 +4995,15 @@ gdk_win32_toplevel_present (GdkToplevel *toplevel,
show_surface (surface);
if (size.margin.is_valid)
{
gdk_win32_surface_set_shadow_width (surface,
size.margin.left,
size.margin.right,
size.margin.top,
size.margin.bottom);
}
return TRUE;
}

View File

@ -1664,6 +1664,7 @@ gdk_x11_surface_layout_popup (GdkSurface *surface,
int height,
GdkPopupLayout *layout)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
GdkMonitor *monitor;
GdkRectangle bounds;
GdkRectangle final_rect;
@ -1676,6 +1677,10 @@ gdk_x11_surface_layout_popup (GdkSurface *surface,
gdk_surface_layout_popup_helper (surface,
width,
height,
impl->shadow_left,
impl->shadow_right,
impl->shadow_top,
impl->shadow_bottom,
monitor,
&bounds,
layout,
@ -2924,15 +2929,6 @@ gdk_x11_surface_set_utf8_property (GdkSurface *surface,
}
}
static void
gdk_x11_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom)
{
}
/**
* gdk_x11_surface_set_theme_variant:
* @surface: (type GdkX11Surface): a #GdkSurface
@ -4658,7 +4654,6 @@ gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
impl_class->drag_begin = _gdk_x11_surface_drag_begin;
impl_class->get_scale_factor = gdk_x11_surface_get_scale_factor;
impl_class->set_opaque_region = gdk_x11_surface_set_opaque_region;
impl_class->set_shadow_width = gdk_x11_surface_set_shadow_width;
impl_class->create_gl_context = gdk_x11_surface_create_gl_context;
impl_class->get_unscaled_size = gdk_x11_surface_get_unscaled_size;
impl_class->request_layout = gdk_x11_surface_request_layout;

View File

@ -4139,10 +4139,6 @@ update_realized_window_properties (GtkWindow *window)
if (!priv->client_decorated)
return;
if (priv->surface && priv->use_client_shadow)
gdk_surface_set_shadow_width (priv->surface,
shadow.left, shadow.right, shadow.top, shadow.bottom);
gtk_native_get_surface_transform (GTK_NATIVE (window), &native_x, &native_y);
/* update the input shape, which makes it so that clicks