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 <[email protected]> - and me; if and when it gets approved here he'll upload it to unstable. -- TH * http://www.realh.co.uk
From: Tony Houghton <[email protected]> Description: Fix issues with tab initialisation and sizing etc. The next upstream release will also include new features, so this patch cherry-picks the bug fixes which affect Debian to make them more eligible for inclusion in Squeeze post-freeze. Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=592984 Bug: https://sourceforge.net/tracker/?func=detail&aid=3041926&group_id=124080&atid=698428 Bug: https://sourceforge.net/tracker/?func=detail&aid=2996296&group_id=124080&atid=698428 Origin: upstream, <http://roxterm.svn.sourceforge.net/viewvc/roxterm/trunk/roxterm/>, revisions 792-298,801-810 Index: roxterm-1.18.5/src/multitab.c =================================================================== --- roxterm-1.18.5.orig/src/multitab.c 2010-08-14 21:14:14.518532321 +0100 +++ roxterm-1.18.5/src/multitab.c 2010-08-15 13:30:00.416242990 +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,100 @@ 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_restore_cached_size(GtkWidget *widget, + GtkAllocation *alloc, MultiWin *win) +{ + /* + int px, py; + GdkGeometry dummy_geom; + */ + 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; + /* + g_debug("Restoring cached size %dx%d", + win->cached_width, win->cached_height); + gtk_window_get_size(GTK_WINDOW(win->gtkwin), &px, &py); + */ + gtk_widget_get_allocation(widget, &c_alloc); + /* + g_debug("Window size %d x %d, allocation %d x %d", + px, py, alloc->width, alloc->height); + g_debug("Child allocation %d x %d", c_alloc.width, c_alloc.height); + */ + multi_win_size_func(win->current_tab->user_data, TRUE, &w, &h); + /* + g_debug("Child wants size %d x %d, setting %d x %d", w, h, + w + px - c_alloc.width, h + py - c_alloc.height); + multi_win_set_geometry_hints(win, widget, &dummy_geom, 0); + */ + 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); + /* + gtk_window_get_size(GTK_WINDOW(win->gtkwin), &px, &py); + g_debug("Window size %d x %d", px, py); + */ +} + +static void multi_win_cache_size(MultiWin *win) +{ + int px, py, cx, cy; + + if (win->size_alloc_tag) + { + /*g_debug("Size already cached");*/ + return; + } + if (!win->current_tab || !win->gtkwin || + !gtk_widget_get_visible(win->gtkwin) || + win->fullscreen || multi_win_is_maximised(win)) + { + /*g_debug("Can't cache size");*/ + return; + } + multi_win_size_func(win->current_tab->user_data, FALSE, + &win->cached_width, &win->cached_height); + /*g_debug("Cached size %dx%d", 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); + /* + g_debug("Window size %d x %d, child size %d x %d", + px, py, cx, cy); + */ + win->size_alloc_tag = g_signal_connect_after( + win->gtkwin, "size-allocate", + G_CALLBACK(multi_win_restore_cached_size), win); +} + static void multi_tab_set_name_or_title(MultiTab *tab, const char *title) { MultiWin *win = tab->parent; @@ -300,9 +385,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 +621,7 @@ win->ignore_tabs_moving = TRUE; if (!notify_only) { - win->ignore_size_allocate = 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 +630,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,8 +638,17 @@ #if DO_OWN_TAB_DRAGGING void multi_tab_move_to_new_window(MultiWin *win, MultiTab *tab, int position) { + MultiWin *old_win = tab->parent; + + 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)); multi_tab_remove_from_parent(tab, FALSE); multi_win_add_tab(win, tab, position, FALSE); + multi_win_set_geometry_hints_for_tab(win, tab); /* 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? */ if (multi_tab_to_new_window_handler) @@ -597,93 +692,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; @@ -792,12 +800,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 +813,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 +847,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 +950,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 +961,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 +980,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 +994,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 +1028,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 +1215,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 +1497,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 +1556,7 @@ { gboolean disable_menu_shortcuts, disable_tab_shortcuts; MultiWin *win; + int n; multi_win_get_disable_menu_shortcuts(user_data_template, &disable_menu_shortcuts, &disable_tab_shortcuts); @@ -1600,7 +1565,7 @@ 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); @@ -1632,12 +1597,9 @@ 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 */ + for (n = numtabs - 1; n >= 0; --n) + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), n); return win; } @@ -1658,7 +1620,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)) { @@ -1728,7 +1692,10 @@ { tab = win->tabs->data; if (!win->always_show_tabs) + { + multi_win_cache_size(win); 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 +1703,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 +1721,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 +1744,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 +1756,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 +1897,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 +1915,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 +1930,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 +2120,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); } } Index: roxterm-1.18.5/src/multitab.h =================================================================== --- roxterm-1.18.5.orig/src/multitab.h 2010-08-14 21:14:14.454560212 +0100 +++ roxterm-1.18.5/src/multitab.h 2010-08-15 13:30:00.416242990 +0100 @@ -56,18 +56,12 @@ 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); @@ -113,14 +107,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 +261,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 +319,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-14 21:14:14.474531813 +0100 +++ roxterm-1.18.5/src/profilegui.c 2010-08-15 13:30:00.428267918 +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-14 21:14:14.494534582 +0100 +++ roxterm-1.18.5/src/roxterm.c 2010-08-15 13:30:00.440582443 +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, @@ -3631,12 +3623,17 @@ static void roxterm_tab_to_new_window(MultiWin *win, MultiTab *tab) { - 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 = 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; + roxterm_attach_state_changed_handler(roxterm); g_return_if_fail(match_tab); match_roxterm = multi_tab_get_user_data(match_tab); if (roxterm == match_roxterm) @@ -3851,10 +3848,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 +3873,7 @@ gboolean fullscreen; char *disp; char *geom; + int width, height; PangoFontDescription *fdesc; char *title_template; double zoom_factor; @@ -3925,7 +3920,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 +3989,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); @@ -4109,7 +4107,6 @@ static void close_tab_tag(_ROXTermParseContext *rctx) { ROXTermData *roxterm = rctx->roxterm; - VteTerminal *vte; if (rctx->commandv) { @@ -4123,7 +4120,7 @@ } } rctx->commandv = NULL; - rctx->tab = multi_tab_new0(rctx->win, roxterm, rctx->current); + rctx->tab = multi_tab_new(rctx->win, roxterm); 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 +4134,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 13:30:04.089238157 +0100 +++ roxterm-1.18.5/src/roxterm-config.glade 2010-08-15 13:30:35.608247939 +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>

