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

Pavel Grunt pgrunt at redhat.com
Tue May 19 07:56:25 UTC 2015


Hi Jonathon,

On Mon, 2015-05-18 at 17:09 -0500, Jonathon Jongsma wrote:
> Hi Pavel,
> 
> To me, it feels a little bit like we're solving the wrong problem 
> here.
> I spent a little bit of time testing the bug listed below, and here 
> are
> my observations:
> 
> - When we use e.g. --zoom=200 at startup, virt-viewer tries to make 
> the
> window 2x as big as the guest resolution.
> - if this window size would be greater than the size of the client
> monitor, gnome-shell will prevent the window from getting that large 
> and
> will limit it to the size of the client monitor.
> - From here, the behavior between vnc and spice-gtk (with vdagent)
> differs:
> 
> spice-gtk:
> - the window is displayed at the requested zoom level, but the guest
> resolution is resized smaller to fit within the client monitor 


Thats true for gnome-shell, but not for GNOME in RHEL6

> (taking
> into account the zoom factor)
> - clicking "view > zoom > normal size" will shrink the display to 
> this
> smaller size and show it at 100% scale. 
> - This doesn't really seem like a bug to me
> 
> VNC:
> - Since the client cannot resize the resolution of a guest in VNC,
> resizing a window is the same as zooming it. If gnome-shell limits 
> the
> window to smaller than requested, it is effectively reducing the zoom
> level. But the application seems to think its zoom level is still 
> 200%.
> - clicking "view > zoom > normal size" shrinks the display and 
> scales it
> to a value less than 100% because it unscales the display by 200% 
> (even
> though its actual zoom level is really only e.g. 150%).
> - In theory this all applies to spice-gtk without a vdagent as well.
> 
> So I think that this bug could be fixed by unscaling the display by 
> the
> actual effective zoom level (150% in the example above) instead of 
> the
> zoom level given on the command line (200%). That seems simpler than
> adding new accessors and calculating maximum zoom levels, etc.
> 
> What do you think?

Well, I don't think that zooming in should resize the guest (this is
happening in gnome-shell and in Windows), also I don't think that the
window should grow to exceed the monitor size (this is happening in
GNOME, Xfce).

I will go the way you suggested (unscaling the display), but I would
like to discuss whether 'resizing of guest' should happen.

Thanks,
Pavel

> 
> Jonathon
> 
> 
> 
> On Thu, 2015-05-14 at 16:36 +0200, Pavel Grunt wrote:
> > 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_displa
> > y(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)
> >  {
> 
> 
> _______________________________________________
> virt-tools-list mailing list
> virt-tools-list at redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list




More information about the virt-tools-list mailing list