Merge branch 'gtk3-monitor-scale' into 'gtk-3-24'

[gtk3/wayland] Fix GdkMonitor sizes on Mutter without fractional scaling.

See merge request GNOME/gtk!6723
This commit is contained in:
Matthias Clasen
2024-02-01 01:51:59 +00:00
2 changed files with 47 additions and 38 deletions

View File

@@ -31,11 +31,10 @@ struct _GdkWaylandMonitor {
struct wl_output *output;
struct zxdg_output_v1 *xdg_output;
/* Size and position, can be either from wl_output or xdg_output */
int32_t x;
int32_t y;
int32_t width;
int32_t height;
/* Raw wl_output data */
GdkRectangle output_geometry;
/* Raw xdg_output data */
GdkRectangle xdg_output_geometry;
char *name;
gboolean wl_output_done;
gboolean xdg_output_done;

View File

@@ -1552,17 +1552,43 @@ should_expect_xdg_output_done (GdkWaylandMonitor *monitor)
static void
apply_monitor_change (GdkWaylandMonitor *monitor)
{
GDK_NOTE (MISC,
g_message ("monitor %d changed position %d %d, size %d %d",
monitor->id, monitor->output_geometry.x,
monitor->output_geometry.y,
monitor->output_geometry.width,
monitor->output_geometry.height));
GdkDisplay *display = GDK_MONITOR (monitor)->display;
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (gdk_display_get_default_screen (display));
GDK_NOTE (MISC,
g_message ("monitor %d changed position %d %d, size %d %d",
monitor->id,
monitor->x, monitor->y,
monitor->width, monitor->height));
GdkRectangle logical_geometry;
gboolean needs_scaling = FALSE;
gdk_monitor_set_position (GDK_MONITOR (monitor), monitor->x, monitor->y);
gdk_monitor_set_size (GDK_MONITOR (monitor), monitor->width, monitor->height);
if (monitor->xdg_output_done)
{
logical_geometry = monitor->xdg_output_geometry;
needs_scaling =
logical_geometry.width == monitor->output_geometry.width ||
logical_geometry.height == monitor->output_geometry.height;
}
else
{
logical_geometry = monitor->output_geometry;
needs_scaling = TRUE;
}
if (needs_scaling)
{
int scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
logical_geometry.y /= scale;
logical_geometry.x /= scale;
logical_geometry.width /= scale;
logical_geometry.height /= scale;
}
gdk_monitor_set_position (GDK_MONITOR (monitor), logical_geometry.x, logical_geometry.y);
gdk_monitor_set_size (GDK_MONITOR (monitor), logical_geometry.width, logical_geometry.height);
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
monitor->wl_output_done = FALSE;
monitor->xdg_output_done = FALSE;
@@ -1582,8 +1608,9 @@ xdg_output_handle_logical_position (void *data,
GDK_NOTE (MISC,
g_message ("handle logical position xdg-output %d, position %d %d",
monitor->id, x, y));
monitor->x = x;
monitor->y = y;
monitor->xdg_output_geometry.x = x;
monitor->xdg_output_geometry.y = y;
}
static void
@@ -1597,8 +1624,9 @@ xdg_output_handle_logical_size (void *data,
GDK_NOTE (MISC,
g_message ("handle logical size xdg-output %d, size %d %d",
monitor->id, width, height));
monitor->width = width;
monitor->height = height;
monitor->xdg_output_geometry.width = width;
monitor->xdg_output_geometry.height = height;
}
static void
@@ -1685,8 +1713,8 @@ output_handle_geometry (void *data,
g_message ("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, manufacturer %s, model %s, transform %s",
monitor->id, x, y, physical_width, physical_height, subpixel_to_string (subpixel), make, model, transform_to_string (transform)));
monitor->x = x;
monitor->y = y;
monitor->output_geometry.x = x;
monitor->output_geometry.y = y;
switch (transform)
{
@@ -1731,29 +1759,13 @@ output_handle_scale (void *data,
int32_t scale)
{
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
GdkRectangle previous_geometry;
int previous_scale;
int width;
int height;
GDK_NOTE (MISC,
g_message ("handle scale output %d, scale %d", monitor->id, scale));
gdk_monitor_get_geometry (GDK_MONITOR (monitor), &previous_geometry);
previous_scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
/* Set the scale from wl_output protocol, regardless of xdg-output support */
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), scale);
if (monitor_has_xdg_output (monitor))
return;
width = previous_geometry.width * previous_scale;
height = previous_geometry.height * previous_scale;
monitor->width = width / scale;
monitor->height = height / scale;
if (should_update_monitor (monitor))
apply_monitor_change (monitor);
}
@@ -1767,7 +1779,6 @@ output_handle_mode (void *data,
int refresh)
{
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
int scale;
GDK_NOTE (MISC,
g_message ("handle mode output %d, size %d %d, rate %d",
@@ -1776,9 +1787,8 @@ output_handle_mode (void *data,
if ((flags & WL_OUTPUT_MODE_CURRENT) == 0)
return;
scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
monitor->width = width / scale;
monitor->height = height / scale;
monitor->output_geometry.width = width;
monitor->output_geometry.height = height;
gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh);
if (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))