[gtk: 31/88] gdk/x11: Flush layout changes to the frame clack dispatch
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk: 31/88] gdk/x11: Flush layout changes to the frame clack dispatch
- Date: Tue, 8 Dec 2020 15:38:41 +0000 (UTC)
commit 65ad9d6d96710c60e23f858373d7fc17488d365e
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Wed Dec 2 09:45:31 2020 +0100
gdk/x11: Flush layout changes to the frame clack dispatch
This follows the trail of the Wayland backend in that GdkSurface changes
happen during the layout phase, and that a GDK_CONFIGURE no longer being
used to communicate the size changes of a surface; this now also uses
the layout signal on the GdkSurface.
gdk/x11/gdkdisplay-x11.c | 28 ++++++--
gdk/x11/gdksurface-x11.c | 168 +++++++++++++++++++++++++++++++++++++++--------
gdk/x11/gdksurface-x11.h | 13 ++++
3 files changed, 175 insertions(+), 34 deletions(-)
---
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 0df79d289b..692f85230c 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -901,11 +901,16 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
xevent->xconfigure.event == xevent->xconfigure.window)
{
int x, y;
- int c_w = (xevent->xconfigure.width + surface_impl->surface_scale - 1) /
surface_impl->surface_scale;
- int c_h = (xevent->xconfigure.height + surface_impl->surface_scale - 1) /
surface_impl->surface_scale;
+ int configured_width;
+ int configured_height;
int new_abs_x, new_abs_y;
- event = gdk_configure_event_new (surface, c_w, c_h);
+ configured_width =
+ (xevent->xconfigure.width + surface_impl->surface_scale - 1) /
+ surface_impl->surface_scale;
+ configured_height =
+ (xevent->xconfigure.height + surface_impl->surface_scale - 1) /
+ surface_impl->surface_scale;
if (!xevent->xconfigure.send_event &&
!xevent->xconfigure.override_redirect &&
@@ -915,6 +920,16 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
int ty = 0;
Window child_window = 0;
+ if (surface_impl->pending_configure_events == 1)
+ {
+ surface_impl->pending_configure_events = 0;
+ gdk_surface_thaw_updates (surface);
+ }
+ else if (surface_impl->pending_configure_events > 1)
+ {
+ surface_impl->pending_configure_events--;
+ }
+
x = y = 0;
gdk_x11_display_error_trap_push (display);
if (XTranslateCoordinates (GDK_SURFACE_XDISPLAY (surface),
@@ -955,10 +970,11 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
{
surface_impl->unscaled_width = xevent->xconfigure.width;
surface_impl->unscaled_height = xevent->xconfigure.height;
- gdk_configure_event_get_size (event, &surface->width, &surface->height);
- _gdk_surface_update_size (surface);
- _gdk_x11_surface_update_size (surface_impl);
+ surface_impl->next_layout.configured_width = configured_width;
+ surface_impl->next_layout.configured_height = configured_height;
+ surface_impl->next_layout.surface_geometry_dirty = TRUE;
+ gdk_surface_request_layout (surface);
}
if (surface->resize_count >= 1)
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index c4b14e11e3..a207c8964b 100644
--- a/gdk/x11/gdksurface-x11.c
+++ b/gdk/x11/gdksurface-x11.c
@@ -192,6 +192,112 @@ gdk_x11_surface_get_unscaled_size (GdkSurface *surface,
*unscaled_height = impl->unscaled_height;
}
+static void
+update_shadow_size (GdkSurface *surface,
+ int shadow_left,
+ int shadow_right,
+ int shadow_top,
+ int shadow_bottom)
+{
+ GdkX11Surface *impl = GDK_X11_SURFACE (surface);
+ Atom frame_extents;
+ gulong data[4];
+
+ if (impl->shadow_left == shadow_left &&
+ impl->shadow_right == shadow_right &&
+ impl->shadow_top == shadow_top &&
+ impl->shadow_bottom == shadow_bottom)
+ return;
+
+ impl->shadow_left = shadow_left;
+ impl->shadow_right = shadow_right;
+ impl->shadow_top = shadow_top;
+ impl->shadow_bottom = shadow_bottom;
+
+ data[0] = shadow_left * impl->surface_scale;
+ data[1] = shadow_right * impl->surface_scale;
+ data[2] = shadow_top * impl->surface_scale;
+ data[3] = shadow_bottom * impl->surface_scale;
+
+ frame_extents = gdk_x11_get_xatom_by_name_for_display (gdk_surface_get_display (surface),
+ "_GTK_FRAME_EXTENTS");
+ XChangeProperty (GDK_SURFACE_XDISPLAY (surface),
+ GDK_SURFACE_XID (surface),
+ frame_extents, XA_CARDINAL,
+ 32, PropModeReplace,
+ (guchar *) &data, 4);
+}
+
+static void
+gdk_x11_surface_request_layout (GdkSurface *surface)
+{
+ GdkX11Surface *impl = GDK_X11_SURFACE (surface);
+
+ impl->next_layout.surface_geometry_dirty = TRUE;
+}
+
+static void
+gdk_x11_surface_compute_size (GdkSurface *surface)
+{
+ GdkX11Surface *impl = GDK_X11_SURFACE (surface);
+
+ if (GDK_IS_TOPLEVEL (surface))
+ {
+ if (impl->next_layout.surface_geometry_dirty)
+ {
+ GdkDisplay *display = gdk_surface_get_display (surface);
+ GdkMonitor *monitor;
+ GdkToplevelSize size;
+ int bounds_width, bounds_height;
+
+ monitor = gdk_display_get_monitor_at_surface (display, surface);
+ if (monitor)
+ {
+ GdkRectangle workarea;
+
+ gdk_x11_monitor_get_workarea (monitor, &workarea);
+ bounds_width = workarea.width;
+ bounds_height = workarea.height;
+ }
+ else
+ {
+ bounds_width = G_MAXINT;
+ bounds_height = G_MAXINT;
+ }
+
+ gdk_toplevel_size_init (&size, bounds_width, bounds_height);
+ gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
+
+ if (size.margin.is_valid)
+ {
+ update_shadow_size (surface,
+ size.margin.left,
+ size.margin.right,
+ size.margin.top,
+ size.margin.bottom);
+ }
+
+ surface->width = impl->next_layout.configured_width;
+ surface->height = impl->next_layout.configured_height;
+
+ _gdk_surface_update_size (surface);
+ _gdk_x11_surface_update_size (impl);
+
+ impl->next_layout.surface_geometry_dirty = FALSE;
+ }
+ }
+ else
+ {
+ surface->width = impl->next_layout.configured_width;
+ surface->height = impl->next_layout.configured_height;
+
+ _gdk_surface_update_size (surface);
+ _gdk_x11_surface_update_size (impl);
+
+ impl->next_layout.surface_geometry_dirty = FALSE;
+ }
+}
+
gboolean
gdk_x11_surface_supports_edge_constraints (GdkSurface *surface)
{
@@ -1424,6 +1530,9 @@ x11_surface_move (GdkSurface *surface,
surface->x = x;
surface->y = y;
}
+
+ impl->next_layout.surface_geometry_dirty = TRUE;
+ gdk_surface_request_layout (surface);
}
}
@@ -1450,10 +1559,10 @@ x11_surface_resize (GdkSurface *surface,
{
impl->unscaled_width = width * impl->surface_scale;
impl->unscaled_height = height * impl->surface_scale;
- surface->width = width;
- surface->height = height;
- _gdk_surface_update_size (surface);
- _gdk_x11_surface_update_size (GDK_X11_SURFACE (surface));
+ impl->next_layout.configured_width = width;
+ impl->next_layout.configured_height = height;
+ impl->next_layout.surface_geometry_dirty = TRUE;
+ gdk_surface_request_layout (surface);
}
else
{
@@ -1491,10 +1600,10 @@ x11_surface_move_resize (GdkSurface *surface,
impl->unscaled_width = width * impl->surface_scale;
impl->unscaled_height = height * impl->surface_scale;
- surface->width = width;
- surface->height = height;
-
- _gdk_x11_surface_update_size (GDK_X11_SURFACE (surface));
+ impl->next_layout.configured_width = width;
+ impl->next_layout.configured_height = height;
+ impl->next_layout.surface_geometry_dirty = TRUE;
+ gdk_surface_request_layout (surface);
if (surface->parent)
{
@@ -2822,22 +2931,6 @@ gdk_x11_surface_set_shadow_width (GdkSurface *surface,
int top,
int bottom)
{
- GdkX11Surface *impl = GDK_X11_SURFACE (surface);
- Atom frame_extents;
- gulong data[4] = {
- left * impl->surface_scale,
- right * impl->surface_scale,
- top * impl->surface_scale,
- bottom * impl->surface_scale
- };
-
- frame_extents = gdk_x11_get_xatom_by_name_for_display (gdk_surface_get_display (surface),
- "_GTK_FRAME_EXTENTS");
- XChangeProperty (GDK_SURFACE_XDISPLAY (surface),
- GDK_SURFACE_XID (surface),
- frame_extents, XA_CARDINAL,
- 32, PropModeReplace,
- (guchar *) &data, 4);
}
/**
@@ -4568,6 +4661,8 @@ gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
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;
+ impl_class->compute_size = gdk_x11_surface_compute_size;
}
#define LAST_PROP 1
@@ -4854,6 +4949,7 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
+ GdkX11Surface *impl = GDK_X11_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor;
GdkToplevelSize size;
@@ -4863,6 +4959,11 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel,
GdkSurfaceHints mask;
gboolean was_mapped;
+ if (surface->destroyed)
+ return;
+
+ was_mapped = GDK_SURFACE_IS_MAPPED (surface);
+
gdk_x11_surface_unminimize (surface);
monitor = gdk_display_get_monitor_at_surface (display, surface);
@@ -4903,6 +5004,19 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel,
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
gdk_x11_surface_toplevel_resize (surface, width, height);
+ if (size.margin.is_valid)
+ {
+ update_shadow_size (surface,
+ size.margin.left,
+ size.margin.right,
+ size.margin.top,
+ size.margin.bottom);
+ }
+
+ impl->pending_configure_events++;
+ if (impl->pending_configure_events == 1)
+ gdk_surface_freeze_updates (surface);
+
if (gdk_toplevel_layout_get_maximized (layout))
gdk_x11_surface_maximize (surface);
else
@@ -4921,10 +5035,8 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel,
else
gdk_x11_surface_unfullscreen (surface);
- if (surface->destroyed)
- return;
-
- was_mapped = GDK_SURFACE_IS_MAPPED (surface);
+ impl->next_layout.surface_geometry_dirty = TRUE;
+ gdk_surface_request_layout (surface);
if (!was_mapped)
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
diff --git a/gdk/x11/gdksurface-x11.h b/gdk/x11/gdksurface-x11.h
index eb23474afd..f6ccfa2f21 100644
--- a/gdk/x11/gdksurface-x11.h
+++ b/gdk/x11/gdksurface-x11.h
@@ -59,6 +59,11 @@ struct _GdkX11Surface
int surface_scale;
+ int shadow_left;
+ int shadow_right;
+ int shadow_top;
+ int shadow_bottom;
+
/* Width and height not divided by surface_scale - this matters in the
* corner-case where the window manager assigns us a size that isn't
* a multiple of surface_scale - for example for a maximized window
@@ -67,6 +72,14 @@ struct _GdkX11Surface
int unscaled_width;
int unscaled_height;
+ int pending_configure_events;
+
+ struct {
+ int configured_width;
+ int configured_height;
+ gboolean surface_geometry_dirty;
+ } next_layout;
+
cairo_surface_t *cairo_surface;
int abs_x;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]