src: add prop to control forced aspect ratio
When the VirtViewerDisplay class resizes the child display widget, it
attempts to preserve the remote desktop aspect ratio. This is useful in
general, if the display widget can't do this itself. The implication,
however, is that VirtViewerDisplay also has to take ownership of the
remote framebuffer resize functionality.
It is thus useful to disable VirtViewerDisplay's aspect ratio
preservation when the display widget can do this natively, as it can
then also do desktop resizes natively.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Daniel P. Berrangé
3 years ago
42 | 42 | VirtViewerSession *session; |
43 | 43 | gboolean fullscreen; |
44 | 44 | gboolean auto_resize; |
45 | gboolean force_aspect; | |
45 | 46 | }; |
46 | 47 | |
47 | 48 | static void virt_viewer_display_get_preferred_width(GtkWidget *widget, |
77 | 78 | PROP_SELECTABLE, |
78 | 79 | PROP_MONITOR, |
79 | 80 | PROP_AUTO_RESIZE, |
81 | PROP_FORCE_ASPECT, | |
80 | 82 | }; |
81 | 83 | |
82 | 84 | static void |
188 | 190 | G_PARAM_READABLE | |
189 | 191 | G_PARAM_WRITABLE)); |
190 | 192 | |
193 | g_object_class_install_property(object_class, | |
194 | PROP_FORCE_ASPECT, | |
195 | g_param_spec_boolean("force-aspect", | |
196 | "Force aspect", | |
197 | "Force aspect ratio for widget", | |
198 | TRUE, | |
199 | G_PARAM_READABLE | | |
200 | G_PARAM_WRITABLE)); | |
201 | ||
191 | 202 | g_signal_new("display-pointer-grab", |
192 | 203 | G_OBJECT_CLASS_TYPE(object_class), |
193 | 204 | G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS, |
259 | 270 | priv->desktopWidth = MIN_DISPLAY_WIDTH; |
260 | 271 | priv->desktopHeight = MIN_DISPLAY_HEIGHT; |
261 | 272 | priv->zoom_level = NORMAL_ZOOM_LEVEL; |
273 | priv->force_aspect = TRUE; | |
262 | 274 | } |
263 | 275 | |
264 | 276 | GtkWidget* |
296 | 308 | case PROP_AUTO_RESIZE: |
297 | 309 | priv->auto_resize = g_value_get_boolean(value); |
298 | 310 | break; |
311 | case PROP_FORCE_ASPECT: | |
312 | priv->force_aspect = g_value_get_boolean(value); | |
313 | break; | |
299 | 314 | |
300 | 315 | default: |
301 | 316 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
339 | 354 | break; |
340 | 355 | case PROP_AUTO_RESIZE: |
341 | 356 | g_value_set_boolean(value, virt_viewer_display_get_auto_resize(display)); |
357 | break; | |
358 | case PROP_FORCE_ASPECT: | |
359 | g_value_set_boolean(value, priv->force_aspect); | |
342 | 360 | break; |
343 | 361 | |
344 | 362 | default: |
417 | 435 | GtkAllocation child_allocation; |
418 | 436 | gint width, height; |
419 | 437 | gint border_width; |
420 | double desktopAspect; | |
421 | double actualAspect; | |
422 | 438 | GtkWidget *child = gtk_bin_get_child(bin); |
423 | 439 | |
424 | 440 | g_debug("Allocated %dx%d", allocation->width, allocation->height); |
433 | 449 | width = MAX(MIN_DISPLAY_WIDTH, allocation->width - 2 * border_width); |
434 | 450 | height = MAX(MIN_DISPLAY_HEIGHT, allocation->height - 2 * border_width); |
435 | 451 | |
436 | desktopAspect = (double) priv->desktopWidth / (double) priv->desktopHeight; | |
437 | actualAspect = (double) width / (double) height; | |
438 | ||
439 | if (actualAspect > desktopAspect) { | |
440 | child_allocation.width = round(height * desktopAspect); | |
441 | child_allocation.height = height; | |
452 | if (priv->force_aspect) { | |
453 | double desktopAspect = (double) priv->desktopWidth / (double) priv->desktopHeight; | |
454 | double actualAspect = (double) width / (double) height; | |
455 | ||
456 | if (actualAspect > desktopAspect) { | |
457 | child_allocation.width = round(height * desktopAspect); | |
458 | child_allocation.height = height; | |
459 | } else { | |
460 | child_allocation.width = width; | |
461 | child_allocation.height = round(width / desktopAspect); | |
462 | } | |
442 | 463 | } else { |
443 | 464 | child_allocation.width = width; |
444 | child_allocation.height = round(width / desktopAspect); | |
465 | child_allocation.height = height; | |
445 | 466 | } |
446 | 467 | |
447 | 468 | child_allocation.x = 0.5 * (width - child_allocation.width) + allocation->x + border_width; |