[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