aboutsummaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorWeifeng Liu <weifeng.liu.z@gmail.com>2025-06-01 12:52:33 +0800
committerMarc-André Lureau <marcandre.lureau@redhat.com>2025-07-15 10:22:33 +0400
commit0ba45b79452b7f1fb7d45a1a555cbd88ccedb228 (patch)
tree70e5a69ad8e9ba98798b565a52465e8095901c7f /ui
parentc65680a76c190d187be1bfd18207b22227541d77 (diff)
downloadqemu-0ba45b79452b7f1fb7d45a1a555cbd88ccedb228.zip
qemu-0ba45b79452b7f1fb7d45a1a555cbd88ccedb228.tar.gz
qemu-0ba45b79452b7f1fb7d45a1a555cbd88ccedb228.tar.bz2
ui/gtk: Add scale option
Allow user to set a preferred scale (defaulting to 1) of the virtual display. Along with zoom-to-fix=false, this would be helpful for users running QEMU on hi-dpi host desktop to achieve pixel to pixel display -- e.g., if the scale factor of a user's host desktop is set to 200%, then they can set a 0.5 scale for the virtual display to avoid magnification that might cause blurriness. Signed-off-by: Weifeng Liu <weifeng.liu.z@gmail.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Tested-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20250601045245.36778-3-weifeng.liu.z@gmail.com>
Diffstat (limited to 'ui')
-rw-r--r--ui/gtk.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/ui/gtk.c b/ui/gtk.c
index 9104509..e91d093 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -67,6 +67,7 @@
#define VC_TERM_X_MIN 80
#define VC_TERM_Y_MIN 25
#define VC_SCALE_MIN 0.25
+#define VC_SCALE_MAX 4
#define VC_SCALE_STEP 0.25
#ifdef GDK_WINDOWING_X11
@@ -272,15 +273,11 @@ static void gd_update_geometry_hints(VirtualConsole *vc)
if (!vc->gfx.ds) {
return;
}
- if (s->free_scale) {
- geo.min_width = surface_width(vc->gfx.ds) * VC_SCALE_MIN;
- geo.min_height = surface_height(vc->gfx.ds) * VC_SCALE_MIN;
- mask |= GDK_HINT_MIN_SIZE;
- } else {
- geo.min_width = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
- geo.min_height = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
- mask |= GDK_HINT_MIN_SIZE;
- }
+ double scale_x = s->free_scale ? VC_SCALE_MIN : vc->gfx.scale_x;
+ double scale_y = s->free_scale ? VC_SCALE_MIN : vc->gfx.scale_y;
+ geo.min_width = surface_width(vc->gfx.ds) * scale_x;
+ geo.min_height = surface_height(vc->gfx.ds) * scale_y;
+ mask |= GDK_HINT_MIN_SIZE;
geo_widget = vc->gfx.drawing_area;
gtk_widget_set_size_request(geo_widget, geo.min_width, geo.min_height);
@@ -1579,8 +1576,8 @@ static void gd_menu_full_screen(GtkMenuItem *item, void *opaque)
}
s->full_screen = FALSE;
if (vc->type == GD_VC_GFX) {
- vc->gfx.scale_x = 1.0;
- vc->gfx.scale_y = 1.0;
+ vc->gfx.scale_x = vc->gfx.preferred_scale;
+ vc->gfx.scale_y = vc->gfx.preferred_scale;
gd_update_windowsize(vc);
}
}
@@ -1636,8 +1633,8 @@ static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
GtkDisplayState *s = opaque;
VirtualConsole *vc = gd_vc_find_current(s);
- vc->gfx.scale_x = 1.0;
- vc->gfx.scale_y = 1.0;
+ vc->gfx.scale_x = vc->gfx.preferred_scale;
+ vc->gfx.scale_y = vc->gfx.preferred_scale;
gd_update_windowsize(vc);
}
@@ -1651,8 +1648,8 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
s->free_scale = TRUE;
} else {
s->free_scale = FALSE;
- vc->gfx.scale_x = 1.0;
- vc->gfx.scale_y = 1.0;
+ vc->gfx.scale_x = vc->gfx.preferred_scale;
+ vc->gfx.scale_y = vc->gfx.preferred_scale;
}
gd_update_windowsize(vc);
@@ -2243,6 +2240,11 @@ static void gl_area_realize(GtkGLArea *area, VirtualConsole *vc)
}
#endif
+static bool gd_scale_valid(double scale)
+{
+ return scale >= VC_SCALE_MIN && scale <= VC_SCALE_MAX;
+}
+
static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
QemuConsole *con, int idx,
GSList *group, GtkWidget *view_menu)
@@ -2252,8 +2254,18 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
vc->label = qemu_console_get_label(con);
vc->s = s;
- vc->gfx.scale_x = 1.0;
- vc->gfx.scale_y = 1.0;
+ vc->gfx.preferred_scale = 1.0;
+ if (s->opts->u.gtk.has_scale) {
+ if (gd_scale_valid(s->opts->u.gtk.scale)) {
+ vc->gfx.preferred_scale = s->opts->u.gtk.scale;
+ } else {
+ error_report("Invalid scale value %lf given, being ignored",
+ s->opts->u.gtk.scale);
+ s->opts->u.gtk.has_scale = false;
+ }
+ }
+ vc->gfx.scale_x = vc->gfx.preferred_scale;
+ vc->gfx.scale_y = vc->gfx.preferred_scale;
#if defined(CONFIG_OPENGL)
if (display_opengl) {