[virt-tools-list] [PATCH 4/4] gtk-3: Rework window size handling

Hans de Goede hdegoede at redhat.com
Mon Apr 22 19:08:58 UTC 2013


With gtk-2 we have a special hack, where at first we make the
virt-viewer-display request its actual size, and then once the window is
mapped, we request a size of 50x50 to allow the user to resize the window
to something smaller.

With the latest gtk-3 this is broken, and the window gets resized to a
smaller size as soon as we change the size request to 50x50.

gtk-3 has a much better way of dealing with this in the form of widgets
being able to specify both a minimal and a natural size. This patch changes
virt-viewer to use this with gtk-3, instead of the gtk-2 hack.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 src/virt-viewer-display.c | 49 ++++++++++++++++++++++++++++++++++++-----------
 src/virt-viewer-window.c  | 26 ++++++++++++++++++++-----
 2 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/src/virt-viewer-display.c b/src/virt-viewer-display.c
index cdbaf45..b7bf6ef 100644
--- a/src/virt-viewer-display.c
+++ b/src/virt-viewer-display.c
@@ -36,7 +36,9 @@
 
 struct _VirtViewerDisplayPrivate
 {
+#if !GTK_CHECK_VERSION(3, 0, 0)
     gboolean dirty;
+#endif
     guint desktopWidth;
     guint desktopHeight;
     guint zoom_level;
@@ -48,9 +50,10 @@ struct _VirtViewerDisplayPrivate
     gboolean auto_resize;
 };
 
+#if !GTK_CHECK_VERSION(3, 0, 0)
 static void virt_viewer_display_size_request(GtkWidget *widget,
                                              GtkRequisition *requisition);
-#if GTK_CHECK_VERSION(3, 0, 0)
+#else
 static void virt_viewer_display_get_preferred_width(GtkWidget *widget,
                                                     int *minwidth,
                                                     int *defwidth);
@@ -255,8 +258,10 @@ virt_viewer_display_init(VirtViewerDisplay *display)
     display->priv->desktopHeight = 100;
     display->priv->zoom_level = 100;
     display->priv->zoom = TRUE;
-    display->priv->dirty = TRUE;
     display->priv->auto_resize = TRUE;
+#if !GTK_CHECK_VERSION(3, 0, 0)
+    display->priv->dirty = TRUE;
+#endif
 }
 
 GtkWidget*
@@ -350,6 +355,7 @@ virt_viewer_display_grab_focus(GtkWidget *widget)
 }
 
 
+#if !GTK_CHECK_VERSION(3, 0, 0)
 static gboolean
 virt_viewer_display_idle(gpointer opaque)
 {
@@ -390,17 +396,24 @@ virt_viewer_display_size_request(GtkWidget *widget,
               priv->desktopWidth, priv->desktopHeight);
 }
 
+#else
 
-#if GTK_CHECK_VERSION(3, 0, 0)
 static void virt_viewer_display_get_preferred_width(GtkWidget *widget,
                                                     int *minwidth,
                                                     int *defwidth)
 {
-    GtkRequisition req;
+    VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(widget);
+    VirtViewerDisplayPrivate *priv = display->priv;
+    int border_width = gtk_container_get_border_width(GTK_CONTAINER(widget));
 
-    virt_viewer_display_size_request(widget, &req);
+    *minwidth = 50 + 2 * border_width;
 
-    *minwidth = *defwidth = req.width;
+    if (priv->zoom) {
+        *defwidth = round(priv->desktopWidth * priv->zoom_level / 100.0) +
+                    2 * border_width;
+    } else {
+        *defwidth = priv->desktopWidth + 2 * border_width;
+    }
 }
 
 
@@ -408,11 +421,18 @@ static void virt_viewer_display_get_preferred_height(GtkWidget *widget,
                                                      int *minheight,
                                                      int *defheight)
 {
-    GtkRequisition req;
+    VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(widget);
+    VirtViewerDisplayPrivate *priv = display->priv;
+    int border_height = gtk_container_get_border_width(GTK_CONTAINER(widget));
 
-    virt_viewer_display_size_request(widget, &req);
+    *minheight = 50 + 2 * border_height;
 
-    *minheight = *defheight = req.height;
+    if (priv->zoom) {
+        *defheight = round(priv->desktopHeight * priv->zoom_level / 100.0) +
+                    2 * border_height;
+    } else {
+        *defheight = priv->desktopHeight + 2 * border_height;
+    }
 }
 #endif
 
@@ -436,7 +456,11 @@ virt_viewer_display_size_allocate(GtkWidget *widget,
 
     if (priv->desktopWidth == 0 ||
         priv->desktopHeight == 0)
+#if !GTK_CHECK_VERSION(3, 0, 0)
         goto end;
+#else
+        return;
+#endif
 
     desktopAspect = (double)priv->desktopWidth / (double)priv->desktopHeight;
 
@@ -462,6 +486,7 @@ virt_viewer_display_size_allocate(GtkWidget *widget,
         gtk_widget_size_allocate(child, &child_allocation);
     }
 
+#if !GTK_CHECK_VERSION(3, 0, 0)
 end:
     /* This unsets the size request, so that the user can
      * manually resize the window smaller again
@@ -471,6 +496,7 @@ end:
         if (gtk_widget_get_mapped(widget))
             priv->dirty = FALSE;
     }
+#endif
 }
 
 
@@ -505,11 +531,12 @@ void virt_viewer_display_get_desktop_size(VirtViewerDisplay *display,
 
 void virt_viewer_display_queue_resize(VirtViewerDisplay *display)
 {
-    VirtViewerDisplayPrivate *priv = display->priv;
     GtkWidget *child = gtk_bin_get_child(GTK_BIN(display));
 
     if (child && gtk_widget_get_visible(child)) {
-        priv->dirty = TRUE;
+#if !GTK_CHECK_VERSION(3, 0, 0)
+        display->priv->dirty = TRUE;
+#endif
         gtk_widget_queue_resize(GTK_WIDGET(display));
     }
 }
diff --git a/src/virt-viewer-window.c b/src/virt-viewer-window.c
index 4a17626..67333f2 100644
--- a/src/virt-viewer-window.c
+++ b/src/virt-viewer-window.c
@@ -372,6 +372,22 @@ virt_viewer_window_menu_view_zoom_reset(GtkWidget *menu G_GNUC_UNUSED,
     virt_viewer_window_set_zoom_level(self, 100);
 }
 
+/* Kick GtkWindow to tell it to adjust to our new widget sizes */
+static void
+virt_viewer_window_queue_resize(VirtViewerWindow *self)
+{
+    VirtViewerWindowPrivate *priv = self->priv;
+#if GTK_CHECK_VERSION(3, 0, 0)
+    GtkRequisition nat;
+
+    gtk_window_set_default_size(GTK_WINDOW(priv->window), -1, -1);
+    gtk_widget_get_preferred_size(GTK_WIDGET(priv->window), NULL, &nat);
+    gtk_window_resize(GTK_WINDOW(priv->window), nat.width, nat.height);
+#else
+    gtk_window_resize(GTK_WINDOW(priv->window), 1, 1);
+#endif
+}
+
 /*
  * This code attempts to resize the top level window to be large enough
  * to contain the entire display desktop at 1:1 ratio. If the local desktop
@@ -399,9 +415,6 @@ virt_viewer_window_resize(VirtViewerWindow *self, gboolean keep_win_size)
         return;
     }
 
-    if (!keep_win_size)
-        gtk_window_resize(GTK_WINDOW(priv->window), 1, 1);
-
     virt_viewer_display_get_desktop_size(VIRT_VIEWER_DISPLAY(priv->display),
                                          &desktopWidth, &desktopHeight);
 
@@ -441,6 +454,9 @@ virt_viewer_window_resize(VirtViewerWindow *self, gboolean keep_win_size)
 
     virt_viewer_display_set_desktop_size(VIRT_VIEWER_DISPLAY(priv->display),
                                          width, height);
+
+    if (!keep_win_size)
+        virt_viewer_window_queue_resize(self);
 }
 
 static void
@@ -1192,9 +1208,9 @@ virt_viewer_window_set_zoom_level(VirtViewerWindow *self, gint zoom_level)
     if (!priv->display)
         return;
 
-    gtk_window_resize(GTK_WINDOW(priv->window), 1, 1);
-
     virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(priv->display), priv->zoomlevel);
+
+    virt_viewer_window_queue_resize(self);
 }
 
 gint virt_viewer_window_get_zoom_level(VirtViewerWindow *self)
-- 
1.8.2




More information about the virt-tools-list mailing list