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 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list