Index: ChangeLog =================================================================== --- ChangeLog (revision 24177) +++ ChangeLog (working copy) @@ -1,3 +1,16 @@ +2006-12-24 Nick Schermer + * terminal/terminal-screen.c: Fix compiler warning because we + ignore the chdir return value. + * terminal-window.c: Add support for DND the tabs between two windows + with GTK+ 2.10.x. + * terminal-window.c: Disconnect the "remove" signal before destroying + the application. This will prevent a lot of GTK+ warnings quiting with + multiple tabs opened. + * terminal/terminal-window.c: Move the code for checking if the tabs + should be visible to the rebuild_gomenu function. This will prevent some + duplicated code and works better with tab dnd. + + 2006-12-21 Benedikt Meurer * NEWS, configure.in.in, terminal/terminal-app.c, @@ -314,7 +327,7 @@ hidden setting "MiscTabPosition" which specifies the position where the notebook tabs should be placed (can be either GTK_POS_TOP, GTK_POS_BOTTOM, GTK_POS_RIGHT or GTK_POS_LEFT). - * terminal/terminal-tab-header.c: Use vertical labels if the tab + * terminal/terminal-tab-header.c: Use vertical labels if the tab position is GTK_POS_RIGHT or GTK_POS_LEFT. * doc/C/Terminal.xml.in: Add new hidden options to the manual. @@ -679,7 +692,7 @@ * terminal/Makefile.am, terminal/terminal-marshal.list: Add custom marshallers for the "get-context-menu" and "open-uri" signals. * terminal/terminal-helper-dialog.c, terminal/terminal-helper.c, - terminal/terminal-helper.h, terminal/terminal-icons.c, + terminal/terminal-helper.h, terminal/terminal-icons.c, terminal/terminal-preferences.c, terminal/terminal-widget.c, terminal/terminal-widget.h, terminal/terminal-window.c: Use the simple way of handling custom helpers just like other helpers. Connect the @@ -687,7 +700,7 @@ improvements. This finally closes bug #52. * terminal/terminal-screen.c: Forward the "get-context-menu" and "open-uri" signals from TerminalWidget. - * terminal/terminal-widget.c(terminal_widget_button_press_event): + * terminal/terminal-widget.c(terminal_widget_button_press_event): Middle-clicking on an URI now fires the associated helper. * po/: Update translations. * NEWS: Add note about the new "URL clicking"-support. More details @@ -696,7 +709,7 @@ 2005-03-12 Benedikt Meurer * helpers/epiphany.desktop.in: Add Epiphany. - * helpers/firefox.desktop.in, helpers/konqueror.desktop.in, + * helpers/firefox.desktop.in, helpers/konqueror.desktop.in, helpers/opera-browser.desktop.in, helpers/mozilla-browser.desktop.in, helpers/mutt.desktop.in, helpers/lynx.desktop.in, helpers/thunderbird.desktop.in, helpers/opera-mailer.desktop.in, @@ -724,13 +737,13 @@ terminal/terminal-helper.h, terminal/terminal-helper-dialog.c, terminal/terminal-helper-dialog.h, Makefile.am, configure.ac, Terminal.ui, terminal/Makefile.am, terminal/stock-icons/Makefile.am, - terminal/terminal-icons.c, terminal/terminal-icons.h, + terminal/terminal-icons.c, terminal/terminal-icons.h, terminal/terminal-preferences.c, terminal/terminal-window.c: Initial import of the helper application framework, which will allow users to open URLs from within Terminal, and which will probably be ported to Xfce later. The new framework still needs to be connected to the TerminalWidget. - * po/fi.po: Update finish translations, thanks to Jari Rahkonen + * po/fi.po: Update finish translations, thanks to Jari Rahkonen . 2005-03-09 Benedikt Meurer @@ -771,7 +784,7 @@ * terminal/Makefile.am, terminal/HACKING, po/POTFILES.in: Added rules to properly auto-generate the built files. These autogeneration rules - are only available if --enable-maintainer-mode is specified for + are only available if --enable-maintainer-mode is specified for configure (which is usually the case for autogen runs, but not for enduser configure runs). * configure.ac, terminal/terminal-dbus.c, terminal/terminal-dbus.h, @@ -834,7 +847,7 @@ * terminal/main.c: Be sure to initialize the locale first, using gtk_set_locale(), because else usage() will not use the available translations. - * po/ru.po, po/ru.gmo, terminal/terminal-window.c: Added russian + * po/ru.po, po/ru.gmo, terminal/terminal-window.c: Added russian translations, thanks to Anthony Ivanoff . 2005-01-21 Benedikt Meurer @@ -1609,7 +1622,7 @@ * configure.ac, NEWS: Version 0.1.6, depends on exo-0.1 >= 0.1.1. * po/de.po: Translation updates. - * terminal/terminal-window.c: Setup correct translation domain + * terminal/terminal-window.c: Setup correct translation domain for the actions. * HACKING: Added note to update translations to Release process section. Index: terminal/terminal-screen.c =================================================================== --- terminal/terminal-screen.c (revision 24177) +++ terminal/terminal-screen.c (working copy) @@ -995,7 +995,7 @@ terminal_dialogs_show_error (GTK_WIDGET (screen), error, _("Failed to execute child")); g_error_free (error); } - else + else { g_object_get (G_OBJECT (screen->preferences), "command-update-records", &update, @@ -1308,7 +1308,9 @@ { g_free (screen->working_directory); screen->working_directory = g_get_current_dir (); - chdir (cwd); + + if (G_UNLIKELY (chdir (cwd) < 0)) + g_warning (_("Failed to enter directory %s"), cwd); } g_free (cwd); Index: terminal/terminal-window.c =================================================================== --- terminal/terminal-window.c (revision 24177) +++ terminal/terminal-window.c (working copy) @@ -58,8 +58,14 @@ #include #include +/* terminal tab dnd support */ +#if GTK_CHECK_VERSION(2,10,0) +#define TERMINAL_GROUP_ID 1 +#define TERMINAL_TAB_DND +#endif + /* Property identifiers */ enum { @@ -103,11 +109,19 @@ GtkNotebookPage *page, guint page_num, TerminalWindow *window); -#if GTK_CHECK_VERSION (2,10,0) +#ifdef TERMINAL_TAB_DND static void terminal_window_page_reordered (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, TerminalWindow *window); +static void terminal_window_page_added (GtkNotebook *notebook, + GtkWidget *child, + guint page_num, + TerminalWindow *window); +static void terminal_window_page_removed (GtkNotebook *notebook, + GtkWidget *child, + guint page_num, + TerminalWindow *window); #endif static GtkWidget *terminal_window_get_context_menu (TerminalScreen *screen, TerminalWindow *window); @@ -182,7 +196,7 @@ GtkActionGroup *action_group; GtkUIManager *ui_manager; - + GtkWidget *menubar; GtkWidget *toolbars; GtkWidget *notebook; @@ -201,8 +215,8 @@ static const GtkActionEntry action_entries[] = { { "file-menu", NULL, N_ ("_File"), NULL, NULL, NULL, }, - { "new-tab", TERMINAL_STOCK_NEWTAB, N_ ("Open _Tab"), NULL, N_ ("Open a new terminal tab"), G_CALLBACK (terminal_window_action_new_tab), }, - { "new-window", TERMINAL_STOCK_NEWWINDOW, N_ ("Open T_erminal"), "N", N_ ("Open a new terminal window"), G_CALLBACK (terminal_window_action_new_window), }, + { "new-tab", TERMINAL_STOCK_NEWTAB, N_ ("Open _Tab"), NULL, N_ ("Open a new terminal tab"), G_CALLBACK (terminal_window_action_new_tab), }, + { "new-window", TERMINAL_STOCK_NEWWINDOW, N_ ("Open T_erminal"), "N", N_ ("Open a new terminal window"), G_CALLBACK (terminal_window_action_new_window), }, { "detach-tab", NULL, N_ ("_Detach Tab"), NULL, N_ ("Open a new window for the current terminal tab"), G_CALLBACK (terminal_window_action_detach_tab), }, { "close-tab", TERMINAL_STOCK_CLOSETAB, N_ ("C_lose Tab"), NULL, N_ ("Close the current terminal tab"), G_CALLBACK (terminal_window_action_close_tab), }, { "close-window", TERMINAL_STOCK_CLOSEWINDOW, N_ ("_Close Window"), NULL, N_ ("Close the terminal window"), G_CALLBACK (terminal_window_action_close_window), }, @@ -236,8 +250,15 @@ { "fullscreen", TERMINAL_STOCK_FULLSCREEN, N_ ("_Fullscreen"), NULL, N_ ("Toggle fullscreen mode"), G_CALLBACK (terminal_window_action_fullscreen), FALSE, }, }; +#ifdef TERMINAL_TAB_DND +static const GtkTargetEntry drag_targets[] = +{ + { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, 0 }, +}; +#endif + G_DEFINE_TYPE (TerminalWindow, terminal_window, GTK_TYPE_WINDOW); @@ -247,7 +268,7 @@ { GtkWidgetClass *gtkwidget_class; GObjectClass *gobject_class; - + gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = terminal_window_dispose; gobject_class->finalize = terminal_window_finalize; @@ -407,9 +428,17 @@ g_signal_connect (G_OBJECT (window->notebook), "remove", G_CALLBACK (terminal_window_screen_removed), window); -#if GTK_CHECK_VERSION (2,10,0) +#ifdef TERMINAL_TAB_DND + /* signals for tab dnd and reorder */ g_signal_connect (G_OBJECT (window->notebook), "page-reordered", G_CALLBACK (terminal_window_page_reordered), window); + g_signal_connect (G_OBJECT (window->notebook), "page-removed", + G_CALLBACK (terminal_window_page_removed), window); + g_signal_connect (G_OBJECT (window->notebook), "page-added", + G_CALLBACK (terminal_window_page_added), window); + + /* you can only exchange tabs between 2 notebooks when they have the same group id */ + gtk_notebook_set_group_id (GTK_NOTEBOOK (window->notebook), TERMINAL_GROUP_ID); #endif gtk_box_pack_start (GTK_BOX (vbox), window->notebook, TRUE, TRUE, 0); @@ -428,7 +457,81 @@ +#ifdef TERMINAL_TAB_DND static void +terminal_window_page_reordered (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num, + TerminalWindow *window) +{ + /* regenerate the "Go" menu */ + terminal_window_rebuild_gomenu (window); +} + + + +static void +terminal_window_page_added (GtkNotebook *notebook, + GtkWidget *child, + guint page_num, + TerminalWindow *window) +{ + GtkWidget *header; + gint tab_id, title_id; + GtkAction *action; + + header = gtk_notebook_get_tab_label (notebook, child); + + /* get the old signal id's */ + tab_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (header), "detach-tab-id")); + title_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (header), "set-title-id")); + + if (tab_id > 0) + { + /* disconnect the signals */ + g_signal_handler_disconnect (G_OBJECT (header), tab_id); + g_signal_handler_disconnect (G_OBJECT (header), title_id); + } + + /* get the new action group */ + action = gtk_action_group_get_action (window->action_group, "set-title"); + + /* add new signals */ + tab_id = g_signal_connect_swapped (G_OBJECT (header), "detach-tab", + G_CALLBACK (terminal_window_detach_screen), window); + title_id = g_signal_connect_swapped (G_OBJECT (header), "set-title", + G_CALLBACK (gtk_action_activate), action); + + /* attach the id's to the header so we can destroy them later */ + g_object_set_data (G_OBJECT (header), "detach-tab-id", GINT_TO_POINTER (tab_id)); + g_object_set_data (G_OBJECT (header), "set-title-id", GINT_TO_POINTER (title_id)); + + /* regenerate the "Go" menu */ + terminal_window_rebuild_gomenu (window); + + /* update all screen sensitive actions (Copy, Prev Tab, ...) */ + terminal_window_update_actions (window); +} + + + +static void +terminal_window_page_removed (GtkNotebook *notebook, + GtkWidget *child, + guint page_num, + TerminalWindow *window) +{ + /* regenerate the "Go" menu */ + terminal_window_rebuild_gomenu (window); + + /* update all screen sensitive actions (Copy, Prev Tab, ...) */ + terminal_window_update_actions (window); +} +#endif + + + +static void terminal_window_dispose (GObject *object) { TerminalWindow *window = TERMINAL_WINDOW (object); @@ -616,7 +719,7 @@ TerminalScreen *active; gint grid_width; gint grid_height; - + /* The trick is rather simple here. This is called before any Gtk+ resizing operation takes * place, so the columns/rows on the active terminal screen are still set to their old values. * We simply query these values and force them to be set with the new style. @@ -794,12 +897,20 @@ gchar name[32]; gchar *path; gint npages; + gboolean always_show_tabs; gint n; + /* check if we should always display tabs */ + g_object_get (G_OBJECT (window->preferences), "misc-always-show-tabs", &always_show_tabs, NULL); + + /* change the visibility of the tabs accordingly */ + npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), always_show_tabs || (npages > 1)); + + /* stop when there is no menu widget */ if (G_UNLIKELY (window->gomenu == NULL)) return; - npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); for (n = 0; n < npages; ++n) { terminal = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), n); @@ -851,7 +962,22 @@ static gboolean terminal_window_delete_event (TerminalWindow *window) { - return !terminal_window_confirm_close (window); + gboolean result = terminal_window_confirm_close (window); + + if (result == TRUE) + { + /* disconnect the "remove" signal */ + g_signal_handlers_disconnect_by_func (G_OBJECT (window->notebook), + G_CALLBACK (terminal_window_screen_removed), window); + +#ifdef TERMINAL_TAB_DND + /* disconnect the "page-removed" signal */ + g_signal_handlers_disconnect_by_func (G_OBJECT (window->notebook), + G_CALLBACK (terminal_window_page_removed), window); +#endif + } + + return !result; } @@ -910,23 +1036,6 @@ -#if GTK_CHECK_VERSION (2,10,0) -static void -terminal_window_page_reordered (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num, - TerminalWindow *window) -{ - - /* Regenerate the "Go" menu. - * This also updates the accelerators. - */ - terminal_window_rebuild_gomenu (window); -} -#endif - - - static GtkWidget* terminal_window_get_context_menu (TerminalScreen *screen, TerminalWindow *window) @@ -1068,7 +1177,6 @@ TerminalWindow *window) { TerminalScreen *active; - gboolean always_show_tabs; gint npages; gint grid_width; gint grid_height; @@ -1080,12 +1188,6 @@ } else { - /* check tabs should always be visible */ - g_object_get (G_OBJECT (window->preferences), "misc-always-show-tabs", &always_show_tabs, NULL); - - /* change the visibility of the tabs accordingly */ - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), always_show_tabs || (npages > 1)); - /* meh, Gtk+, who wants focus on the notebook? */ GTK_WIDGET_UNSET_FLAGS (window->notebook, GTK_CAN_FOCUS); @@ -1096,11 +1198,13 @@ terminal_window_set_size_force_grid (window, active, grid_width, grid_height); } +#ifndef TERMINAL_TAB_DND /* regenerate the "Go" menu */ terminal_window_rebuild_gomenu (window); /* update all screen sensitive actions (Copy, Prev Tab, ...) */ terminal_window_update_actions (window); +#endif } } @@ -1183,7 +1287,19 @@ TerminalWindow *window) { if (terminal_window_confirm_close (window)) - gtk_widget_destroy (GTK_WIDGET (window)); + { + /* disconnect the "remove" signal */ + g_signal_handlers_disconnect_by_func (G_OBJECT (window->notebook), + G_CALLBACK (terminal_window_screen_removed), window); + +#ifdef TERMINAL_TAB_DND + /* disconnect the "page-removed" signal */ + g_signal_handlers_disconnect_by_func (G_OBJECT (window->notebook), + G_CALLBACK (terminal_window_page_removed), window); +#endif + + gtk_widget_destroy (GTK_WIDGET (window)); + } } @@ -1275,7 +1391,7 @@ TerminalWindow *window) { /* check if we already have a preferences dialog instance */ - if (G_UNLIKELY (window->preferences_dialog != NULL)) + if (G_UNLIKELY (window->preferences_dialog != NULL)) { /* move to the current screen and make transient for this window */ gtk_window_set_screen (GTK_WINDOW (window->preferences_dialog), gtk_widget_get_screen (GTK_WIDGET (window))); @@ -1556,7 +1672,7 @@ TerminalWindow *window; GtkAction *action; gboolean setting; - + window = g_object_new (TERMINAL_TYPE_WINDOW, NULL); /* setup full screen */ @@ -1605,13 +1721,13 @@ TerminalScreen *screen) { TerminalScreen *active; - GtkWidget *header; - GtkAction *action; - gboolean always_show_tabs; - gint npages; gint page; gint grid_width; gint grid_height; + GtkWidget *header; +#ifndef TERMINAL_TAB_DND + GtkAction *action; +#endif g_return_if_fail (TERMINAL_IS_WINDOW (window)); g_return_if_fail (TERMINAL_IS_SCREEN (screen)); @@ -1623,36 +1739,42 @@ terminal_screen_set_size (screen, grid_width, grid_height); } +#ifndef TERMINAL_TAB_DND action = gtk_action_group_get_action (window->action_group, "set-title"); +#endif header = terminal_tab_header_new (); exo_binding_new (G_OBJECT (screen), "title", G_OBJECT (header), "title"); exo_binding_new (G_OBJECT (window->notebook), "tab-pos", G_OBJECT (header), "tab-pos"); g_signal_connect_swapped (G_OBJECT (header), "close-tab", G_CALLBACK (gtk_widget_destroy), screen); + +#ifndef TERMINAL_TAB_DND g_signal_connect_swapped (G_OBJECT (header), "detach-tab", G_CALLBACK (terminal_window_detach_screen), window); g_signal_connect_swapped (G_OBJECT (header), "set-title", G_CALLBACK (gtk_action_activate), action); +#endif + g_object_set_data_full (G_OBJECT (header), "terminal-window-screen", g_object_ref (G_OBJECT (screen)), (GDestroyNotify) g_object_unref); gtk_widget_show (header); page = gtk_notebook_append_page (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (screen), header); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (screen), TRUE, TRUE, GTK_PACK_START); -#if GTK_CHECK_VERSION(2,10,0) +#ifdef TERMINAL_TAB_DND + /* allow sorting the tab in the same window */ gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (screen), TRUE); + + /* allow dragging the tab to another window */ + gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (window->notebook), + GTK_WIDGET (screen), + TRUE); #endif - /* check if we should always display tabs */ - g_object_get (G_OBJECT (window->preferences), "misc-always-show-tabs", &always_show_tabs, NULL); - - /* change the visibility of the tabs accordingly */ - npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), always_show_tabs || (npages > 1)); - /* yep, still no focus on the notebook! */ GTK_WIDGET_UNSET_FLAGS (window->notebook, GTK_CAN_FOCUS); @@ -1665,7 +1787,9 @@ g_signal_connect_swapped (G_OBJECT (screen), "selection-changed", G_CALLBACK (terminal_window_update_actions), window); +#ifndef TERMINAL_TAB_DND terminal_window_rebuild_gomenu (window); +#endif /* need to save the grid size here for detached screens */ terminal_screen_get_size (screen, &grid_width, &grid_height); Index: NEWS =================================================================== --- NEWS (revision 24177) +++ NEWS (working copy) @@ -2,6 +2,8 @@ ========== - Add support for real transparency with GTK+ 2.10 and a compositing manager, i.e. the one built into xfwm4 (Bug #2671). +- Fix compiler warnings. +- Support for DND tabs between two windows with GTK+ 2.10. 0.2.5.8rc2 @@ -218,7 +220,7 @@ 0.1.7 ===== -- New icons for the preferences dialog by Francois Le +- New icons for the preferences dialog by Francois Le Clainche , available as PNG and scalable images. - Online documentation updated. All of Terminal is now documented.