Index: Terminal.ui =================================================================== --- Terminal.ui (revision 26104) +++ Terminal.ui (working copy) @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Index: configure.in.in =================================================================== --- configure.in.in (revision 26104) +++ configure.in.in (working copy) @@ -82,7 +82,7 @@ dnl *** Check for required packages *** dnl *********************************** XDT_CHECK_PACKAGE([EXO], [exo-0.3], [0.3.2]) -XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.6.0]) +XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.10.0]) XDT_CHECK_PACKAGE([VTE], [vte], [0.11.11]) dnl ************************************************* Index: Makefile.am =================================================================== --- Makefile.am (revision 26104) +++ Makefile.am (working copy) @@ -33,8 +33,7 @@ uidir = $(datadir)/Terminal ui_DATA = \ - Terminal-toolbars.ui \ - Terminal.ui + Terminal-toolbars.ui EXTRA_DIST = \ HACKING \ Index: terminal/terminal-window-ui.xml =================================================================== --- terminal/terminal-window-ui.xml (revision 0) +++ terminal/terminal-window-ui.xml (revision 0) @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: terminal/terminal-screen.c =================================================================== --- terminal/terminal-screen.c (revision 26104) +++ terminal/terminal-screen.c (working copy) @@ -373,7 +373,7 @@ static void terminal_screen_realize (GtkWidget *widget) { -#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY) +#ifdef HAVE_VTE_TERMINAL_SET_OPACITY GdkScreen *screen; #endif @@ -383,7 +383,7 @@ if (!GTK_WIDGET_REALIZED (TERMINAL_SCREEN (widget)->terminal)) gtk_widget_realize (TERMINAL_SCREEN (widget)->terminal); -#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY) +#ifdef HAVE_VTE_TERMINAL_SET_OPACITY /* connect to the "composited-changed" signal */ screen = gtk_widget_get_screen (widget); g_signal_connect_swapped (G_OBJECT (screen), "composited-changed", G_CALLBACK (terminal_screen_update_background), widget); @@ -395,7 +395,7 @@ static void terminal_screen_unrealize (GtkWidget *widget) { -#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY) +#ifdef HAVE_VTE_TERMINAL_SET_OPACITY GdkScreen *screen; /* disconnect the "composited-changed" handler */ @@ -861,7 +861,7 @@ vte_terminal_set_background_image (VTE_TERMINAL (screen->terminal), NULL); vte_terminal_set_background_saturation (VTE_TERMINAL (screen->terminal), 1.0); vte_terminal_set_background_transparent (VTE_TERMINAL (screen->terminal), FALSE); -#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY) +#ifdef HAVE_VTE_TERMINAL_SET_OPACITY vte_terminal_set_opacity (VTE_TERMINAL (screen->terminal), 0xFFFF); #endif } @@ -875,7 +875,7 @@ screen->terminal->allocation.width, screen->terminal->allocation.height); vte_terminal_set_background_image (VTE_TERMINAL (screen->terminal), image); -#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY) +#ifdef HAVE_VTE_TERMINAL_SET_OPACITY vte_terminal_set_opacity (VTE_TERMINAL (screen->terminal), 0xFFFF); #endif if (image != NULL) @@ -887,7 +887,7 @@ g_object_get (G_OBJECT (screen->preferences), "background-darkness", &background_darkness, NULL); vte_terminal_set_background_image (VTE_TERMINAL (screen->terminal), NULL); -#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY) +#ifdef HAVE_VTE_TERMINAL_SET_OPACITY /* check if the X screen is composited */ if (gdk_screen_is_composited (gtk_widget_get_screen (user_data))) { @@ -900,7 +900,7 @@ #endif vte_terminal_set_background_saturation (VTE_TERMINAL (screen->terminal), 1.0 - background_darkness); vte_terminal_set_background_transparent (VTE_TERMINAL (screen->terminal), TRUE); -#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY) +#ifdef HAVE_VTE_TERMINAL_SET_OPACITY vte_terminal_set_opacity (VTE_TERMINAL (screen->terminal), 0xFFFF); } #endif @@ -960,7 +960,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, @@ -1062,21 +1062,23 @@ gint force_columns, gint force_rows) { - GtkRequisition terminal_requisition; - GtkRequisition window_requisition; - gint width; - gint height; - gint columns; - gint rows; - gint xpad; - gint ypad; + GtkRequisition terminal_requisition; + GtkRequisition toplevel_requisition; + GtkWidget *toplevel; + gint width; + gint height; + gint columns; + gint rows; + gint xpad; + gint ypad; - gtk_widget_set_size_request (screen->terminal, 2000, 2000); - gtk_widget_size_request (GTK_WIDGET (window), &window_requisition); + toplevel = gtk_widget_get_toplevel (screen->terminal); + + gtk_widget_size_request (toplevel, &toplevel_requisition); gtk_widget_size_request (screen->terminal, &terminal_requisition); - width = window_requisition.width - terminal_requisition.width; - height = window_requisition.height - terminal_requisition.height; + width = toplevel_requisition.width - terminal_requisition.width; + height = toplevel_requisition.height - terminal_requisition.height; if (force_columns < 0) columns = VTE_TERMINAL (screen->terminal)->column_count; Index: terminal/terminal-marshal.list =================================================================== --- terminal/terminal-marshal.list (revision 26104) +++ terminal/terminal-marshal.list (working copy) @@ -1,2 +1,3 @@ OBJECT:VOID VOID:STRING,ENUM +VOID:OBJECT,INT,INT Index: terminal/terminal-widget.c =================================================================== --- terminal/terminal-widget.c (revision 26104) +++ terminal/terminal-widget.c (working copy) @@ -39,7 +39,6 @@ #include - #define USERCHARS "-A-Za-z0-9" #define PASSCHARS "-A-Za-z0-9,?;.:/!%$^*&~\"#'" #define HOSTCHARS "-A-Za-z0-9" @@ -72,6 +71,7 @@ TARGET_TEXT_PLAIN, TARGET_MOZ_URL, TARGET_APPLICATION_X_COLOR, + TARGET_GTK_NOTEBOOK_TAB, }; @@ -132,6 +132,7 @@ { "STRING", 0, TARGET_STRING }, { "text/plain", 0, TARGET_TEXT_PLAIN }, { "application/x-color", 0, TARGET_APPLICATION_X_COLOR }, + { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, TARGET_GTK_NOTEBOOK_TAB }, }; @@ -185,7 +186,7 @@ GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, targets, G_N_ELEMENTS (targets), - GDK_ACTION_COPY | GDK_ACTION_LINK); + GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_MOVE); /* monitor the misc-highlight-urls setting */ g_signal_connect_swapped (G_OBJECT (widget->preferences), "notify::misc-highlight-urls", @@ -437,6 +438,7 @@ gchar *text; gint argc; gint n; + GtkWidget *screen; switch (info) { @@ -564,6 +566,15 @@ g_value_unset (&value); } break; + case TARGET_GTK_NOTEBOOK_TAB: + /* 'send' the drag to the parent widget (TerminalScreen) */ + screen = gtk_widget_get_parent (widget); + if (G_LIKELY (screen)) + { + g_signal_emit_by_name (G_OBJECT (screen), "drag_data_received", context, + x, y, selection_data, info, time); + } + break; } } Index: terminal/terminal-tab-header.c =================================================================== --- terminal/terminal-tab-header.c (revision 26104) +++ terminal/terminal-tab-header.c (working copy) @@ -78,21 +78,8 @@ void (*set_title) (TerminalTabHeader *header); }; -struct _TerminalTabHeader -{ - GtkHBox __parent__; - TerminalPreferences *preferences; - GtkWidget *ebox; - GtkWidget *label; - - /* the popup menu */ - GtkWidget *menu; -}; - - - static guint header_signals[LAST_SIGNAL]; @@ -185,6 +172,8 @@ header->preferences = terminal_preferences_get (); + header->tab_pos_binding = NULL; + gtk_widget_push_composite_child (); header->ebox = g_object_new (GTK_TYPE_EVENT_BOX, "border-width", 2, NULL); @@ -377,7 +366,7 @@ /** * terminal_tab_header_new: - * + * * Allocates a new #TerminalTabHeader object. * * Return value : Pointer to the allocated #TerminalTabHeader object. Index: terminal/terminal-preferences-dialog.c =================================================================== --- terminal/terminal-preferences-dialog.c (revision 26104) +++ terminal/terminal-preferences-dialog.c (working copy) @@ -171,7 +171,7 @@ gtk_box_pack_start (GTK_BOX (hbox), dialog->notebook, TRUE, TRUE, 0); gtk_widget_show (dialog->notebook); - + /* General */ @@ -187,7 +187,7 @@ label = g_object_new (GTK_TYPE_LABEL, "label", _("Title"), "use-markup", TRUE, NULL); gtk_frame_set_label_widget (GTK_FRAME (frame), label); gtk_widget_show (label); - + table = gtk_table_new (2, 2, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 6); gtk_table_set_col_spacings (GTK_TABLE (table), 12); @@ -226,16 +226,14 @@ hbox = gtk_hbox_new (FALSE, 0); gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show (hbox); - + combo = gtk_combo_box_new_text (); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Replaces initial title")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Goes before initial title")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Goes after initial title")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Isn't displayed")); exo_mutual_binding_new (G_OBJECT (dialog->preferences), "title-mode", G_OBJECT (combo), "active"); -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif + gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, TRUE, 0); gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); gtk_widget_show (combo); @@ -318,9 +316,7 @@ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("On the left side")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("On the right side")); exo_mutual_binding_new (G_OBJECT (dialog->preferences), "scrolling-bar", G_OBJECT (combo), "active"); -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif + gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); gtk_widget_show (combo); @@ -422,9 +418,6 @@ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Background image")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Transparent background")); exo_mutual_binding_new (G_OBJECT (dialog->preferences), "background-mode", G_OBJECT (combo), "active"); -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, TRUE, 0); gtk_widget_show (combo); @@ -473,9 +466,6 @@ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Scaled")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Stretched")); exo_mutual_binding_new (G_OBJECT (dialog->preferences), "background-image-style", G_OBJECT (combo), "active"); -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); gtk_widget_show (combo); @@ -522,7 +512,7 @@ label = g_object_new (GTK_TYPE_LABEL, "label", _("Opening New Windows"), "use-markup", TRUE, NULL); gtk_frame_set_label_widget (GTK_FRAME (frame), label); gtk_widget_show (label); - + vbox = gtk_vbox_new (FALSE, 6); gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); gtk_container_add (GTK_CONTAINER (frame), vbox); @@ -881,9 +871,6 @@ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Escape sequence")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Control-H")); exo_mutual_binding_new (G_OBJECT (dialog->preferences), "binding-backspace", G_OBJECT (combo), "active"); -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0); gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); gtk_widget_show (combo); @@ -902,9 +889,6 @@ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Escape sequence")); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Control-H")); exo_mutual_binding_new (G_OBJECT (dialog->preferences), "binding-delete", G_OBJECT (combo), "active"); -#if !GTK_CHECK_VERSION(2,9,0) - g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (g_object_notify), "active"); -#endif gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 0, 0); gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); gtk_widget_show (combo); @@ -1095,7 +1079,7 @@ if (G_LIKELY (spec != NULL)) { g_value_init (&value, spec->value_type); - g_param_value_set_default (spec, &value); + g_param_value_set_default (spec, &value); g_object_set_property (G_OBJECT (dialog->preferences), "binding-backspace", &value); g_value_unset (&value); } @@ -1105,7 +1089,7 @@ if (G_LIKELY (spec != NULL)) { g_value_init (&value, spec->value_type); - g_param_value_set_default (spec, &value); + g_param_value_set_default (spec, &value); g_object_set_property (G_OBJECT (dialog->preferences), "binding-delete", &value); g_value_unset (&value); } @@ -1115,7 +1099,7 @@ if (G_LIKELY (spec != NULL)) { g_value_init (&value, spec->value_type); - g_param_value_set_default (spec, &value); + g_param_value_set_default (spec, &value); g_object_set_property (G_OBJECT (dialog->preferences), "term", &value); g_value_unset (&value); } @@ -1133,7 +1117,7 @@ terminal_preferences_dialog_new (GtkWindow *parent) { GtkWidget *dialog; - + dialog = g_object_new (TERMINAL_TYPE_PREFERENCES_DIALOG, NULL); if (parent != NULL) gtk_window_set_transient_for (GTK_WINDOW (dialog), parent); Index: terminal/terminal-tab-header.h =================================================================== --- terminal/terminal-tab-header.h (revision 26104) +++ terminal/terminal-tab-header.h (working copy) @@ -36,6 +36,21 @@ typedef struct _TerminalTabHeaderClass TerminalTabHeaderClass; typedef struct _TerminalTabHeader TerminalTabHeader; +struct _TerminalTabHeader +{ + GtkHBox __parent__; + + TerminalPreferences *preferences; + + GtkWidget *ebox; + GtkWidget *label; + + /* the popup menu */ + GtkWidget *menu; + + ExoBinding *tab_pos_binding; +}; + GType terminal_tab_header_get_type (void) G_GNUC_CONST; GtkWidget *terminal_tab_header_new (void); Index: terminal/terminal-window.c =================================================================== --- terminal/terminal-window.c (revision 26104) +++ terminal/terminal-window.c (working copy) @@ -36,6 +36,9 @@ #ifdef HAVE_UNISTD_H #include #endif +#ifdef HAVE_STRING_H +#include +#endif #include @@ -54,9 +57,11 @@ #include #include #include +#include #include #include #include +#include @@ -84,14 +89,14 @@ static void terminal_window_show (GtkWidget *widget); static gboolean terminal_window_confirm_close (TerminalWindow *window); static void terminal_window_queue_reset_size (TerminalWindow *window); -static gboolean terminal_window_reset_size (TerminalWindow *window); -static void terminal_window_reset_size_destroy (TerminalWindow *window); +static void terminal_window_update_geometry (TerminalWindow *window, + TerminalScreen *screen); static void terminal_window_set_size_force_grid (TerminalWindow *window, TerminalScreen *screen, gint force_grid_width, gint force_grid_height); -static void terminal_window_update_geometry (TerminalWindow *window, - TerminalScreen *screen); +static gboolean terminal_window_reset_size (TerminalWindow *window); +static void terminal_window_reset_size_destroy (TerminalWindow *window); static void terminal_window_update_actions (TerminalWindow *window); static void terminal_window_update_mnemonics (TerminalWindow *window); static void terminal_window_rebuild_gomenu (TerminalWindow *window); @@ -99,16 +104,31 @@ static void terminal_window_page_notified (GtkNotebook *notebook, GParamSpec *pspec, TerminalWindow *window); -static void terminal_window_page_switched (GtkNotebook *notebook, +static void terminal_window_page_reordered (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, TerminalWindow *window); -#if GTK_CHECK_VERSION (2,10,0) -static void terminal_window_page_reordered (GtkNotebook *notebook, - GtkNotebookPage *page, +static void terminal_window_page_added (GtkNotebook *notebook, + GtkWidget *child, guint page_num, TerminalWindow *window); -#endif +static void terminal_window_page_removed (GtkNotebook *notebook, + GtkWidget *child, + guint page_num, + TerminalWindow *window); +static void terminal_window_page_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time, + TerminalWindow *window); +static void terminal_window_page_detach (GtkNotebook *notebook, + GtkWidget *child, + gint x, + gint y, + TerminalWindow *window); static GtkWidget *terminal_window_get_context_menu (TerminalScreen *screen, TerminalWindow *window); static void terminal_window_detach_screen (TerminalWindow *window, @@ -116,9 +136,6 @@ static void terminal_window_notify_title (TerminalScreen *screen, GParamSpec *pspec, TerminalWindow *window); -static void terminal_window_screen_removed (GtkNotebook *notebook, - TerminalScreen *screen, - TerminalWindow *window); static void terminal_window_action_new_tab (GtkAction *action, TerminalWindow *window); static void terminal_window_action_new_window (GtkAction *action, @@ -143,26 +160,28 @@ TerminalWindow *window); static void terminal_window_action_show_toolbars (GtkToggleAction *action, TerminalWindow *window); -static void terminal_window_action_show_borders (GtkToggleAction *action, - TerminalWindow *window); -static void terminal_window_action_fullscreen (GtkToggleAction *action, - TerminalWindow *window); -static void terminal_window_action_prev_tab (GtkAction *action, - TerminalWindow *window); -static void terminal_window_action_next_tab (GtkAction *action, - TerminalWindow *window); -static void terminal_window_action_set_title (GtkAction *action, - TerminalWindow *window); -static void terminal_window_action_reset (GtkAction *action, - TerminalWindow *window); -static void terminal_window_action_reset_and_clear (GtkAction *action, - TerminalWindow *window); -static void terminal_window_action_contents (GtkAction *action, - TerminalWindow *window); -static void terminal_window_action_report_bug (GtkAction *action, - TerminalWindow *window); -static void terminal_window_action_about (GtkAction *action, - TerminalWindow *window); +static void terminal_window_action_show_borders (GtkToggleAction *action, + TerminalWindow *window); +static void terminal_window_action_fullscreen (GtkToggleAction *action, + TerminalWindow *window); +static void terminal_window_action_prev_tab (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_next_tab (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_goto (GtkRadioAction *action, + GtkNotebook *notebook); +static void terminal_window_action_set_title (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_reset (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_reset_and_clear (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_contents (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_report_bug (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_about (GtkAction *action, + TerminalWindow *window); @@ -177,27 +196,29 @@ GtkActionGroup *action_group; GtkUIManager *ui_manager; - + GtkWidget *menubar; GtkWidget *toolbars; GtkWidget *notebook; - GtkWidget *gomenu; - guint reset_size_idle_id; + guint gomenu_merge_id; }; static guint window_signals[LAST_SIGNAL]; +#if GTK_CHECK_VERSION (2,12,0) +static gpointer window_notebook_group = "Terminal"; +#endif 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), }, @@ -241,7 +262,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; @@ -271,9 +292,10 @@ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (TerminalWindowClass, new_window_with_screen), NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - G_TYPE_OBJECT); + _terminal_marshal_VOID__OBJECT_INT_INT, + G_TYPE_NONE, 3, + G_TYPE_OBJECT, + G_TYPE_INT, G_TYPE_INT); } @@ -283,13 +305,11 @@ { GtkAccelGroup *accel_group; GtkAction *action; - GtkWidget *item; GtkWidget *vbox; gboolean bval; - GError *error = NULL; gchar *role; - gchar *file; + window->gomenu_merge_id = 0; window->preferences = terminal_preferences_get (); /* The Terminal size needs correction when the font name or the scrollbar @@ -303,39 +323,14 @@ G_CALLBACK (terminal_window_update_mnemonics), window); window->action_group = gtk_action_group_new ("terminal-window"); - gtk_action_group_set_translation_domain (window->action_group, - GETTEXT_PACKAGE); - gtk_action_group_add_actions (window->action_group, - action_entries, - G_N_ELEMENTS (action_entries), - GTK_WIDGET (window)); - gtk_action_group_add_toggle_actions (window->action_group, - toggle_action_entries, - G_N_ELEMENTS (toggle_action_entries), - GTK_WIDGET (window)); + gtk_action_group_set_translation_domain (window->action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions (window->action_group, action_entries, G_N_ELEMENTS (action_entries), GTK_WIDGET (window)); + gtk_action_group_add_toggle_actions (window->action_group, toggle_action_entries, G_N_ELEMENTS (toggle_action_entries), GTK_WIDGET (window)); window->ui_manager = gtk_ui_manager_new (); gtk_ui_manager_insert_action_group (window->ui_manager, window->action_group, 0); + gtk_ui_manager_add_ui_from_string (window->ui_manager, terminal_window_ui, terminal_window_ui_length, NULL); - xfce_resource_push_path (XFCE_RESOURCE_DATA, DATADIR); - file = xfce_resource_lookup (XFCE_RESOURCE_DATA, "Terminal/Terminal.ui"); - xfce_resource_pop_path (XFCE_RESOURCE_DATA); - - if (G_LIKELY (file != NULL)) - { - if (gtk_ui_manager_add_ui_from_file (window->ui_manager, file, &error) == 0) - { - g_warning ("Unable to load %s: %s", file, error->message); - g_error_free (error); - } - gtk_ui_manager_ensure_update (window->ui_manager); - g_free (file); - } - else - { - g_warning ("Unable to locate Terminal/Terminal.ui, the menus won't be available"); - } - accel_group = gtk_ui_manager_get_accel_group (window->ui_manager); gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); @@ -350,23 +345,6 @@ gtk_widget_show (window->menubar); } - /* determine if we have a "Go" menu */ - item = gtk_ui_manager_get_widget (window->ui_manager, "/main-menu/go-menu"); - if (GTK_IS_MENU_ITEM (item)) - { - window->gomenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (item)); - if (G_LIKELY (window->gomenu != NULL)) - { - /* required for gtk_menu_item_set_accel_path() later */ - gtk_menu_set_accel_group (GTK_MENU (window->gomenu), accel_group); - - /* add an explicit separator */ - item = gtk_separator_menu_item_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (window->gomenu), item); - gtk_widget_show (item); - } - } - /* setup mnemonics */ g_object_get (G_OBJECT (window->preferences), "shortcuts-no-mnemonics", &bval, NULL); if (G_UNLIKELY (bval)) @@ -394,16 +372,26 @@ "tab-vborder", 0, NULL); exo_binding_new (G_OBJECT (window->preferences), "misc-tab-position", G_OBJECT (window->notebook), "tab-pos"); - g_signal_connect_after (G_OBJECT (window->notebook), "switch-page", - G_CALLBACK (terminal_window_page_switched), window); + + /* set the notebook group id */ +#if GTK_CHECK_VERSION (2,12,0) + gtk_notebook_set_group (GTK_NOTEBOOK (window->notebook), window_notebook_group); +#else + gtk_notebook_set_group_id (GTK_NOTEBOOK (window->notebook), 1); +#endif + + /* signals */ g_signal_connect (G_OBJECT (window->notebook), "notify::page", G_CALLBACK (terminal_window_page_notified), window); - g_signal_connect (G_OBJECT (window->notebook), "remove", - G_CALLBACK (terminal_window_screen_removed), window); - -#if GTK_CHECK_VERSION (2,10,0) 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); +#if GTK_CHECK_VERSION (2,12,0) + g_signal_connect (G_OBJECT (window->notebook), "create-window", + G_CALLBACK (terminal_window_page_detach), window); #endif gtk_box_pack_start (GTK_BOX (vbox), window->notebook, TRUE, TRUE, 0); @@ -604,13 +592,39 @@ +static void +terminal_window_update_geometry (TerminalWindow *window, + TerminalScreen *screen) +{ + terminal_screen_set_window_geometry_hints (screen, GTK_WINDOW (window)); +} + + + +static void +terminal_window_set_size_force_grid (TerminalWindow *window, + TerminalScreen *screen, + gint force_grid_width, + gint force_grid_height) +{ + /* Required to get the char height/width right */ + if (!GTK_WIDGET_REALIZED (GTK_WIDGET (screen))) + gtk_widget_realize (GTK_WIDGET (screen)); + + terminal_window_update_geometry (window, screen); + terminal_screen_force_resize_window (screen, GTK_WINDOW (window), + force_grid_width, force_grid_height); +} + + + static gboolean terminal_window_reset_size (TerminalWindow *window) { 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. @@ -618,8 +632,15 @@ active = terminal_window_get_active (window); if (G_LIKELY (active != NULL)) { + if (!GTK_WIDGET_REALIZED (GTK_WIDGET (active))) + gtk_widget_realize (GTK_WIDGET (active)); + terminal_screen_get_size (active, &grid_width, &grid_height); + terminal_window_set_size_force_grid (window, active, grid_width, grid_height); + + //~ terminal_screen_force_resize_window (active, GTK_WINDOW (window), + //~ grid_width, grid_height); } return FALSE; @@ -636,38 +657,11 @@ static void -terminal_window_set_size_force_grid (TerminalWindow *window, - TerminalScreen *screen, - gint force_grid_width, - gint force_grid_height) -{ - /* Required to get the char height/width right */ - if (!GTK_WIDGET_REALIZED (GTK_WIDGET (screen))) - gtk_widget_realize (GTK_WIDGET (screen)); - - terminal_window_update_geometry (window, screen); - terminal_screen_force_resize_window (screen, GTK_WINDOW (window), - force_grid_width, force_grid_height); -} - - - -static void -terminal_window_update_geometry (TerminalWindow *window, - TerminalScreen *screen) -{ - terminal_screen_set_window_geometry_hints (screen, GTK_WINDOW (window)); -} - - - -static void terminal_window_update_actions (TerminalWindow *window) { TerminalScreen *terminal; GtkNotebook *notebook = GTK_NOTEBOOK (window->notebook); GtkAction *action; - GtkWidget *tabitem; gboolean cycle_tabs; gint page_num; gint n_pages; @@ -703,9 +697,9 @@ gtk_action_set_sensitive (action, terminal_screen_has_selection (terminal)); /* update the "Go" menu */ - tabitem = g_object_get_data (G_OBJECT (terminal), "terminal-window-go-menu-item"); - if (G_LIKELY (tabitem != NULL)) - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (tabitem), TRUE); + action = g_object_get_data (G_OBJECT (terminal), I_("terminal-window-go-menu-action")); + if (G_LIKELY (action != NULL)) + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); } } @@ -750,94 +744,82 @@ static void -item_destroy (gpointer item) +terminal_window_rebuild_gomenu (TerminalWindow *window) { - gtk_widget_destroy (GTK_WIDGET (item)); - g_object_unref (G_OBJECT (item)); -} + gint npages, n; + GtkWidget *screen; + GtkRadioAction *action; + gchar name[32]; + gchar *path; + GSList *group = NULL; + GList *actions, *li; + /* cleanup */ + if (window->gomenu_merge_id != 0) + { + /* unmerge the old menu */ + gtk_ui_manager_remove_ui (window->ui_manager, window->gomenu_merge_id); - -static void -item_toggled (GtkWidget *item, - GtkNotebook *notebook) -{ - GtkWidget *screen; - gint page; - - if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item))) - { - screen = g_object_get_data (G_OBJECT (item), "terminal-window-screen"); - if (G_LIKELY (screen != NULL)) - { - page = gtk_notebook_page_num (notebook, screen); - gtk_notebook_set_current_page (notebook, page); - } + /* drop previous actions */ + actions = gtk_action_group_list_actions (window->action_group); + for (li = actions; li != NULL; li = li->next) + if (strncmp (gtk_action_get_name (li->data), "accel-switch-to-tab", 19) == 0) + gtk_action_group_remove_action (window->action_group, li->data); + g_list_free (actions); } -} + /* create a new merge id */ + window->gomenu_merge_id = gtk_ui_manager_new_merge_id (window->ui_manager); + /* walk through the notebook pages */ + npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); -static void -terminal_window_rebuild_gomenu (TerminalWindow *window) -{ - GtkWidget *terminal; - GtkWidget *label; - GtkWidget *item; - GSList *group = NULL; - gchar name[32]; - gchar *path; - gint npages; - gint n; - - 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); + screen = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), n); - /* Create the new radio menu item, and be sure to override - * the "can-activate-accel" method, which by default requires - * that the widget is on-screen, but we want the accelerators - * to work even if the menubar is hidden. - */ - item = gtk_radio_menu_item_new (group); - g_signal_connect (G_OBJECT (item), "can-activate-accel", G_CALLBACK (gtk_true), NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (window->gomenu), item); - gtk_widget_show (item); + /* create action name */ + g_snprintf (name, sizeof (name), "accel-switch-to-tab%d", n + 1); - label = g_object_new (GTK_TYPE_ACCEL_LABEL, "xalign", 0.0, NULL); - exo_binding_new (G_OBJECT (terminal), "title", G_OBJECT (label), "label"); - gtk_container_add (GTK_CONTAINER (item), label); - gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), item); - gtk_widget_show (label); + /* create a new action */ + action = gtk_radio_action_new (name, NULL, NULL, NULL, n); + exo_binding_new (G_OBJECT (screen), "title", G_OBJECT (action), "label"); + gtk_radio_action_set_group (action, group); + group = gtk_radio_action_get_group (action); + /* connect to the screen */ + g_object_set_data (G_OBJECT (screen), I_("terminal-window-go-menu-action"), action); + /* only connect an accelerator if we have a preference for this item */ - g_snprintf (name, 32, "accel-switch-to-tab%d", n + 1); if (g_object_class_find_property (G_OBJECT_GET_CLASS (window->preferences), name) != NULL) { /* connect the menu item to an accelerator */ path = g_strconcat ("/terminal-window/", name + 6, NULL); - gtk_menu_item_set_accel_path (GTK_MENU_ITEM (item), path); + gtk_action_set_accel_path (GTK_ACTION (action), path); g_free (path); } + /* add the action to the action group */ + gtk_action_group_add_action (window->action_group, GTK_ACTION (action)); + + /* select the active action */ if (gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook)) == n) - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); - /* keep an extra ref terminal -> item, so we don't in trouble with gtk_widget_destroy */ - g_object_set_data_full (G_OBJECT (terminal), I_("terminal-window-go-menu-item"), - G_OBJECT (item), (GDestroyNotify) item_destroy); - g_object_ref (G_OBJECT (item)); + /* connect signal */ + g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (terminal_window_action_goto), window->notebook); - /* do the item -> terminal connects */ - g_object_set_data (G_OBJECT (item), I_("terminal-window-screen"), terminal); - g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (item_toggled), window->notebook); + /* release the action */ + g_object_unref (G_OBJECT (action)); - group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); + /* add the action to the go menu */ + gtk_ui_manager_add_ui (window->ui_manager, window->gomenu_merge_id, + "/main-menu/go-menu/placeholder-go-items", + name, name, GTK_UI_MANAGER_MENUITEM, FALSE); } + + /* be sure to update the UI manager to avoid flickering */ + gtk_ui_manager_ensure_update (window->ui_manager); } @@ -845,7 +827,17 @@ static gboolean terminal_window_delete_event (TerminalWindow *window) { - return !terminal_window_confirm_close (window); + gboolean result; + + /* get close confirmation from the user */ + result = terminal_window_confirm_close (window); + + /* disconnect remove signal if we're closing the window */ + if (result) + g_signal_handlers_disconnect_by_func (G_OBJECT (window->notebook), + G_CALLBACK (terminal_window_page_removed), window); + + return !result; } @@ -872,55 +864,268 @@ static void -terminal_window_page_switched (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num, - TerminalWindow *window) +terminal_window_page_reordered (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num, + TerminalWindow *window) { - TerminalScreen *terminal; - gint grid_width; - gint grid_height; - terminal = terminal_window_get_active (window); - if (G_LIKELY (terminal != NULL)) + /* Regenerate the "Go" menu */ + terminal_window_rebuild_gomenu (window); +} + + + +static void +terminal_window_notebook_visibility (TerminalWindow *window) +{ + TerminalScreen *active; + gboolean always_show_tabs, tabs_shown; + gint npages; + gint grid_width, grid_height; + + /* check if we should always display tabs */ + g_object_get (G_OBJECT (window->preferences), "misc-always-show-tabs", &always_show_tabs, NULL); + + /* current notebook status */ + tabs_shown = gtk_notebook_get_show_tabs (GTK_NOTEBOOK (window->notebook)); + npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); + + /* change the visibility if the new status differs */ + if (((npages > 1) != tabs_shown) || (always_show_tabs && !tabs_shown)) { - /* FIXME: This isn't really needed anymore, instead we - * could grab the grid size of the previously selected - * page and apply that to the newly selected page. - */ + /* get active screen */ + active = terminal_window_get_active (window); - /* This is a bit tricky, but seems to be necessary to get the - * sizing correct: First we query the current terminal size - * (rows x columns), then we force a size update on the terminal - * window (which may reset the terminal size). Afterwards we - * reset the terminal screen size to the original values and - * resize the terminal window accordingly. - */ - terminal_screen_get_size (terminal, &grid_width, &grid_height); - terminal_screen_set_size (terminal, grid_width, grid_height); - terminal_window_set_size_force_grid (window, terminal, grid_width, grid_height); + /* get screen grid size */ + terminal_screen_get_size (active, &grid_width, &grid_height); + + /* show or hide the tabs */ + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), !tabs_shown); + + /* don't focus the notebook */ + GTK_WIDGET_UNSET_FLAGS (window->notebook, GTK_CAN_FOCUS); + + /* resize the window */ + terminal_screen_force_resize_window (active, GTK_WINDOW (window), grid_width, grid_height); } } -#if GTK_CHECK_VERSION (2,10,0) static void -terminal_window_page_reordered (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num, - TerminalWindow *window) +terminal_window_page_added (GtkNotebook *notebook, + GtkWidget *child, + guint page_num, + TerminalWindow *window) { - - /* Regenerate the "Go" menu. - * This also updates the accelerators. - */ + gint grid_width, grid_height; + GtkAction *action; + TerminalTabHeader *header; + TerminalScreen *active; + + _terminal_return_if_fail (TERMINAL_IS_SCREEN (child)); + _terminal_return_if_fail (TERMINAL_IS_WINDOW (window)); + + /* get tab header */ + header = g_object_get_data (G_OBJECT (child), I_("terminal-tab-header")); + + _terminal_return_if_fail (TERMINAL_IS_TAB_HEADER (header)); + + /* tab position binding */ + header->tab_pos_binding = exo_binding_new (G_OBJECT (window->notebook), "tab-pos", G_OBJECT (header), "tab-pos"); + + /* connect screen signals */ + g_signal_connect (G_OBJECT (child), "get-context-menu", G_CALLBACK (terminal_window_get_context_menu), window); + g_signal_connect (G_OBJECT (child), "notify::title", G_CALLBACK (terminal_window_notify_title), window); + g_signal_connect_swapped (G_OBJECT (child), "selection-changed", G_CALLBACK (terminal_window_update_actions), window); + g_signal_connect (G_OBJECT (child), "drag-data-received", G_CALLBACK (terminal_window_page_drag_data_received), window); + + /* get action from window action group */ + action = gtk_action_group_get_action (window->action_group, "set-title"); + + /* connect tab label signals */ + 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); + + /* set visibility of the notebook */ + terminal_window_notebook_visibility (window); + + /* get the active tab */ + active = terminal_window_get_active (window); + if (G_LIKELY (active != NULL)) + { + /* set new screen grid size based on the old one */ + terminal_screen_get_size (active, &grid_width, &grid_height); + terminal_screen_set_size (TERMINAL_SCREEN (child), grid_width, grid_height); + } + else + { + /* set the window size (needed for resizing) */ + terminal_screen_get_size (TERMINAL_SCREEN (child), &grid_width, &grid_height); + terminal_window_set_size_force_grid (window, TERMINAL_SCREEN (child), grid_width, grid_height); + } + + /* 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_page_removed (GtkNotebook *notebook, + GtkWidget *child, + guint page_num, + TerminalWindow *window) +{ + TerminalTabHeader *header; + GtkAction *action; + gint npages; + + _terminal_return_if_fail (TERMINAL_IS_SCREEN (child)); + _terminal_return_if_fail (TERMINAL_IS_WINDOW (window)); + _terminal_return_if_fail (header->tab_pos_binding != NULL); + + /* get header */ + header = g_object_get_data (G_OBJECT (child), I_("terminal-tab-header")); + + /* get old window action */ + action = gtk_action_group_get_action (window->action_group, "set-title"); + + /* disconnect signals */ + g_signal_handlers_disconnect_by_func (G_OBJECT (child), terminal_window_get_context_menu, window); + g_signal_handlers_disconnect_by_func (G_OBJECT (child), terminal_window_notify_title, window); + g_signal_handlers_disconnect_by_func (G_OBJECT (child), terminal_window_update_actions, window); + g_signal_handlers_disconnect_by_func (G_OBJECT (child), terminal_window_page_drag_data_received, window); + g_signal_handlers_disconnect_by_func (G_OBJECT (header), terminal_window_detach_screen, window); + g_signal_handlers_disconnect_by_func (G_OBJECT (header), gtk_action_activate, action); + + /* remove exo binding */ + exo_binding_unbind (header->tab_pos_binding); + + /* set tab visibility */ + npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); + if (G_UNLIKELY (npages == 0)) + { + /* no tabs, destroy the window */ + gtk_widget_destroy (GTK_WIDGET (window)); + } + else + { + /* set visibility of the notebook */ + terminal_window_notebook_visibility (window); + + /* 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_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time, + TerminalWindow *window) +{ + GtkWidget *source_widget; + GtkWidget **screen; + GtkWidget *child, *label; + gint i, n_pages; + + _terminal_return_if_fail (TERMINAL_IS_WINDOW (window)); + + /* get the source notebook (other window) */ + source_widget = gtk_drag_get_source_widget (context); + + /* get the dragged screen */ + screen = (GtkWidget **) selection_data->data; + + /* check */ + if (source_widget && TERMINAL_IS_SCREEN (*screen)) + { + /* take a reference */ + g_object_ref (G_OBJECT (*screen)); + + /* remove the document from the source notebook */ + gtk_container_remove (GTK_CONTAINER (source_widget), *screen); + + /* get the number of pages in the new window */ + n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); + + /* figure out where to insert the tab in the notebook */ + for (i = 0; i < n_pages; i++) + { + /* get the child label */ + child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), i); + label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (window->notebook), child); + + /* break if we have a matching drop position */ + if (x < (label->allocation.x + label->allocation.width / 2)) + break; + } + + /* add the screen to the new window */ + terminal_window_add (window, TERMINAL_SCREEN (*screen)); + + /* move the child to the correct position */ + gtk_notebook_reorder_child (GTK_NOTEBOOK (window->notebook), *screen, i); + + /* release reference */ + g_object_unref (G_OBJECT (*screen)); + + /* finish the drag */ + gtk_drag_finish (context, TRUE, TRUE, time); + } +} + + + +static void +terminal_window_page_detach (GtkNotebook *notebook, + GtkWidget *child, + gint x, + gint y, + TerminalWindow *window) +{ + TerminalScreen *screen; + + _terminal_return_if_fail (TERMINAL_IS_WINDOW (window)); + _terminal_return_if_fail (TERMINAL_IS_SCREEN (child)); + _terminal_return_if_fail (notebook == GTK_NOTEBOOK (window->notebook)); + + /* only create new window when there are more then 2 tabs (bug #2686) */ + if (gtk_notebook_get_n_pages (notebook) >= 2) + { + /* get the screen */ + screen = TERMINAL_SCREEN (child); + + /* take a reference */ + g_object_ref (G_OBJECT (screen)); + + /* remove screen from active window */ + gtk_container_remove (GTK_CONTAINER (window->notebook), child); + + /* create new window with the screen */ + g_signal_emit (G_OBJECT (window), window_signals[NEW_WINDOW_WITH_SCREEN], 0, screen, x, y); + + /* release our reference */ + g_object_unref (G_OBJECT (screen)); + } +} + + + static GtkWidget* terminal_window_get_context_menu (TerminalScreen *screen, TerminalWindow *window) @@ -961,20 +1166,10 @@ { GtkWidget *screen; - /* verify that we have atleast two tabs, otherwise we'll crash, - * see http://bugzilla.xfce.org/show_bug.cgi?id=2686. - */ - if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) >= 2) - { - screen = g_object_get_data (G_OBJECT (header), "terminal-window-screen"); - if (G_LIKELY (screen != NULL)) - { - g_object_ref (G_OBJECT (screen)); - gtk_container_remove (GTK_CONTAINER (window->notebook), screen); - g_signal_emit (G_OBJECT (window), window_signals[NEW_WINDOW_WITH_SCREEN], 0, screen); - g_object_unref (G_OBJECT (screen)); - } - } + /* get the screen */ + screen = g_object_get_data (G_OBJECT (header), I_("terminal-window-screen")); + if (G_LIKELY (screen != NULL)) + terminal_window_page_detach (GTK_NOTEBOOK (window->notebook), screen, -1, -1, window); } @@ -1000,50 +1195,6 @@ static void -terminal_window_screen_removed (GtkNotebook *notebook, - TerminalScreen *screen, - TerminalWindow *window) -{ - TerminalScreen *active; - gboolean always_show_tabs; - gint npages; - gint grid_width; - gint grid_height; - - npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); - if (G_UNLIKELY (npages == 0)) - { - gtk_widget_destroy (GTK_WIDGET (window)); - } - 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); - - active = terminal_window_get_active (window); - if (G_LIKELY (active != NULL)) - { - terminal_screen_get_size (screen, &grid_width, &grid_height); - terminal_window_set_size_force_grid (window, active, grid_width, grid_height); - } - - /* 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_action_new_tab (GtkAction *action, TerminalWindow *window) { @@ -1090,14 +1241,11 @@ { TerminalScreen *terminal; + /* get active terminal window */ terminal = terminal_window_get_active (window); + if (G_LIKELY (terminal != NULL)) - { - g_object_ref (G_OBJECT (terminal)); - gtk_container_remove (GTK_CONTAINER (window->notebook), GTK_WIDGET (terminal)); - g_signal_emit (G_OBJECT (window), window_signals[NEW_WINDOW_WITH_SCREEN], 0, terminal); - g_object_unref (G_OBJECT (terminal)); - } + terminal_window_page_detach (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (terminal), -1, -1, window); } @@ -1179,7 +1327,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))); @@ -1309,6 +1457,21 @@ static void +terminal_window_action_goto (GtkRadioAction *action, + GtkNotebook *notebook) +{ + gint page; + + /* get the page number from the action value */ + page = gtk_radio_action_get_current_value (action); + + /* set the page */ + gtk_notebook_set_current_page (notebook, page); +} + + + +static void title_dialog_response (GtkWidget *dialog, gint response) { @@ -1460,7 +1623,7 @@ TerminalWindow *window; GtkAction *action; gboolean setting; - + window = g_object_new (TERMINAL_TYPE_WINDOW, NULL); /* setup full screen */ @@ -1508,77 +1671,29 @@ terminal_window_add (TerminalWindow *window, TerminalScreen *screen) { - TerminalScreen *active; GtkWidget *header; - GtkAction *action; - gboolean always_show_tabs; - gint npages; gint page; - gint grid_width; - gint grid_height; _terminal_return_if_fail (TERMINAL_IS_WINDOW (window)); _terminal_return_if_fail (TERMINAL_IS_SCREEN (screen)); - active = terminal_window_get_active (window); - if (G_LIKELY (active != NULL)) - { - terminal_screen_get_size (active, &grid_width, &grid_height); - terminal_screen_set_size (screen, grid_width, grid_height); - } - - action = gtk_action_group_get_action (window->action_group, "set-title"); - 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); - 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); g_object_set_data_full (G_OBJECT (header), I_("terminal-window-screen"), g_object_ref (G_OBJECT (screen)), (GDestroyNotify) g_object_unref); + g_object_set_data_full (G_OBJECT (screen), I_("terminal-tab-header"), g_object_ref (G_OBJECT (header)), (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); + 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) - gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (window->notebook), - GTK_WIDGET (screen), - TRUE); -#endif + /* allow tab sorting and dnd */ + gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (screen), TRUE); + gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (screen), TRUE); - /* 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); - - g_signal_connect (G_OBJECT (screen), "get-context-menu", - G_CALLBACK (terminal_window_get_context_menu), window); - g_signal_connect (G_OBJECT (screen), "notify::title", - G_CALLBACK (terminal_window_notify_title), window); - g_signal_connect_swapped (G_OBJECT (screen), "selection-changed", - G_CALLBACK (terminal_window_update_actions), window); - - terminal_window_rebuild_gomenu (window); - - /* need to save the grid size here for detached screens */ - terminal_screen_get_size (screen, &grid_width, &grid_height); - /* need to show this first, else we cannot switch to it */ gtk_widget_show (GTK_WIDGET (screen)); gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), page); - - terminal_window_set_size_force_grid (window, screen, grid_width, grid_height); - - gtk_widget_queue_draw (GTK_WIDGET (screen)); } Index: terminal/terminal-window.h =================================================================== --- terminal/terminal-window.h (revision 26104) +++ terminal/terminal-window.h (working copy) @@ -44,7 +44,9 @@ void (*new_window) (TerminalWindow *window, const gchar *working_directory); void (*new_window_with_screen) (TerminalWindow *window, - TerminalScreen *screen); + TerminalScreen *screen, + gint x, + gint y); }; GType terminal_window_get_type (void) G_GNUC_CONST; Index: terminal/Makefile.am =================================================================== --- terminal/Makefile.am (revision 26104) +++ terminal/Makefile.am (working copy) @@ -42,7 +42,8 @@ terminal-toolbars-model.h \ terminal-toolbars-view.h \ terminal-widget.h \ - terminal-window.h + terminal-window.h \ + terminal-window-ui.h Terminal_SOURCES = \ $(Terminal_built_sources) \ @@ -94,6 +95,7 @@ if HAVE_DBUS Terminal_CFLAGS += \ -DDBUS_API_SUBJECT_TO_CHANGE + Terminal_SOURCES += \ $(Terminal_dbus_sources) endif @@ -118,11 +120,16 @@ DISTCLEANFILES = \ stamp-terminal-enum-types.h \ stamp-terminal-marshal.h \ + terminal-window-ui.h \ $(Terminal_built_sources) BUILT_SOURCES = \ + terminal-window-ui.h \ $(Terminal_built_sources) +terminal-window-ui.h: Makefile $(srcdir)/terminal-window-ui.xml + exo-csource --strip-comments --strip-content --static --name=terminal_window_ui $(srcdir)/terminal-window-ui.xml > terminal-window-ui.h + terminal-enum-types.h: stamp-terminal-enum-types.h @true stamp-terminal-enum-types.h: $(Terminal_headers) Makefile @@ -170,6 +177,7 @@ EXTRA_DIST = \ terminal-config.h.in \ - terminal-marshal.list + terminal-marshal.list \ + terminal-window-ui.xml # vi:set ts=8 sw=8 noet ai nocindent: Index: terminal/terminal-app.c =================================================================== --- terminal/terminal-app.c (revision 26104) +++ terminal/terminal-app.c (working copy) @@ -60,6 +60,8 @@ TerminalApp *app); static void terminal_app_new_window_with_terminal (TerminalWindow *window, TerminalScreen *terminal, + gint x, + gint y, TerminalApp *app); static void terminal_app_window_destroyed (GtkWidget *window, TerminalApp *app); @@ -105,7 +107,7 @@ terminal_app_class_init (TerminalAppClass *klass) { GObjectClass *gobject_class; - + gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = terminal_app_finalize; } @@ -170,7 +172,7 @@ const gchar *accel; gboolean shortcuts_no_menukey; - g_object_get (G_OBJECT (app->preferences), + g_object_get (G_OBJECT (app->preferences), "shortcuts-no-menukey", &shortcuts_no_menukey, NULL); @@ -253,6 +255,8 @@ static void terminal_app_new_window_with_terminal (TerminalWindow *existing, TerminalScreen *terminal, + gint x, + gint y, TerminalApp *app) { GtkWidget *window; @@ -263,6 +267,10 @@ TERMINAL_VISIBILITY_DEFAULT, TERMINAL_VISIBILITY_DEFAULT); + /* set new window position */ + if (x > -1 && y > -1) + gtk_window_move (GTK_WINDOW (window), x, y); + /* place the new window on the same screen as * the existing window. */ @@ -347,9 +355,7 @@ terminal_app_find_screen (const gchar *display_name) { const gchar *other_name; -#if GTK_CHECK_VERSION(2,10,0) GdkColormap *colormap; -#endif GdkDisplay *display = NULL; GdkScreen *screen = NULL; GSList *displays; @@ -410,7 +416,6 @@ g_object_ref (G_OBJECT (screen)); } -#if GTK_CHECK_VERSION(2,10,0) /* check if we already checked this screen */ if (g_object_get_data (G_OBJECT (screen), "terminal-checked-screen") == NULL) { @@ -427,7 +432,6 @@ /* mark this screen as handled */ g_object_set_data (G_OBJECT (screen), I_("terminal-checked-screen"), GINT_TO_POINTER (1)); } -#endif return screen; }