mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
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.
This commit is contained in:
parent
e0f13ecae7
commit
65ad9d6d96
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user