[virt-tools-list] [PATCH virt-viewer 3/3] virt-viewer-window: Check for maximum zoom level

Pavel Grunt pgrunt at redhat.com
Thu May 14 14:36:34 UTC 2015


On some desktop environment (e.g. gnome-shell) zooming in can cause
resizing of the guest's display, because the window manager of DE
changes the aspect ratio of the window instead when the window could
exceed the size of the monitor. Other DEs (e.g. GNOME, Xfce) allow
windows to exceed size of the monitor, so the resize does not happen,
but part of the guest display is not visible.

This commit avoids 'zooming in' when it can cause the resizing or
the exceeding of monitor. The maximum zoom level of the window is
calculated with respect to dimensions of the monitor where the window
is placed.

Resolves: rhbz#1221501
---
 src/virt-viewer-window.c | 49 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 5 deletions(-)

diff --git a/src/virt-viewer-window.c b/src/virt-viewer-window.c
index 0ed4b5f..899efc2 100644
--- a/src/virt-viewer-window.c
+++ b/src/virt-viewer-window.c
@@ -71,6 +71,7 @@ static void virt_viewer_window_toolbar_setup(VirtViewerWindow *self);
 static GtkMenu* virt_viewer_window_get_keycombo_menu(VirtViewerWindow *self);
 static void virt_viewer_window_get_minimal_dimensions(VirtViewerWindow *self, guint *width, guint *height);
 static gint virt_viewer_window_get_minimal_zoom_level(VirtViewerWindow *self);
+static gint virt_viewer_window_get_maximum_zoom_level(VirtViewerWindow *self);
 static void virt_viewer_window_get_monitor_geometry(VirtViewerWindow *self, GdkRectangle *geometry);
 
 G_DEFINE_TYPE (VirtViewerWindow, virt_viewer_window, G_TYPE_OBJECT)
@@ -1447,7 +1448,6 @@ void
 virt_viewer_window_set_zoom_level(VirtViewerWindow *self, gint zoom_level)
 {
     VirtViewerWindowPrivate *priv;
-    gint min_zoom;
 
     g_return_if_fail(VIRT_VIEWER_IS_WINDOW(self));
     priv = self->priv;
@@ -1461,10 +1461,12 @@ virt_viewer_window_set_zoom_level(VirtViewerWindow *self, gint zoom_level)
     if (!priv->display)
         return;
 
-    min_zoom = virt_viewer_window_get_minimal_zoom_level(self);
-    if (min_zoom > priv->zoomlevel) {
-        g_debug("Cannot set zoom level %d, using %d", priv->zoomlevel, min_zoom);
-        priv->zoomlevel = min_zoom;
+    zoom_level = CLAMP(priv->zoomlevel,
+                       virt_viewer_window_get_minimal_zoom_level(self),
+                       virt_viewer_window_get_maximum_zoom_level(self));
+    if (zoom_level != priv->zoomlevel) {
+        g_debug("Cannot set zoom level %d, using %d", priv->zoomlevel, zoom_level);
+        priv->zoomlevel = zoom_level;
     }
 
     if (priv->zoomlevel == virt_viewer_display_get_zoom_level(priv->display)) {
@@ -1588,6 +1590,43 @@ virt_viewer_window_get_minimal_zoom_level(VirtViewerWindow *self)
     return CLAMP(zoom * ZOOM_STEP, MIN_ZOOM_LEVEL, NORMAL_ZOOM_LEVEL);
 }
 
+/**
+ * virt_viewer_window_get_maximum_zoom_level:
+ * @self: a #VirtViewerWindow
+ *
+ * Calculates the zoom level with respect to the size of monitor
+ *
+ * Returns: maximum possible zoom level (multiple of ZOOM_STEP)
+ */
+static gint
+virt_viewer_window_get_maximum_zoom_level(VirtViewerWindow *self)
+{
+    GdkRectangle monitor;
+    guint width, height; /* desktop dimensions */
+    guint menu_height;
+    gint zoom;
+    double width_ratio, height_ratio;
+
+    g_return_val_if_fail(VIRT_VIEWER_IS_WINDOW(self) &&
+                         self->priv->display != NULL, MAX_ZOOM_LEVEL);
+
+    if (self->priv->fullscreen)
+        return MAX_ZOOM_LEVEL;
+
+    virt_viewer_window_get_monitor_geometry(self, &monitor);
+    virt_viewer_display_get_desktop_size(virt_viewer_window_get_display(self), &width, &height);
+    /* it is neccessary to add 'menu_height' to 'height' otherwise window can exceed monitor */
+    virt_viewer_window_top_menu_dimensions(self, NULL, &menu_height);
+
+    width_ratio = (double) monitor.width / width;
+    height_ratio = (double) monitor.height / (height + menu_height);
+
+    zoom = floor(10 * MIN(width_ratio, height_ratio));
+
+    /* make sure that the returned zoom level is in the range from NORMAL_ZOOM_LEVEL to MAX_ZOOM_LEVEL */
+    return CLAMP(zoom * ZOOM_STEP, NORMAL_ZOOM_LEVEL, MAX_ZOOM_LEVEL);
+}
+
 static void
 virt_viewer_window_get_monitor_geometry(VirtViewerWindow *self, GdkRectangle *geometry)
 {
-- 
2.4.0




More information about the virt-tools-list mailing list