[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Freeze exception for roxterm 1.18.5-2



Tony Houghton writes:
> Hi,
> 
> I am the upstream developer and sponsored Debian maintainer of roxterm;
> the current release in testing and unstable is 1.18.5-1.
> 
> Shortly after the freeze a bug was found in roxterm 1.18.5 and I would
> like to have it fixed in squeeze by allowing the inclusion of 1.18.5-2.
> The Debian bug is 592984
> <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=592984>.
> 
> Unfortunately there was no satisfactory quick fix and I had to rewrite a
> considerable amount of code. On the positive side I think the new code
> is simpler and "cleaner" than the new code. I have some other changes in
> the pipeline for the next upstream release, and on consulting
> debian-mentors we decided the best action was to backport the bug fixes
> alone to 1.18.5.
> 
> I've attached the diff and the new package is waiting to be sponsored on
> mentors.debian.net:
> 
> - URL: http://mentors.debian.net/debian/pool/main/r/roxterm
> - Source repository: deb-src http://mentors.debian.net/debian unstable main
> contrib non-free - dget
> http://mentors.debian.net/debian/pool/main/r/roxterm/roxterm_1.18.5-2.dsc
> 
> Please Cc all replies to my sponsor - George Danchev <danchev@spnet.net> -
> and me; if and when it gets approved here he'll upload it to unstable.

Hi,

(sponsor replies;-)

The above information still stands, except that it is actually a request to 
upload to unstable. We are aware that this patch is large enough, but 
unfortunately there is hardly a more trivial fix, and that bug somehow affects 
the usability. We have tested -2 for few days (the latest fix), and found no 
regressions. Would you allow upload to unstable where it eventually resides 
for a week or so and in case of no regressions are found we will come back 
with unblock request to allow it to enter squeeze. If you deem these changes 
way too intrusive, well, at least we tried ;-)

1) roxterm (1.18.5-2) unstable; urgency=low

  * Backported fixes from forthcoming upstream release to fix problems with
    initialising and resizing multiple tabs (Closes: #592984).
  * Standards-Version: 3.9.1.

2) diffstat against 1.18.5-2 which is in squeeze and sid:

  debian/changelog                       |    8 
 debian/changelog.in                    |    8 
 debian/control                         |    2 
 debian/patches/init_tabs               | 1551 +++++++++++
 debian/patches/series                  |    1 
 src/menutree.c                         |    8 
 src/multitab.c                         |  374 +-
 src/multitab.h                         |   41 
 src/profilegui.c                       |    3 
 src/roxterm-config.glade               |    2 
 src/roxterm.c                          |  301 +-
 src/tabdrag.c                          |   61 
 20 files changed, 15405 insertions(+), 432 deletions(-)

3) init_tabs patch attached.

-- 
pub 4096R/0E4BD0AB <people.fccf.net/danchev/key pgp.mit.edu>
--- Begin Message ---
===================================================================
--- roxterm-1.18.5.orig/src/multitab.c	2010-08-15 21:37:35.776571737 +0100
+++ roxterm-1.18.5/src/multitab.c	2010-08-15 21:45:19.424237976 +0100
@@ -81,13 +81,6 @@
     gboolean show_menu_bar;
     Options *shortcuts;
     GtkAccelGroup *accel_group;
-    int child_width, child_height; /* Need to store size of child widget before
-                                      removing or adding a tab so we can
-                                      correct size afterwards */
-    int ignore_size_allocate;       /* 0 = Don't ignore
-                                       1 = Ignore
-                                       2 = Special case after tab label has
-                                           changed */
     MultiTabSelectionHandler tab_selection_handler;
     gboolean menu_bar_set;        /* Menu bar can be configured either from
                                    profile when opening a window, or when user
@@ -108,6 +101,8 @@
     gboolean composite;
 #endif
     char *display_name;
+    int cached_width, cached_height;
+    gulong size_alloc_tag;
 };
 
 static double multi_win_zoom_factors[] = {
@@ -204,8 +199,7 @@
     multi_tab_get_show_close_button = get_show_close_button;
 }
 
-MultiTab *multi_tab_new0(MultiWin * parent, gpointer user_data_template,
-        gboolean make_current)
+MultiTab *multi_tab_new(MultiWin * parent, gpointer user_data_template)
 {
     MultiTab *tab = g_new0(MultiTab, 1);
 
@@ -216,8 +210,7 @@
     g_object_set_data(G_OBJECT(tab->widget), "roxterm_tab", tab);
 
     multi_win_add_tab(parent, tab, -1, FALSE);
-    if (make_current)
-        multi_win_select_tab(parent, tab);
+    multi_win_select_tab(parent, tab);
 
     return tab;
 }
@@ -273,13 +266,11 @@
 {
     MultiWin *win = tab->parent;
 
-    win->ignore_size_allocate = 1;
     win->ignore_tabs_moving = TRUE;
     multi_tab_delete_without_notifying_parent(tab, TRUE);
     if (!multi_win_notify_tab_removed(win, tab))
     {
         win->ignore_tabs_moving = FALSE;
-        win->ignore_size_allocate = 0;
     }
 }
 
@@ -293,6 +284,70 @@
     return tab->parent ? tab->parent->display_name : NULL;
 }
 
+void multi_win_set_geometry_hints(MultiWin *win, GtkWidget *child,
+    GdkGeometry *geometry, GdkWindowHints geom_mask)
+{
+    gtk_window_set_geometry_hints(GTK_WINDOW(win->gtkwin), child,
+        geometry, geom_mask);
+}
+
+static void multi_win_set_geometry_hints_for_tab(MultiWin * win, MultiTab * tab)
+{
+    GdkGeometry geom;
+    GdkWindowHints hints;
+
+    if (multi_win_geometry_func)
+    {
+        (*multi_win_geometry_func) (tab->user_data, &geom, &hints);
+        multi_win_set_geometry_hints(win, tab->active_widget, &geom, hints);
+    }
+}
+
+static void multi_win_size_alloc_handler(GtkWidget *widget,
+        GtkAllocation *alloc, MultiWin *win)
+{
+    int w = win->cached_width;
+    int h = win->cached_height;
+    GtkAllocation c_alloc;
+    
+    g_signal_handler_disconnect(widget, win->size_alloc_tag);
+    win->size_alloc_tag = 0;
+    if (!win->current_tab)
+        return;
+    widget = win->current_tab->active_widget;
+    gtk_widget_get_allocation(widget, &c_alloc);
+    multi_win_size_func(win->current_tab->user_data, TRUE, &w, &h);
+    gtk_window_resize(GTK_WINDOW(win->gtkwin),
+            w + alloc->width - c_alloc.width,
+            h + alloc->height - c_alloc.height);
+    multi_win_set_geometry_hints_for_tab(win, win->current_tab);
+}
+
+static void multi_win_cache_size(MultiWin *win)
+{
+    int px, py, cx, cy;
+    
+    if (win->size_alloc_tag)
+    {
+        return;
+    }
+    if (!win->current_tab || !win->gtkwin ||
+            !gtk_widget_get_visible(win->gtkwin) ||
+            win->fullscreen || multi_win_is_maximised(win))
+    {
+        return;
+    }
+    multi_win_size_func(win->current_tab->user_data, FALSE,
+            &win->cached_width, &win->cached_height);
+    gtk_window_get_size(GTK_WINDOW(win->gtkwin), &px, &py);
+    gdk_drawable_get_size(GDK_DRAWABLE(
+            gtk_widget_get_window(win->current_tab->active_widget)),
+            &cx, &cy);
+    win->size_alloc_tag = g_signal_connect_after(
+            win->gtkwin, "size-allocate",
+            G_CALLBACK(multi_win_size_alloc_handler), win);
+}
+
 static void multi_tab_set_name_or_title(MultiTab *tab, const char *title)
 {
     MultiWin *win = tab->parent;
@@ -300,9 +355,11 @@
     if (tab->label)
     {
         GtkPositionType tab_pos = tab->parent->tab_pos;
-
-        if ((tab_pos == GTK_POS_LEFT || tab_pos == GTK_POS_RIGHT) && win)
-            win->ignore_size_allocate = 2;
+        gboolean cache_size = (tab_pos == GTK_POS_LEFT ||
+                tab_pos == GTK_POS_RIGHT) && win;
+        
+        if (cache_size)
+            multi_win_cache_size(win);
         gtk_label_set_text(GTK_LABEL(tab->label), title);
     }
     if (win)
@@ -534,7 +591,8 @@
     win->ignore_tabs_moving = TRUE;
     if (!notify_only)
     {
-        win->ignore_size_allocate = 1;
+        if (win->ntabs > 1)
+            multi_win_cache_size(win);
         g_object_ref(tab->widget);
         gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook),
                 multi_tab_get_page_num(tab));
@@ -543,7 +601,6 @@
     multi_tab_remove_menutree_items(win, tab);
     if (!multi_win_notify_tab_removed(win, tab))
     {
-        win->ignore_size_allocate = 0;
         win->ignore_tabs_moving = FALSE;
     }
     tab->parent = NULL;
@@ -552,12 +609,28 @@
 #if DO_OWN_TAB_DRAGGING
 void multi_tab_move_to_new_window(MultiWin *win, MultiTab *tab, int position)
 {
+    MultiWin *old_win = tab->parent;
+    gboolean old_win_destroyed;
+    
+    multi_win_set_always_show_tabs(win, old_win->always_show_tabs);
+    multi_win_set_show_menu_bar(win, old_win->show_menu_bar);
+    if (multi_win_is_fullscreen(old_win))
+        multi_win_set_fullscreen(win, TRUE);
+    else if (multi_win_is_maximised(old_win))
+        gtk_window_maximize(GTK_WINDOW(win->gtkwin));
+    if (!win->tabs)
+    {
+        win->default_title_template = old_win->default_title_template ?
+                g_strdup(old_win->default_title_template) : NULL;
+        win->title_template = old_win->default_title_template ?
+                g_strdup(old_win->default_title_template) : NULL;
+    }
+    old_win_destroyed = old_win->ntabs <= 1;
     multi_tab_remove_from_parent(tab, FALSE);
     multi_win_add_tab(win, tab, position, FALSE);
-    /* Really we want this before multi_win_add_tab but it seems to crash
-     * vte_terminal_set_font; maybe it can't cope with unmapped widgets? */
+    multi_win_set_geometry_hints_for_tab(win, tab);
     if (multi_tab_to_new_window_handler)
-        multi_tab_to_new_window_handler(win, tab);
+        multi_tab_to_new_window_handler(win, tab, old_win_destroyed);
     /* Remove extra references added by multi_tab_remove_from_parent */
     g_object_unref(tab->widget);
 }
@@ -597,93 +670,6 @@
     }
 }
 
-void multi_win_set_geometry_hints(MultiWin *win, GtkWidget *child,
-    GdkGeometry *geometry, GdkWindowHints geom_mask)
-{
-    gtk_window_set_geometry_hints(GTK_WINDOW(win->gtkwin), child,
-        geometry, geom_mask);
-}
-
-/*
-static void difference_between_child_and_parent(GtkWidget *child,
-    GtkWidget *parent, int *pwidth, int *pheight)
-{
-    GtkRequisition parent_req, child_req;
-
-    gtk_widget_size_request(parent, &parent_req);
-    gtk_widget_size_request(child, &child_req);
-    if (pwidth)
-        *pwidth = parent_req.width - child_req.width;
-    if (pheight)
-        *pheight = parent_req.height - child_req.height;
-}
-*/
-
-static void difference_between_child_and_parent(GtkWidget *child,
-    GtkWidget *parent, int *pwidth, int *pheight)
-{
-    GtkRequisition child_req;
-    GtkRequisition parent_req;
-
-    gtk_widget_size_request(child, &child_req);
-    gtk_widget_size_request(parent, &parent_req);
-    if (pwidth)
-        *pwidth = parent_req.width - child_req.width;
-    if (pheight)
-        *pheight = parent_req.height - child_req.height;
-}
-
-/*
-static void show_size_request(const char *desc, GtkWidget *widget)
-{
-    GtkRequisition req;
-
-    gtk_widget_size_request(widget, &req);
-    g_debug("%s has size %d x %d allocation %d x %d", desc,
-            req.width, req.height,
-            widget->allocation.width, widget->allocation.height);
-}
-*/
-
-void
-multi_win_set_size(MultiWin * win, GtkWidget * child, int width, int height)
-{
-    int dw, dh;
-
-    g_return_if_fail(width > 0 && height > 0);
-    win->child_width = width;
-    win->child_height = height;
-    if (!GTK_WIDGET_MAPPED(win->gtkwin))
-    {
-        /* If window isn't shown yet, force VTE widget to correct size before
-         * showing, and that will automatically force window to correct size */
-        gtk_widget_set_size_request(child, width, height);
-        return;
-    }
-    win->ignore_size_allocate = 1;
-    /* If window is already showing it's more complicated.
-     * gtk_widget_set_size_request() on child doesn't perform corresponding
-     * resize on parent window, so we need to resize window instead. It may
-     * need to be bigger than child because of scrollbars and tabs etc, so
-     * we have to find difference in size between window and child. */
-    gtk_widget_set_size_request(child, 10000, 10000);
-    difference_between_child_and_parent(child, win->gtkwin, &dw, &dh);
-    gtk_window_resize(GTK_WINDOW(win->gtkwin), width + dw, height + dh);
-    win->ignore_size_allocate = 0;
-}
-
-static void multi_win_set_geometry_hints_for_tab(MultiWin * win, MultiTab * tab)
-{
-    GdkGeometry geom;
-    GdkWindowHints hints;
-
-    if (multi_win_geometry_func)
-    {
-        (*multi_win_geometry_func) (tab->user_data, &geom, &hints);
-        multi_win_set_geometry_hints(win, tab->active_widget, &geom, hints);
-    }
-}
-
 static char *make_title(MultiWin *win, const char *title)
 {
     char *title0 = NULL;
@@ -737,7 +723,9 @@
      * consistent; doing this will cause extra tab change related events to be
      * generated so we have to ignore them for the duration */
     if (win->ignore_tab_selections || tab == win->current_tab)
+    {
         return;
+    }
     win->ignore_tab_selections = TRUE;
     win->ignore_toggles = TRUE;
     win->current_tab = tab;
@@ -756,7 +744,7 @@
         if (GTK_WIDGET_REALIZED(tab->active_widget) &&
             win->tab_selection_handler)
         {
-            (*win->tab_selection_handler)(tab->user_data, tab);
+            win->tab_selection_handler(tab->user_data, tab);
         }
     }
     multi_win_shade_for_next_and_previous_tab(win);
@@ -792,12 +780,12 @@
     win->show_menu_bar = FALSE;
 }
 
-void multi_win_set_show_menu_bar(MultiWin * win, gboolean show, gboolean resize)
+void multi_win_set_show_menu_bar(MultiWin * win, gboolean show)
 {
-    if (!resize && win->menu_bar_set)
+    if (win->menu_bar_set == show)
         return;
-    win->menu_bar_set = TRUE;
-    win->ignore_size_allocate = 1;
+    multi_win_cache_size(win);
+    win->menu_bar_set = show;
     if (show)
         add_menu_bar(win);
     else
@@ -805,12 +793,6 @@
     menutree_set_show_menu_bar_active(win->menu_bar, show);
     menutree_set_show_menu_bar_active(win->popup_menu, show);
     menutree_set_show_menu_bar_active(win->short_popup, show);
-    if (resize && win->current_tab)
-    {
-        multi_win_set_size(win, win->current_tab->active_widget,
-            win->child_width, win->child_height);
-    }
-    win->ignore_size_allocate = 0;
 }
 
 gboolean multi_win_get_show_menu_bar(MultiWin * win)
@@ -845,40 +827,6 @@
     return FALSE;
 }
 
-static void
-multi_win_size_allocate(GtkWidget * widget, GtkAllocation * allocation,
-    MultiWin * win)
-{
-    GList *link;
-    MultiTab *tab;
-
-    switch (win->ignore_size_allocate)
-    {
-        case 0:
-            for (link = win->tabs; link; link = g_list_next(link))
-            {
-                tab = (MultiTab *) link->data;
-                (*multi_win_size_func) (tab->user_data,
-                    MultiWin_UpdateConfiguredSize,
-                    &win->child_width, &win->child_height);
-            }
-            break;
-        case 1:
-            break;
-        case 2:
-            tab = win->current_tab;
-            if (!tab)
-                win->ignore_size_allocate = 0;
-            g_return_if_fail(tab != NULL);
-            (*multi_win_size_func) (tab->user_data,
-                MultiWin_GetTargetSize,
-                &win->child_width, &win->child_height);
-            multi_win_set_size(win, tab->active_widget,
-                win->child_width, win->child_height);
-            break;
-    }
-}
-
 static void multi_win_realize_handler(GtkWidget *win, gpointer data)
 {
     GdkWindow *w = win->window;
@@ -982,6 +930,7 @@
     g_return_if_fail(tab);
     if (!win->ignore_tabs_moving)
     {
+        multi_win_cache_size(win);
         /* If tab->parent == win, it's already been added by
          * multi_win_notebook_creation_hook so don't add,
          * but set size and show */
@@ -992,11 +941,6 @@
         else
         {
             gtk_widget_show_all(win->notebook);
-            (*multi_win_size_func) (tab->user_data,
-                MultiWin_GetTargetSize,
-                &win->child_width, &win->child_height);
-            multi_win_set_size(win, tab->active_widget,
-                win->child_width, win->child_height);
             gtk_widget_show_all(win->gtkwin);
         }
     }
@@ -1016,14 +960,6 @@
         {
             multi_tab_remove_from_parent(tab, TRUE);
         }
-        else if (win->ntabs == 1)
-        {
-            /* If we use multi_win_set_size here, for some reason it honours
-             * the silly large size request instead of the gtk_window_resize */
-            tab = (MultiTab *) win->tabs->data;
-            multi_win_set_size(win, tab->active_widget,
-                    win->child_width, win->child_height);
-        }
     }
 }
 
@@ -1038,10 +974,6 @@
 
     g_return_val_if_fail(tab, NULL);
     win = tab->parent;
-    /* Remember widget's size for later */
-    (*multi_win_size_func) (tab->user_data,
-        MultiWin_GetTargetSize,
-        &win->child_width, &win->child_height);
     multi_tab_remove_from_parent(tab, TRUE);
     multi_win_get_disable_menu_shortcuts(tab->user_data,
             &disable_menu_shortcuts, &disable_tab_shortcuts);
@@ -1076,11 +1008,25 @@
 
     multi_win_initial_tabs(user_data_template, &tab_pos, &num_tabs);
     if (old->fullscreen)
+    {
         creator = multi_win_new_fullscreen;
+    }
     else if (multi_win_is_maximised(old))
+    {
         creator = multi_win_new_maximised;
+    }
     else
-        creator = multi_win_new;
+    {
+        char geom[16];
+        int width, height;
+        
+        multi_win_size_func(multi_tab_get_user_data(old->current_tab),
+                FALSE, &width, &height);
+        sprintf(geom, "%dx%d", width, height);
+        return multi_win_new_with_geom(old->display_name, old->shortcuts,
+                old->zoom_index, user_data_template, geom,
+                num_tabs, tab_pos, always_show_tabs);
+    }
     return creator(old->display_name, old->shortcuts, old->zoom_index,
             user_data_template, num_tabs, tab_pos, always_show_tabs);
 }
@@ -1249,7 +1195,7 @@
     gboolean show = gtk_check_menu_item_get_active(item);
 
     if (show != win->show_menu_bar)
-        multi_win_set_show_menu_bar(win, show, TRUE);
+        multi_win_set_show_menu_bar(win, show);
 }
 
 static void
@@ -1531,8 +1477,6 @@
 
     multi_win_connect_actions(win);
     (*multi_win_menu_signal_connector) (win);
-    g_signal_connect_after(win->gtkwin, "size-allocate",
-        G_CALLBACK(multi_win_size_allocate), win);
     g_signal_connect(win->gtkwin, "window-state-event",
         G_CALLBACK(multi_win_state_event_handler), win);
 
@@ -1592,6 +1536,8 @@
 {
     gboolean disable_menu_shortcuts, disable_tab_shortcuts; 
     MultiWin *win;
+    MultiTab *tab;
+    int n;
     
     multi_win_get_disable_menu_shortcuts(user_data_template,
             &disable_menu_shortcuts, &disable_tab_shortcuts);
@@ -1600,10 +1546,9 @@
             tab_pos, always_show_tabs);
     win->user_data_template = user_data_template;
     win->tab_pos = tab_pos;
-    while (numtabs--)
+    for (n = 0; n < numtabs; ++n)
         multi_tab_new(win, user_data_template);
 
-    gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0);
     if (tab_pos == -1)
     {
         gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
@@ -1632,12 +1577,12 @@
     multi_win_show(win);
 
     /* Need to do this after multi_tab_new's initial call of
-     * multi_win_select_tab to ensure child widget is realized */
-    if (win->current_tab && win->tab_selection_handler)
-    {
-        (*win->tab_selection_handler) (win->current_tab->user_data,
-            win->current_tab);
-    }
+     * multi_win_select_tab to ensure child widgets are realized
+     * and tab selection handler is activated */
+    for (n = numtabs - 1; n >= 0; --n)
+        gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), n);
+    tab = win->tabs->data;
+    win->tab_selection_handler(tab->user_data, tab);
 
     return win;
 }
@@ -1658,7 +1603,9 @@
         win->accel_group = NULL;
     }
     if (destroy_widgets && win->gtkwin)
+    {
         g_signal_handler_disconnect(win->gtkwin, win->destroy_handler);
+    }
 
     for (link = win->tabs; link; link = g_list_next(link))
     {
@@ -1724,11 +1671,14 @@
     }
     else
     {
+        multi_win_cache_size(win);
         if (win->ntabs == 1)
         {
             tab = win->tabs->data;
             if (!win->always_show_tabs)
+            {
                 multi_win_hide_tabs(win);
+            }
             if (win->tab_pos != GTK_POS_LEFT && win->tab_pos != GTK_POS_RIGHT)
             {
                 gtk_label_set_ellipsize(GTK_LABEL(tab->label),
@@ -1736,12 +1686,6 @@
             }
             single_tab(win, tab);
         }
-        if (win->current_tab)
-        {
-            multi_win_set_geometry_hints_for_tab(win, win->current_tab);
-            multi_win_set_size(win, win->current_tab->active_widget,
-                win->child_width, win->child_height);
-        }
     }
     multi_win_shade_menus_for_tabs(win);
     return FALSE;
@@ -1760,9 +1704,7 @@
     win = tab->parent;
     if (win)
     {
-        win->ignore_size_allocate =
-                (win->tab_pos == GTK_POS_LEFT || win->tab_pos == GTK_POS_RIGHT)
-                ? 2 : 1;
+        multi_win_cache_size(win);
     }
     tab->close_button = gtk_button_new();
     tab->image = gtk_image_new_from_stock(
@@ -1785,16 +1727,6 @@
     gtk_widget_show_all(tab->close_button);
     if (win)
     {
-        if (win->current_tab)
-        {
-            multi_win_set_size(win, win->current_tab->active_widget,
-                win->child_width, win->child_height);
-        }
-        else
-        {
-            if (win->ignore_size_allocate == 1)
-                win->ignore_size_allocate = 0;
-        }
     }
 }
 
@@ -1807,26 +1739,10 @@
         win = tab->parent;
         if (win)
         {
-            win->ignore_size_allocate =
-                    (win->tab_pos == GTK_POS_LEFT ||
-                            win->tab_pos == GTK_POS_RIGHT)
-                    ? 2 : 1;
+            multi_win_cache_size(win);
         }
         gtk_widget_destroy(tab->close_button);
         tab->close_button = NULL;
-        if (win)
-        {
-            if (win->current_tab)
-            {
-                multi_win_set_size(win, win->current_tab->active_widget,
-                    win->child_width, win->child_height);
-            }
-            else
-            {
-                if (win->ignore_size_allocate == 1)
-                    win->ignore_size_allocate = 0;
-            }
-        }
     }
     tab->image = NULL;
 }
@@ -1964,7 +1880,7 @@
         gboolean notify_only)
 {
     tab->parent = win;
-    win->ignore_size_allocate = 1;
+    multi_win_cache_size(win);
     win->ignore_tabs_moving = TRUE;
     if (position == -1)
         win->tabs = g_list_append(win->tabs, tab);
@@ -1982,15 +1898,6 @@
         gtk_widget_show(tab->widget);
     }
     multi_win_shade_menus_for_tabs(win);
-    multi_win_set_geometry_hints_for_tab(win, tab);
-    if (!win->child_width || !win->child_height)
-    {
-        (*multi_win_size_func) (tab->user_data,
-            MultiWin_GetTargetSize,
-            &win->child_width, &win->child_height);
-    }
-    multi_win_set_size(win, tab->active_widget,
-        win->child_width, win->child_height);
     win->ignore_tabs_moving = FALSE;
 }
 
@@ -2006,8 +1913,9 @@
 
 gboolean multi_win_is_maximised(MultiWin *win)
 {
-    return (gdk_window_get_state(win->gtkwin->window) &
-            GDK_WINDOW_STATE_MAXIMIZED) != 0;
+    return (win->gtkwin->window &&
+            (gdk_window_get_state(win->gtkwin->window) &
+                GDK_WINDOW_STATE_MAXIMIZED) != 0);
 }
 
 int multi_win_get_zoom_index(MultiWin *win)
@@ -2195,15 +2103,13 @@
     if (win->ntabs == 1 && old_show != show)
     {
         MultiTab *tab = win->current_tab;
-        int w, h;
         
         g_return_if_fail(tab != NULL);
-        (*multi_win_size_func)(tab->user_data, MultiWin_GetTargetSize, &w, &h);
+        multi_win_cache_size(win);
         if (show)
             multi_win_show_tabs(win);
         else
             multi_win_hide_tabs(win);
-        multi_win_set_size(win, tab->active_widget, w, h);
     }
 }
 
@@ -2281,7 +2187,7 @@
         g_free(win->title_template);
         win->title_template = tt ? g_strdup(tt) : NULL;
     	multi_win_set_title(win, win->child_title);
-	multi_win_set_icon_title(win, win->child_icon);
+        multi_win_set_icon_title(win, win->child_icon);
     }
 }
 
Index: roxterm-1.18.5/src/multitab.h
===================================================================
--- roxterm-1.18.5.orig/src/multitab.h	2010-08-15 21:37:35.696580829 +0100
+++ roxterm-1.18.5/src/multitab.h	2010-08-15 21:45:19.428239732 +0100
@@ -56,25 +56,22 @@
 typedef void (*MultiWinGeometryFunc) (gpointer user_data, GdkGeometry * geom,
     GdkWindowHints * hints);
 
-/* Size function. pwidth and pheight point to return values for width and
- * height in pixels of the core of the widget ie minus any borders */
-typedef enum {
-    MultiWin_GetActualSize,        /* Return the current actual size of the
-                                   widget's core */
-    MultiWin_GetTargetSize,        /* Return the size it should be from
-                                   config settings or whatever */
-    MultiWin_UpdateConfiguredSize    /* User has resized window; update config
-                                       from current size */
-} MultiWinSizeReason;
-typedef void (*MultiWinSizeFunc) (gpointer user_data, MultiWinSizeReason,
-        int *pwidth, int *pheight);
+/* If set is TRUE, the child widget may use the width and height values
+ * to resize itself and must update width and height to desired size in pixels,
+ * otherwise it must update width and height with its current size
+ */
+typedef gboolean (*MultiWinSizeFunc) (gpointer user_data, gboolean set,
+    int *pwidth, int *pheight);
 
 /* Called when a tab is selected */
 typedef void (*MultiTabSelectionHandler) (gpointer user_data, MultiTab * tab);
 
 /* Called when a tab is dragged to a new window; should be used to try to make
- * sure page is same size as other tabs in new window */
-typedef void (*MultiTabToNewWindowHandler)(MultiWin *win, MultiTab *tab);
+ * sure page is same size as other tabs in new window and to update references.
+ * old_win_destroyed is TRUE if the tab's previous window was destroyed.
+ */
+typedef void (*MultiTabToNewWindowHandler)(MultiWin *win, MultiTab *tab,
+        gboolean old_win_destroyed);
 
 /* Called when the zoom factor is changed */
 typedef void (*MultiWinZoomHandler)(gpointer user_data, double zoom_factor,
@@ -113,14 +110,7 @@
 void
 multi_tab_connect_tab_selection_handler(MultiWin *, MultiTabSelectionHandler);
 
-MultiTab *multi_tab_new0(MultiWin * parent, gpointer user_data_template,
-        gboolean make_current);
-
-inline static MultiTab *multi_tab_new(MultiWin *parent,
-        gpointer user_data_template)
-{
-    return multi_tab_new0(parent, user_data_template, TRUE);
-}
+MultiTab *multi_tab_new(MultiWin * parent, gpointer user_data_template);
 
 /* When all tabs are destroyed the window is destroyed too */
 void multi_tab_delete(MultiTab *);
@@ -274,10 +264,6 @@
 multi_win_set_geometry_hints(MultiWin * win, GtkWidget * child,
     GdkGeometry * geometry, GdkWindowHints geom_mask);
 
-/* Set window size to fit child at given size */
-void
-multi_win_set_size(MultiWin * win, GtkWidget * child, int width, int height);
-
 void multi_win_set_fullscreen(MultiWin *win, gboolean fullscreen);
 
 GtkWidget *multi_win_get_widget(MultiWin * win);
@@ -336,9 +322,8 @@
 
 GtkAccelGroup *multi_win_get_accel_group(MultiWin * win);
 
-/* If resize is TRUE, force window resize to accommodate change in height */
 void
-multi_win_set_show_menu_bar(MultiWin * win, gboolean show, gboolean resize);
+multi_win_set_show_menu_bar(MultiWin * win, gboolean show);
 
 gboolean multi_win_get_show_menu_bar(MultiWin * win);
 
Index: roxterm-1.18.5/src/profilegui.c
===================================================================
--- roxterm-1.18.5.orig/src/profilegui.c	2010-08-15 21:37:35.736581376 +0100
+++ roxterm-1.18.5/src/profilegui.c	2010-08-15 21:45:19.428239732 +0100
@@ -648,6 +648,8 @@
     capplet_set_text_entry(glade, profile, "color_term", "roxterm");
     capplet_set_text_entry(glade, profile, "term", "xterm");
     /*capplet_set_text_entry(glade, profile, "emulation", NULL);*/
+    capplet_set_combo(glade, profile, "tab_pos", 0);
+    capplet_set_spin_button(glade, profile, "init_tabs", 1);
     capplet_set_boolean_toggle(glade, profile, "wrap_switch_tab", FALSE);
     capplet_set_boolean_toggle(glade, profile, "tab_close_btn", TRUE);
     capplet_set_boolean_toggle(glade, profile, "show_tab_status", FALSE);
@@ -696,7 +698,6 @@
     capplet_set_boolean_toggle(glade, profile, "use_custom_command", FALSE);
     capplet_set_text_entry(glade, profile, "command", NULL);
     capplet_set_combo(glade, profile, "exit_action", 0);
-    capplet_set_combo(glade, profile, "tab_pos", 0);
     capplet_set_spin_button_float(glade, profile, "exit_pause");
     capplet_set_text_entry(glade, profile, "title_string", "%s");
     exit_action_changed(GTK_COMBO_BOX(profilegui_widget(pg, "exit_action")),
Index: roxterm-1.18.5/src/roxterm.c
===================================================================
--- roxterm-1.18.5.orig/src/roxterm.c	2010-08-15 21:37:35.752572964 +0100
+++ roxterm-1.18.5/src/roxterm.c	2010-08-15 21:46:21.668234542 +0100
@@ -65,8 +65,6 @@
     GtkWidget *widget;            /* VteTerminal */
     GtkWidget *hbox;
     GtkWidget *scrollbar;
-    int geom_width, geom_height;
-    int nonfs_width, nonfs_height;
     pid_t pid;
     /* We own a reference to colour_scheme */
     Options *colour_scheme;
@@ -110,6 +108,7 @@
     gboolean setup_encodings;
     gboolean dont_lookup_dimensions;
     char *reply;
+    int columns, rows;
 };
 
 #define PROFILE_NAME_KEY "roxterm_profile_name"
@@ -278,15 +277,6 @@
     return roxterm_profiles;
 }
 
-static void roxterm_save_nonfs_dimensions(ROXTermData *roxterm)
-{
-    if (!roxterm->win || !multi_win_is_fullscreen(roxterm->win))
-    {
-        roxterm->nonfs_width = roxterm->geom_width;
-        roxterm->nonfs_height = roxterm->geom_height;
-    }
-}
-
 /* Foreground (and palette?) colour change doesn't cause a redraw so force it */
 inline static void roxterm_force_redraw(ROXTermData *roxterm)
 {
@@ -294,20 +284,6 @@
         gtk_widget_queue_draw(roxterm->widget);
 }
 
-static void roxterm_set_geometry(ROXTermData *roxterm, int width, int height)
-{
-    roxterm->geom_width = width;
-    roxterm->geom_height = height;
-    roxterm_save_nonfs_dimensions(roxterm);
-}
-
-static void roxterm_default_dimensions(ROXTermData *roxterm)
-{
-    roxterm_set_geometry(roxterm,
-            options_lookup_int_with_default(roxterm->profile, "width", 80),
-            options_lookup_int_with_default(roxterm->profile, "height", 24));
-}
-
 char *roxterm_get_cwd(ROXTermData *roxterm)
 {
     char *pidfile = NULL;
@@ -363,24 +339,6 @@
         new_gt->profile = dynamic_options_lookup_and_ref(roxterm_profiles,
             options_get_leafname(old_gt->profile), "roxterm profile");
     }
-    if (old_gt->widget)
-    {
-        if (!multi_win_is_fullscreen(old_gt->win))
-        {
-            roxterm_set_geometry(new_gt,
-                    (VTE_TERMINAL(old_gt->widget))->column_count,
-                    (VTE_TERMINAL(old_gt->widget))->row_count);
-        }
-        else
-        {
-            roxterm_set_geometry(new_gt,
-                    old_gt->nonfs_width, old_gt->nonfs_height);
-        }
-    }
-    else if (!old_gt->maximise && !old_gt->dont_lookup_dimensions)
-    {
-        roxterm_default_dimensions(new_gt);
-    }
     /* special_command should be transferred to new data and removed from old
      * one */
     old_gt->special_command = NULL;
@@ -414,6 +372,13 @@
     {
         new_gt->pango_desc = pango_font_description_copy(old_gt->pango_desc);
     }
+    if (old_gt->widget && GTK_WIDGET_REALIZED(old_gt->widget))
+    {
+        VteTerminal *vte = VTE_TERMINAL(old_gt->widget);
+        
+        new_gt->columns = vte->column_count;
+        new_gt->rows = vte->row_count;
+    }
 
     return new_gt;
 }
@@ -794,7 +759,9 @@
     
     gwin = roxterm_get_toplevel(roxterm);
     if (gwin)
+    {
         g_signal_handler_disconnect(gwin, roxterm->win_state_changed_tag);
+    }
     if (roxterm->post_exit_tag)
         g_source_remove(roxterm->post_exit_tag);
     if (roxterm->colour_scheme)
@@ -994,15 +961,59 @@
     GtkBorder *border = NULL;
     
     gtk_widget_style_get(GTK_WIDGET(vte), "inner-border", &border, NULL);
-    g_return_if_fail(border != NULL);
-    *w = border->left + border->right;
-    *h = border->top + border->bottom;
-    gtk_border_free(border);
+    if (border == NULL)
+    {
+        g_warning(_("VTE's inner-border property unavailable"));
+        *w = *h = 0;
+    }
+    else
+    {
+        *w = border->left + border->right;
+        *h = border->top + border->bottom;
+        gtk_border_free(border);
+    }
 }
 #else
 #define roxterm_get_vte_padding vte_terminal_get_padding
 #endif
 
+static void
+roxterm_set_vte_size(ROXTermData *roxterm, VteTerminal *vte,
+        int columns, int rows)
+{
+    /* First get current size of vte and parent window so we know difference */
+    int cw, ch, ww, wh;
+    GtkWidget *vw = GTK_WIDGET(vte);
+    GdkWindow *drbl = gtk_widget_get_window(vw);
+    GtkWidget *pw = roxterm->win ? multi_win_get_widget(roxterm->win) : NULL;
+    GdkWindow *pd = pw ? gtk_widget_get_window(pw) : NULL;
+    
+    if (drbl && pd)
+    {
+        gdk_drawable_get_size(GDK_DRAWABLE(drbl), &cw, &ch);
+        gtk_window_get_size(GTK_WINDOW(pw), &ww, &wh);
+    }
+    vte_terminal_set_size(vte, columns, rows);
+    /* If we're in a realized window, resize it as required, otherwise the
+     * vte's size request won't be honoured.
+     */
+    if (drbl && pd)
+    {
+        int px, py;
+        int req_w, req_h;
+        
+        roxterm_get_vte_padding(vte, &px, &py);
+        req_w = vte->char_width * columns + px;
+        req_h = vte->char_height * rows + py;
+        /*
+        g_debug("Child was %dx%d, window bigger by %dx%d; "
+                "resizing for child calc %dx%d",
+                cw, ch, ww - cw, wh - ch, req_w, req_h);
+        */
+        gtk_window_resize(GTK_WINDOW(pw), req_w + ww - cw, req_h + wh - ch);
+    }
+}
+
 static void roxterm_geometry_func(ROXTermData *roxterm,
         GdkGeometry *geom, GdkWindowHints *hints)
 {
@@ -1016,55 +1027,41 @@
     *hints = GDK_HINT_RESIZE_INC | GDK_HINT_BASE_SIZE | GDK_HINT_MIN_SIZE;
 }
 
-static void
-roxterm_cell_to_pixel_size(ROXTermData * roxterm, int *pwidth, int *pheight)
-{
-    int xpad, ypad;
-    VteTerminal *vte = VTE_TERMINAL(roxterm->widget);
-
-    roxterm_get_vte_padding(vte, &xpad, &ypad);
-    *pwidth = *pwidth * vte->char_width + xpad;
-    *pheight = *pheight * vte->char_height + ypad;
-}
-
-static void roxterm_size_func(ROXTermData *roxterm, MultiWinSizeReason reason,
+static void roxterm_size_func(ROXTermData *roxterm, gboolean set,
         int *pwidth, int *pheight)
 {
-    VteTerminal *vte = VTE_TERMINAL(roxterm->widget);
+    /* column_/row_count may contain garbage if the widget isn't showing,
+     * so read values from current tab's vte */
+    MultiTab *ctab = multi_win_get_current_tab(roxterm->win);
+    ROXTermData *crt = ctab ? multi_tab_get_user_data(ctab) : roxterm;
+    VteTerminal *vte = VTE_TERMINAL(crt->widget);
 
-    if (reason == MultiWin_UpdateConfiguredSize)
+    if (set)
     {
-        roxterm_set_geometry(roxterm,
-                *pwidth = vte->column_count, *pheight = vte->row_count);
+        if (crt == roxterm)
+        {
+            int px, py;
+            
+            vte_terminal_set_size(vte, *pwidth, *pheight);
+            roxterm_get_vte_padding(vte, &px, &py);
+            *pwidth = *pwidth * vte->char_width + px;
+            *pheight = *pheight * vte->char_height + py;
+        }
     }
-    else if (reason == MultiWin_GetActualSize)
+    else
     {
         *pwidth = vte->column_count;
         *pheight = vte->row_count;
     }
-    else /* if (reason == MultiWin_GetTargetSize) */
-    {
-        *pwidth = roxterm->nonfs_width;
-        *pheight = roxterm->nonfs_height;
-    }
-    roxterm_cell_to_pixel_size(roxterm, pwidth, pheight);
 }
 
 static void roxterm_update_size(ROXTermData * roxterm, VteTerminal * vte)
 {
     if (multi_win_get_current_tab(roxterm->win) == roxterm->tab)
     {
-        int width;
-        int height;
-
-        roxterm_set_geometry(roxterm,
+        roxterm_set_vte_size(roxterm, vte,
             options_lookup_int_with_default(roxterm->profile, "width", 80),
             options_lookup_int_with_default(roxterm->profile, "height", 24));
-        vte_terminal_set_size(vte, roxterm->geom_width, roxterm->geom_height);
-        width = roxterm->geom_width;
-        height = roxterm->geom_height;
-        roxterm_cell_to_pixel_size(roxterm, &width, &height);
-        multi_win_set_size(roxterm->win, roxterm->widget, width, height);
     }
 }
 
@@ -1074,19 +1071,10 @@
     {
         GdkGeometry geom;
         GdkWindowHints hints;
-        int width = roxterm->geom_width;
-        int height = roxterm->geom_height;
-
-        /*
-           int width = vte->column_count;
-           int height = vte->row_count;
-         */
 
         roxterm_geometry_func(roxterm, &geom, &hints);
         multi_win_set_geometry_hints(roxterm->win, roxterm->widget,
             &geom, hints);
-        roxterm_cell_to_pixel_size(roxterm, &width, &height);
-        multi_win_set_size(roxterm->win, roxterm->widget, width, height);
     }
 }
 
@@ -1116,6 +1104,8 @@
 {
     char *fdesc;
     PangoFontDescription *pango_desc = NULL;
+    int w = vte->column_count;
+    int h = vte->row_count;
 
     if (roxterm->pango_desc)
     {
@@ -1163,7 +1153,10 @@
     g_free(fdesc);
     roxterm->current_zoom_factor = roxterm->target_zoom_factor;
     if (update_geometry)
+    {
+        roxterm_set_vte_size(roxterm, vte, w, h);
         roxterm_update_geometry(roxterm, vte);
+    }
 }
 
 static void
@@ -1172,12 +1165,15 @@
 {
     PangoFontDescription *pango_desc = NULL;
     double zf;
+    int w, h;
 
     if (!roxterm->pango_desc)
     {
         roxterm_apply_profile_font(roxterm, vte, update_geometry);
         return;
     }
+    w = vte->column_count;
+    h = vte->row_count;
     zf = roxterm->target_zoom_factor /
             (roxterm->current_zoom_factor ?
                     roxterm->current_zoom_factor : 1);
@@ -1186,7 +1182,10 @@
     vte_terminal_set_font(vte, pango_desc);
     roxterm->current_zoom_factor = roxterm->target_zoom_factor;
     if (update_geometry)
+    {
+        roxterm_set_vte_size(roxterm, vte, w, h);
         roxterm_update_geometry(roxterm, vte);
+    }
 }
 
 static void roxterm_set_zoom_factor(ROXTermData *roxterm, double factor,
@@ -1201,26 +1200,31 @@
 static void roxterm_match_text_size(ROXTermData *roxterm, ROXTermData *other)
 {
     VteTerminal *vte;
+    VteTerminal *other_vte;
     const PangoFontDescription *fd;
+    int width, height;
     
     if (roxterm == other)
         return;
     vte = VTE_TERMINAL(roxterm->widget);
+    other_vte = VTE_TERMINAL(other->widget);
+    width = other_vte->column_count;
+    height = other_vte->row_count;
     fd = vte_terminal_get_font(VTE_TERMINAL(other->widget));
     roxterm->target_zoom_factor = other->current_zoom_factor;
     roxterm->current_zoom_factor = other->current_zoom_factor;
     roxterm->zoom_index = other->zoom_index;
     if (!pango_font_description_equal(
             vte_terminal_get_font(VTE_TERMINAL(roxterm->widget)), fd))
+    {
         vte_terminal_set_font(vte, fd);
-    if (roxterm->geom_width != other->geom_width
-            || roxterm->geom_height != other->geom_height)
+    }
+    if (vte->column_count != width || vte->row_count != height)
     {
-        roxterm_set_geometry(roxterm,
-                other->geom_width, other->geom_height);
-        vte_terminal_set_size(VTE_TERMINAL(roxterm->widget),
-                roxterm->geom_width, roxterm->geom_height);
+        roxterm_set_vte_size(roxterm, VTE_TERMINAL(roxterm->widget),
+                width, height);
     }
+    roxterm_update_geometry(roxterm, vte);
 }
 
 static void roxterm_about_www_hook(GtkAboutDialog *about,
@@ -1432,7 +1436,7 @@
         ROXTermData * roxterm)
 {
     multi_tab_set_window_title(roxterm->tab,
-        vte->window_title ? vte->window_title : "roxterm");
+        vte->window_title ? vte->window_title : _("ROXTerm"));
 }
 
 static void roxterm_icon_title_handler(VteTerminal *vte,
@@ -1441,12 +1445,6 @@
     multi_tab_set_icon_title(roxterm->tab, vte->icon_title);
 }
 
-inline static void
-roxterm_update_geom_record(ROXTermData * roxterm, VteTerminal * vte)
-{
-    roxterm_set_geometry(roxterm, vte->column_count, vte->row_count);
-}
-
 /* data is cast to char const **pname - indirect pointer to name to check for -
  * if a match is found, *pname is set to NULL */
 static void check_if_name_matches_property(GtkWidget *widget, gpointer data)
@@ -1582,8 +1580,6 @@
     menutree_select_encoding(menu_bar, roxterm->encoding);
     menutree_select_encoding(short_popup, roxterm->encoding);
     multi_win_set_ignore_toggles(roxterm->win, FALSE);
-
-    roxterm_update_geom_record(roxterm, vte);
 }
 
 static void roxterm_widget_realized(VteTerminal *vte, ROXTermData *roxterm)
@@ -2643,6 +2639,15 @@
     return FALSE;
 }
 
+inline static void
+roxterm_attach_state_changed_handler(ROXTermData *roxterm)
+{
+    roxterm->win_state_changed_tag = 
+            g_signal_connect(roxterm_get_toplevel(roxterm),
+            "window-state-event",
+            G_CALLBACK(roxterm_window_state_changed), roxterm);
+}
+
 static GtkWidget *roxterm_multi_tab_filler(MultiWin * win, MultiTab * tab,
     ROXTermData * roxterm_template, ROXTermData ** roxterm_out,
     char **title, GtkWidget ** vte_widget, GtkAdjustment **adjustment)
@@ -2653,7 +2658,6 @@
     int hide_menu_bar;
     MultiWinScrollBar_Position scrollbar_pos;
     char *tab_name;
-    /* GtkWidget *gwin; */
 
     if ((!roxterm_template->win || roxterm_template->win == win)
         && roxterm_template->title_template)
@@ -2675,7 +2679,7 @@
                 "hide_menubar") == 1;
         }
     }
-    multi_win_set_show_menu_bar(win, !hide_menu_bar, FALSE);
+    multi_win_set_show_menu_bar(win, !hide_menu_bar);
 
     roxterm->win = win;
     roxterm->tab = tab;
@@ -2727,16 +2731,7 @@
         g_free(tab_name);
     }
 
-    /* Used to call vte_terminal_set_size() here, but doing so before parent
-     * window is shown seems to mess up scrollbar in libvte9, and everything
-     * works OK without */
-    /*
-    gwin = multi_win_get_widget(win);
-    if (win && gwin->window)
-    {
-        vte_terminal_set_size(vte, roxterm->geom_width, roxterm->geom_height);
-    }
-    */
+    roxterm_set_vte_size(roxterm, vte, roxterm->columns, roxterm->rows);
 
     title_orig = vte_terminal_get_window_title(vte);
     *title = g_strdup(title_orig ? title_orig : _("ROXTerm"));
@@ -2747,10 +2742,7 @@
     roxterm->drd = drag_receive_setup_dest_widget(roxterm->widget,
             roxterm_drag_data_received, roxterm);
     
-    roxterm->win_state_changed_tag = 
-            g_signal_connect(roxterm_get_toplevel(roxterm),
-            "window-state-event",
-            G_CALLBACK(roxterm_window_state_changed), roxterm);
+    roxterm_attach_state_changed_handler(roxterm);
 
     return scrollbar_pos ? roxterm->hbox : roxterm->widget;
 }
@@ -2830,7 +2822,7 @@
             multi_win_get_current_tab(roxterm->win) == roxterm->tab)
         {
             multi_win_set_show_menu_bar(roxterm->win,
-                !options_lookup_int(roxterm->profile, "hide_menubar"), TRUE);
+                !options_lookup_int(roxterm->profile, "hide_menubar"));
         }
         else if (!strcmp(key, "audible_bell"))
         {
@@ -3407,7 +3399,7 @@
 }
 
 /* Takes over ownership of profile and non-const strings;
- * on exit size_on_cli indicates * whether dimensions were given in *geom;
+ * on exit size_on_cli indicates whether dimensions were given in *geom;
  * geom is freed and set to NULL if it's invalid
  */
 static ROXTermData *roxterm_data_new(const char *display_name,
@@ -3477,7 +3469,8 @@
             }
             if (*geom)
             {
-                roxterm_set_geometry(roxterm, width, height);
+                roxterm->columns = width;
+                roxterm->rows = height;
                 if (size_on_cli)
                     *size_on_cli = TRUE;
             }
@@ -3488,10 +3481,6 @@
         }
     }
     roxterm->maximise = maximise;
-    if ((!geom || !*geom) && !maximise)
-    {
-        roxterm_default_dimensions(roxterm);
-    }
     if (colour_scheme_name)
     {
         roxterm->colour_scheme = colour_scheme_lookup_and_ref
@@ -3534,6 +3523,13 @@
             global_options_lookup_string("encoding"),
             &geom, &size_on_cli);
             
+    if (!size_on_cli)
+    {
+        roxterm->columns = options_lookup_int_with_default(roxterm->profile,
+                "width", 80);
+        roxterm->rows = options_lookup_int_with_default(roxterm->profile,
+                "height", 24);
+    }
     if (global_options_commandv)
     {
         roxterm->commandv = global_options_copy_strv(global_options_commandv);
@@ -3565,10 +3561,6 @@
             {
                 roxterm->current_zoom_factor = 1.0;
             }
-            roxterm->nonfs_width = partner->nonfs_width;
-            roxterm->nonfs_height = partner->nonfs_height;
-            roxterm_set_geometry(roxterm,
-                    partner->geom_width, partner->geom_height);
             /* roxterm_data_clone needs to see a widget to get geometry
              * correct */
             roxterm->widget = partner->widget;
@@ -3609,13 +3601,13 @@
                 char *old_geom = geom;
 
                 geom = g_strdup_printf("%dx%d%s",
-                        roxterm->geom_width, roxterm->geom_height, old_geom);
+                        roxterm->columns, roxterm->rows, old_geom);
                 g_free(old_geom);
             }
             else
             {
                 geom = g_strdup_printf("%dx%d",
-                        roxterm->geom_width, roxterm->geom_height);
+                        roxterm->columns, roxterm->rows);
             }
         }
         multi_win_new_with_geom(display_name, shortcuts, roxterm->zoom_index,
@@ -3629,15 +3621,23 @@
     g_free(profile_name);
 }
 
-static void roxterm_tab_to_new_window(MultiWin *win, MultiTab *tab)
+static void roxterm_tab_to_new_window(MultiWin *win, MultiTab *tab,
+        gboolean old_win_destroyed)
 {
-    ROXTermData *roxterm;
+    ROXTermData *roxterm = multi_tab_get_user_data(tab);
     ROXTermData *match_roxterm;
     MultiTab *match_tab = multi_win_get_current_tab(win);
+    GtkWindow *old_gwin = old_win_destroyed ? NULL :
+            roxterm_get_toplevel(roxterm);
 
-    roxterm = multi_tab_get_user_data(tab);
+    if (old_gwin)
+    {
+        g_signal_handler_disconnect(old_gwin, roxterm->win_state_changed_tag);
+    }
     roxterm->win = win;
-    g_return_if_fail(match_tab);
+    roxterm_attach_state_changed_handler(roxterm);
+    if (!match_tab);
+        return;
     match_roxterm = multi_tab_get_user_data(match_tab);
     if (roxterm == match_roxterm)
     {
@@ -3851,10 +3851,7 @@
 
 void roxterm_get_nonfs_dimensions(ROXTermData *roxterm, int *cols, int *rows)
 {
-    if (cols)
-        *cols = roxterm->nonfs_width;
-    if (rows)
-        *rows = roxterm->nonfs_height;
+    roxterm_size_func(roxterm, FALSE, cols, rows);
 }
 
 double roxterm_get_zoom_factor(ROXTermData *roxterm)
@@ -3879,6 +3876,7 @@
     gboolean fullscreen;
     char *disp;
     char *geom;
+    int width, height;
     PangoFontDescription *fdesc;
     char *title_template;
     double zoom_factor;
@@ -3891,6 +3889,7 @@
     char *tab_title;
     char *icon_title;
     gboolean current;
+    MultiTab *active_tab;
 } _ROXTermParseContext;
 
 static void parse_open_win(_ROXTermParseContext *rctx,
@@ -3917,6 +3916,7 @@
     rctx->fullscreen = FALSE;
     rctx->maximised = FALSE;
     rctx->zoom_factor = 1.0;
+    rctx->active_tab = NULL;
     for (n = 0; attribute_names[n]; ++n)
     {
         const char *a = attribute_names[n];
@@ -3925,7 +3925,10 @@
         if (!strcmp(a, "disp"))
             rctx->disp = g_strdup(v);
         else if (!strcmp(a, "geometry"))
+        {
             rctx->geom = g_strdup(v);
+            sscanf(v, "%dx%d+", &rctx->width, &rctx->height);
+        }
         else if (!strcmp(a, "title_template"))
             title_template = g_strdup(v);
         else if (!strcmp(a, "font"))
@@ -3991,7 +3994,7 @@
     }
     if (disp && disp[0])
         rctx->disp = g_strdup(disp);
-    multi_win_set_show_menu_bar(win, show_mbar, FALSE);
+    multi_win_set_show_menu_bar(win, show_mbar);
     multi_win_set_always_show_tabs(win, show_tabs);
     if (title_template && title_template[0])
         rctx->title_template = g_strdup(title_template);
@@ -4030,6 +4033,13 @@
         if (rctx->title)
             gtk_window_set_title(gwin, rctx->title);
         multi_win_show(rctx->win);
+        if (rctx->active_tab)
+        {
+            multi_win_select_tab(rctx->win, rctx->active_tab);
+            roxterm_tab_selection_handler(
+                    multi_tab_get_user_data(rctx->active_tab),
+                    rctx->active_tab);
+        }
     }
     rctx->win = NULL;
     g_free(rctx->title_template);
@@ -4109,7 +4119,6 @@
 static void close_tab_tag(_ROXTermParseContext *rctx)
 {
     ROXTermData *roxterm = rctx->roxterm;
-    VteTerminal *vte;
     
     if (rctx->commandv)
     {
@@ -4123,7 +4132,9 @@
         }
     }
     rctx->commandv = NULL;
-    rctx->tab = multi_tab_new0(rctx->win, roxterm, rctx->current);
+    rctx->tab = multi_tab_new(rctx->win, roxterm);
+    if (rctx->current)
+        rctx->active_tab = rctx->tab;
     if (rctx->tab_name && rctx->tab_name[0])
         multi_tab_set_name(rctx->tab, rctx->tab_name);
     if (rctx->tab_title && rctx->tab_title[0])
@@ -4137,9 +4148,11 @@
     g_free(rctx->icon_title);
     rctx->icon_title = NULL;
     roxterm_data_delete(roxterm);
+    /*
     roxterm = multi_tab_get_user_data(rctx->tab);
     vte = VTE_TERMINAL(roxterm->widget);
-    vte_terminal_set_size(vte, roxterm->geom_width, roxterm->geom_height);
+    roxterm_set_vte_size(roxterm, vte, rctx->width, rctx->height);
+    */
 }
 
 static void parse_open_command(_ROXTermParseContext *rctx,
Index: roxterm-1.18.5/src/roxterm-config.glade
===================================================================
--- roxterm-1.18.5.orig/src/roxterm-config.glade	2010-08-15 21:37:35.716581538 +0100
+++ roxterm-1.18.5/src/roxterm-config.glade	2010-08-15 21:45:19.436239348 +0100
@@ -2120,7 +2120,7 @@
                                         <property name="visible">True</property>
                                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                                         <property name="xalign">0</property>
-                                        <property name="label" translatable="yes">_Number of initial tabs:</property>
+                                        <property name="label" translatable="yes">Initial _number of tabs:</property>
                                         <property name="use_underline">True</property>
                                         <property name="justify">right</property>
                                         <property name="mnemonic_widget">init_tabs</property>
Index: roxterm-1.18.5/src/menutree.c
===================================================================
--- roxterm-1.18.5.orig/src/menutree.c	2010-08-15 21:37:35.672571921 +0100
+++ roxterm-1.18.5/src/menutree.c	2010-08-15 21:45:19.436239348 +0100
@@ -372,11 +372,17 @@
 static GtkWidget *menutree_find_encoding(MenuTree *mtree,
         const char *encoding, int *position)
 {
-    GList *link = gtk_container_get_children(GTK_CONTAINER(mtree->encodings));
+    GList *link;
     int n = 0;
 
     if (!position)
         position = &n;
+    if (!mtree->encodings)
+    {
+        *position = -1;
+        return NULL;
+    }
+    link = gtk_container_get_children(GTK_CONTAINER(mtree->encodings));
     if (!encoding)
     {
         if (mtree->encodings)
Index: roxterm-1.18.5/src/tabdrag.c
===================================================================
--- roxterm-1.18.5.orig/src/tabdrag.c	2010-08-15 21:37:35.652581609 +0100
+++ roxterm-1.18.5/src/tabdrag.c	2010-08-15 21:45:19.436239348 +0100
@@ -47,37 +47,54 @@
     return FALSE;
 }
 
+inline static void
+tab_drag_move_win_for_event(MultiWin *win, GdkEventButton *event)
+{
+    gtk_window_move(GTK_WINDOW(multi_win_get_widget(win)),
+            MAX((int) event->x_root - 20, 0),
+            MAX((int) event->y_root - 8, 0));
+}
+
 static gboolean tab_drag_end_release_handler(GtkWidget *widget,
         GdkEventButton *event, TabDrag *td)
 {
     if (event->button == td->button)
     {
         MultiWin *orig_parent = multi_tab_get_parent(td->tab);
+        
         tab_drag_release(td);
         if (!multi_win_get_win_under_pointer())
         {
-            /* Dropped on backdrop or foreign window, make new window */
-            char *display_name = gdk_screen_make_display_name(
-                    gdk_drawable_get_screen(GDK_DRAWABLE(event->window)));
-            gpointer user_data = multi_tab_get_user_data(td->tab);
-            gboolean disable_menu_shortcuts, disable_tab_shortcuts;
-            MultiWin *win;
-            
-            multi_win_get_disable_menu_shortcuts(user_data,
-                    &disable_menu_shortcuts, &disable_tab_shortcuts);
-            win = multi_win_new_blank(display_name,
-                multi_win_get_shortcut_scheme(multi_tab_get_parent(td->tab)),
-                multi_win_get_zoom_index(orig_parent),
-                disable_menu_shortcuts, disable_tab_shortcuts,
-                multi_win_get_tab_pos(orig_parent),
-                multi_win_get_always_show_tabs(orig_parent));
-            g_free(display_name);
-            multi_tab_move_to_new_window(win, td->tab, -1); 
-            gtk_window_move(GTK_WINDOW(multi_win_get_widget(win)),
-                    MAX((int) event->x_root - 20, 0),
-                    MAX((int) event->y_root - 8, 0));
-            multi_win_show(win);
-            multi_win_select_tab(win, td->tab);
+            /* Dropped on backdrop or foreign window, make new window, or
+             * simply move old window if it only contained one tab.
+             */
+            if (multi_win_get_ntabs(orig_parent) == 1)
+            {
+                tab_drag_move_win_for_event(orig_parent, event);
+            }
+            else
+            {
+                char *display_name = gdk_screen_make_display_name(
+                        gdk_drawable_get_screen(GDK_DRAWABLE(event->window)));
+                gpointer user_data = multi_tab_get_user_data(td->tab);
+                gboolean disable_menu_shortcuts, disable_tab_shortcuts;
+                MultiWin *win;
+                
+                multi_win_get_disable_menu_shortcuts(user_data,
+                        &disable_menu_shortcuts, &disable_tab_shortcuts);
+                win = multi_win_new_blank(display_name,
+                    multi_win_get_shortcut_scheme(
+                            multi_tab_get_parent(td->tab)),
+                    multi_win_get_zoom_index(orig_parent),
+                    disable_menu_shortcuts, disable_tab_shortcuts,
+                    multi_win_get_tab_pos(orig_parent),
+                    multi_win_get_always_show_tabs(orig_parent));
+                g_free(display_name);
+                multi_tab_move_to_new_window(win, td->tab, -1); 
+                tab_drag_move_win_for_event(win, event);
+                multi_win_show(win);
+                multi_win_select_tab(win, td->tab);
+            }
         }
         else
         {

--- End Message ---

Attachment: signature.asc
Description: This is a digitally signed message part.


Reply to: