diff options
-rw-r--r-- | src/terminal-window.c | 161 |
1 files changed, 120 insertions, 41 deletions
diff --git a/src/terminal-window.c b/src/terminal-window.c index e0004c3..04fbca8 100644 --- a/src/terminal-window.c +++ b/src/terminal-window.c @@ -66,9 +66,24 @@ struct _TerminalWindowPrivate GtkWidget *menubar; GtkWidget *notebook; + GtkWidget *main_vbox; TerminalScreen *active_screen; + + /* Size of a character cell in pixels */ int old_char_width; int old_char_height; + + /* Width and height added to the actual terminal grid by "chrome" inside + * what was traditionally the X11 window: menu bar, title bar, + * style-provided padding. This must be included when resizing the window + * and also included in geometry hints. */ + int old_chrome_width; + int old_chrome_height; + + /* Width and height of the padding around the geometry widget. */ + int old_padding_width; + int old_padding_height; + void *old_geometry_widget; /* only used for pointer value as it may be freed */ GtkWidget *confirm_close_dialog; @@ -902,7 +917,7 @@ terminal_size_to_cb (GtkAction *action, vte_terminal_set_size (VTE_TERMINAL (priv->active_screen), width, height); - terminal_window_set_size_force_grid (window, priv->active_screen, TRUE, -1, -1); + terminal_window_set_size (window, priv->active_screen, TRUE); } static void @@ -1077,7 +1092,7 @@ screen_resize_window_cb (TerminalScreen *screen, if (screen != priv->active_screen) return; - terminal_window_set_size_force_grid (window, screen, TRUE, -1, -1); + terminal_window_set_size (window, screen, TRUE); } static void @@ -1971,7 +1986,6 @@ terminal_window_init (TerminalWindow *window) GtkActionGroup *action_group; GtkAction *action; GtkUIManager *manager; - GtkWidget *main_vbox; GError *error; GtkWindowGroup *window_group; GtkAccelGroup *accel_group; @@ -2003,9 +2017,9 @@ terminal_window_init (TerminalWindow *window) priv->active_screen = NULL; priv->menubar_visible = FALSE; - main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_container_add (GTK_CONTAINER (window), main_vbox); - gtk_widget_show (main_vbox); + priv->main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add (GTK_CONTAINER (window), priv->main_vbox); + gtk_widget_show (priv->main_vbox); priv->notebook = gtk_notebook_new (); gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook), TRUE); @@ -2033,11 +2047,17 @@ terminal_window_init (TerminalWindow *window) g_signal_connect (priv->notebook, "create-window", G_CALLBACK (handle_tab_droped_on_desktop), window); - gtk_box_pack_end (GTK_BOX (main_vbox), priv->notebook, TRUE, TRUE, 0); + gtk_box_pack_end (GTK_BOX (priv->main_vbox), priv->notebook, TRUE, TRUE, 0); gtk_widget_show (priv->notebook); priv->old_char_width = -1; priv->old_char_height = -1; + + priv->old_chrome_width = -1; + priv->old_chrome_height = -1; + priv->old_padding_width = -1; + priv->old_padding_height = -1; + priv->old_geometry_widget = NULL; /* Create the UI manager */ @@ -2087,7 +2107,7 @@ terminal_window_init (TerminalWindow *window) } priv->menubar = gtk_ui_manager_get_widget (manager, "/menubar"); - gtk_box_pack_start (GTK_BOX (main_vbox), + gtk_box_pack_start (GTK_BOX (priv->main_vbox), priv->menubar, FALSE, FALSE, 0); @@ -2556,15 +2576,33 @@ terminal_window_set_size_force_grid (TerminalWindow *window, int force_grid_width, int force_grid_height) { + TerminalWindowPrivate *priv = window->priv; GtkWidget *widget; GtkWidget *app; - int grid_width; - int grid_height; + int grid_width, grid_height; + gint pixel_width, pixel_height; + GdkWindow *gdk_window; + + gdk_window = gtk_widget_get_window (GTK_WIDGET (window)); + result = TRUE; + + if (gdk_window != NULL && + (gdk_window_get_state (gdk_window) & + (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_TILED))) + { + /* Don't adjust the size of maximized or tiled (snapped, half-maximized) + * windows: if we do, there will be ugly gaps of up to 1 character cell + * around otherwise tiled windows. */ + return result; + } /* be sure our geometry is up-to-date */ terminal_window_update_geometry (window); - widget = GTK_WIDGET (screen); + if (GTK_IS_WIDGET (screen)) + widget = GTK_WIDGET (screen); + else + widget = GTK_WIDGET (window); app = gtk_widget_get_toplevel (widget); g_assert (app != NULL); @@ -2575,10 +2613,29 @@ terminal_window_set_size_force_grid (TerminalWindow *window, grid_width = force_grid_width; if (force_grid_height >= 0) grid_height = force_grid_height; + + /* the "old" struct members were updated by update_geometry */ + pixel_width = priv->old_chrome_width + grid_width * priv->old_char_width; + pixel_height = priv->old_chrome_height + grid_height * priv->old_char_height; + + _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY, + "[window %p] size is %dx%d cells of %dx%d px\n", + window, grid_width, grid_height, + priv->old_char_width, priv->old_char_height); + + _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY, + "[window %p] %dx%d + %dx%d = %dx%d\n", + window, grid_width * priv->old_char_width, + grid_height * priv->old_char_height, + priv->old_chrome_width, priv->old_chrome_height, + pixel_width, pixel_height); + if (even_if_mapped && gtk_widget_get_mapped (app)) - gtk_window_resize_to_geometry (GTK_WINDOW (app), grid_width, grid_height); + gtk_window_resize (GTK_WINDOW (app), pixel_width, pixel_height); else - gtk_window_set_default_geometry (GTK_WINDOW (app), grid_width, grid_height); + gtk_window_set_default_size (GTK_WINDOW (app), pixel_width, pixel_height); + + return result; } void @@ -2961,9 +3018,10 @@ terminal_window_update_geometry (TerminalWindow *window) GtkWidget *widget; GdkGeometry hints; GtkBorder padding; - GtkRequisition toplevel_request, widget_request; - int base_width, base_height; + GtkRequisition toplevel_request, vbox_request, widget_request; + int grid_width, grid_height; int char_width, char_height; + int chrome_width, chrome_height; if (priv->active_screen == NULL) return; @@ -2977,26 +3035,46 @@ terminal_window_update_geometry (TerminalWindow *window) */ terminal_screen_get_cell_size (priv->active_screen, &char_width, &char_height); - if (char_width != priv->old_char_width || - char_height != priv->old_char_height || - widget != (GtkWidget*) priv->old_geometry_widget) - { - /* FIXME Since we're using xthickness/ythickness to compute - * padding we need to change the hints when the theme changes. - */ + terminal_screen_get_size (priv->active_screen, &grid_width, &grid_height); + _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY, "%dx%d cells of %dx%d px = %dx%d px\n", + grid_width, grid_height, char_width, char_height, + char_width * grid_width, char_height * grid_height); + + gtk_style_context_get_padding(gtk_widget_get_style_context (widget), + gtk_widget_get_state_flags (widget), + &padding); - gtk_widget_get_preferred_size (GTK_WIDGET (window), NULL, &toplevel_request); - gtk_widget_get_preferred_size (widget, NULL, &widget_request); + _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY, "padding = %dx%d px\n", + padding.left + padding.right, + padding.top + padding.bottom); - base_width = toplevel_request.width - widget_request.width; - base_height = toplevel_request.height - widget_request.height; + gtk_widget_get_preferred_size (priv->main_vbox, NULL, &vbox_request); + _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY, "content area requests %dx%d px\n", + vbox_request.width, vbox_request.height); - gtk_style_context_get_padding (gtk_widget_get_style_context (widget), - gtk_widget_get_state_flags (widget), - &padding); + gtk_widget_get_preferred_size (GTK_WIDGET (window), NULL, &toplevel_request); + _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY, "window requests %dx%d px\n", + toplevel_request.width, toplevel_request.height); - hints.base_width = base_width + padding.left + padding.right; - hints.base_height = base_height + padding.top + padding.bottom; + chrome_width = vbox_request.width - (char_width * grid_width); + chrome_height = vbox_request.height - (char_height * grid_height); + _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY, "chrome: %dx%d px\n", + chrome_width, chrome_height); + + gtk_widget_get_preferred_size (widget, NULL, &widget_request); + _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY, "terminal widget requests %dx%d px\n", + widget_request.width, widget_request.height); + + if (char_width != priv->old_char_width || + char_height != priv->old_char_height || + padding.left + padding.right != priv->old_padding_width || + padding.top + padding.bottom != priv->old_padding_height || + chrome_width != priv->old_chrome_width || + chrome_height != priv->old_chrome_height || + widget != GTK_WIDGET (priv->old_geometry_widget)) + { + hints.base_width = chrome_width; + hints.base_height = chrome_height; #define MIN_WIDTH_CHARS 4 #define MIN_HEIGHT_CHARS 1 @@ -3025,8 +3103,6 @@ terminal_window_update_geometry (TerminalWindow *window) hints.width_inc, hints.height_inc); - priv->old_char_width = hints.width_inc; - priv->old_char_height = hints.height_inc; priv->old_geometry_widget = widget; } else @@ -3035,6 +3111,15 @@ terminal_window_update_geometry (TerminalWindow *window) "[window %p] hints: increment unchanged, not setting\n", window); } + + /* We need these for the size calculation in terminal_window_set_size(), + * so we set them unconditionally. */ + priv->old_char_width = char_width; + priv->old_char_height = char_height; + priv->old_chrome_width = chrome_width; + priv->old_chrome_height = chrome_height; + priv->old_padding_width = padding.left + padding.right; + priv->old_padding_height = padding.top + padding.bottom; } static void @@ -3929,23 +4014,17 @@ tabs_detach_tab_callback (GtkAction *action, TerminalApp *app; TerminalWindow *new_window; TerminalScreen *screen; - char *geometry; - int width, height; app = terminal_app_get (); screen = priv->active_screen; - /* FIXME: this seems wrong if tabs are shown in the window */ - terminal_screen_get_size (screen, &width, &height); - geometry = g_strdup_printf ("%dx%d", width, height); - new_window = terminal_app_new_window (app, gtk_widget_get_screen (GTK_WIDGET (window))); terminal_window_move_screen (window, new_window, screen, -1); - gtk_window_parse_geometry (GTK_WINDOW (new_window), geometry); - g_free (geometry); + /* FIXME: this seems wrong if tabs are shown in the window */ + terminal_window_set_size (new_window, screen, FALSE); gtk_window_present_with_time (GTK_WINDOW (new_window), gtk_get_current_event_time ()); } |