On 5/24/25 20:35, [email protected] wrote:
From: Weifeng Liu <[email protected]>

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 <[email protected]>
Message-ID: <[email protected]>
Acked-by: Gerd Hoffmann <[email protected]>
Acked-by: Marc-AndrĂ© Lureau <[email protected]>
---
  ui/gtk.c | 25 +++++++++++++++++++++++--
  1 file changed, 23 insertions(+), 2 deletions(-)

Hi!

I just stumbled upon this change, which looks like a good candidate
for qemu-stable 10.0.x series (lts), what do you think?

Thanks,

/mjt

diff --git a/ui/gtk.c b/ui/gtk.c
index 47af49e387..8c4a94c8f6 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;
  }


Reply via email to