diff --git a/gdk/wayland/gdkmonitor-wayland.h b/gdk/wayland/gdkmonitor-wayland.h index 8c65bbfc4a..b4a831e0fa 100644 --- a/gdk/wayland/gdkmonitor-wayland.h +++ b/gdk/wayland/gdkmonitor-wayland.h @@ -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; diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c index 9aec01b0b6..7017534f8c 100644 --- a/gdk/wayland/gdkscreen-wayland.c +++ b/gdk/wayland/gdkscreen-wayland.c @@ -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))