diff mbox

[5/6] gtk: add support for screen scaling and full screen

Message ID 1329695104-15174-6-git-send-email-aliguori@us.ibm.com
State New
Headers show

Commit Message

Anthony Liguori Feb. 19, 2012, 11:45 p.m. UTC
Basic menu items to enter full screen mode and zoom in/out.  Unlike SDL, we
don't allow arbitrary scaling based on window resizing.  The current behavior
with SDL causes a lot of problems for me.

Sometimes I accidentally resize the window a tiny bit while trying to move it
(Ubuntu's 1-pixel window decorations don't help here).  After that, scaling is
now active and if the screen changes size again, badness ensues since the
aspect ratio is skewed.

Allowing zooming by 25% in and out should cover most use cases.  We can add a
more flexible scaling later but for now, I think this is a more friendly
behavior.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 ui/gtk.c |   89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 85 insertions(+), 4 deletions(-)

Comments

Paolo Bonzini Feb. 20, 2012, 7:41 a.m. UTC | #1
On 02/20/2012 12:45 AM, Anthony Liguori wrote:
> +static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque)
> +{
> +    GtkDisplayState *s = opaque;
> +
> +    s->scale_x *= 1.25;
> +    s->scale_y *= 1.25;
> +
> +    gd_resize(s->ds);
> +}
> +
> +static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
> +{
> +    GtkDisplayState *s = opaque;
> +
> +    s->scale_x *= .75;
> +    s->scale_y *= .75;

This should be /= 1.25, because the inverse of 1.25 is _not_ 0.75. :)

Paolo
Anthony Liguori Feb. 20, 2012, 1:45 p.m. UTC | #2
On 02/20/2012 01:41 AM, Paolo Bonzini wrote:
> On 02/20/2012 12:45 AM, Anthony Liguori wrote:
>> +static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque)
>> +{
>> +    GtkDisplayState *s = opaque;
>> +
>> +    s->scale_x *= 1.25;
>> +    s->scale_y *= 1.25;
>> +
>> +    gd_resize(s->ds);
>> +}
>> +
>> +static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
>> +{
>> +    GtkDisplayState *s = opaque;
>> +
>> +    s->scale_x *= .75;
>> +    s->scale_y *= .75;
>
> This should be /= 1.25, because the inverse of 1.25 is _not_ 0.75. :)

Indeed, thanks :-)

Regards,

Anthony Liguori

>
> Paolo
>
Stefan Weil Feb. 25, 2012, 3:49 p.m. UTC | #3
Am 20.02.2012 00:45, schrieb Anthony Liguori:
> Basic menu items to enter full screen mode and zoom in/out. Unlike SDL, we
> don't allow arbitrary scaling based on window resizing. The current 
> behavior
> with SDL causes a lot of problems for me.
>
> Sometimes I accidentally resize the window a tiny bit while trying to 
> move it
> (Ubuntu's 1-pixel window decorations don't help here). After that, 
> scaling is
> now active and if the screen changes size again, badness ensues since the
> aspect ratio is skewed.
>
> Allowing zooming by 25% in and out should cover most use cases. We can 
> add a
> more flexible scaling later but for now, I think this is a more friendly
> behavior.
>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
> ui/gtk.c | 89 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
> 1 files changed, 85 insertions(+), 4 deletions(-)
>
> diff --git a/ui/gtk.c b/ui/gtk.c
> index 73051db..b9a9bc3 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
[...]
> + s->zoom_in_item = 
> gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_IN, NULL);
> + gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_in_item),
> + "<QEMU>/View/Zoom In");
> + gtk_accel_map_add_entry("<QEMU>/View/Zoom In", GDK_KEY_equal, 
> GDK_CONTROL_MASK | GDK_MOD1_MASK);
> + gtk_menu_append(GTK_MENU(s->view_menu), s->zoom_in_item);
> +
> + s->zoom_out_item = 
> gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_OUT, NULL);
> + gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_out_item),
> + "<QEMU>/View/Zoom Out");
> + gtk_accel_map_add_entry("<QEMU>/View/Zoom Out", GDK_KEY_minus, 
> GDK_CONTROL_MASK | GDK_MOD1_MASK);
> + gtk_menu_append(GTK_MENU(s->view_menu), s->zoom_out_item);
> +
> separator = gtk_separator_menu_item_new();
> gtk_menu_append(GTK_MENU(s->view_menu), separator);

I think GDK_KEY_plus would be a better choice instead of GDK_KEY_equal
because that's the key used to zoom in by GNOME terminal, most web browsers
and many more programs.

Usually there is also a "Zoom 100 %" with GDK_KEY_0 which resets
zooming to 100 %.

Regards,

Stefan Weil
diff mbox

Patch

diff --git a/ui/gtk.c b/ui/gtk.c
index 73051db..b9a9bc3 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -58,6 +58,9 @@  typedef struct GtkDisplayState
 
     GtkWidget *view_menu_item;
     GtkWidget *view_menu;
+    GtkWidget *full_screen_item;
+    GtkWidget *zoom_in_item;
+    GtkWidget *zoom_out_item;
     GtkWidget *grab_item;
     GtkWidget *vga_item;
 
@@ -78,6 +81,7 @@  typedef struct GtkDisplayState
 
     double scale_x;
     double scale_y;
+    gboolean full_screen;
 
     GdkCursor *null_cursor;
     Notifier mouse_mode_notifier;
@@ -102,7 +106,7 @@  static void gd_update_cursor(GtkDisplayState *s, gboolean override)
     on_vga = (gtk_notebook_get_current_page(GTK_NOTEBOOK(s->notebook)) == 0);
 
     if ((override || on_vga) &&
-        (kbd_mouse_is_absolute() || gd_is_grab_active(s))) {
+        (s->full_screen || kbd_mouse_is_absolute() || gd_is_grab_active(s))) {
 	gdk_window_set_cursor(window, s->null_cursor);
     } else {
 	gdk_window_set_cursor(window, NULL);
@@ -194,9 +198,11 @@  static void gd_resize(DisplayState *ds)
                                                      ds->surface->height,
                                                      ds->surface->linesize);
 
-    gtk_widget_set_size_request(s->drawing_area,
-                                ds->surface->width * s->scale_x,
-                                ds->surface->height * s->scale_y);
+    if (!s->full_screen) {
+        gtk_widget_set_size_request(s->drawing_area,
+                                    ds->surface->width * s->scale_x,
+                                    ds->surface->height * s->scale_y);
+    }
 }
 
 /** QEMU Events **/
@@ -453,6 +459,51 @@  static void gd_menu_show_tabs(GtkMenuItem *item, void *opaque)
     }
 }
 
+static void gd_menu_full_screen(GtkMenuItem *item, void *opaque)
+{
+    GtkDisplayState *s = opaque;
+
+    if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->full_screen_item))) {
+        gtk_notebook_set_show_tabs(GTK_NOTEBOOK(s->notebook), FALSE);
+        gtk_widget_set_size_request(s->menu_bar, 0, 0);
+        gtk_widget_set_size_request(s->drawing_area, -1, -1);
+        gtk_window_set_resizable(GTK_WINDOW(s->window), TRUE);
+        gtk_window_fullscreen(GTK_WINDOW(s->window));
+        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), TRUE);
+        s->full_screen = TRUE;
+    } else {
+        gtk_window_unfullscreen(GTK_WINDOW(s->window));
+        gd_menu_show_tabs(GTK_MENU_ITEM(s->show_tabs_item), s);
+        gtk_widget_set_size_request(s->menu_bar, -1, -1);
+        gtk_widget_set_size_request(s->drawing_area, s->ds->surface->width, s->ds->surface->height);
+        gtk_window_set_resizable(GTK_WINDOW(s->window), FALSE);
+        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), FALSE);
+        s->full_screen = FALSE;
+    }
+
+    gd_update_cursor(s, FALSE);
+}
+
+static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque)
+{
+    GtkDisplayState *s = opaque;
+
+    s->scale_x *= 1.25;
+    s->scale_y *= 1.25;
+
+    gd_resize(s->ds);
+}
+
+static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
+{
+    GtkDisplayState *s = opaque;
+
+    s->scale_x *= .75;
+    s->scale_y *= .75;
+
+    gd_resize(s->ds);
+}
+
 static void gd_menu_grab_input(GtkMenuItem *item, void *opaque)
 {
     GtkDisplayState *s = opaque;
@@ -495,6 +546,9 @@  static void gd_change_page(GtkNotebook *nb, gpointer arg1, guint arg2,
     if (!on_vga) {
         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
                                        FALSE);
+    } else if (s->full_screen) {
+        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
+                                       TRUE);
     }
 
     gtk_widget_set_sensitive(s->grab_item, on_vga);
@@ -647,6 +701,12 @@  static void gd_connect_signals(GtkDisplayState *s)
 
     g_signal_connect(s->quit_item, "activate",
                      G_CALLBACK(gd_menu_quit), s);
+    g_signal_connect(s->full_screen_item, "activate",
+                     G_CALLBACK(gd_menu_full_screen), s);
+    g_signal_connect(s->zoom_in_item, "activate",
+                     G_CALLBACK(gd_menu_zoom_in), s);
+    g_signal_connect(s->zoom_out_item, "activate",
+                     G_CALLBACK(gd_menu_zoom_out), s);
     g_signal_connect(s->vga_item, "activate",
                      G_CALLBACK(gd_menu_switch_vc), s);
     g_signal_connect(s->grab_item, "activate",
@@ -678,6 +738,27 @@  static void gd_create_menus(GtkDisplayState *s)
     gtk_menu_set_accel_group(GTK_MENU(s->view_menu), accel_group);
     s->view_menu_item = gtk_menu_item_new_with_mnemonic("_View");
 
+    s->full_screen_item = gtk_check_menu_item_new_with_mnemonic("_Full Screen");
+    gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->full_screen_item),
+                                 "<QEMU>/View/Full Screen");
+    gtk_accel_map_add_entry("<QEMU>/View/Full Screen", GDK_KEY_f, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+    gtk_menu_append(GTK_MENU(s->view_menu), s->full_screen_item);
+
+    separator = gtk_separator_menu_item_new();
+    gtk_menu_append(GTK_MENU(s->view_menu), separator);
+
+    s->zoom_in_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_IN, NULL);
+    gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_in_item),
+                                 "<QEMU>/View/Zoom In");
+    gtk_accel_map_add_entry("<QEMU>/View/Zoom In", GDK_KEY_equal, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+    gtk_menu_append(GTK_MENU(s->view_menu), s->zoom_in_item);
+
+    s->zoom_out_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_OUT, NULL);
+    gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_out_item),
+                                 "<QEMU>/View/Zoom Out");
+    gtk_accel_map_add_entry("<QEMU>/View/Zoom Out", GDK_KEY_minus, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+    gtk_menu_append(GTK_MENU(s->view_menu), s->zoom_out_item);
+
     separator = gtk_separator_menu_item_new();
     gtk_menu_append(GTK_MENU(s->view_menu), separator);