Blob Blame History Raw
From 4b12dda42e1c1b49a14474045c2013cb87e6be58 Mon Sep 17 00:00:00 2001
From: Alexei Sorokin <sor.alexei@meowr.ru>
Date: Tue, 6 Sep 2016 16:35:11 +0300
Subject: [PATCH 1/2] fix resize menu buttons (#122)

based on https://github.com/GNOME/gnome-terminal/commit/88bd325
---
 src/terminal-window.c | 161 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 120 insertions(+), 41 deletions(-)

diff --git a/src/terminal-window.c b/src/terminal-window.c
index e7b53a2..c0e5f1f 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;
@@ -899,7 +914,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
@@ -1074,7 +1089,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
@@ -1968,7 +1983,6 @@ terminal_window_init (TerminalWindow *window)
     GtkActionGroup *action_group;
     GtkAction *action;
     GtkUIManager *manager;
-    GtkWidget *main_vbox;
     GError *error;
     GtkWindowGroup *window_group;
     GtkAccelGroup *accel_group;
@@ -2000,9 +2014,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);
@@ -2026,11 +2040,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 */
@@ -2080,7 +2100,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);
 
@@ -2549,15 +2569,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);
@@ -2568,10 +2606,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
@@ -2892,9 +2949,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;
@@ -2908,26 +2966,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
@@ -2956,8 +3034,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
@@ -2966,6 +3042,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
@@ -3860,23 +3945,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 ());
 }
-- 
2.7.4