aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeifeng Liu <weifeng.liu.z@gmail.com>2025-05-11 15:33:17 +0800
committerMarc-André Lureau <marcandre.lureau@redhat.com>2025-05-24 17:03:50 +0200
commita1b28f71f7ff0fcafbe0672b788e8e57ee4fe8f6 (patch)
tree56c0f2c3fe1eb6df3596c4bc545c558e5a1fe802
parent02f25490879096b679ab3d7cb7f0facfef7c6484 (diff)
downloadqemu-a1b28f71f7ff0fcafbe0672b788e8e57ee4fe8f6.zip
qemu-a1b28f71f7ff0fcafbe0672b788e8e57ee4fe8f6.tar.gz
qemu-a1b28f71f7ff0fcafbe0672b788e8e57ee4fe8f6.tar.bz2
ui/gtk: Consider scaling when propagating ui info
The ui width and height sent to guest is supposed to be in buffer coordinate. Hence conversion is required. If scaling (global window scale and zooming scale) is not respected in non-free-scale mode, window size could keep changing because of the existence of the iteration of the following steps: 1. In resize event or configure event, a size larger (or smaller) than the currently used one might be calculated due to not considering scaling. 2. On reception of the display size change event in guest, the guest might decide to do a mode setting and use the larger (or smaller) mode. 3. When the new guest scan-out command arrives, QEMU would request the window size to change to fit the new buffer size. This will trigger a resize event or a configure event, making us go back to step 1. Signed-off-by: Weifeng Liu <weifeng.liu.z@gmail.com> Message-ID: <20250511073337.876650-8-weifeng.liu.z@gmail.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
-rw-r--r--ui/gtk.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/ui/gtk.c b/ui/gtk.c
index 47af49e..8c4a94c 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -772,8 +772,21 @@ static void gd_resize_event(GtkGLArea *area,
gint width, gint height, gpointer *opaque)
{
VirtualConsole *vc = (void *)opaque;
+ double pw = width, ph = height;
+ double sx = vc->gfx.scale_x, sy = vc->gfx.scale_y;
+ GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(area));
+ const int gs = gdk_window_get_scale_factor(window);
- gd_set_ui_size(vc, width, height);
+ if (!vc->s->free_scale && !vc->s->full_screen) {
+ pw /= sx;
+ ph /= sy;
+ }
+
+ /**
+ * width and height here are in pixel coordinate, so we must divide it
+ * by global window scale (gs)
+ */
+ gd_set_ui_size(vc, pw / gs, ph / gs);
}
#endif
@@ -1836,8 +1849,16 @@ static gboolean gd_configure(GtkWidget *widget,
GdkEventConfigure *cfg, gpointer opaque)
{
VirtualConsole *vc = opaque;
+ const double sx = vc->gfx.scale_x, sy = vc->gfx.scale_y;
+ double width = cfg->width, height = cfg->height;
+
+ if (!vc->s->free_scale && !vc->s->full_screen) {
+ width /= sx;
+ height /= sy;
+ }
+
+ gd_set_ui_size(vc, width, height);
- gd_set_ui_size(vc, cfg->width, cfg->height);
return FALSE;
}