x11/surface: Move the scattered compute-size calls to helper

This simplifies things, and fixes issue where we'd resize the wrong
time, and miss resizing other times.
This commit is contained in:
Jonas Ådahl 2020-12-05 11:38:17 +01:00
parent c791185c20
commit 994aa41ccc

View File

@ -98,6 +98,14 @@ const int _gdk_x11_event_mask_table[21] =
ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */ ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
}; };
typedef struct {
GdkX11Surface parent_instance;
} GdkX11Toplevel;
typedef struct {
GdkX11SurfaceClass parent_class;
} GdkX11ToplevelClass;
const int _gdk_x11_event_mask_table_size = G_N_ELEMENTS (_gdk_x11_event_mask_table); const int _gdk_x11_event_mask_table_size = G_N_ELEMENTS (_gdk_x11_event_mask_table);
/* Forward declarations */ /* Forward declarations */
@ -115,6 +123,10 @@ static void gdk_x11_surface_toplevel_resize (GdkSurface *surface,
int width, int width,
int height); int height);
static void gdk_x11_surface_set_geometry_hints (GdkSurface *surface,
const GdkGeometry *geometry,
GdkSurfaceHints geom_mask);
/* Return whether time1 is considered later than time2 as far as xserver /* Return whether time1 is considered later than time2 as far as xserver
* time is concerned. Accounts for wraparound. * time is concerned. Accounts for wraparound.
*/ */
@ -232,26 +244,20 @@ update_shadow_size (GdkSurface *surface,
(guchar *) &data, 4); (guchar *) &data, 4);
} }
#define UPDATE_GEOMETRY TRUE
#define DONT_UPDATE_GEOMETRY FALSE
static gboolean static gboolean
compute_size_idle (gpointer user_data) compute_toplevel_size (GdkSurface *surface,
gboolean update_geometry,
int *width,
int *height)
{ {
GdkSurface *surface = user_data;
GdkX11Surface *impl = GDK_X11_SURFACE (surface); GdkX11Surface *impl = GDK_X11_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface); GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor; GdkMonitor *monitor;
GdkToplevelSize size; GdkToplevelSize size;
int bounds_width, bounds_height; int bounds_width, bounds_height;
int width, height;
impl->compute_size_source_id = 0;
if (impl->next_layout.surface_geometry_dirty)
return G_SOURCE_REMOVE;
if (surface->state & (GDK_TOPLEVEL_STATE_MAXIMIZED &
GDK_TOPLEVEL_STATE_FULLSCREEN &
GDK_TOPLEVEL_STATE_TILED))
return G_SOURCE_REMOVE;
monitor = gdk_display_get_monitor_at_surface (display, surface); monitor = gdk_display_get_monitor_at_surface (display, surface);
if (monitor) if (monitor)
@ -271,10 +277,76 @@ compute_size_idle (gpointer user_data)
gdk_toplevel_size_init (&size, bounds_width, bounds_height); gdk_toplevel_size_init (&size, bounds_width, bounds_height);
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size); gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
width = size.width; if (size.shadow.is_valid && update_geometry)
height = size.height; {
if (width != impl->unscaled_width * impl->surface_scale || update_shadow_size (surface,
height != impl->unscaled_height * impl->surface_scale) size.shadow.left,
size.shadow.right,
size.shadow.top,
size.shadow.bottom);
}
if (update_geometry)
{
GdkGeometry geometry;
GdkSurfaceHints mask;
if (gdk_toplevel_layout_get_resizable (impl->toplevel_layout))
{
geometry.min_width = size.min_width;
geometry.min_height = size.min_height;
mask = GDK_HINT_MIN_SIZE;
}
else
{
geometry.max_width = geometry.min_width = size.width;
geometry.max_height = geometry.min_height = size.height;
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
}
gdk_x11_surface_set_geometry_hints (surface, &geometry, mask);
}
if (!(surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN |
GDK_TOPLEVEL_STATE_MAXIMIZED |
GDK_TOPLEVEL_STATE_TILED |
GDK_TOPLEVEL_STATE_TOP_TILED |
GDK_TOPLEVEL_STATE_RIGHT_TILED |
GDK_TOPLEVEL_STATE_BOTTOM_TILED |
GDK_TOPLEVEL_STATE_LEFT_TILED |
GDK_TOPLEVEL_STATE_MINIMIZED)) &&
(!impl->next_layout.configure_pending || surface->resize_count > 0))
{
GdkToplevelX11 *toplevel = _gdk_x11_surface_get_toplevel (surface);
GdkGeometry geometry;
GdkSurfaceHints mask;
geometry = toplevel->last_geometry_hints;
mask = toplevel->last_geometry_hints_mask;
gdk_surface_constrain_size (&geometry, mask,
size.width, size.height,
&size.width, &size.height);
if ((impl->next_layout.configured_width != size.width ||
impl->next_layout.configured_height != size.height))
{
*width = size.width;
*height = size.height;
return TRUE;
}
}
return FALSE;
}
static gboolean
compute_size_idle (gpointer user_data)
{
GdkSurface *surface = user_data;
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
int width, height;
impl->compute_size_source_id = 0;
if (compute_toplevel_size (surface, UPDATE_GEOMETRY, &width, &height))
gdk_x11_surface_toplevel_resize (surface, width, height); gdk_x11_surface_toplevel_resize (surface, width, height);
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
@ -302,43 +374,18 @@ gdk_x11_surface_compute_size (GdkSurface *surface)
if (GDK_IS_TOPLEVEL (surface)) if (GDK_IS_TOPLEVEL (surface))
{ {
GdkDisplay *display = gdk_surface_get_display (surface); int width, height;
GdkMonitor *monitor;
GdkToplevelSize size;
int bounds_width, bounds_height;
monitor = gdk_display_get_monitor_at_surface (display, surface); if (compute_toplevel_size (surface, UPDATE_GEOMETRY, &width, &height))
if (monitor) gdk_x11_surface_toplevel_resize (surface, width, height);
if (surface->resize_count == 0)
{ {
GdkRectangle workarea; surface->width = impl->next_layout.configured_width;
surface->height = impl->next_layout.configured_height;
gdk_x11_monitor_get_workarea (monitor, &workarea); _gdk_surface_update_size (surface);
bounds_width = workarea.width; _gdk_x11_surface_update_size (impl);
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.shadow.is_valid)
{
update_shadow_size (surface,
size.shadow.left,
size.shadow.right,
size.shadow.top,
size.shadow.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; impl->next_layout.surface_geometry_dirty = FALSE;
impl->next_layout.configure_pending = FALSE; impl->next_layout.configure_pending = FALSE;
@ -1926,10 +1973,6 @@ gdk_x11_surface_enter_leave_monitors (GdkSurface *surface)
} }
} }
static void gdk_x11_surface_set_geometry_hints (GdkSurface *surface,
const GdkGeometry *geometry,
GdkSurfaceHints geom_mask);
void void
_gdk_x11_surface_set_surface_scale (GdkSurface *surface, _gdk_x11_surface_set_surface_scale (GdkSurface *surface,
int scale) int scale)
@ -4880,14 +4923,6 @@ gdk_x11_popup_iface_init (GdkPopupInterface *iface)
iface->get_position_y = gdk_x11_popup_get_position_y; iface->get_position_y = gdk_x11_popup_get_position_y;
} }
typedef struct {
GdkX11Surface parent_instance;
} GdkX11Toplevel;
typedef struct {
GdkX11SurfaceClass parent_class;
} GdkX11ToplevelClass;
static void gdk_x11_toplevel_iface_init (GdkToplevelInterface *iface); static void gdk_x11_toplevel_iface_init (GdkToplevelInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GdkX11Toplevel, gdk_x11_toplevel, GDK_TYPE_X11_SURFACE, G_DEFINE_TYPE_WITH_CODE (GdkX11Toplevel, gdk_x11_toplevel, GDK_TYPE_X11_SURFACE,
@ -5039,13 +5074,7 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel,
{ {
GdkSurface *surface = GDK_SURFACE (toplevel); GdkSurface *surface = GDK_SURFACE (toplevel);
GdkX11Surface *impl = GDK_X11_SURFACE (surface); GdkX11Surface *impl = GDK_X11_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor;
GdkToplevelSize size;
int bounds_width, bounds_height;
int width, height; int width, height;
GdkGeometry geometry;
GdkSurfaceHints mask;
gboolean was_mapped; gboolean was_mapped;
if (surface->destroyed) if (surface->destroyed)
@ -5058,52 +5087,8 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel,
g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref); g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
impl->toplevel_layout = gdk_toplevel_layout_copy (layout); impl->toplevel_layout = gdk_toplevel_layout_copy (layout);
monitor = gdk_display_get_monitor_at_surface (display, surface); if (compute_toplevel_size (surface, DONT_UPDATE_GEOMETRY, &width, &height))
if (monitor) gdk_x11_surface_toplevel_resize (surface, width, height);
{
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 (toplevel, &size);
g_warn_if_fail (size.width > 0);
g_warn_if_fail (size.height > 0);
width = size.width;
height = size.height;
if (gdk_toplevel_layout_get_resizable (layout))
{
geometry.min_width = size.min_width;
geometry.min_height = size.min_height;
mask = GDK_HINT_MIN_SIZE;
}
else
{
geometry.max_width = geometry.min_width = width;
geometry.max_height = geometry.min_height = height;
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
}
gdk_x11_surface_set_geometry_hints (surface, &geometry, mask);
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
gdk_x11_surface_toplevel_resize (surface, width, height);
if (size.shadow.is_valid)
{
update_shadow_size (surface,
size.shadow.left,
size.shadow.right,
size.shadow.top,
size.shadow.bottom);
}
if (gdk_toplevel_layout_get_maximized (layout)) if (gdk_toplevel_layout_get_maximized (layout))
gdk_x11_surface_maximize (surface); gdk_x11_surface_maximize (surface);