[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:
parent
40fe09855b
commit
09373bf7ee
@ -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;
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user