Skip to content

Commit

Permalink
gtk: window sizing overhaul
Browse files Browse the repository at this point in the history
Major overhaul for window size handling.  This basically switches qemu
over to use geometry hints for the window manager instead of trying to
get the job done with widget resize requests.  This allows to specify
better what we need and also avoids window resizes.

FIXME: on gtk2 someone overwrites the geometry hints :(

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
  • Loading branch information
kraxel committed May 26, 2014
1 parent 0f61a61 commit 82fc180
Showing 1 changed file with 70 additions and 30 deletions.
100 changes: 70 additions & 30 deletions ui/gtk.c
Expand Up @@ -74,6 +74,12 @@
#endif

#define MAX_VCS 10
#define VC_WINDOW_X_MIN 320
#define VC_WINDOW_Y_MIN 240
#define VC_TERM_X_MIN 80
#define VC_TERM_Y_MIN 25
#define VC_SCALE_MIN 0.25
#define VC_SCALE_STEP 0.25

#if !defined(CONFIG_VTE)
# define VTE_CHECK_VERSION(a, b, c) 0
Expand Down Expand Up @@ -322,29 +328,63 @@ static void gd_update_caption(GtkDisplayState *s)
g_free(prefix);
}

static void gd_update_windowsize(VirtualConsole *vc)
static void gd_update_geometry_hints(VirtualConsole *vc)
{
GtkDisplayState *s = vc->s;
double sx, sy;
GdkWindowHints mask = 0;
GdkGeometry geo = {};
GtkWidget *geo_widget = NULL;
GtkWindow *geo_window;

if (vc->type != GD_VC_GFX || s->full_screen) {
return;
if (vc->type == GD_VC_GFX) {
if (s->free_scale) {
geo.min_width = surface_width(vc->gfx.ds) * VC_SCALE_MIN;
geo.min_height = surface_height(vc->gfx.ds) * VC_SCALE_MIN;
mask |= GDK_HINT_MIN_SIZE;
} else {
geo.min_width = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
geo.min_height = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
mask |= GDK_HINT_MIN_SIZE;
}
geo_widget = vc->gfx.drawing_area;
gtk_widget_set_size_request(geo_widget, geo.min_width, geo.min_height);

#if defined(CONFIG_VTE)
} else if (vc->type == GD_VC_VTE) {
VteTerminal *term = VTE_TERMINAL(vc->vte.terminal);
GtkBorder *ib;

geo.width_inc = vte_terminal_get_char_width(term);
geo.height_inc = vte_terminal_get_char_height(term);
mask |= GDK_HINT_RESIZE_INC;
geo.base_width = geo.width_inc;
geo.base_height = geo.height_inc;
mask |= GDK_HINT_BASE_SIZE;
geo.min_width = geo.width_inc * VC_TERM_X_MIN;
geo.min_height = geo.height_inc * VC_TERM_Y_MIN;
mask |= GDK_HINT_MIN_SIZE;
gtk_widget_style_get(vc->vte.terminal, "inner-border", &ib, NULL);
geo.base_width += ib->left + ib->right;
geo.base_height += ib->top + ib->bottom;
geo.min_width += ib->left + ib->right;
geo.min_height += ib->top + ib->bottom;
geo_widget = vc->vte.terminal;
#endif
}

if (s->free_scale) {
sx = 1.0;
sy = 1.0;
} else {
sx = vc->gfx.scale_x;
sy = vc->gfx.scale_y;
}
gtk_widget_set_size_request(vc->gfx.drawing_area,
surface_width(vc->gfx.ds) * sx,
surface_height(vc->gfx.ds) * sy);
if (vc->window) {
gtk_window_resize(GTK_WINDOW(vc->window), 320, 240);
} else {
gtk_window_resize(GTK_WINDOW(s->window), 320, 240);
geo_window = GTK_WINDOW(vc->window ? vc->window : s->window);
gtk_window_set_geometry_hints(geo_window, geo_widget, &geo, mask);
}

static void gd_update_windowsize(VirtualConsole *vc)
{
GtkDisplayState *s = vc->s;

gd_update_geometry_hints(vc);

if (vc->type == GD_VC_GFX && !s->full_screen && !s->free_scale) {
gtk_window_resize(GTK_WINDOW(vc->window ? vc->window : s->window),
VC_WINDOW_X_MIN, VC_WINDOW_Y_MIN);
}
}

Expand Down Expand Up @@ -991,7 +1031,7 @@ static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
GClosure *cb = g_cclosure_new_swap(G_CALLBACK(gd_win_grab), vc, NULL);
gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0, cb);

fprintf(stderr, "%s: %p\n", __func__, vc);
gd_update_geometry_hints(vc);
gd_update_caption(s);
}
}
Expand Down Expand Up @@ -1019,9 +1059,7 @@ static void gd_menu_full_screen(GtkMenuItem *item, void *opaque)
if (vc->type == GD_VC_GFX) {
vc->gfx.scale_x = 1.0;
vc->gfx.scale_y = 1.0;
gtk_widget_set_size_request(vc->gfx.drawing_area,
surface_width(vc->gfx.ds),
surface_height(vc->gfx.ds));
gd_update_windowsize(vc);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
FALSE);
}
Expand All @@ -1038,8 +1076,8 @@ static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque)
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item),
FALSE);

vc->gfx.scale_x += .25;
vc->gfx.scale_y += .25;
vc->gfx.scale_x += VC_SCALE_STEP;
vc->gfx.scale_y += VC_SCALE_STEP;

gd_update_windowsize(vc);
}
Expand All @@ -1052,11 +1090,11 @@ static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item),
FALSE);

vc->gfx.scale_x -= .25;
vc->gfx.scale_y -= .25;
vc->gfx.scale_x -= VC_SCALE_STEP;
vc->gfx.scale_y -= VC_SCALE_STEP;

vc->gfx.scale_x = MAX(vc->gfx.scale_x, .25);
vc->gfx.scale_y = MAX(vc->gfx.scale_y, .25);
vc->gfx.scale_x = MAX(vc->gfx.scale_x, VC_SCALE_MIN);
vc->gfx.scale_y = MAX(vc->gfx.scale_y, VC_SCALE_MIN);

gd_update_windowsize(vc);
}
Expand All @@ -1083,9 +1121,9 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
s->free_scale = FALSE;
vc->gfx.scale_x = 1.0;
vc->gfx.scale_y = 1.0;
gd_update_windowsize(vc);
}

gd_update_windowsize(vc);
gd_update_full_redraw(vc);
}

Expand Down Expand Up @@ -1279,6 +1317,7 @@ static void gd_change_page(GtkNotebook *nb, gpointer arg1, guint arg2,
}
gtk_widget_set_sensitive(s->grab_item, on_vga);

gd_update_windowsize(vc);
gd_update_cursor(vc);
}

Expand Down Expand Up @@ -1408,7 +1447,8 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
g_signal_connect(vc->vte.terminal, "commit", G_CALLBACK(gd_vc_in), vc);

vte_terminal_set_scrollback_lines(VTE_TERMINAL(vc->vte.terminal), -1);
vte_terminal_set_size(VTE_TERMINAL(vc->vte.terminal), 80, 25);
vte_terminal_set_size(VTE_TERMINAL(vc->vte.terminal),
VC_TERM_X_MIN, VC_TERM_Y_MIN);

#if VTE_CHECK_VERSION(0, 28, 0) && GTK_CHECK_VERSION(3, 0, 0)
vadjustment = gtk_scrollable_get_vadjustment
Expand Down

0 comments on commit 82fc180

Please sign in to comment.