[virt-tools-list] [PATCH virt-viewer 1/3] Adjust zoom level when window is resized and guest cannot be resized

Pavel Grunt pgrunt at redhat.com
Thu May 21 17:19:18 UTC 2015


When resizing the window and it is not possible to resize the guest
desktop, VirtViewerDisplay acts like the zoom level was changed.
Because this change is not stored anywhere, zoom operations are not
working correctly (e.g. 'zooming in' decreases the zoom level).

This commit solves the problem by dynamically adjusting the zoom level
when it is not possible to resize the guest display.

Related: rhbz#1221501
---
 src/virt-viewer-display.c       |  9 +++++++++
 src/virt-viewer-session-spice.c | 15 +++++++++++++++
 src/virt-viewer-session.c       | 11 +++++++++++
 src/virt-viewer-session.h       |  2 ++
 src/virt-viewer-window.c        | 11 +++++++++++
 5 files changed, 48 insertions(+)

diff --git a/src/virt-viewer-display.c b/src/virt-viewer-display.c
index 3efe24c..3bdc9b8 100644
--- a/src/virt-viewer-display.c
+++ b/src/virt-viewer-display.c
@@ -519,6 +519,7 @@ virt_viewer_display_size_allocate(GtkWidget *widget,
     desktopAspect = (double)priv->desktopWidth / (double)priv->desktopHeight;
 
     if (child && gtk_widget_get_visible(child)) {
+        guint new_zoom;
         border_width = gtk_container_get_border_width(GTK_CONTAINER(display));
 
         width  = MAX(1, allocation->width - 2 * border_width);
@@ -532,6 +533,14 @@ virt_viewer_display_size_allocate(GtkWidget *widget,
             child_allocation.width = width;
             child_allocation.height = round(width / desktopAspect);
         }
+        new_zoom = round((double) NORMAL_ZOOM_LEVEL * child_allocation.width / priv->desktopWidth);
+
+        if (!virt_viewer_session_can_resize_guest(priv->session) && new_zoom != priv->zoom_level) {
+            g_debug("cannot resize guest, changing zoom level from %d to %d",
+                    priv->zoom_level, new_zoom);
+            priv->zoom_level = new_zoom;
+            g_object_notify(G_OBJECT(display), "zoom-level");
+        }
 
         child_allocation.x = 0.5 * (width - child_allocation.width) + allocation->x + border_width;
         child_allocation.y = 0.5 * (height - child_allocation.height) + allocation->y + border_width;
diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c
index b69faa6..4256d4c 100644
--- a/src/virt-viewer-session-spice.c
+++ b/src/virt-viewer-session-spice.c
@@ -165,6 +165,20 @@ virt_viewer_session_spice_can_share_folder(VirtViewerSession *session)
     return spice_session_has_channel_type(self->priv->session, SPICE_CHANNEL_WEBDAV);
 }
 
+static gboolean
+virt_viewer_session_spice_can_resize_guest(VirtViewerSession *session)
+{
+    gboolean agent_connected;
+
+    g_return_val_if_fail(VIRT_VIEWER_IS_SESSION_SPICE(session), FALSE);
+
+    g_object_get(virt_viewer_session_spice_get_main_channel(VIRT_VIEWER_SESSION_SPICE(session)),
+                 "agent-connected", &agent_connected,
+                 NULL);
+
+    return agent_connected;
+}
+
 static void
 virt_viewer_session_spice_class_init(VirtViewerSessionSpiceClass *klass)
 {
@@ -186,6 +200,7 @@ virt_viewer_session_spice_class_init(VirtViewerSessionSpiceClass *klass)
     dclass->mime_type = virt_viewer_session_spice_mime_type;
     dclass->apply_monitor_geometry = virt_viewer_session_spice_apply_monitor_geometry;
     dclass->can_share_folder = virt_viewer_session_spice_can_share_folder;
+    dclass->can_resize_guest = virt_viewer_session_spice_can_resize_guest;
 
     g_type_class_add_private(klass, sizeof(VirtViewerSessionSpicePrivate));
 
diff --git a/src/virt-viewer-session.c b/src/virt-viewer-session.c
index 131a500..fccaa19 100644
--- a/src/virt-viewer-session.c
+++ b/src/virt-viewer-session.c
@@ -678,6 +678,17 @@ gboolean virt_viewer_session_can_share_folder(VirtViewerSession *self)
     return klass->can_share_folder ? klass->can_share_folder(self) : FALSE;
 }
 
+gboolean virt_viewer_session_can_resize_guest(VirtViewerSession *self)
+{
+    VirtViewerSessionClass *klass;
+
+    g_return_val_if_fail(VIRT_VIEWER_IS_SESSION(self), FALSE);
+
+    klass = VIRT_VIEWER_SESSION_GET_CLASS(self);
+
+    return klass->can_resize_guest ? klass->can_resize_guest(self) : FALSE;
+}
+
 /*
  * Local variables:
  *  c-indent-level: 4
diff --git a/src/virt-viewer-session.h b/src/virt-viewer-session.h
index 533d79a..4afc176 100644
--- a/src/virt-viewer-session.h
+++ b/src/virt-viewer-session.h
@@ -74,6 +74,7 @@ struct _VirtViewerSessionClass {
     void (* smartcard_insert) (VirtViewerSession* session);
     void (* smartcard_remove) (VirtViewerSession* session);
     const gchar* (* mime_type) (VirtViewerSession* session);
+    gboolean (*can_resize_guest)(VirtViewerSession *session);
 
     /* signals */
     void (*session_connected)(VirtViewerSession *session);
@@ -132,6 +133,7 @@ gchar* virt_viewer_session_get_uri(VirtViewerSession *self);
 void virt_viewer_session_set_file(VirtViewerSession *self, VirtViewerFile *file);
 VirtViewerFile* virt_viewer_session_get_file(VirtViewerSession *self);
 gboolean virt_viewer_session_can_share_folder(VirtViewerSession *self);
+gboolean virt_viewer_session_can_resize_guest(VirtViewerSession *self);
 
 G_END_DECLS
 
diff --git a/src/virt-viewer-window.c b/src/virt-viewer-window.c
index d67fbc1..2a72207 100644
--- a/src/virt-viewer-window.c
+++ b/src/virt-viewer-window.c
@@ -1327,6 +1327,15 @@ display_show_hint(VirtViewerDisplay *display,
 
     gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(self->priv->builder, "menu-file-screenshot")), hint);
 }
+
+static void
+display_zoom_changed(VirtViewerDisplay *display,
+                     GParamSpec *pspec G_GNUC_UNUSED,
+                     VirtViewerWindow *self)
+{
+    self->priv->zoomlevel = virt_viewer_display_get_zoom_level(display);
+}
+
 static gboolean
 window_key_pressed (GtkWidget *widget G_GNUC_UNUSED,
                     GdkEvent  *event,
@@ -1381,6 +1390,8 @@ virt_viewer_window_set_display(VirtViewerWindow *self, VirtViewerDisplay *displa
                                           G_CALLBACK(virt_viewer_window_desktop_resize), self, 0);
         virt_viewer_signal_connect_object(display, "notify::show-hint",
                                           G_CALLBACK(display_show_hint), self, 0);
+        virt_viewer_signal_connect_object(display, "notify::zoom-level",
+                                          G_CALLBACK(display_zoom_changed), self, 0);
 
         display_show_hint(display, NULL, self);
 
-- 
2.4.1




More information about the virt-tools-list mailing list