[gtk3/wayland] Fix GdkMonitor sizes on Mutter without fractional scaling.
This is the gtk3 version of !6722. This fixes a problem that is apparent in https://bugzilla.mozilla.org/show_bug.cgi?id=1869724, but that also reproduces on any GTK application as described in https://bugzilla.mozilla.org/show_bug.cgi?id=1869724#c16. xdg_output sizes might be physical if the compositor doesn't scale them, it seems. So to report the correct logical geometry in GDK pixels, we need to detect this case. We do this by checking whether the wl_output size matches the xdg_output size.
This commit is contained in:
@ -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_has_xdg_output(monitor))
|
||||
{
|
||||
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))
|
||||
|
||||
Reference in New Issue
Block a user