1 /*-
2  * Copyright (c) 2004-2008 os-cillation e.K.
3  *
4  * Written by Benedikt Meurer <benny@xfce.org>.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 2 of the License, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 
24 #ifdef HAVE_SYS_TYPES_H
25 #include <sys/types.h>
26 #endif
27 
28 #ifdef HAVE_TIME_H
29 #include <time.h>
30 #endif
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 
35 #include <libxfce4ui/libxfce4ui.h>
36 
37 #if defined(GDK_WINDOWING_X11)
38 #include <gdk/gdkx.h>
39 #endif
40 
41 #include <terminal/terminal-util.h>
42 #include <terminal/terminal-enum-types.h>
43 #include <terminal/terminal-options.h>
44 #include <terminal/terminal-preferences-dialog.h>
45 #include <terminal/terminal-search-dialog.h>
46 #include <terminal/terminal-private.h>
47 #include <terminal/terminal-marshal.h>
48 #include <terminal/terminal-encoding-action.h>
49 #include <terminal/terminal-window.h>
50 #include <terminal/terminal-window-dropdown.h>
51 #include <terminal/terminal-window-ui.h>
52 #include <terminal/terminal-widget.h>
53 
54 
55 
56 /* Signal identifiers */
57 enum
58 {
59   NEW_WINDOW,
60   NEW_WINDOW_WITH_SCREEN,
61   LAST_SIGNAL
62 };
63 
64 /* Used by confirm_close() */
65 enum
66 {
67   CONFIRMED_NONE,
68   CONFIRMED_CLOSE_TAB,
69   CONFIRMED_CLOSE_WINDOW
70 };
71 
72 /* CSS for slim notebook tabs style */
73 #define NOTEBOOK_NAME PACKAGE_NAME "-notebook"
74 const gchar *CSS_SLIM_TABS =
75 "#" NOTEBOOK_NAME " tab {\n"
76 "  min-height: 0;\n"
77 "  font-weight: normal;\n"
78 "  padding: 1px;\n"
79 "  margin: 0;\n"
80 "}\n"
81 "#" NOTEBOOK_NAME " tab button {\n"
82 "  min-height: 0;\n"
83 "  min-width: 0;\n"
84 "  padding: 1px;\n"
85 "  margin: 0;\n"
86 "}\n"
87 "#" NOTEBOOK_NAME " button {\n"
88 "  min-height: 0;\n"
89 "  min-width: 0;\n"
90 "  padding: 1px;\n"
91 "}\n";
92 
93 /* See gnome-terminal bug #789356 */
94 #if GTK_CHECK_VERSION (3, 22, 23)
95 #define WINDOW_STATE_TILED (GDK_WINDOW_STATE_TILED       | \
96                             GDK_WINDOW_STATE_LEFT_TILED  | \
97                             GDK_WINDOW_STATE_RIGHT_TILED | \
98                             GDK_WINDOW_STATE_TOP_TILED   | \
99                             GDK_WINDOW_STATE_BOTTOM_TILED)
100 #else
101 #define WINDOW_STATE_TILED (GDK_WINDOW_STATE_TILED)
102 #endif
103 
104 
105 
106 static void         terminal_window_finalize                      (GObject             *object);
107 static gboolean     terminal_window_delete_event                  (GtkWidget           *widget,
108                                                                    GdkEventAny         *event);
109 static gboolean     terminal_window_state_event                   (GtkWidget           *widget,
110                                                                    GdkEventWindowState *event);
111 static void         terminal_window_style_set                     (GtkWidget           *widget,
112                                                                    GtkStyle            *previous_style);
113 static gboolean     terminal_window_scroll_event                  (GtkWidget           *widget,
114                                                                    GdkEventScroll      *event);
115 static gboolean     terminal_window_map_event                     (GtkWidget           *widget,
116                                                                    GdkEventAny         *event);
117 static gboolean     terminal_window_focus_in_event                (GtkWidget           *widget,
118                                                                    GdkEventFocus       *event);
119 static gboolean     terminal_window_key_press_event               (GtkWidget           *widget,
120                                                                    GdkEventKey         *event);
121 static gint         terminal_window_confirm_close                 (TerminalScreen      *screen,
122                                                                    TerminalWindow      *window);
123 static void         terminal_window_size_push                     (TerminalWindow      *window);
124 static gboolean     terminal_window_size_pop                      (gpointer             data);
125 static void         terminal_window_set_size_force_grid           (TerminalWindow      *window,
126                                                                    TerminalScreen      *screen,
127                                                                    glong                force_grid_width,
128                                                                    glong                force_grid_height);
129 static void         terminal_window_update_actions                (TerminalWindow      *window);
130 static void         terminal_window_update_slim_tabs              (TerminalWindow      *window);
131 static void         terminal_window_update_scroll_on_output       (TerminalWindow      *window);
132 static void         terminal_window_update_mnemonic_modifier      (TerminalWindow      *window);
133 static void         terminal_window_notebook_page_switched        (GtkNotebook         *notebook,
134                                                                    GtkWidget           *page,
135                                                                    guint                page_num,
136                                                                    TerminalWindow      *window);
137 static void         terminal_window_notebook_page_reordered       (GtkNotebook         *notebook,
138                                                                    GtkWidget           *child,
139                                                                    guint                page_num,
140                                                                    TerminalWindow      *window);
141 static void         terminal_window_notebook_page_added           (GtkNotebook         *notebook,
142                                                                    GtkWidget           *child,
143                                                                    guint                page_num,
144                                                                    TerminalWindow      *window);
145 static void         terminal_window_notebook_page_removed         (GtkNotebook         *notebook,
146                                                                    GtkWidget           *child,
147                                                                    guint                page_num,
148                                                                    TerminalWindow      *window);
149 static gboolean     terminal_window_notebook_event_in_allocation  (gint                 event_x,
150                                                                    gint                 event_y,
151                                                                    GtkWidget           *widget);
152 static gboolean     terminal_window_notebook_button_press_event   (GtkNotebook         *notebook,
153                                                                    GdkEventButton      *event,
154                                                                    TerminalWindow      *window);
155 static gboolean     terminal_window_notebook_button_release_event (GtkNotebook         *notebook,
156                                                                    GdkEventButton      *event,
157                                                                    TerminalWindow      *window);
158 static gboolean     terminal_window_notebook_scroll_event         (GtkNotebook         *notebook,
159                                                                    GdkEventScroll      *event,
160                                                                    TerminalWindow      *window);
161 static void         terminal_window_notebook_drag_data_received   (GtkWidget           *widget,
162                                                                    GdkDragContext      *context,
163                                                                    gint                 x,
164                                                                    gint                 y,
165                                                                    GtkSelectionData    *selection_data,
166                                                                    guint                info,
167                                                                    guint                time,
168                                                                    TerminalWindow      *window);
169 static GtkNotebook *terminal_window_notebook_create_window        (GtkNotebook         *notebook,
170                                                                    GtkWidget           *child,
171                                                                    gint                 x,
172                                                                    gint                 y,
173                                                                    TerminalWindow      *window);
174 static GtkWidget   *terminal_window_get_context_menu              (TerminalScreen      *screen,
175                                                                    TerminalWindow      *window);
176 static void         terminal_window_notify_title                  (TerminalScreen      *screen,
177                                                                    GParamSpec          *pspec,
178                                                                    TerminalWindow      *window);
179 static void         terminal_window_action_set_encoding           (GtkAction           *action,
180                                                                    const gchar         *charset,
181                                                                    TerminalWindow      *window);
182 static void         terminal_window_action_new_tab                (GtkAction           *action,
183                                                                    TerminalWindow      *window);
184 static void         terminal_window_action_new_window             (GtkAction           *action,
185                                                                    TerminalWindow      *window);
186 static void         terminal_window_action_undo_close_tab         (GtkAction           *action,
187                                                                    TerminalWindow      *window);
188 static void         terminal_window_action_detach_tab             (GtkAction           *action,
189                                                                    TerminalWindow      *window);
190 static void         terminal_window_action_close_tab              (GtkAction           *action,
191                                                                    TerminalWindow      *window);
192 static void         terminal_window_action_close_other_tabs       (GtkAction           *action,
193                                                                    TerminalWindow      *window);
194 static void         terminal_window_action_close_window           (GtkAction           *action,
195                                                                    TerminalWindow      *window);
196 static void         terminal_window_action_copy                   (GtkAction           *action,
197                                                                    TerminalWindow      *window);
198 #if VTE_CHECK_VERSION (0, 49, 2)
199 static void         terminal_window_action_copy_html              (GtkAction           *action,
200                                                                    TerminalWindow      *window);
201 #endif
202 static void         terminal_window_action_paste                  (GtkAction           *action,
203                                                                    TerminalWindow      *window);
204 static void         terminal_window_action_paste_selection        (GtkAction           *action,
205                                                                    TerminalWindow      *window);
206 static void         terminal_window_action_select_all             (GtkAction           *action,
207                                                                    TerminalWindow      *window);
208 static void         terminal_window_action_copy_input             (GtkAction           *action,
209                                                                    TerminalWindow      *window);
210 static void         terminal_window_action_prefs                  (GtkAction           *action,
211                                                                    TerminalWindow      *window);
212 static void         terminal_window_action_show_toolbar           (GtkToggleAction     *action,
213                                                                    TerminalWindow      *window);
214 static void         terminal_window_action_show_borders           (GtkToggleAction     *action,
215                                                                    TerminalWindow      *window);
216 static void         terminal_window_action_fullscreen             (GtkToggleAction     *action,
217                                                                    TerminalWindow      *window);
218 static void         terminal_window_action_readonly               (GtkToggleAction     *action,
219                                                                    TerminalWindow      *window);
220 static void         terminal_window_action_scroll_on_output       (GtkToggleAction     *action,
221                                                                    TerminalWindow      *window);
222 static void         terminal_window_action_zoom_in                (GtkAction           *action,
223                                                                    TerminalWindow      *window);
224 static void         terminal_window_action_zoom_out               (GtkAction           *action,
225                                                                    TerminalWindow      *window);
226 static void         terminal_window_action_zoom_reset             (GtkAction           *action,
227                                                                    TerminalWindow      *window);
228 static void         terminal_window_action_prev_tab               (GtkAction           *action,
229                                                                    TerminalWindow      *window);
230 static void         terminal_window_action_next_tab               (GtkAction           *action,
231                                                                    TerminalWindow      *window);
232 static void         terminal_window_action_last_active_tab        (GtkAction           *action,
233                                                                    TerminalWindow      *window);
234 static void         terminal_window_action_move_tab_left          (GtkAction           *action,
235                                                                    TerminalWindow      *window);
236 static void         terminal_window_action_move_tab_right         (GtkAction           *action,
237                                                                    TerminalWindow      *window);
238 static void         terminal_window_action_goto_tab               (GtkRadioAction      *action,
239                                                                    GtkNotebook         *notebook);
240 static void         terminal_window_action_set_title              (GtkAction           *action,
241                                                                    TerminalWindow      *window);
242 static void         terminal_window_action_set_title_color        (GtkAction           *action,
243                                                                    TerminalWindow      *window);
244 static void         terminal_window_action_search                 (GtkAction           *action,
245                                                                    TerminalWindow      *window);
246 static void         terminal_window_action_search_next            (GtkAction           *action,
247                                                                    TerminalWindow      *window);
248 static void         terminal_window_action_search_prev            (GtkAction           *action,
249                                                                    TerminalWindow      *window);
250 static void         terminal_window_action_save_contents          (GtkAction           *action,
251                                                                    TerminalWindow      *window);
252 static void         terminal_window_action_reset                  (GtkAction           *action,
253                                                                    TerminalWindow      *window);
254 static void         terminal_window_action_reset_and_clear        (GtkAction           *action,
255                                                                    TerminalWindow      *window);
256 static void         terminal_window_action_contents               (GtkAction           *action,
257                                                                    TerminalWindow      *window);
258 static void         terminal_window_action_about                  (GtkAction           *action,
259                                                                    TerminalWindow      *window);
260 static void         terminal_window_zoom_update_screens           (TerminalWindow      *window);
261 static void         terminal_window_switch_tab                    (GtkNotebook         *notebook,
262                                                                    gboolean             switch_left);
263 static void         terminal_window_move_tab                      (GtkNotebook         *notebook,
264                                                                    gboolean             move_left);
265 static void         terminal_window_toggle_menubar                (GtkWidget           *widget,
266                                                                    TerminalWindow      *window);
267 static void         terminal_window_menubar_deactivate            (GtkWidget           *widget,
268                                                                    TerminalWindow      *window);
269 static void         title_popover_close                           (GtkWidget           *popover,
270                                                                    TerminalWindow      *window);
271 static void         terminal_window_do_close_tab                  (TerminalScreen      *screen,
272                                                                    TerminalWindow      *window);
273 
274 
275 
276 struct _TerminalWindowPrivate
277 {
278   GtkUIManager        *ui_manager;
279 
280   GtkWidget           *vbox;
281   GtkWidget           *notebook;
282   GtkWidget           *menubar;
283   GtkWidget           *toolbar;
284 
285   /* for the drop-down to keep open with dialogs */
286   guint                n_child_windows;
287 
288   guint                tabs_menu_merge_id;
289   GSList              *tabs_menu_actions;
290 
291   TerminalPreferences *preferences;
292   GtkWidget           *preferences_dialog;
293 
294   GtkActionGroup      *action_group;
295 
296   GtkWidget           *search_dialog;
297   GtkWidget           *title_popover;
298 
299   /* pushed size of screen */
300   glong                grid_width;
301   glong                grid_height;
302 
303   GtkAction           *encoding_action;
304 
305   TerminalScreen      *active;
306   TerminalScreen      *last_active;
307 
308   /* cached actions to avoid lookups */
309   GtkAction           *action_undo_close_tab;
310   GtkAction           *action_detach_tab;
311   GtkAction           *action_close_other_tabs;
312   GtkAction           *action_prev_tab;
313   GtkAction           *action_next_tab;
314   GtkAction           *action_last_active_tab;
315   GtkAction           *action_move_tab_left;
316   GtkAction           *action_move_tab_right;
317   GtkAction           *action_copy;
318   GtkAction           *action_search_next;
319   GtkAction           *action_search_prev;
320   GtkAction           *action_fullscreen;
321 
322   GQueue              *closed_tabs_list;
323 
324   gchar               *font;
325 
326   TerminalVisibility   scrollbar_visibility;
327   TerminalZoomLevel    zoom;
328 
329   GSList              *tab_key_accels;
330 
331   /* if this is a TerminalWindowDropdown */
332   guint                drop_down : 1;
333 };
334 
335 static guint   window_signals[LAST_SIGNAL];
336 static gchar  *window_notebook_group = PACKAGE_NAME;
337 static GQuark  tabs_menu_action_quark = 0;
338 
339 
340 
341 static const GtkActionEntry action_entries[] =
342 {
343   { "file-menu", NULL, N_ ("_File"), NULL, NULL, NULL, },
344     { "new-tab", "tab-new", N_ ("Open _Tab"), "<control><shift>t", N_ ("Open a new terminal tab"), G_CALLBACK (terminal_window_action_new_tab), },
345     { "new-window", "window-new", N_ ("Open T_erminal"), "<control><shift>n", N_ ("Open a new terminal window"), G_CALLBACK (terminal_window_action_new_window), },
346     { "undo-close-tab", "document-revert", N_ ("_Undo Close Tab"), NULL, NULL, G_CALLBACK (terminal_window_action_undo_close_tab), },
347     { "detach-tab", NULL, N_ ("_Detach Tab"), "<control><shift>d", NULL, G_CALLBACK (terminal_window_action_detach_tab), },
348     { "close-tab", "window-close", N_ ("Close T_ab"), "<control><shift>w", NULL, G_CALLBACK (terminal_window_action_close_tab), },
349     { "close-other-tabs", "edit-clear", N_ ("Close Other Ta_bs"), NULL, NULL, G_CALLBACK (terminal_window_action_close_other_tabs), },
350     { "close-window", "application-exit", N_ ("Close _Window"), "<control><shift>q", NULL, G_CALLBACK (terminal_window_action_close_window), },
351   { "edit-menu", NULL, N_ ("_Edit"), NULL, NULL, NULL, },
352     { "copy", "edit-copy", N_ ("_Copy"), "<control><shift>c", N_ ("Copy to clipboard"), G_CALLBACK (terminal_window_action_copy), },
353 #if VTE_CHECK_VERSION (0, 49, 2)
354     { "copy-html", "edit-copy", N_ ("Copy as _HTML"), NULL, N_ ("Copy to clipboard as HTML"), G_CALLBACK (terminal_window_action_copy_html), },
355 #endif
356     { "paste", "edit-paste", N_ ("_Paste"), "<control><shift>v", N_ ("Paste from clipboard"), G_CALLBACK (terminal_window_action_paste), },
357     { "paste-selection", NULL, N_ ("Paste _Selection"), NULL, NULL, G_CALLBACK (terminal_window_action_paste_selection), },
358     { "select-all", "edit-select-all", N_ ("Select _All"), "<control><shift>a", NULL, G_CALLBACK (terminal_window_action_select_all), },
359     { "copy-input", NULL, N_ ("Copy _Input To All Tabs..."), NULL, NULL, G_CALLBACK (terminal_window_action_copy_input), },
360     { "preferences", "preferences-system", N_ ("Pr_eferences..."), NULL, N_ ("Open the preferences dialog"), G_CALLBACK (terminal_window_action_prefs), },
361   { "view-menu", NULL, N_ ("_View"), NULL, NULL, NULL, },
362     { "zoom-in", "zoom-in", N_ ("Zoom _In"), "<control>plus", N_ ("Zoom in with larger font"), G_CALLBACK (terminal_window_action_zoom_in), },
363     { "zoom-out", "zoom-out", N_ ("Zoom _Out"), "<control>minus", N_ ("Zoom out with smaller font"), G_CALLBACK (terminal_window_action_zoom_out), },
364     { "zoom-reset", "zoom-original", N_ ("_Normal Size"), "<control>0", N_ ("Zoom to default size"), G_CALLBACK (terminal_window_action_zoom_reset), },
365   { "terminal-menu", NULL, N_ ("_Terminal"), NULL, NULL, NULL, },
366     { "set-title", NULL, N_ ("_Set Title..."), "<control><shift>s", NULL, G_CALLBACK (terminal_window_action_set_title), },
367     { "set-title-color", NULL, N_ ("Set Title Co_lor..."), NULL, NULL, G_CALLBACK (terminal_window_action_set_title_color), },
368     { "search", "edit-find", N_ ("_Find..."), "<control><shift>f", N_ ("Search terminal contents"), G_CALLBACK (terminal_window_action_search), },
369     { "search-next", NULL, N_ ("Find Ne_xt"), NULL, NULL, G_CALLBACK (terminal_window_action_search_next), },
370     { "search-prev", NULL, N_ ("Find Pre_vious"), NULL, NULL, G_CALLBACK (terminal_window_action_search_prev), },
371     { "save-contents", "document-save-as", N_ ("Sa_ve Contents..."), NULL, NULL, G_CALLBACK (terminal_window_action_save_contents), },
372     { "reset", NULL, N_ ("_Reset"), NULL, NULL, G_CALLBACK (terminal_window_action_reset), },
373     { "reset-and-clear", NULL, N_ ("_Clear Scrollback and Reset"), NULL, NULL, G_CALLBACK (terminal_window_action_reset_and_clear), },
374   { "tabs-menu", NULL, N_ ("T_abs"), NULL, NULL, NULL, },
375     { "prev-tab", "go-previous", N_ ("_Previous Tab"), "<control>Page_Up", N_ ("Switch to previous tab"), G_CALLBACK (terminal_window_action_prev_tab), },
376     { "next-tab", "go-next", N_ ("_Next Tab"), "<control>Page_Down", N_ ("Switch to next tab"), G_CALLBACK (terminal_window_action_next_tab), },
377     { "last-active-tab", NULL, N_ ("Last _Active Tab"), NULL, N_ ("Switch to last active tab"), G_CALLBACK (terminal_window_action_last_active_tab), },
378     { "move-tab-left", NULL, N_ ("Move Tab _Left"), "<control><shift>Page_Up", NULL, G_CALLBACK (terminal_window_action_move_tab_left), },
379     { "move-tab-right", NULL, N_ ("Move Tab _Right"), "<control><shift>Page_Down", NULL, G_CALLBACK (terminal_window_action_move_tab_right), },
380   { "help-menu", NULL, N_ ("_Help"), NULL, NULL, NULL, },
381     { "contents", "help-browser", N_ ("_Contents"), "F1", N_ ("Display help contents"), G_CALLBACK (terminal_window_action_contents), },
382     { "about", "help-about", N_ ("_About"), NULL, NULL, G_CALLBACK (terminal_window_action_about), },
383   { "zoom-menu", NULL, N_ ("_Zoom"), NULL, NULL, NULL, },
384 };
385 
386 static const GtkToggleActionEntry toggle_action_entries[] =
387 {
388   { "show-menubar", NULL, N_ ("Show _Menubar"), NULL, N_ ("Show/hide the menubar"), G_CALLBACK (terminal_window_action_show_menubar), FALSE, },
389   { "show-toolbar", NULL, N_ ("Show _Toolbar"), NULL, N_ ("Show/hide the toolbar"), G_CALLBACK (terminal_window_action_show_toolbar), FALSE, },
390   { "show-borders", NULL, N_ ("Show Window _Borders"), NULL, N_ ("Show/hide the window decorations"), G_CALLBACK (terminal_window_action_show_borders), TRUE, },
391   { "fullscreen", "view-fullscreen", N_ ("_Fullscreen"), "F11", N_ ("Toggle fullscreen mode"), G_CALLBACK (terminal_window_action_fullscreen), FALSE, },
392   { "read-only", NULL, N_ ("_Read-Only"), NULL, N_ ("Toggle read-only mode"), G_CALLBACK (terminal_window_action_readonly), FALSE, },
393   { "scroll-on-output", NULL, N_ ("Scroll on _Output"), NULL, N_ ("Toggle scroll on output"), G_CALLBACK (terminal_window_action_scroll_on_output), FALSE, },
394 };
395 
396 
397 
G_DEFINE_TYPE_WITH_CODE(TerminalWindow,terminal_window,GTK_TYPE_WINDOW,G_ADD_PRIVATE (TerminalWindow))398 G_DEFINE_TYPE_WITH_CODE (TerminalWindow, terminal_window, GTK_TYPE_WINDOW, G_ADD_PRIVATE (TerminalWindow))
399 
400 
401 
402 static void
403 terminal_window_class_init (TerminalWindowClass *klass)
404 {
405   GtkWidgetClass *gtkwidget_class;
406   GObjectClass   *gobject_class;
407 
408   gobject_class = G_OBJECT_CLASS (klass);
409   gobject_class->finalize = terminal_window_finalize;
410 
411   gtkwidget_class = GTK_WIDGET_CLASS (klass);
412   gtkwidget_class->window_state_event = terminal_window_state_event;
413   gtkwidget_class->delete_event = terminal_window_delete_event;
414   gtkwidget_class->style_set = terminal_window_style_set;
415   gtkwidget_class->scroll_event = terminal_window_scroll_event;
416   gtkwidget_class->map_event = terminal_window_map_event;
417   gtkwidget_class->focus_in_event = terminal_window_focus_in_event;
418   gtkwidget_class->key_press_event = terminal_window_key_press_event;
419 
420   /**
421    * TerminalWindow::new-window
422    **/
423   window_signals[NEW_WINDOW] =
424     g_signal_new (I_("new-window"),
425                   G_TYPE_FROM_CLASS (gobject_class),
426                   G_SIGNAL_RUN_LAST,
427                   0, NULL, NULL,
428                   g_cclosure_marshal_VOID__STRING,
429                   G_TYPE_NONE, 1,
430                   G_TYPE_STRING);
431 
432   /**
433    * TerminalWindow::new-window-with-screen:
434    **/
435   window_signals[NEW_WINDOW_WITH_SCREEN] =
436     g_signal_new (I_("new-window-with-screen"),
437                   G_TYPE_FROM_CLASS (gobject_class),
438                   G_SIGNAL_RUN_FIRST,
439                   0, NULL, NULL,
440                   _terminal_marshal_VOID__OBJECT_INT_INT,
441                   G_TYPE_NONE, 3,
442                   G_TYPE_OBJECT,
443                   G_TYPE_INT, G_TYPE_INT);
444 
445   /* initialize quark */
446   tabs_menu_action_quark = g_quark_from_static_string ("tabs-menu-item");
447 }
448 
449 
450 
451 static void
terminal_window_init(TerminalWindow * window)452 terminal_window_init (TerminalWindow *window)
453 {
454   GtkAccelGroup   *accel_group;
455   gboolean         always_show_tabs;
456   GdkScreen       *screen;
457   GdkVisual       *visual;
458   GtkStyleContext *context;
459 
460   GClosure *toggle_menubar_closure = g_cclosure_new (G_CALLBACK (terminal_window_toggle_menubar), window, NULL);
461 
462   window->priv = terminal_window_get_instance_private (window);
463 
464   window->priv->preferences = terminal_preferences_get ();
465 
466   window->priv->font = NULL;
467   window->priv->zoom = TERMINAL_ZOOM_LEVEL_DEFAULT;
468   window->priv->closed_tabs_list = g_queue_new ();
469 
470   /* try to set the rgba colormap so vte can use real transparency */
471   screen = gtk_window_get_screen (GTK_WINDOW (window));
472   visual = gdk_screen_get_rgba_visual (screen);
473   if (visual != NULL)
474     gtk_widget_set_visual (GTK_WIDGET (window), visual);
475 
476   /* required for vte transparency support: see https://bugzilla.gnome.org/show_bug.cgi?id=729884 */
477   gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
478 
479 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
480   window->priv->action_group = gtk_action_group_new ("terminal-window");
481   gtk_action_group_set_translation_domain (window->priv->action_group,
482                                            GETTEXT_PACKAGE);
483   gtk_action_group_add_actions (window->priv->action_group,
484                                 action_entries,
485                                 G_N_ELEMENTS (action_entries),
486                                 GTK_WIDGET (window));
487   gtk_action_group_add_toggle_actions (window->priv->action_group,
488                                        toggle_action_entries,
489                                        G_N_ELEMENTS (toggle_action_entries),
490                                        GTK_WIDGET (window));
491 
492   window->priv->ui_manager = gtk_ui_manager_new ();
493   gtk_ui_manager_insert_action_group (window->priv->ui_manager, window->priv->action_group, 0);
494 #if VTE_CHECK_VERSION (0, 49, 2)
495   {
496     /* add "Copy as HTML" to Edit and context menus */
497     const gchar *p1 = strstr (terminal_window_ui, "<menuitem action=\"paste\"/>"); // Edit menu
498     const gchar *p2 = strstr (p1 + 1, "<menuitem action=\"paste\"/>"); // context menu
499     const guint length_new = terminal_window_ui_length + 2 * strlen ("<menuitem action=\"copy-html\"/>");
500     gchar *ui_new = g_new0 (gchar, length_new + 1);
501     memcpy (ui_new, terminal_window_ui, p1 - terminal_window_ui);
502     strcat (ui_new, "<menuitem action=\"copy-html\"/>");
503     memcpy (ui_new + strlen (ui_new), p1, p2 - p1);
504     strcat (ui_new, "<menuitem action=\"copy-html\"/>");
505     strcat (ui_new, p2);
506     gtk_ui_manager_add_ui_from_string (window->priv->ui_manager, ui_new, length_new, NULL);
507     g_free (ui_new);
508   }
509 #else
510   gtk_ui_manager_add_ui_from_string (window->priv->ui_manager, terminal_window_ui, terminal_window_ui_length, NULL);
511 #endif
512 
513   accel_group = gtk_ui_manager_get_accel_group (window->priv->ui_manager);
514 G_GNUC_END_IGNORE_DEPRECATIONS
515   gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
516 
517   gtk_accel_group_connect_by_path (accel_group, "<Actions>/terminal-window/toggle-menubar", toggle_menubar_closure);
518 
519   window->priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
520   gtk_container_add (GTK_CONTAINER (window), window->priv->vbox);
521 
522   /* avoid transparent widgets, such as menubar or tabbar */
523   context = gtk_widget_get_style_context (window->priv->vbox);
524   gtk_style_context_add_class (context, GTK_STYLE_CLASS_BACKGROUND);
525 
526   /* allocate the notebook for the terminal screens */
527   g_object_get (G_OBJECT (window->priv->preferences), "misc-always-show-tabs", &always_show_tabs, NULL);
528   window->priv->notebook = g_object_new (GTK_TYPE_NOTEBOOK,
529                                    "scrollable", TRUE,
530                                    "show-border", FALSE,
531                                    "show-tabs", always_show_tabs,
532                                    NULL);
533   gtk_widget_add_events (window->priv->notebook, GDK_SCROLL_MASK);
534 
535   /* set the notebook group id */
536   gtk_notebook_set_group_name (GTK_NOTEBOOK (window->priv->notebook), window_notebook_group);
537 
538   /* set notebook tabs style */
539   gtk_widget_set_name (window->priv->notebook, NOTEBOOK_NAME);
540   terminal_window_update_slim_tabs (window);
541 
542   /* signals */
543   g_signal_connect (G_OBJECT (window->priv->notebook), "switch-page",
544       G_CALLBACK (terminal_window_notebook_page_switched), window);
545   g_signal_connect (G_OBJECT (window->priv->notebook), "page-reordered",
546       G_CALLBACK (terminal_window_notebook_page_reordered), window);
547   g_signal_connect (G_OBJECT (window->priv->notebook), "page-removed",
548       G_CALLBACK (terminal_window_notebook_page_removed), window);
549   g_signal_connect (G_OBJECT (window->priv->notebook), "page-added",
550       G_CALLBACK (terminal_window_notebook_page_added), window);
551   g_signal_connect (G_OBJECT (window->priv->notebook), "create-window",
552       G_CALLBACK (terminal_window_notebook_create_window), window);
553   g_signal_connect (G_OBJECT (window->priv->notebook), "button-press-event",
554       G_CALLBACK (terminal_window_notebook_button_press_event), window);
555   g_signal_connect (G_OBJECT (window->priv->notebook), "button-release-event",
556       G_CALLBACK (terminal_window_notebook_button_release_event), window);
557   g_signal_connect (G_OBJECT (window->priv->notebook), "scroll-event",
558       G_CALLBACK (terminal_window_notebook_scroll_event), window);
559 
560   gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->notebook, TRUE, TRUE, 0);
561   gtk_widget_show_all (window->priv->vbox);
562 
563   /* create encoding action */
564   window->priv->encoding_action = terminal_encoding_action_new ("set-encoding", _("Set _Encoding"));
565 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
566   gtk_action_group_add_action (window->priv->action_group, window->priv->encoding_action);
567 G_GNUC_END_IGNORE_DEPRECATIONS
568   g_signal_connect (G_OBJECT (window->priv->encoding_action), "encoding-changed",
569       G_CALLBACK (terminal_window_action_set_encoding), window);
570 
571 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
572   window->priv->menubar = gtk_ui_manager_get_widget (window->priv->ui_manager, "/main-menu");
573 G_GNUC_END_IGNORE_DEPRECATIONS
574   gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->menubar, FALSE, FALSE, 0);
575   gtk_box_reorder_child (GTK_BOX (window->priv->vbox), window->priv->menubar, 0);
576   /* don't show menubar by default */
577   gtk_widget_hide (window->priv->menubar);
578   /* auto-hide menubar if it was shown temporarily */
579   g_signal_connect (G_OBJECT (window->priv->menubar), "deactivate",
580       G_CALLBACK (terminal_window_menubar_deactivate), window);
581 
582   /* cache action pointers */
583   window->priv->action_undo_close_tab = terminal_window_get_action (window, "undo-close-tab");
584   window->priv->action_detach_tab = terminal_window_get_action (window, "detach-tab");
585   window->priv->action_close_other_tabs = terminal_window_get_action (window, "close-other-tabs");
586   window->priv->action_prev_tab = terminal_window_get_action (window, "prev-tab");
587   window->priv->action_next_tab = terminal_window_get_action (window, "next-tab");
588   window->priv->action_last_active_tab = terminal_window_get_action (window, "last-active-tab");
589   window->priv->action_move_tab_left = terminal_window_get_action (window, "move-tab-left");
590   window->priv->action_move_tab_right = terminal_window_get_action (window, "move-tab-right");
591   window->priv->action_copy = terminal_window_get_action (window, "copy");
592   window->priv->action_search_next = terminal_window_get_action (window, "search-next");
593   window->priv->action_search_prev = terminal_window_get_action (window, "search-prev");
594   window->priv->action_fullscreen = terminal_window_get_action (window, "fullscreen");
595 
596   /* monitor the scrolling-on-output setting */
597   g_signal_connect_swapped (G_OBJECT (window->priv->preferences), "notify::scrolling-on-output",
598                             G_CALLBACK (terminal_window_update_scroll_on_output), window);
599 
600   /* monitor the shortcuts-no-mnemonics setting */
601   terminal_window_update_mnemonic_modifier (window);
602   g_signal_connect_swapped (G_OBJECT (window->priv->preferences), "notify::shortcuts-no-mnemonics",
603                             G_CALLBACK (terminal_window_update_mnemonic_modifier), window);
604 
605 #if defined(GDK_WINDOWING_X11)
606   if (GDK_IS_X11_SCREEN (screen))
607     {
608       /* setup fullscreen mode */
609       if (!gdk_x11_screen_supports_net_wm_hint (screen, gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", FALSE)))
610         {
611 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
612           gtk_action_set_sensitive (window->priv->action_fullscreen, FALSE);
613 G_GNUC_END_IGNORE_DEPRECATIONS
614         }
615     }
616 #endif
617 }
618 
619 
620 
621 static void
terminal_window_finalize(GObject * object)622 terminal_window_finalize (GObject *object)
623 {
624   TerminalWindow *window = TERMINAL_WINDOW (object);
625 
626   /* disconnect scrolling-on-output and shortcuts-no-mnemonics watches */
627   g_signal_handlers_disconnect_by_func (G_OBJECT (window->priv->preferences),
628                                         G_CALLBACK (terminal_window_update_scroll_on_output), window);
629   g_signal_handlers_disconnect_by_func (G_OBJECT (window->priv->preferences),
630                                         G_CALLBACK (terminal_window_update_mnemonic_modifier), window);
631 
632   if (window->priv->preferences_dialog != NULL)
633     gtk_widget_destroy (window->priv->preferences_dialog);
634   g_object_unref (G_OBJECT (window->priv->preferences));
635   g_object_unref (G_OBJECT (window->priv->action_group));
636   g_object_unref (G_OBJECT (window->priv->ui_manager));
637   g_object_unref (G_OBJECT (window->priv->encoding_action));
638 
639   g_slist_free (window->priv->tabs_menu_actions);
640   g_free (window->priv->font);
641   g_queue_free_full (window->priv->closed_tabs_list, (GDestroyNotify) terminal_tab_attr_free);
642 
643   (*G_OBJECT_CLASS (terminal_window_parent_class)->finalize) (object);
644 }
645 
646 
647 
648 static gboolean
terminal_window_delete_event(GtkWidget * widget,GdkEventAny * event)649 terminal_window_delete_event (GtkWidget   *widget,
650                               GdkEventAny *event)
651 {
652   TerminalWindow *window = TERMINAL_WINDOW (widget);
653   GtkWidget      *child;
654   gint            n_pages, i, response;
655 
656   response = terminal_window_confirm_close (NULL, window);
657 
658   /* disconnect remove signal if we're closing the window */
659   if (response == CONFIRMED_CLOSE_WINDOW)
660     {
661       /* disconnect handlers for closing Set Title dialog */
662       if (window->priv->title_popover != NULL)
663         {
664           n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook));
665           for (i = 0; i < n_pages; i++)
666             {
667               child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->priv->notebook), i);
668               g_signal_handlers_disconnect_by_func (G_OBJECT (child),
669                   G_CALLBACK (title_popover_close), window);
670             }
671         }
672 
673       /* avoid a lot of page remove calls */
674       g_signal_handlers_disconnect_by_func (G_OBJECT (window->priv->notebook),
675           G_CALLBACK (terminal_window_notebook_page_removed), window);
676 
677       /* let gtk close the window */
678       if (GTK_WIDGET_CLASS (terminal_window_parent_class)->delete_event != NULL)
679         return (*GTK_WIDGET_CLASS (terminal_window_parent_class)->delete_event) (widget, event);
680 
681       return FALSE;
682     }
683   else if (response == CONFIRMED_CLOSE_TAB)
684     terminal_window_do_close_tab (window->priv->active, window);
685 
686   return TRUE;
687 }
688 
689 
690 
691 static gboolean
terminal_window_state_event(GtkWidget * widget,GdkEventWindowState * event)692 terminal_window_state_event (GtkWidget           *widget,
693                              GdkEventWindowState *event)
694 {
695   TerminalWindow *window = TERMINAL_WINDOW (widget);
696   gboolean        fullscreen;
697 
698   terminal_return_val_if_fail (TERMINAL_IS_WINDOW (window), FALSE);
699 
700   /* update the fullscreen action if the fullscreen state changed by the wm */
701   if ((event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) != 0
702       && gtk_widget_get_visible (widget))
703     {
704       fullscreen = (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) != 0;
705 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
706       if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (window->priv->action_fullscreen)) != fullscreen)
707         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (window->priv->action_fullscreen), fullscreen);
708 G_GNUC_END_IGNORE_DEPRECATIONS
709 
710       /* update drop-down window geometry, otherwise it'll be incorrect */
711       if (!fullscreen && window->priv->drop_down)
712         terminal_window_dropdown_update_geometry (TERMINAL_WINDOW_DROPDOWN (window));
713   }
714 
715   if (GTK_WIDGET_CLASS (terminal_window_parent_class)->window_state_event != NULL)
716     return (*GTK_WIDGET_CLASS (terminal_window_parent_class)->window_state_event) (widget, event);
717 
718   return FALSE;
719 }
720 
721 
722 
723 static void
terminal_window_style_set(GtkWidget * widget,GtkStyle * previous_style)724 terminal_window_style_set (GtkWidget *widget,
725                            GtkStyle  *previous_style)
726 {
727   TerminalWindow *window = TERMINAL_WINDOW (widget);
728 
729   if (previous_style != NULL)
730     terminal_window_size_push (window);
731 
732   (*GTK_WIDGET_CLASS (terminal_window_parent_class)->style_set) (widget, previous_style);
733 
734   /* delay the pop until after size allocate */
735   if (previous_style != NULL)
736     gdk_threads_add_idle (terminal_window_size_pop, window);
737 }
738 
739 
740 
741 static gboolean
terminal_window_scroll_event(GtkWidget * widget,GdkEventScroll * event)742 terminal_window_scroll_event (GtkWidget      *widget,
743                               GdkEventScroll *event)
744 {
745   TerminalWindow *window = TERMINAL_WINDOW (widget);
746   gboolean        mouse_wheel_zoom;
747 
748   g_object_get (G_OBJECT (window->priv->preferences),
749                 "misc-mouse-wheel-zoom", &mouse_wheel_zoom, NULL);
750 
751   if (mouse_wheel_zoom && event->state == (GDK_SHIFT_MASK | GDK_CONTROL_MASK)
752       && event->direction == GDK_SCROLL_UP)
753     {
754       terminal_window_action_zoom_in (NULL, window);
755       return TRUE;
756     }
757 
758   if (mouse_wheel_zoom && event->state == (GDK_SHIFT_MASK | GDK_CONTROL_MASK)
759       && event->direction == GDK_SCROLL_DOWN)
760     {
761       terminal_window_action_zoom_out (NULL, window);
762       return TRUE;
763     }
764 
765   return FALSE;
766 }
767 
768 
769 
770 static gboolean
terminal_window_map_event(GtkWidget * widget,GdkEventAny * event)771 terminal_window_map_event (GtkWidget   *widget,
772                            GdkEventAny *event)
773 {
774   TerminalWindow *window = TERMINAL_WINDOW (widget);
775 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
776   gboolean        fullscreen = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (window->priv->action_fullscreen));
777 G_GNUC_END_IGNORE_DEPRECATIONS
778 
779   if (fullscreen)
780     gtk_window_fullscreen (GTK_WINDOW (widget));
781 
782   return FALSE;
783 }
784 
785 
786 
787 static gboolean
terminal_window_focus_in_event(GtkWidget * widget,GdkEventFocus * event)788 terminal_window_focus_in_event (GtkWidget     *widget,
789                                 GdkEventFocus *event)
790 {
791   TerminalWindow *window = TERMINAL_WINDOW (widget);
792 
793   /* reset activity indicator for the active tab when focusing window */
794   terminal_screen_reset_activity (window->priv->active);
795 
796   return (*GTK_WIDGET_CLASS (terminal_window_parent_class)->focus_in_event) (widget, event);
797 }
798 
799 
800 
801 static gboolean
terminal_window_key_press_event(GtkWidget * widget,GdkEventKey * event)802 terminal_window_key_press_event (GtkWidget   *widget,
803                                  GdkEventKey *event)
804 {
805   TerminalWindow *window = TERMINAL_WINDOW (widget);
806   const guint     modifiers = event->state & gtk_accelerator_get_default_mod_mask ();
807 
808   /* support shortcuts that contain the Tab key
809      Tab sometimes becomes ISO_Left_Tab (e.g. in Ctrl+Shift+Tab) so check both here */
810   if (G_UNLIKELY (window->priv->tab_key_accels != NULL
811                   && (event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_ISO_Left_Tab)))
812     {
813       GSList *lp;
814       for (lp = window->priv->tab_key_accels; lp != NULL; lp = lp->next)
815         {
816           TerminalAccel *accel = lp->data;
817           if (accel->mods == modifiers)
818             {
819               GtkAction *action = terminal_window_get_action (window, accel->path);
820 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
821               if (G_LIKELY (GTK_IS_ACTION (action)))
822                 {
823                   gtk_action_activate (action);
824                   return TRUE;
825                 }
826 G_GNUC_END_IGNORE_DEPRECATIONS
827             }
828         }
829     }
830 
831   /* handle Ctrl+Shift+Ins (paste clipboard) and Shift+Ins (paste selection) */
832   if (event->keyval == GDK_KEY_Insert || event->keyval == GDK_KEY_KP_Insert)
833     {
834       if (modifiers == (GDK_CONTROL_MASK | GDK_SHIFT_MASK))
835         {
836           terminal_window_action_paste (NULL, window);
837           return TRUE;
838         }
839       else if (modifiers == GDK_SHIFT_MASK)
840         {
841           terminal_window_action_paste_selection (NULL, window);
842           return TRUE;
843         }
844     }
845 
846   return (*GTK_WIDGET_CLASS (terminal_window_parent_class)->key_press_event) (widget, event);
847 }
848 
849 
850 
851 static gint
terminal_window_confirm_close(TerminalScreen * screen,TerminalWindow * window)852 terminal_window_confirm_close (TerminalScreen *screen,
853                                TerminalWindow *window)
854 {
855   GtkWidget   *dialog;
856   GtkWidget   *button;
857   GtkWidget   *hbox;
858   GtkWidget   *image;
859   GtkWidget   *vbox;
860   GtkWidget   *label;
861   GtkWidget   *checkbox;
862   const gchar *title;
863   gchar       *message;
864   gchar       *markup;
865   gint         response;
866   gint         i, n_tabs;
867   gboolean     confirm_close;
868 
869   g_object_get (G_OBJECT (window->priv->preferences), "misc-confirm-close", &confirm_close, NULL);
870   if (!confirm_close)
871     return (screen != NULL) ? CONFIRMED_CLOSE_TAB : CONFIRMED_CLOSE_WINDOW;
872 
873   n_tabs = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook));
874   confirm_close = FALSE;
875   for (i = 0; i < n_tabs; ++i)
876     {
877       TerminalScreen *tab = TERMINAL_SCREEN (gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->priv->notebook), i));
878       if ((screen == NULL || screen == tab) && terminal_screen_has_foreground_process (tab))
879         {
880           confirm_close = TRUE;
881           break;
882         }
883     }
884 
885   if ((screen != NULL || n_tabs < 2) && !confirm_close)
886     return (screen != NULL) ? CONFIRMED_CLOSE_TAB : CONFIRMED_CLOSE_WINDOW;
887 
888   dialog = gtk_dialog_new ();
889   gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
890   gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
891   gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
892   gtk_window_set_title (GTK_WINDOW (dialog), _("Warning"));
893 
894   button = xfce_gtk_button_new_mixed ("gtk-cancel", _("_Cancel"));
895   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_CANCEL);
896 
897   if (screen == NULL && n_tabs > 1)
898     {
899       /* closing window with multiple tabs */
900       if (confirm_close)
901         {
902           /* and process running */
903           message = g_strdup (_("There are still processes running in some tabs.\n"
904                                 "Closing this window will kill all of them."));
905         }
906       else
907         {
908           /* and no process running */
909           message = g_strdup_printf (_("This window has %d tabs open. Closing this window\n"
910                                        "will also close all its tabs."), n_tabs);
911         }
912 
913       title = _("Close all tabs?");
914     }
915   else
916     {
917       if (screen != NULL)
918         {
919           /* closing a tab, and process running */
920           message = g_strdup (_("There is still a process running.\n"
921                                 "Closing this tab will kill it."));
922           title = _("Close tab?");
923         }
924       else
925         {
926           /* closing a single tab window, and process running */
927           message = g_strdup (_("There is still a process running.\n"
928                                 "Closing this window will kill it."));
929           title = _("Close window?");
930         }
931     }
932 
933   if (screen != NULL || n_tabs > 1)
934     {
935       button = xfce_gtk_button_new_mixed ("window-close", _("Close T_ab"));
936       gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_CLOSE);
937       gtk_widget_grab_focus (button);
938     }
939 
940   if (screen == NULL)
941     {
942       button = xfce_gtk_button_new_mixed ("application-exit", _("Close _Window"));
943       gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_YES);
944       gtk_widget_grab_focus (button);
945     }
946 
947   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
948   gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
949   gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox, TRUE, TRUE, 0);
950 
951   image = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_DIALOG);
952   gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
953   gtk_widget_set_valign (image, GTK_ALIGN_START);
954   gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
955 
956   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
957   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
958 
959   markup = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s", title, message);
960   g_free (message);
961 
962   label = g_object_new (GTK_TYPE_LABEL,
963                         "label", markup,
964                         "use-markup", TRUE,
965                         "xalign", 0.0,
966                         NULL);
967   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
968 
969   g_free (markup);
970 
971   checkbox = gtk_check_button_new_with_mnemonic (_("Do _not ask me again"));
972   gtk_box_pack_start (GTK_BOX (vbox), checkbox, FALSE, FALSE, 0);
973 
974   gtk_widget_show_all (dialog);
975 
976   response = gtk_dialog_run (GTK_DIALOG (dialog));
977   if (response == GTK_RESPONSE_YES)
978     {
979       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)))
980         {
981           g_object_set (G_OBJECT (window->priv->preferences),
982                         "misc-confirm-close", FALSE,
983                         NULL);
984         }
985     }
986 
987   gtk_widget_destroy (dialog);
988 
989   if (response == GTK_RESPONSE_YES)
990     return CONFIRMED_CLOSE_WINDOW;
991   if (response == GTK_RESPONSE_CLOSE)
992     return CONFIRMED_CLOSE_TAB;
993   return CONFIRMED_NONE;
994 }
995 
996 
997 
998 static void
terminal_window_size_push(TerminalWindow * window)999 terminal_window_size_push (TerminalWindow *window)
1000 {
1001   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
1002 
1003   if (window->priv->active != NULL)
1004     {
1005       terminal_screen_get_size (window->priv->active,
1006                                 &window->priv->grid_width,
1007                                 &window->priv->grid_height);
1008     }
1009 }
1010 
1011 
1012 
1013 static gboolean
terminal_window_size_pop(gpointer data)1014 terminal_window_size_pop (gpointer data)
1015 {
1016   TerminalWindow *window = TERMINAL_WINDOW (data);
1017 
1018   terminal_return_val_if_fail (TERMINAL_IS_WINDOW (window), FALSE);
1019 
1020   if (window->priv->active != NULL)
1021     {
1022       terminal_window_set_size_force_grid (window, window->priv->active,
1023                                            window->priv->grid_width,
1024                                            window->priv->grid_height);
1025     }
1026 
1027   return FALSE;
1028 }
1029 
1030 
1031 
1032 static void
terminal_window_set_size_force_grid(TerminalWindow * window,TerminalScreen * screen,glong force_grid_width,glong force_grid_height)1033 terminal_window_set_size_force_grid (TerminalWindow *window,
1034                                      TerminalScreen *screen,
1035                                      glong           force_grid_width,
1036                                      glong           force_grid_height)
1037 {
1038   GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
1039 
1040   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
1041   terminal_return_if_fail (TERMINAL_IS_SCREEN (screen));
1042 
1043   /* required to get the char height/width right */
1044   if (gtk_widget_get_realized (GTK_WIDGET (screen))
1045       && gdk_window != NULL
1046       && (gdk_window_get_state (gdk_window) & (GDK_WINDOW_STATE_FULLSCREEN | WINDOW_STATE_TILED)) == 0
1047       && !window->priv->drop_down )
1048     {
1049       terminal_screen_force_resize_window (screen, GTK_WINDOW (window),
1050                                            force_grid_width, force_grid_height);
1051     }
1052 }
1053 
1054 
1055 
1056 static void
terminal_window_update_actions(TerminalWindow * window)1057 terminal_window_update_actions (TerminalWindow *window)
1058 {
1059   GtkNotebook *notebook = GTK_NOTEBOOK (window->priv->notebook);
1060   GtkAction   *action;
1061   gboolean     cycle_tabs;
1062   gint         page_num;
1063   gint         n_pages;
1064 
1065   /* determine the number of pages */
1066   n_pages = gtk_notebook_get_n_pages (notebook);
1067 
1068   /* "Detach Tab" and "Close Other Tabs" are sensitive if we have at least two pages.
1069    * "Undo Close" is sensitive if there is a tab to unclose. */
1070 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1071   gtk_action_set_sensitive (window->priv->action_detach_tab, (n_pages > 1));
1072   gtk_action_set_sensitive (window->priv->action_close_other_tabs, n_pages > 1);
1073 
1074   gtk_action_set_sensitive (window->priv->action_undo_close_tab, !g_queue_is_empty (window->priv->closed_tabs_list));
1075 G_GNUC_END_IGNORE_DEPRECATIONS
1076 
1077   /* update the actions for the current terminal screen */
1078   if (G_LIKELY (window->priv->active != NULL))
1079     {
1080       gboolean can_go_left, can_go_right, can_search, input_enabled;
1081 
1082       page_num = gtk_notebook_page_num (notebook, GTK_WIDGET (window->priv->active));
1083 
1084       g_object_get (G_OBJECT (window->priv->preferences),
1085                     "misc-cycle-tabs", &cycle_tabs,
1086                     NULL);
1087 
1088       can_go_left = (cycle_tabs && n_pages > 1) || (page_num > 0);
1089       can_go_right = (cycle_tabs && n_pages > 1) || (page_num < n_pages - 1);
1090 
1091 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1092       gtk_action_set_sensitive (window->priv->action_prev_tab, can_go_left);
1093       gtk_action_set_sensitive (window->priv->action_move_tab_left, can_go_left);
1094       gtk_action_set_sensitive (window->priv->action_next_tab, can_go_right);
1095       gtk_action_set_sensitive (window->priv->action_move_tab_right, can_go_right);
1096       gtk_action_set_sensitive (window->priv->action_last_active_tab, window->priv->last_active != NULL);
1097 
1098       gtk_action_set_sensitive (window->priv->action_copy,
1099                                 terminal_screen_has_selection (window->priv->active));
1100 #if VTE_CHECK_VERSION (0, 49, 2)
1101       gtk_action_set_sensitive (terminal_window_get_action (window, "copy-html"),
1102                                 terminal_screen_has_selection (window->priv->active));
1103 #endif
1104 
1105       can_search = terminal_screen_search_has_gregex (window->priv->active);
1106       gtk_action_set_sensitive (window->priv->action_search_next, can_search);
1107       gtk_action_set_sensitive (window->priv->action_search_prev, can_search);
1108 
1109       /* update read-only mode */
1110       input_enabled = terminal_screen_get_input_enabled (window->priv->active);
1111       action = terminal_window_get_action (window, "read-only");
1112       gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !input_enabled);
1113 
1114       /* update "Paste" actions */
1115       action = terminal_window_get_action (window, "paste");
1116       gtk_action_set_sensitive (action, input_enabled);
1117       action = terminal_window_get_action (window, "paste-selection");
1118       gtk_action_set_sensitive (action, input_enabled);
1119 
1120       /* update scroll on output mode */
1121       action = terminal_window_get_action (window, "scroll-on-output");
1122       gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1123                                     terminal_screen_get_scroll_on_output (window->priv->active));
1124 
1125       /* update the "Go" menu */
1126       action = g_object_get_qdata (G_OBJECT (window->priv->active), tabs_menu_action_quark);
1127       if (G_LIKELY (action != NULL))
1128         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1129 G_GNUC_END_IGNORE_DEPRECATIONS
1130     }
1131 }
1132 
1133 
1134 
1135 static void
terminal_window_update_slim_tabs(TerminalWindow * window)1136 terminal_window_update_slim_tabs (TerminalWindow *window)
1137 {
1138   GdkScreen      *screen = gtk_window_get_screen (GTK_WINDOW (window));
1139   GtkCssProvider *provider;
1140   gboolean        slim_tabs;
1141 
1142   g_object_get (G_OBJECT (window->priv->preferences),
1143                 "misc-slim-tabs", &slim_tabs,
1144                 NULL);
1145   if (slim_tabs)
1146     {
1147       provider = gtk_css_provider_new ();
1148       gtk_style_context_add_provider_for_screen (screen,
1149                                                  GTK_STYLE_PROVIDER (provider),
1150                                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1151       gtk_css_provider_load_from_data (provider, CSS_SLIM_TABS, -1, NULL);
1152       g_object_unref (provider);
1153     }
1154 }
1155 
1156 
1157 
1158 static void
terminal_window_update_scroll_on_output(TerminalWindow * window)1159 terminal_window_update_scroll_on_output (TerminalWindow *window)
1160 {
1161   GtkAction *action;
1162   gboolean   scroll;
1163 
1164   g_object_get (G_OBJECT (window->priv->preferences),
1165                 "scrolling-on-output", &scroll,
1166                 NULL);
1167   action = terminal_window_get_action (window, "scroll-on-output");
1168 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1169   gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), scroll);
1170 G_GNUC_END_IGNORE_DEPRECATIONS
1171 }
1172 
1173 
1174 
1175 static void
terminal_window_update_mnemonic_modifier(TerminalWindow * window)1176 terminal_window_update_mnemonic_modifier (TerminalWindow *window)
1177 {
1178   gboolean no_mnemonics;
1179 
1180   g_object_get (G_OBJECT (window->priv->preferences),
1181                 "shortcuts-no-mnemonics", &no_mnemonics,
1182                 NULL);
1183   if (no_mnemonics)
1184     gtk_window_set_mnemonic_modifier (GTK_WINDOW (window), GDK_MODIFIER_MASK & ~GDK_RELEASE_MASK);
1185   else
1186     gtk_window_set_mnemonic_modifier (GTK_WINDOW (window), GDK_MOD1_MASK);
1187 }
1188 
1189 
1190 
1191 static void
terminal_window_notebook_page_switched(GtkNotebook * notebook,GtkWidget * page,guint page_num,TerminalWindow * window)1192 terminal_window_notebook_page_switched (GtkNotebook     *notebook,
1193                                         GtkWidget       *page,
1194                                         guint            page_num,
1195                                         TerminalWindow  *window)
1196 {
1197   TerminalScreen *active = TERMINAL_SCREEN (page);
1198   const gchar    *encoding;
1199 
1200   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
1201   terminal_return_if_fail (active == NULL || TERMINAL_IS_SCREEN (active));
1202 
1203   /* only update when really changed */
1204   if (G_LIKELY (window->priv->active != active))
1205     {
1206       /* store last and set new active tab */
1207       window->priv->last_active = window->priv->active;
1208       window->priv->active = active;
1209 
1210       /* set the new window title */
1211       terminal_window_notify_title (active, NULL, window);
1212 
1213       /* reset the activity counter */
1214       terminal_screen_reset_activity (active);
1215 
1216       /* set charset for menu */
1217       encoding = terminal_screen_get_encoding (window->priv->active);
1218       terminal_encoding_action_set_charset (window->priv->encoding_action, encoding);
1219     }
1220 
1221   /* update actions in the window */
1222   terminal_window_update_actions (window);
1223 }
1224 
1225 
1226 
1227 static void
terminal_window_notebook_page_reordered(GtkNotebook * notebook,GtkWidget * child,guint page_num,TerminalWindow * window)1228 terminal_window_notebook_page_reordered (GtkNotebook     *notebook,
1229                                          GtkWidget       *child,
1230                                          guint            page_num,
1231                                          TerminalWindow  *window)
1232 {
1233   /* Regenerate the "Go" menu and update actions */
1234   terminal_window_rebuild_tabs_menu (window);
1235   terminal_window_update_actions (window);
1236 }
1237 
1238 
1239 
1240 static void
terminal_window_close_tab_request(TerminalScreen * screen,TerminalWindow * window)1241 terminal_window_close_tab_request (TerminalScreen *screen,
1242                                    TerminalWindow *window)
1243 {
1244   if (terminal_window_confirm_close (screen, window) == CONFIRMED_CLOSE_TAB)
1245     terminal_window_do_close_tab (screen, window);
1246 }
1247 
1248 
1249 
1250 static void
terminal_window_notebook_page_added(GtkNotebook * notebook,GtkWidget * child,guint page_num,TerminalWindow * window)1251 terminal_window_notebook_page_added (GtkNotebook    *notebook,
1252                                      GtkWidget      *child,
1253                                      guint           page_num,
1254                                      TerminalWindow *window)
1255 {
1256   TerminalScreen *screen = TERMINAL_SCREEN (child);
1257   glong           w, h;
1258 
1259   terminal_return_if_fail (TERMINAL_IS_SCREEN (child));
1260   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
1261   terminal_return_if_fail (GTK_IS_NOTEBOOK (notebook));
1262   terminal_return_if_fail (window->priv->notebook == GTK_WIDGET (notebook));
1263 
1264   /* connect screen signals */
1265   g_signal_connect (G_OBJECT (screen), "get-context-menu",
1266       G_CALLBACK (terminal_window_get_context_menu), window);
1267   g_signal_connect (G_OBJECT (screen), "notify::title",
1268       G_CALLBACK (terminal_window_notify_title), window);
1269   g_signal_connect_swapped (G_OBJECT (screen), "selection-changed",
1270       G_CALLBACK (terminal_window_update_actions), window);
1271   g_signal_connect (G_OBJECT (screen), "close-tab-request",
1272       G_CALLBACK (terminal_window_close_tab_request), window);
1273   g_signal_connect (G_OBJECT (screen), "drag-data-received",
1274       G_CALLBACK (terminal_window_notebook_drag_data_received), window);
1275 
1276   /* release to the grid size applies */
1277   gtk_widget_realize (GTK_WIDGET (screen));
1278 
1279   /* match zoom and font */
1280   if (window->priv->font || window->priv->zoom != TERMINAL_ZOOM_LEVEL_DEFAULT)
1281     terminal_screen_update_font (screen);
1282 
1283   if (G_LIKELY (window->priv->active != NULL))
1284     {
1285       /* match the size of the active screen */
1286       terminal_screen_get_size (window->priv->active, &w, &h);
1287       terminal_screen_set_size (screen, w, h);
1288 
1289       /* show the tabs when needed */
1290       terminal_window_notebook_show_tabs (window);
1291     }
1292   else if (G_UNLIKELY (window->priv->drop_down))
1293     {
1294       /* try to calculate a decent grid size based on the info we have now */
1295       terminal_window_dropdown_get_size (TERMINAL_WINDOW_DROPDOWN (window), screen, &w, &h);
1296       terminal_screen_set_size (screen, w, h);
1297     }
1298 
1299   /* regenerate the "Go" menu */
1300   terminal_window_rebuild_tabs_menu (window);
1301 }
1302 
1303 
1304 
1305 static void
terminal_window_notebook_page_removed(GtkNotebook * notebook,GtkWidget * child,guint page_num,TerminalWindow * window)1306 terminal_window_notebook_page_removed (GtkNotebook    *notebook,
1307                                        GtkWidget      *child,
1308                                        guint           page_num,
1309                                        TerminalWindow *window)
1310 {
1311   GtkWidget *new_page;
1312   gint       new_page_num;
1313   gint       npages;
1314 
1315   terminal_return_if_fail (TERMINAL_IS_SCREEN (child));
1316   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
1317 
1318   /* unset the go menu item */
1319   g_object_set_qdata (G_OBJECT (child), tabs_menu_action_quark, NULL);
1320 
1321   /* disconnect signals */
1322   g_signal_handlers_disconnect_by_func (G_OBJECT (child),
1323       terminal_window_get_context_menu, window);
1324   g_signal_handlers_disconnect_by_func (G_OBJECT (child),
1325       terminal_window_notify_title, window);
1326   g_signal_handlers_disconnect_by_func (G_OBJECT (child),
1327       terminal_window_update_actions, window);
1328   g_signal_handlers_disconnect_by_func (G_OBJECT (child),
1329       terminal_window_close_tab_request, window);
1330   g_signal_handlers_disconnect_by_func (G_OBJECT (child),
1331       terminal_window_notebook_drag_data_received, window);
1332 
1333   /* set tab visibility */
1334   npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook));
1335   if (G_UNLIKELY (npages == 0))
1336     {
1337       /* no tabs, destroy the window */
1338       gtk_widget_destroy (GTK_WIDGET (window));
1339       return;
1340     }
1341 
1342   /* clear last_active tab if it has just been closed */
1343   if (child == GTK_WIDGET (window->priv->last_active))
1344     window->priv->last_active = NULL;
1345 
1346   /* show the tabs when needed */
1347   terminal_window_notebook_show_tabs (window);
1348 
1349   /* regenerate the "Go" menu */
1350   terminal_window_rebuild_tabs_menu (window);
1351 
1352   /* send a signal about switching to another tab */
1353   new_page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->priv->notebook));
1354   new_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->priv->notebook), new_page_num);
1355   terminal_window_notebook_page_switched (notebook, new_page, new_page_num, window);
1356 }
1357 
1358 
1359 
1360 static gboolean
terminal_window_notebook_event_in_allocation(gint event_x,gint event_y,GtkWidget * widget)1361 terminal_window_notebook_event_in_allocation (gint       event_x,
1362                                               gint       event_y,
1363                                               GtkWidget *widget)
1364 {
1365   GtkAllocation allocation;
1366 
1367   gtk_widget_get_allocation (widget, &allocation);
1368 
1369   if (event_x >= allocation.x && event_x <= allocation.x + allocation.width
1370       && event_y >= allocation.y && event_y <= allocation.y + allocation.height)
1371     {
1372       return TRUE;
1373     }
1374 
1375   return FALSE;
1376 }
1377 
1378 
1379 
1380 static gboolean
terminal_window_notebook_button_press_event(GtkNotebook * notebook,GdkEventButton * event,TerminalWindow * window)1381 terminal_window_notebook_button_press_event (GtkNotebook    *notebook,
1382                                              GdkEventButton *event,
1383                                              TerminalWindow *window)
1384 {
1385   GtkWidget *page, *label, *menu;
1386   gint       page_num = 0;
1387   gboolean   close_middle_click;
1388   gint       x, y;
1389 
1390   terminal_return_val_if_fail (TERMINAL_IS_WINDOW (window), FALSE);
1391   terminal_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
1392 
1393   gdk_window_get_position (event->window, &x, &y);
1394   x += event->x;
1395   y += event->y;
1396 
1397   if (event->button == 1)
1398     {
1399       if (event->type == GDK_2BUTTON_PRESS)
1400         {
1401           /* check if the user double-clicked on the label */
1402           label = gtk_notebook_get_tab_label (notebook, GTK_WIDGET (window->priv->active));
1403           if (terminal_window_notebook_event_in_allocation (x, y, label))
1404             {
1405               terminal_window_action_set_title (NULL, window);
1406               return TRUE;
1407             }
1408         }
1409     }
1410   else if (event->type == GDK_BUTTON_PRESS && event->button <= 3)
1411     {
1412       /* select the page the user clicked on */
1413       while ((page = gtk_notebook_get_nth_page (notebook, page_num)) != NULL)
1414         {
1415           label = gtk_notebook_get_tab_label (notebook, page);
1416           if (terminal_window_notebook_event_in_allocation (x, y, label))
1417             break;
1418           page_num++;
1419         }
1420 
1421       /* leave if somehow no tab was found */
1422       if (G_UNLIKELY (page == NULL))
1423         return FALSE;
1424 
1425       if (event->button == 2)
1426         {
1427           /* close the tab on middle click */
1428           g_object_get (G_OBJECT (window->priv->preferences),
1429                         "misc-tab-close-middle-click", &close_middle_click, NULL);
1430           if (close_middle_click)
1431             terminal_window_close_tab_request (TERMINAL_SCREEN (page), window);
1432         }
1433       else
1434         {
1435           /* update the current tab before we show the menu */
1436           gtk_notebook_set_current_page (notebook, page_num);
1437 
1438           /* show the tab menu */
1439 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1440           menu = gtk_ui_manager_get_widget (window->priv->ui_manager, "/tab-menu");
1441 G_GNUC_END_IGNORE_DEPRECATIONS
1442           gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
1443         }
1444 
1445       return TRUE;
1446     }
1447 
1448   return FALSE;
1449 }
1450 
1451 
1452 
1453 static gboolean
terminal_window_notebook_button_release_event(GtkNotebook * notebook,GdkEventButton * event,TerminalWindow * window)1454 terminal_window_notebook_button_release_event (GtkNotebook    *notebook,
1455                                                GdkEventButton *event,
1456                                                TerminalWindow *window)
1457 {
1458   terminal_return_val_if_fail (TERMINAL_IS_WINDOW (window), FALSE);
1459   terminal_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
1460 
1461   if (G_LIKELY (window->priv->active != NULL))
1462     terminal_screen_focus (window->priv->active);
1463 
1464   return FALSE;
1465 }
1466 
1467 
1468 
1469 static gboolean
terminal_window_notebook_scroll_event(GtkNotebook * notebook,GdkEventScroll * event,TerminalWindow * window)1470 terminal_window_notebook_scroll_event (GtkNotebook    *notebook,
1471                                        GdkEventScroll *event,
1472                                        TerminalWindow *window)
1473 {
1474   terminal_return_val_if_fail (TERMINAL_IS_WINDOW (window), FALSE);
1475   terminal_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
1476 
1477   if ((event->state & gtk_accelerator_get_default_mod_mask ()) != 0)
1478     return FALSE;
1479 
1480   switch (event->direction) {
1481     case GDK_SCROLL_RIGHT:
1482     case GDK_SCROLL_DOWN:
1483       gtk_notebook_next_page (notebook);
1484       return TRUE;
1485 
1486     case GDK_SCROLL_LEFT:
1487     case GDK_SCROLL_UP:
1488       gtk_notebook_prev_page (notebook);
1489       return TRUE;
1490 
1491     default: /* GDK_SCROLL_SMOOTH */
1492       switch (gtk_notebook_get_tab_pos (notebook)) {
1493         case GTK_POS_LEFT:
1494         case GTK_POS_RIGHT:
1495           if (event->delta_y > 0)
1496             gtk_notebook_next_page (notebook);
1497           else if (event->delta_y < 0)
1498             gtk_notebook_prev_page (notebook);
1499           break;
1500 
1501         default: /* GTK_POS_TOP or GTK_POS_BOTTOM */
1502           if (event->delta_x > 0)
1503             gtk_notebook_next_page (notebook);
1504           else if (event->delta_x < 0)
1505             gtk_notebook_prev_page (notebook);
1506           break;
1507       }
1508       return TRUE;
1509   }
1510 
1511   return FALSE;
1512 }
1513 
1514 
1515 
1516 static void
terminal_window_notebook_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * selection_data,guint info,guint time,TerminalWindow * window)1517 terminal_window_notebook_drag_data_received (GtkWidget        *widget,
1518                                              GdkDragContext   *context,
1519                                              gint              x,
1520                                              gint              y,
1521                                              GtkSelectionData *selection_data,
1522                                              guint             info,
1523                                              guint             time,
1524                                              TerminalWindow   *window)
1525 {
1526   GtkWidget *notebook;
1527   GtkWidget *screen;
1528   gint       i, n_pages;
1529   gboolean   succeed = FALSE;
1530 
1531   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
1532   terminal_return_if_fail (TERMINAL_IS_SCREEN (widget));
1533 
1534   /* check */
1535   if (G_LIKELY (info == TARGET_GTK_NOTEBOOK_TAB))
1536     {
1537       /* get the source notebook (other window) */
1538       notebook = gtk_drag_get_source_widget (context);
1539       terminal_return_if_fail (GTK_IS_NOTEBOOK (notebook));
1540 
1541       /* get the dragged screen: selection_data's data is a (GtkWidget **) screen */
1542       memcpy (&screen, gtk_selection_data_get_data (selection_data), sizeof (screen));
1543       if (!TERMINAL_IS_SCREEN (screen))
1544         goto leave;
1545 
1546       /* leave if we dropped in the same screen and there is only one
1547        * page in the notebook (window will close before we insert) */
1548       if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) < 2 && screen == widget)
1549         goto leave;
1550 
1551       /* figure out where to insert the tab in the notebook */
1552       n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook));
1553       for (i = 0; i < n_pages; i++)
1554         {
1555           /* get the child label */
1556           GtkAllocation allocation;
1557           GtkWidget *child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->priv->notebook), i);
1558           GtkWidget *label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (window->priv->notebook), child);
1559           gtk_widget_get_allocation (label, &allocation);
1560 
1561           /* break if we have a matching drop position */
1562           if (x < (allocation.x + allocation.width / 2))
1563             break;
1564         }
1565 
1566       if (notebook == window->priv->notebook)
1567         {
1568           /* if we're in the same notebook, don't risk anything and do a
1569            * simple reorder */
1570           gtk_notebook_reorder_child (GTK_NOTEBOOK (notebook), screen, i);
1571         }
1572       else
1573         {
1574           /* take a reference */
1575           g_object_ref (G_OBJECT (screen));
1576           g_object_ref (G_OBJECT (window));
1577 
1578           /* remove the document from the source notebook */
1579           gtk_notebook_detach_tab (GTK_NOTEBOOK (notebook), screen);
1580 
1581           /* add the screen to the new window */
1582           terminal_window_add (window, TERMINAL_SCREEN (screen));
1583 
1584           /* move the child to the correct position */
1585           gtk_notebook_reorder_child (GTK_NOTEBOOK (window->priv->notebook), screen, i);
1586 
1587           /* release reference */
1588           g_object_unref (G_OBJECT (screen));
1589           g_object_unref (G_OBJECT (window));
1590         }
1591 
1592       /* looks like everything worked out */
1593       succeed = TRUE;
1594     }
1595 
1596   /* finish the drag */
1597 leave:
1598   gtk_drag_finish (context, succeed, FALSE, time);
1599 }
1600 
1601 
1602 
1603 static GtkNotebook*
terminal_window_notebook_create_window(GtkNotebook * notebook,GtkWidget * child,gint x,gint y,TerminalWindow * window)1604 terminal_window_notebook_create_window (GtkNotebook    *notebook,
1605                                         GtkWidget      *child,
1606                                         gint            x,
1607                                         gint            y,
1608                                         TerminalWindow *window)
1609 {
1610   terminal_return_val_if_fail (TERMINAL_IS_WINDOW (window), NULL);
1611   terminal_return_val_if_fail (TERMINAL_IS_SCREEN (child), NULL);
1612   terminal_return_val_if_fail (notebook == GTK_NOTEBOOK (window->priv->notebook), NULL);
1613 
1614   /* only create new window when there are more then 2 tabs (bug #2686) */
1615   if (gtk_notebook_get_n_pages (notebook) >= 2)
1616     {
1617       /* take a reference */
1618       g_object_ref (G_OBJECT (child));
1619 
1620       /* remove screen from active window */
1621       gtk_notebook_detach_tab (notebook, child);
1622 
1623       /* create new window with the screen */
1624       g_signal_emit (G_OBJECT (window), window_signals[NEW_WINDOW_WITH_SCREEN], 0, TERMINAL_SCREEN (child), x, y);
1625 
1626       /* release our reference */
1627       g_object_unref (G_OBJECT (child));
1628 
1629       /* update actions */
1630       terminal_window_update_actions (window);
1631     }
1632 
1633   return NULL;
1634 }
1635 
1636 
1637 
1638 static GtkWidget*
terminal_window_get_context_menu(TerminalScreen * screen,TerminalWindow * window)1639 terminal_window_get_context_menu (TerminalScreen  *screen,
1640                                   TerminalWindow  *window)
1641 {
1642   GtkWidget *popup = NULL;
1643 
1644 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1645   if (G_LIKELY (screen == window->priv->active))
1646     popup = gtk_ui_manager_get_widget (window->priv->ui_manager, "/popup-menu");
1647 G_GNUC_END_IGNORE_DEPRECATIONS
1648 
1649   return popup;
1650 }
1651 
1652 
1653 
1654 static void
terminal_window_notify_title(TerminalScreen * screen,GParamSpec * pspec,TerminalWindow * window)1655 terminal_window_notify_title (TerminalScreen *screen,
1656                               GParamSpec     *pspec,
1657                               TerminalWindow *window)
1658 {
1659   gchar *title;
1660 
1661   /* update window title */
1662   if (screen == window->priv->active)
1663     {
1664       title = terminal_screen_get_title (window->priv->active);
1665       gtk_window_set_title (GTK_WINDOW (window), title);
1666       g_free (title);
1667     }
1668 }
1669 
1670 
1671 
1672 static void
terminal_window_action_set_encoding(GtkAction * action,const gchar * charset,TerminalWindow * window)1673 terminal_window_action_set_encoding (GtkAction      *action,
1674                                      const gchar    *charset,
1675                                      TerminalWindow *window)
1676 {
1677   const gchar *new;
1678 
1679   if (G_LIKELY (window->priv->active != NULL))
1680     {
1681       /* set the charset */
1682       terminal_screen_set_encoding (window->priv->active, charset);
1683 
1684       /* update menu */
1685       new = terminal_screen_get_encoding (window->priv->active);
1686       terminal_encoding_action_set_charset (action, new);
1687     }
1688 }
1689 
1690 
1691 
1692 static gchar*
terminal_window_get_working_directory(TerminalWindow * window)1693 terminal_window_get_working_directory (TerminalWindow *window)
1694 {
1695   gchar    *default_dir;
1696   gboolean  use_default_dir;
1697 
1698   g_object_get (G_OBJECT (window->priv->preferences),
1699                 "use-default-working-dir", &use_default_dir,
1700                 "default-working-dir", &default_dir,
1701                 NULL);
1702 
1703   if (use_default_dir && g_strcmp0 (default_dir, "") != 0)
1704     return default_dir;
1705 
1706   if (G_LIKELY (window->priv->active != NULL))
1707     return g_strdup (terminal_screen_get_working_directory (window->priv->active));
1708 
1709   return NULL;
1710 }
1711 
1712 
1713 
1714 static void
terminal_window_action_new_tab(GtkAction * action,TerminalWindow * window)1715 terminal_window_action_new_tab (GtkAction      *action,
1716                                 TerminalWindow *window)
1717 {
1718   TerminalScreen *terminal = TERMINAL_SCREEN (g_object_new (TERMINAL_TYPE_SCREEN, NULL));
1719   gchar          *directory = terminal_window_get_working_directory (window);
1720 
1721   if (directory != NULL)
1722     {
1723       terminal_screen_set_working_directory (terminal, directory);
1724       g_free (directory);
1725     }
1726 
1727   terminal_window_add (window, terminal);
1728   terminal_screen_launch_child (terminal);
1729 }
1730 
1731 
1732 
1733 static void
terminal_window_action_new_window(GtkAction * action,TerminalWindow * window)1734 terminal_window_action_new_window (GtkAction      *action,
1735                                    TerminalWindow *window)
1736 {
1737   gchar *directory = terminal_window_get_working_directory (window);
1738 
1739   if (directory != NULL)
1740     {
1741       g_signal_emit (G_OBJECT (window), window_signals[NEW_WINDOW], 0, directory);
1742       g_free (directory);
1743     }
1744 }
1745 
1746 
1747 
1748 static void
terminal_window_action_undo_close_tab(GtkAction * action,TerminalWindow * window)1749 terminal_window_action_undo_close_tab (GtkAction      *action,
1750                                        TerminalWindow *window)
1751 {
1752   TerminalScreen  *terminal;
1753   TerminalTabAttr *tab_attr;
1754   GtkWidget       *current = GTK_WIDGET (window->priv->active);
1755 
1756   if (G_UNLIKELY (g_queue_is_empty (window->priv->closed_tabs_list)))
1757     return;
1758 
1759   /* get info on the last closed tab and remove it from the list */
1760   tab_attr = g_queue_pop_tail (window->priv->closed_tabs_list);
1761 
1762   terminal = terminal_screen_new (tab_attr, window->priv->grid_width, window->priv->grid_height);
1763   terminal_window_add (window, terminal);
1764 
1765   /* restore tab title color */
1766   if (tab_attr->color_title != NULL)
1767     terminal_screen_set_custom_title_color (terminal, tab_attr->color_title);
1768 
1769   /* restore tab position */
1770   gtk_notebook_reorder_child (GTK_NOTEBOOK (window->priv->notebook), GTK_WIDGET (terminal), tab_attr->position);
1771 
1772   /* restore tab focus if the unclosed one wasn't active when it was closed */
1773   if (!tab_attr->active)
1774     {
1775       gint page_num = gtk_notebook_page_num (GTK_NOTEBOOK (window->priv->notebook), current);
1776       gtk_notebook_set_current_page (GTK_NOTEBOOK (window->priv->notebook), page_num);
1777     }
1778 
1779   /* free info */
1780   terminal_tab_attr_free (tab_attr);
1781 
1782   terminal_window_update_actions (window);
1783   terminal_screen_launch_child (terminal);
1784 }
1785 
1786 
1787 
1788 static void
terminal_window_action_detach_tab(GtkAction * action,TerminalWindow * window)1789 terminal_window_action_detach_tab (GtkAction      *action,
1790                                    TerminalWindow *window)
1791 {
1792   if (G_LIKELY (window->priv->active != NULL))
1793     terminal_window_notebook_create_window (GTK_NOTEBOOK (window->priv->notebook),
1794                                             GTK_WIDGET (window->priv->active),
1795                                             -1, -1, window);
1796 }
1797 
1798 
1799 
1800 static void
terminal_window_action_close_tab(GtkAction * action,TerminalWindow * window)1801 terminal_window_action_close_tab (GtkAction      *action,
1802                                   TerminalWindow *window)
1803 {
1804   if (G_LIKELY (window->priv->active != NULL))
1805     terminal_window_close_tab_request (window->priv->active, window);
1806 }
1807 
1808 
1809 
1810 static void
terminal_window_action_close_other_tabs(GtkAction * action,TerminalWindow * window)1811 terminal_window_action_close_other_tabs (GtkAction      *action,
1812                                          TerminalWindow *window)
1813 {
1814   GtkNotebook *notebook = GTK_NOTEBOOK (window->priv->notebook);
1815   gint         npages, n;
1816 
1817   /* move current page to the beginning */
1818   gtk_notebook_reorder_child (notebook, GTK_WIDGET (window->priv->active), 0);
1819 
1820   /* remove the others */
1821   npages = gtk_notebook_get_n_pages (notebook);
1822   for (n = npages - 1; n > 0; n--)
1823     terminal_window_close_tab_request (TERMINAL_SCREEN (gtk_notebook_get_nth_page (notebook, n)), window);
1824 }
1825 
1826 
1827 
1828 static void
terminal_window_action_close_window(GtkAction * action,TerminalWindow * window)1829 terminal_window_action_close_window (GtkAction      *action,
1830                                      TerminalWindow *window)
1831 {
1832   /* this will invoke the "delete-event" handler */
1833   gtk_window_close (GTK_WINDOW (window));
1834 }
1835 
1836 
1837 
1838 static void
terminal_window_action_copy(GtkAction * action,TerminalWindow * window)1839 terminal_window_action_copy (GtkAction      *action,
1840                              TerminalWindow *window)
1841 {
1842   if (G_LIKELY (window->priv->active != NULL))
1843     terminal_screen_copy_clipboard (window->priv->active);
1844 }
1845 
1846 
1847 
1848 #if VTE_CHECK_VERSION (0, 49, 2)
1849 static void
terminal_window_action_copy_html(GtkAction * action,TerminalWindow * window)1850 terminal_window_action_copy_html (GtkAction      *action,
1851                                   TerminalWindow *window)
1852 {
1853   if (G_LIKELY (window->priv->active != NULL))
1854     terminal_screen_copy_clipboard_html (window->priv->active);
1855 }
1856 #endif
1857 
1858 
1859 
1860 static void
terminal_window_action_paste(GtkAction * action,TerminalWindow * window)1861 terminal_window_action_paste (GtkAction      *action,
1862                               TerminalWindow *window)
1863 {
1864   if (G_LIKELY (window->priv->active != NULL))
1865     terminal_screen_paste_clipboard (window->priv->active);
1866 }
1867 
1868 
1869 
1870 static void
terminal_window_action_paste_selection(GtkAction * action,TerminalWindow * window)1871 terminal_window_action_paste_selection (GtkAction      *action,
1872                                         TerminalWindow *window)
1873 {
1874   if (G_LIKELY (window->priv->active != NULL))
1875     terminal_screen_paste_primary (window->priv->active);
1876 }
1877 
1878 
1879 
1880 static void
terminal_window_action_select_all(GtkAction * action,TerminalWindow * window)1881 terminal_window_action_select_all (GtkAction      *action,
1882                                    TerminalWindow *window)
1883 {
1884   if (G_LIKELY (window->priv->active != NULL))
1885     terminal_screen_select_all (window->priv->active);
1886 }
1887 
1888 
1889 
1890 static void
copy_input_popover_close(GtkWidget * popover,TerminalWindow * window)1891 copy_input_popover_close (GtkWidget      *popover,
1892                           TerminalWindow *window)
1893 {
1894   /* need for hiding on focus */
1895   if (window->priv->drop_down)
1896     terminal_util_activate_window (GTK_WINDOW (window));
1897 
1898   /* close the dialog */
1899   gtk_widget_destroy (popover);
1900 
1901   /* focus the terminal */
1902   if (TERMINAL_IS_SCREEN (window->priv->active))
1903     terminal_screen_focus (window->priv->active);
1904 }
1905 
1906 
1907 
1908 static void
copy_input_popover_do_copy(GtkWidget * popover,GtkWidget * entry)1909 copy_input_popover_do_copy (GtkWidget *popover,
1910                             GtkWidget *entry)
1911 {
1912   TerminalWindow *window = TERMINAL_WINDOW (gtk_widget_get_toplevel (popover));
1913   GtkNotebook    *notebook = GTK_NOTEBOOK (window->priv->notebook);
1914   gint            n, npages = gtk_notebook_get_n_pages (notebook);
1915 
1916   /* copy the input to all tabs */
1917   for (n = 0; n < npages; n++)
1918     {
1919       TerminalScreen *screen = TERMINAL_SCREEN (gtk_notebook_get_nth_page (notebook, n));
1920       terminal_screen_feed_text (screen, gtk_entry_get_text (GTK_ENTRY (entry)));
1921     }
1922 }
1923 
1924 
1925 
1926 static void
terminal_window_action_copy_input(GtkAction * action,TerminalWindow * window)1927 terminal_window_action_copy_input (GtkAction      *action,
1928                                    TerminalWindow *window)
1929 {
1930   GtkWidget *popover, *button, *box, *label, *entry;
1931 
1932   popover = gtk_popover_new (GTK_WIDGET (window->priv->menubar));
1933   gtk_popover_set_position (GTK_POPOVER (popover), GTK_POS_BOTTOM);
1934 
1935   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
1936   gtk_container_set_border_width (GTK_CONTAINER (box), 6);
1937   gtk_container_add (GTK_CONTAINER (popover), box);
1938 
1939   label = gtk_label_new_with_mnemonic (_("Copy _Input:"));
1940   gtk_container_add (GTK_CONTAINER (box), label);
1941 
1942   entry = gtk_entry_new ();
1943   gtk_widget_set_tooltip_text (entry, _("Enter the text to be copied to all tabs"));
1944   gtk_container_add (GTK_CONTAINER (box), entry);
1945   gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
1946   gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
1947   g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (copy_input_popover_do_copy), entry);
1948 
1949   button = gtk_button_new_from_icon_name ("edit-copy-symbolic", GTK_ICON_SIZE_BUTTON);
1950   gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
1951   gtk_widget_set_tooltip_text (button, _("Copy input"));
1952   gtk_container_add (GTK_CONTAINER (box), button);
1953   g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (copy_input_popover_do_copy), entry);
1954 
1955   g_signal_connect (G_OBJECT (popover), "closed", G_CALLBACK (copy_input_popover_close), window);
1956 
1957   gtk_widget_show_all (popover);
1958 }
1959 
1960 
1961 
1962 static void
terminal_window_action_prefs_died(gpointer user_data,GObject * where_the_object_was)1963 terminal_window_action_prefs_died (gpointer  user_data,
1964                                    GObject  *where_the_object_was)
1965 {
1966   TerminalWindow *window = TERMINAL_WINDOW (user_data);
1967 
1968   window->priv->preferences_dialog = NULL;
1969   window->priv->n_child_windows--;
1970 
1971   if (window->priv->drop_down)
1972     terminal_util_activate_window (GTK_WINDOW (window));
1973 }
1974 
1975 
1976 
1977 static void
terminal_window_action_prefs(GtkAction * action,TerminalWindow * window)1978 terminal_window_action_prefs (GtkAction      *action,
1979                               TerminalWindow *window)
1980 {
1981   if (window->priv->preferences_dialog == NULL)
1982     {
1983       window->priv->preferences_dialog = terminal_preferences_dialog_new (window->priv->drop_down, window->priv->drop_down);
1984       if (G_LIKELY (window->priv->preferences_dialog != NULL))
1985         {
1986           window->priv->n_child_windows++;
1987           g_object_weak_ref (G_OBJECT (window->priv->preferences_dialog),
1988                              terminal_window_action_prefs_died, window);
1989         }
1990     }
1991 
1992   if (window->priv->preferences_dialog != NULL)
1993     {
1994       gtk_window_set_transient_for (GTK_WINDOW (window->priv->preferences_dialog), GTK_WINDOW (window));
1995       gtk_window_present (GTK_WINDOW (window->priv->preferences_dialog));
1996     }
1997 }
1998 
1999 
2000 
2001 static void
terminal_window_action_show_toolbar(GtkToggleAction * action,TerminalWindow * window)2002 terminal_window_action_show_toolbar (GtkToggleAction *action,
2003                                      TerminalWindow  *window)
2004 {
2005   gboolean show;
2006 
2007   terminal_return_if_fail (GTK_IS_UI_MANAGER (window->priv->ui_manager));
2008   terminal_return_if_fail (GTK_IS_ACTION_GROUP (window->priv->action_group));
2009 
2010   terminal_window_size_push (window);
2011 
2012 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2013   show = gtk_toggle_action_get_active (action);
2014 G_GNUC_END_IGNORE_DEPRECATIONS
2015   if (show)
2016     {
2017       if (window->priv->toolbar == NULL)
2018         {
2019 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2020           window->priv->toolbar = gtk_ui_manager_get_widget (window->priv->ui_manager, "/main-toolbar");
2021 G_GNUC_END_IGNORE_DEPRECATIONS
2022           gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->toolbar, FALSE, FALSE, 0);
2023           gtk_box_reorder_child (GTK_BOX (window->priv->vbox),
2024                                  window->priv->toolbar,
2025                                  window->priv->menubar != NULL ? 1 : 0);
2026         }
2027 
2028       gtk_widget_show (window->priv->toolbar);
2029     }
2030   else if (window->priv->toolbar != NULL)
2031     {
2032       gtk_widget_hide (window->priv->toolbar);
2033     }
2034 
2035   terminal_window_size_pop (window);
2036 }
2037 
2038 
2039 
2040 static void
terminal_window_action_show_borders(GtkToggleAction * action,TerminalWindow * window)2041 terminal_window_action_show_borders (GtkToggleAction *action,
2042                                      TerminalWindow  *window)
2043 {
2044 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2045   gboolean decorated = gtk_toggle_action_get_active (action);
2046 G_GNUC_END_IGNORE_DEPRECATIONS
2047 
2048   gtk_window_set_decorated (GTK_WINDOW (window), decorated);
2049 }
2050 
2051 
2052 
2053 static void
terminal_window_action_fullscreen(GtkToggleAction * action,TerminalWindow * window)2054 terminal_window_action_fullscreen (GtkToggleAction *action,
2055                                    TerminalWindow  *window)
2056 {
2057   gboolean fullscreen;
2058 
2059   if (gtk_widget_get_visible (GTK_WIDGET (window)))
2060     {
2061 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2062       fullscreen = gtk_toggle_action_get_active (action);
2063 G_GNUC_END_IGNORE_DEPRECATIONS
2064       if (fullscreen)
2065         gtk_window_fullscreen (GTK_WINDOW (window));
2066       else
2067         gtk_window_unfullscreen (GTK_WINDOW (window));
2068     }
2069 }
2070 
2071 
2072 
2073 static void
terminal_window_action_readonly(GtkToggleAction * action,TerminalWindow * window)2074 terminal_window_action_readonly (GtkToggleAction *action,
2075                                  TerminalWindow  *window)
2076 {
2077   gboolean input_enabled;
2078 
2079   terminal_return_if_fail (window->priv->active != NULL);
2080 
2081 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2082   input_enabled = !gtk_toggle_action_get_active (action);
2083   if (terminal_screen_get_input_enabled (window->priv->active) != input_enabled)
2084     {
2085       gtk_action_set_sensitive (terminal_window_get_action (window, "reset"), input_enabled);
2086       gtk_action_set_sensitive (terminal_window_get_action (window, "reset-and-clear"), input_enabled);
2087       gtk_action_set_sensitive (terminal_window_get_action (window, "paste"), input_enabled);
2088       gtk_action_set_sensitive (terminal_window_get_action (window, "paste-selection"), input_enabled);
2089       terminal_screen_set_input_enabled (window->priv->active, input_enabled);
2090     }
2091 G_GNUC_END_IGNORE_DEPRECATIONS
2092 }
2093 
2094 
2095 
2096 static void
terminal_window_action_scroll_on_output(GtkToggleAction * action,TerminalWindow * window)2097 terminal_window_action_scroll_on_output (GtkToggleAction *action,
2098                                          TerminalWindow  *window)
2099 {
2100   gboolean scroll_enabled;
2101 
2102   terminal_return_if_fail (window->priv->active != NULL);
2103 
2104 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2105   scroll_enabled = gtk_toggle_action_get_active (action);
2106   if (terminal_screen_get_scroll_on_output (window->priv->active) != scroll_enabled)
2107     terminal_screen_set_scroll_on_output (window->priv->active, scroll_enabled);
2108 G_GNUC_END_IGNORE_DEPRECATIONS
2109 }
2110 
2111 
2112 
2113 static void
terminal_window_action_zoom_in(GtkAction * action,TerminalWindow * window)2114 terminal_window_action_zoom_in (GtkAction     *action,
2115                                TerminalWindow *window)
2116 {
2117   terminal_return_if_fail (window->priv->active != NULL);
2118 
2119   if (window->priv->zoom < TERMINAL_ZOOM_LEVEL_MAXIMUM)
2120     {
2121       ++window->priv->zoom;
2122       terminal_window_zoom_update_screens (window);
2123     }
2124 }
2125 
2126 
2127 
2128 static void
terminal_window_action_zoom_out(GtkAction * action,TerminalWindow * window)2129 terminal_window_action_zoom_out (GtkAction      *action,
2130                                  TerminalWindow *window)
2131 {
2132   terminal_return_if_fail (window->priv->active != NULL);
2133 
2134   if (window->priv->zoom > TERMINAL_ZOOM_LEVEL_MINIMUM)
2135     {
2136       --window->priv->zoom;
2137       terminal_window_zoom_update_screens (window);
2138     }
2139 }
2140 
2141 
2142 
2143 static void
terminal_window_action_zoom_reset(GtkAction * action,TerminalWindow * window)2144 terminal_window_action_zoom_reset (GtkAction      *action,
2145                                    TerminalWindow *window)
2146 {
2147   terminal_return_if_fail (window->priv->active != NULL);
2148 
2149   if (window->priv->zoom != TERMINAL_ZOOM_LEVEL_DEFAULT)
2150     {
2151       window->priv->zoom = TERMINAL_ZOOM_LEVEL_DEFAULT;
2152       terminal_window_zoom_update_screens (window);
2153     }
2154 }
2155 
2156 
2157 
2158 static void
terminal_window_action_prev_tab(GtkAction * action,TerminalWindow * window)2159 terminal_window_action_prev_tab (GtkAction      *action,
2160                                  TerminalWindow *window)
2161 {
2162   terminal_window_switch_tab (GTK_NOTEBOOK (window->priv->notebook), TRUE);
2163   terminal_window_update_actions (window);
2164 }
2165 
2166 
2167 
2168 static void
terminal_window_action_next_tab(GtkAction * action,TerminalWindow * window)2169 terminal_window_action_next_tab (GtkAction      *action,
2170                                  TerminalWindow *window)
2171 {
2172   terminal_window_switch_tab (GTK_NOTEBOOK (window->priv->notebook), FALSE);
2173   terminal_window_update_actions (window);
2174 }
2175 
2176 
2177 
2178 static void
terminal_window_action_last_active_tab(GtkAction * action,TerminalWindow * window)2179 terminal_window_action_last_active_tab (GtkAction      *action,
2180                                         TerminalWindow *window)
2181 {
2182   if (window->priv->last_active != NULL)
2183     {
2184       GtkNotebook *notebook = GTK_NOTEBOOK (window->priv->notebook);
2185       gint page_num = gtk_notebook_page_num (notebook, GTK_WIDGET (window->priv->last_active));
2186       gtk_notebook_set_current_page (notebook, page_num);
2187       terminal_window_update_actions (window);
2188     }
2189 }
2190 
2191 
2192 
2193 static void
terminal_window_action_move_tab_left(GtkAction * action,TerminalWindow * window)2194 terminal_window_action_move_tab_left (GtkAction      *action,
2195                                       TerminalWindow *window)
2196 {
2197   terminal_window_move_tab (GTK_NOTEBOOK (window->priv->notebook), TRUE);
2198   terminal_window_update_actions (window);
2199 }
2200 
2201 
2202 
2203 static void
terminal_window_action_move_tab_right(GtkAction * action,TerminalWindow * window)2204 terminal_window_action_move_tab_right (GtkAction      *action,
2205                                        TerminalWindow *window)
2206 {
2207   terminal_window_move_tab (GTK_NOTEBOOK (window->priv->notebook), FALSE);
2208   terminal_window_update_actions (window);
2209 }
2210 
2211 
2212 
2213 static void
terminal_window_action_goto_tab(GtkRadioAction * action,GtkNotebook * notebook)2214 terminal_window_action_goto_tab (GtkRadioAction *action,
2215                                  GtkNotebook    *notebook)
2216 {
2217   gint page;
2218 
2219   terminal_return_if_fail (GTK_IS_NOTEBOOK (notebook));
2220   terminal_return_if_fail (GTK_IS_RADIO_ACTION (action));
2221 
2222 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2223   if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2224     {
2225       /* switch to the new page */
2226       page = gtk_radio_action_get_current_value (action);
2227       gtk_notebook_set_current_page (notebook, page);
2228     }
2229 G_GNUC_END_IGNORE_DEPRECATIONS
2230 }
2231 
2232 
2233 
2234 static void
title_popover_close(GtkWidget * popover,TerminalWindow * window)2235 title_popover_close (GtkWidget      *popover,
2236                      TerminalWindow *window)
2237 {
2238   terminal_return_if_fail (window->priv->title_popover != NULL);
2239 
2240   /* need for hiding on focus */
2241   if (window->priv->drop_down)
2242     terminal_util_activate_window (GTK_WINDOW (window));
2243 
2244   /* close the dialog */
2245   gtk_widget_destroy (window->priv->title_popover);
2246   window->priv->title_popover = NULL;
2247 
2248   /* focus the terminal: bug #13754 */
2249   if (TERMINAL_IS_SCREEN (window->priv->active))
2250     terminal_screen_focus (window->priv->active);
2251 }
2252 
2253 
2254 
2255 static void
title_popover_help(GtkWidget * popover,TerminalWindow * window)2256 title_popover_help (GtkWidget      *popover,
2257                     TerminalWindow *window)
2258 {
2259   /* open the "Set Title" paragraph in the "Usage" section */
2260   xfce_dialog_show_help (GTK_WINDOW (window), "terminal", "usage#to_change_the_terminal_title", NULL);
2261 }
2262 
2263 
2264 
2265 static void
title_popover_clear(GtkWidget * entry,GtkEntryIconPosition icon_pos)2266 title_popover_clear (GtkWidget            *entry,
2267                      GtkEntryIconPosition  icon_pos)
2268 {
2269   if (icon_pos == GTK_ENTRY_ICON_SECONDARY)
2270     gtk_entry_set_text (GTK_ENTRY (entry), "");
2271 }
2272 
2273 
2274 
2275 static void
terminal_window_action_set_title(GtkAction * action,TerminalWindow * window)2276 terminal_window_action_set_title (GtkAction      *action,
2277                                   TerminalWindow *window)
2278 {
2279   GtkWidget *button;
2280   GtkWidget *box;
2281   GtkWidget *label;
2282   GtkWidget *entry;
2283 
2284   terminal_return_if_fail (window->priv->active != NULL);
2285 
2286   if (window->priv->title_popover == NULL)
2287     {
2288       if (gtk_notebook_get_show_tabs (GTK_NOTEBOOK (window->priv->notebook)))
2289         {
2290           window->priv->title_popover =
2291               gtk_popover_new (gtk_notebook_get_tab_label (GTK_NOTEBOOK (window->priv->notebook),
2292                                                            GTK_WIDGET (window->priv->active)));
2293         }
2294       else
2295         {
2296           window->priv->title_popover = gtk_popover_new (GTK_WIDGET (window->priv->menubar));
2297           gtk_popover_set_position (GTK_POPOVER (window->priv->title_popover), GTK_POS_BOTTOM);
2298         }
2299 
2300       box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
2301       gtk_container_set_border_width (GTK_CONTAINER (box), 6);
2302       gtk_container_add (GTK_CONTAINER (window->priv->title_popover), box);
2303 
2304       label = gtk_label_new_with_mnemonic (_("_Title:"));
2305       gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
2306 
2307       entry = gtk_entry_new ();
2308       gtk_widget_set_tooltip_text (entry, _("Enter the title for the current terminal tab"));
2309       gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0);
2310       gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
2311       gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
2312       gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, "edit-clear");
2313       gtk_entry_set_icon_tooltip_text (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, _("Reset"));
2314       g_signal_connect (G_OBJECT (entry), "icon-release", G_CALLBACK (title_popover_clear), NULL);
2315       g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (title_popover_close), window);
2316 
2317       g_object_bind_property (G_OBJECT (window->priv->active), "custom-title",
2318                               G_OBJECT (entry), "text",
2319                               G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
2320 
2321       button = gtk_button_new_from_icon_name ("help-browser", GTK_ICON_SIZE_BUTTON);
2322       gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
2323       gtk_widget_set_tooltip_text (button, _("Help"));
2324       g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (title_popover_help), window);
2325       gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
2326 
2327       button = gtk_button_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_BUTTON);
2328       gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
2329       gtk_widget_set_tooltip_text (button, _("Close"));
2330       g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (title_popover_close), window);
2331       gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
2332 
2333       g_signal_connect (G_OBJECT (window->priv->title_popover), "closed",
2334                         G_CALLBACK (title_popover_close), window);
2335     }
2336 
2337   gtk_widget_show_all (window->priv->title_popover);
2338 }
2339 
2340 
2341 
2342 static void
terminal_window_action_set_title_color(GtkAction * action,TerminalWindow * window)2343 terminal_window_action_set_title_color (GtkAction      *action,
2344                                         TerminalWindow *window)
2345 {
2346   GtkWidget *dialog;
2347   gchar     *color_string;
2348   GdkRGBA    color;
2349   int        response;
2350 
2351   dialog = gtk_color_chooser_dialog_new (_("Choose title color"), GTK_WINDOW (window));
2352   gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Reset"), GTK_RESPONSE_NO);
2353   response = gtk_dialog_run (GTK_DIALOG (dialog));
2354 
2355   if (response == GTK_RESPONSE_OK)
2356     {
2357       gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (dialog), &color);
2358       color_string = gdk_rgba_to_string (&color);
2359       terminal_screen_set_custom_title_color (window->priv->active, color_string);
2360       g_free (color_string);
2361     }
2362   else if (response == GTK_RESPONSE_NO)
2363     terminal_screen_set_custom_title_color (window->priv->active, NULL);
2364 
2365   gtk_widget_destroy (dialog);
2366 }
2367 
2368 
2369 
2370 static void
terminal_window_action_search_response(GtkWidget * dialog,gint response_id,TerminalWindow * window)2371 terminal_window_action_search_response (GtkWidget      *dialog,
2372                                         gint            response_id,
2373                                         TerminalWindow *window)
2374 {
2375   gboolean  can_search;
2376 
2377   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
2378   terminal_return_if_fail (TERMINAL_IS_SEARCH_DIALOG (dialog));
2379   terminal_return_if_fail (TERMINAL_IS_SCREEN (window->priv->active));
2380   terminal_return_if_fail (window->priv->search_dialog == dialog);
2381 
2382   if (response_id == TERMINAL_RESPONSE_SEARCH_NEXT)
2383     terminal_window_action_search_next (NULL, window);
2384   else if (response_id == TERMINAL_RESPONSE_SEARCH_PREV)
2385     terminal_window_action_search_prev (NULL, window);
2386   else
2387     {
2388       /* need for hiding on focus */
2389       if (window->priv->drop_down)
2390         terminal_util_activate_window (GTK_WINDOW (window));
2391 
2392       /* hide dialog */
2393       window->priv->n_child_windows--;
2394       gtk_widget_hide (dialog);
2395     }
2396 
2397   /* update actions */
2398   can_search = terminal_screen_search_has_gregex (window->priv->active);
2399 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2400   gtk_action_set_sensitive (window->priv->action_search_next, can_search);
2401   gtk_action_set_sensitive (window->priv->action_search_prev, can_search);
2402 G_GNUC_END_IGNORE_DEPRECATIONS
2403 }
2404 
2405 
2406 
2407 static void
terminal_window_action_search(GtkAction * action,TerminalWindow * window)2408 terminal_window_action_search (GtkAction      *action,
2409                                TerminalWindow *window)
2410 {
2411   if (window->priv->search_dialog == NULL)
2412     {
2413       window->priv->search_dialog = terminal_search_dialog_new (GTK_WINDOW (window));
2414       g_signal_connect (G_OBJECT (window->priv->search_dialog), "response",
2415           G_CALLBACK (terminal_window_action_search_response), window);
2416       g_signal_connect (G_OBJECT (window->priv->search_dialog), "delete-event",
2417           G_CALLBACK (gtk_widget_hide_on_delete), NULL);
2418     }
2419 
2420   /* increase child counter */
2421   if (!gtk_widget_get_visible (window->priv->search_dialog))
2422     window->priv->n_child_windows++;
2423 
2424   terminal_search_dialog_present (TERMINAL_SEARCH_DIALOG (window->priv->search_dialog));
2425 }
2426 
2427 
2428 
2429 static gboolean
prepare_regex(TerminalWindow * window)2430 prepare_regex (TerminalWindow *window)
2431 {
2432   VteRegex *regex;
2433   GError   *error = NULL;
2434   gboolean  wrap_around;
2435 
2436   regex = terminal_search_dialog_get_regex (TERMINAL_SEARCH_DIALOG (window->priv->search_dialog), &error);
2437   if (G_LIKELY (error == NULL))
2438     {
2439       wrap_around = terminal_search_dialog_get_wrap_around (TERMINAL_SEARCH_DIALOG (window->priv->search_dialog));
2440       terminal_screen_search_set_gregex (window->priv->active, regex, wrap_around);
2441       if (regex != NULL)
2442         vte_regex_unref (regex);
2443 
2444       return TRUE;
2445     }
2446 
2447   xfce_dialog_show_error (GTK_WINDOW (window->priv->search_dialog), error,
2448                           _("Failed to create the regular expression"));
2449   g_error_free (error);
2450 
2451   return FALSE;
2452 }
2453 
2454 
2455 
2456 static void
terminal_window_action_search_next(GtkAction * action,TerminalWindow * window)2457 terminal_window_action_search_next (GtkAction      *action,
2458                                     TerminalWindow *window)
2459 {
2460   if (prepare_regex (window))
2461     terminal_screen_search_find_next (window->priv->active);
2462 }
2463 
2464 
2465 
2466 static void
terminal_window_action_search_prev(GtkAction * action,TerminalWindow * window)2467 terminal_window_action_search_prev (GtkAction      *action,
2468                                     TerminalWindow *window)
2469 {
2470   if (prepare_regex (window))
2471     terminal_screen_search_find_previous (window->priv->active);
2472 }
2473 
2474 
2475 
2476 static void
terminal_window_action_save_contents(GtkAction * action,TerminalWindow * window)2477 terminal_window_action_save_contents (GtkAction      *action,
2478                                       TerminalWindow *window)
2479 {
2480   GtkWidget     *dialog;
2481   GFile         *file;
2482   GOutputStream *stream;
2483   GError        *error = NULL;
2484   gchar         *filename_uri;
2485   gint           response;
2486 
2487   terminal_return_if_fail (window->priv->active != NULL);
2488 
2489   dialog = gtk_file_chooser_dialog_new (_("Save contents..."),
2490                                         GTK_WINDOW (window),
2491                                         GTK_FILE_CHOOSER_ACTION_SAVE,
2492                                         _("_Cancel"), GTK_RESPONSE_CANCEL,
2493                                         _("_Save"), GTK_RESPONSE_ACCEPT,
2494                                         NULL);
2495   gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
2496 
2497   /* save to current working directory */
2498   gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
2499                                        terminal_screen_get_working_directory (TERMINAL_SCREEN (window->priv->active)));
2500 
2501   gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
2502   gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
2503   gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
2504 
2505   gtk_widget_show_all (dialog);
2506 
2507   response = gtk_dialog_run (GTK_DIALOG (dialog));
2508   if (response != GTK_RESPONSE_ACCEPT)
2509     {
2510       gtk_widget_destroy (dialog);
2511       return;
2512     }
2513 
2514   filename_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
2515   gtk_widget_destroy (dialog);
2516 
2517   if (filename_uri == NULL)
2518     return;
2519 
2520   file = g_file_new_for_uri (filename_uri);
2521   stream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error));
2522   if (stream)
2523     {
2524       terminal_screen_save_contents (TERMINAL_SCREEN (window->priv->active), stream, error);
2525       g_object_unref (stream);
2526     }
2527 
2528   if (error)
2529     {
2530       xfce_dialog_show_error (GTK_WINDOW (window), error, _("Failed to save terminal contents"));
2531       g_error_free (error);
2532     }
2533 
2534   g_object_unref (file);
2535   g_free (filename_uri);
2536 }
2537 
2538 
2539 
2540 static void
terminal_window_action_reset(GtkAction * action,TerminalWindow * window)2541 terminal_window_action_reset (GtkAction      *action,
2542                               TerminalWindow *window)
2543 {
2544   if (G_LIKELY (window->priv->active != NULL))
2545     terminal_screen_reset (window->priv->active, FALSE);
2546 }
2547 
2548 
2549 
2550 static void
terminal_window_action_reset_and_clear(GtkAction * action,TerminalWindow * window)2551 terminal_window_action_reset_and_clear (GtkAction       *action,
2552                                         TerminalWindow  *window)
2553 {
2554   if (G_LIKELY (window->priv->active != NULL))
2555     {
2556       terminal_screen_reset (window->priv->active, TRUE);
2557       terminal_window_update_actions (window);
2558     }
2559 }
2560 
2561 
2562 
2563 static void
terminal_window_action_contents(GtkAction * action,TerminalWindow * window)2564 terminal_window_action_contents (GtkAction       *action,
2565                                  TerminalWindow  *window)
2566 {
2567   /* open the Terminal user manual */
2568   xfce_dialog_show_help (GTK_WINDOW (window), "terminal", NULL, NULL);
2569 }
2570 
2571 
2572 
2573 static void
terminal_window_action_about(GtkAction * action,TerminalWindow * window)2574 terminal_window_action_about (GtkAction      *action,
2575                               TerminalWindow *window)
2576 {
2577   /* display the about dialog */
2578   terminal_util_show_about_dialog (GTK_WINDOW (window));
2579 }
2580 
2581 
2582 
2583 static void
terminal_window_zoom_update_screens(TerminalWindow * window)2584 terminal_window_zoom_update_screens (TerminalWindow *window)
2585 {
2586   gint            npages, n;
2587   TerminalScreen *screen;
2588   GtkAction      *action;
2589 
2590   terminal_return_if_fail (GTK_IS_NOTEBOOK (window->priv->notebook));
2591 
2592   /* walk the tabs */
2593   npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook));
2594   for (n = 0; n < npages; n++)
2595     {
2596       screen = TERMINAL_SCREEN (gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->priv->notebook), n));
2597       terminal_screen_update_font (screen);
2598     }
2599 
2600   /* update zoom actions */
2601   action = terminal_window_get_action (window, "zoom-in");
2602 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2603   if (window->priv->zoom == TERMINAL_ZOOM_LEVEL_MAXIMUM)
2604     gtk_action_set_sensitive (action, FALSE);
2605   else if (!gtk_action_is_sensitive (action))
2606     gtk_action_set_sensitive (action, TRUE);
2607 
2608   action = terminal_window_get_action (window, "zoom-out");
2609   if (window->priv->zoom == TERMINAL_ZOOM_LEVEL_MINIMUM)
2610     gtk_action_set_sensitive (action, FALSE);
2611   else if (!gtk_action_is_sensitive (action))
2612     gtk_action_set_sensitive (action, TRUE);
2613 G_GNUC_END_IGNORE_DEPRECATIONS
2614 }
2615 
2616 
2617 
2618 static void
terminal_window_switch_tab(GtkNotebook * notebook,gboolean switch_left)2619 terminal_window_switch_tab (GtkNotebook *notebook,
2620                             gboolean     switch_left)
2621 {
2622   gint page_num;
2623   gint n_pages;
2624 
2625   page_num = gtk_notebook_get_current_page (notebook);
2626   n_pages = gtk_notebook_get_n_pages (notebook);
2627   gtk_notebook_set_current_page (notebook,
2628                                  (switch_left ? page_num - 1 : page_num + 1) % n_pages);
2629 }
2630 
2631 
2632 
2633 static void
terminal_window_move_tab(GtkNotebook * notebook,gboolean move_left)2634 terminal_window_move_tab (GtkNotebook *notebook,
2635                           gboolean     move_left)
2636 {
2637   gint       page_num;
2638   gint       last_page;
2639   GtkWidget *page;
2640 
2641   page_num = gtk_notebook_get_current_page (notebook);
2642   last_page = gtk_notebook_get_n_pages (notebook) - 1;
2643   page = gtk_notebook_get_nth_page (notebook, page_num);
2644 
2645   if (move_left)
2646     gtk_notebook_reorder_child (notebook, page,
2647                                 page_num == 0 ? last_page : page_num - 1);
2648   else
2649     gtk_notebook_reorder_child (notebook, page,
2650                                 page_num == last_page ? 0 : page_num + 1);
2651 }
2652 
2653 
2654 
2655 static void
terminal_window_toggle_menubar(GtkWidget * widget,TerminalWindow * window)2656 terminal_window_toggle_menubar (GtkWidget      *widget,
2657                                 TerminalWindow *window)
2658 {
2659   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
2660 
2661   terminal_window_size_push (window);
2662   if (terminal_window_get_menubar_height (window) == 0)
2663     gtk_widget_show (window->priv->menubar);
2664   terminal_window_size_pop (window);
2665 }
2666 
2667 
2668 
2669 static void
terminal_window_menubar_deactivate(GtkWidget * widget,TerminalWindow * window)2670 terminal_window_menubar_deactivate (GtkWidget      *widget,
2671                                     TerminalWindow *window)
2672 {
2673   GtkAction *action;
2674 
2675   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
2676 
2677   action = terminal_window_get_action (window, "show-menubar");
2678 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2679   terminal_window_action_show_menubar (GTK_TOGGLE_ACTION (action), window);
2680 G_GNUC_END_IGNORE_DEPRECATIONS
2681 }
2682 
2683 
2684 
2685 static void
terminal_window_do_close_tab(TerminalScreen * screen,TerminalWindow * window)2686 terminal_window_do_close_tab (TerminalScreen *screen,
2687                               TerminalWindow *window)
2688 {
2689   GtkNotebook *notebook = GTK_NOTEBOOK (window->priv->notebook);
2690 
2691   /* store attrs of the tab being closed */
2692   TerminalTabAttr *tab_attr = terminal_tab_attr_new ();
2693   tab_attr->active = (screen == window->priv->active);
2694   tab_attr->position = gtk_notebook_page_num (notebook, GTK_WIDGET (screen));
2695   tab_attr->directory = g_strdup (terminal_screen_get_working_directory (screen));
2696   if (IS_STRING (terminal_screen_get_custom_title (screen)))
2697     tab_attr->title = g_strdup (terminal_screen_get_custom_title (screen));
2698   if (IS_STRING (terminal_screen_get_custom_fg_color (screen)))
2699     tab_attr->color_text = g_strdup (terminal_screen_get_custom_fg_color (screen));
2700   if (IS_STRING (terminal_screen_get_custom_bg_color (screen)))
2701     tab_attr->color_bg = g_strdup (terminal_screen_get_custom_bg_color (screen));
2702   if (IS_STRING (terminal_screen_get_custom_title_color (screen)))
2703     tab_attr->color_title = g_strdup (terminal_screen_get_custom_title_color (screen));
2704   g_queue_push_tail (window->priv->closed_tabs_list, tab_attr);
2705 
2706   /* switch to the previously active tab */
2707   if (screen == window->priv->active && window->priv->last_active != NULL)
2708     {
2709       gint page_num = gtk_notebook_page_num (notebook, GTK_WIDGET (window->priv->last_active));
2710       gtk_notebook_set_current_page (notebook, page_num);
2711     }
2712 
2713   gtk_widget_destroy (GTK_WIDGET (screen));
2714 }
2715 
2716 
2717 
2718 /**
2719  * terminal_window_new:
2720  * @fullscreen: Whether to set the window to fullscreen.
2721  * @menubar   : Visibility setting for the menubar.
2722  * @borders   : Visibility setting for the window borders.
2723  * @toolbar   : Visibility setting for the toolbar.
2724  *
2725  * Return value:
2726  **/
2727 GtkWidget*
terminal_window_new(const gchar * role,gboolean fullscreen,TerminalVisibility menubar,TerminalVisibility borders,TerminalVisibility toolbar)2728 terminal_window_new (const gchar       *role,
2729                      gboolean           fullscreen,
2730                      TerminalVisibility menubar,
2731                      TerminalVisibility borders,
2732                      TerminalVisibility toolbar)
2733 {
2734   TerminalWindow *window;
2735   GtkAction      *action;
2736   gboolean        show_menubar;
2737   gboolean        show_toolbar;
2738   gboolean        show_borders;
2739 
2740   window = g_object_new (TERMINAL_TYPE_WINDOW, "role", role, NULL);
2741 
2742   /* read default preferences */
2743   g_object_get (G_OBJECT (window->priv->preferences),
2744                 "misc-menubar-default", &show_menubar,
2745                 "misc-toolbar-default", &show_toolbar,
2746                 "misc-borders-default", &show_borders,
2747                 NULL);
2748 
2749 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2750   /* setup full screen */
2751   if (fullscreen && gtk_action_is_sensitive (window->priv->action_fullscreen))
2752     gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (window->priv->action_fullscreen), TRUE);
2753 
2754   /* setup menubar visibility */
2755   if (G_LIKELY (menubar != TERMINAL_VISIBILITY_DEFAULT))
2756     show_menubar = (menubar == TERMINAL_VISIBILITY_SHOW);
2757   action = terminal_window_get_action (window, "show-menubar");
2758   gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), show_menubar);
2759   terminal_window_action_show_menubar (GTK_TOGGLE_ACTION (action), window);
2760 
2761   /* setup toolbar visibility */
2762   if (G_LIKELY (toolbar != TERMINAL_VISIBILITY_DEFAULT))
2763     show_toolbar = (toolbar == TERMINAL_VISIBILITY_SHOW);
2764   action = terminal_window_get_action (window, "show-toolbar");
2765   gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), show_toolbar);
2766 
2767   /* setup borders visibility */
2768   if (G_LIKELY (borders != TERMINAL_VISIBILITY_DEFAULT))
2769     show_borders = (borders == TERMINAL_VISIBILITY_SHOW);
2770   action = terminal_window_get_action (window, "show-borders");
2771   gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), show_borders);
2772 G_GNUC_END_IGNORE_DEPRECATIONS
2773 
2774   /* property that is not suitable for init */
2775   g_object_bind_property (G_OBJECT (window->priv->preferences), "misc-tab-position",
2776                           G_OBJECT (window->priv->notebook), "tab-pos",
2777                           G_BINDING_SYNC_CREATE);
2778 
2779   return GTK_WIDGET (window);
2780 }
2781 
2782 
2783 
2784 /**
2785  * terminal_window_add:
2786  * @window  : A #TerminalWindow.
2787  * @screen  : A #TerminalScreen.
2788  **/
2789 void
terminal_window_add(TerminalWindow * window,TerminalScreen * screen)2790 terminal_window_add (TerminalWindow *window,
2791                      TerminalScreen *screen)
2792 {
2793   GtkWidget *label;
2794   gint       page, position = -1;
2795   gboolean   adjacent;
2796 
2797   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
2798   terminal_return_if_fail (TERMINAL_IS_SCREEN (screen));
2799 
2800   /* show the terminal screen first: see bug #13263*/
2801   gtk_widget_show (GTK_WIDGET (screen));
2802 
2803   /* create the tab label */
2804   label = terminal_screen_get_tab_label (screen);
2805 
2806   /* determine the tab position */
2807   g_object_get (G_OBJECT (window->priv->preferences), "misc-new-tab-adjacent", &adjacent, NULL);
2808   if (G_UNLIKELY (adjacent))
2809     position = gtk_notebook_page_num (GTK_NOTEBOOK (window->priv->notebook), GTK_WIDGET (window->priv->active)) + 1;
2810 
2811   page = gtk_notebook_insert_page (GTK_NOTEBOOK (window->priv->notebook), GTK_WIDGET (screen), label, position);
2812   gtk_container_child_set (GTK_CONTAINER (window->priv->notebook), GTK_WIDGET (screen), "tab-expand", TRUE, NULL);
2813   gtk_container_child_set (GTK_CONTAINER (window->priv->notebook), GTK_WIDGET (screen), "tab-fill", TRUE, NULL);
2814 
2815   /* allow tab sorting and dnd */
2816   gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (window->priv->notebook), GTK_WIDGET (screen), TRUE);
2817   gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (window->priv->notebook), GTK_WIDGET (screen), TRUE);
2818 
2819   /* update scrollbar visibility */
2820   if (window->priv->scrollbar_visibility != TERMINAL_VISIBILITY_DEFAULT)
2821     terminal_screen_update_scrolling_bar (screen);
2822 
2823   /* switch to the new tab */
2824   gtk_notebook_set_current_page (GTK_NOTEBOOK (window->priv->notebook), page);
2825 
2826   /* focus the terminal */
2827   terminal_screen_focus (screen);
2828 }
2829 
2830 
2831 
2832 /**
2833  * terminal_window_get_active:
2834  * @window : a #TerminalWindow.
2835  *
2836  * Returns the active #TerminalScreen for @window
2837  * or %NULL.
2838  *
2839  * Return value: the active #TerminalScreen for @window.
2840  **/
2841 TerminalScreen*
terminal_window_get_active(TerminalWindow * window)2842 terminal_window_get_active (TerminalWindow *window)
2843 {
2844   terminal_return_val_if_fail (TERMINAL_IS_WINDOW (window), NULL);
2845   return window->priv->active;
2846 }
2847 
2848 
2849 
2850 /**
2851  * terminal_window_notebook_show_tabs:
2852  * @window  : A #TerminalWindow.
2853  **/
2854 void
terminal_window_notebook_show_tabs(TerminalWindow * window)2855 terminal_window_notebook_show_tabs (TerminalWindow *window)
2856 {
2857   GtkNotebook *notebook = GTK_NOTEBOOK (window->priv->notebook);
2858   gboolean     show_tabs = TRUE;
2859   gint         npages;
2860 
2861   terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
2862 
2863   /* check preferences */
2864   npages = gtk_notebook_get_n_pages (notebook);
2865   if (npages < 2)
2866     {
2867       g_object_get (G_OBJECT (window->priv->preferences),
2868                     window->priv->drop_down ? "dropdown-always-show-tabs" :
2869                     "misc-always-show-tabs", &show_tabs, NULL);
2870     }
2871 
2872   /* set the visibility of the tabs */
2873   if (gtk_notebook_get_show_tabs (notebook) != show_tabs)
2874     {
2875       /* store size */
2876       terminal_window_size_push (window);
2877 
2878       /* show or hide the tabs */
2879       gtk_notebook_set_show_tabs (notebook, show_tabs);
2880 
2881       /* update the window geometry */
2882       terminal_window_size_pop (window);
2883     }
2884 }
2885 
2886 
2887 
2888 /**
2889  * terminal_window_get_restart_command:
2890  * @window  : A #TerminalWindow.
2891  *
2892  * Return value: A list of strings, which are required to
2893  *               restart the window properly with all tabs
2894  *               and settings. The strings and the list itself
2895  *               need to be freed afterwards.
2896  **/
2897 GSList*
terminal_window_get_restart_command(TerminalWindow * window)2898 terminal_window_get_restart_command (TerminalWindow *window)
2899 {
2900   const gchar *role;
2901   GtkAction   *action;
2902   GdkScreen   *gscreen;
2903   GList       *children, *lp;
2904   GSList      *result = NULL;
2905   glong        w;
2906   glong        h;
2907 
2908   terminal_return_val_if_fail (TERMINAL_IS_WINDOW (window), NULL);
2909 
2910   if (G_LIKELY (window->priv->active != NULL))
2911     {
2912       terminal_screen_get_size (window->priv->active, &w, &h);
2913       result = g_slist_prepend (result, g_strdup_printf ("--geometry=%ldx%ld", w, h));
2914     }
2915 
2916   gscreen = gtk_window_get_screen (GTK_WINDOW (window));
2917   if (G_LIKELY (gscreen != NULL))
2918     {
2919       result = g_slist_prepend (result, g_strdup ("--display"));
2920       result = g_slist_prepend (result, g_strdup (gdk_display_get_name (gdk_screen_get_display (gscreen))));
2921     }
2922 
2923   role = gtk_window_get_role (GTK_WINDOW (window));
2924   if (G_LIKELY (role != NULL))
2925     result = g_slist_prepend (result, g_strdup_printf ("--role=%s", role));
2926 
2927 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2928   if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (window->priv->action_fullscreen)))
2929     result = g_slist_prepend (result, g_strdup ("--fullscreen"));
2930 
2931   action = terminal_window_get_action (window, "show-menubar");
2932   if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2933     result = g_slist_prepend (result, g_strdup ("--show-menubar"));
2934   else
2935     result = g_slist_prepend (result, g_strdup ("--hide-menubar"));
2936 
2937   action = terminal_window_get_action (window, "show-borders");
2938   if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2939     result = g_slist_prepend (result, g_strdup ("--show-borders"));
2940   else
2941     result = g_slist_prepend (result, g_strdup ("--hide-borders"));
2942 
2943   action = terminal_window_get_action (window, "show-toolbar");
2944   if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2945     result = g_slist_prepend (result, g_strdup ("--show-toolbar"));
2946   else
2947     result = g_slist_prepend (result, g_strdup ("--hide-toolbar"));
2948 G_GNUC_END_IGNORE_DEPRECATIONS
2949 
2950   if (window->priv->zoom != TERMINAL_ZOOM_LEVEL_DEFAULT)
2951     result = g_slist_prepend (result, g_strdup_printf ("--zoom=%d", window->priv->zoom));
2952   if (window->priv->font != NULL)
2953     result = g_slist_prepend (result, g_strdup_printf ("--font=%s", window->priv->font));
2954 
2955   /* set restart commands of the tabs */
2956   children = gtk_container_get_children (GTK_CONTAINER (window->priv->notebook));
2957   for (lp = children; lp != NULL; lp = lp->next)
2958     {
2959       if (lp != children)
2960         result = g_slist_prepend (result, g_strdup ("--tab"));
2961       if (window->priv->active == lp->data)
2962         result = g_slist_prepend (result, g_strdup ("--active-tab"));
2963       result = g_slist_concat (terminal_screen_get_restart_command (lp->data), result);
2964     }
2965   g_list_free (children);
2966 
2967   return g_slist_reverse (result);
2968 }
2969 
2970 
2971 
2972 /**
2973  * terminal_window_set_grid_size:
2974  * @window  : A #TerminalWindow.
2975  * @width   : Window width.
2976  * @height  : Window height.
2977  **/
2978 void
terminal_window_set_grid_size(TerminalWindow * window,glong width,glong height)2979 terminal_window_set_grid_size (TerminalWindow *window,
2980                                glong           width,
2981                                glong           height)
2982 {
2983   window->priv->grid_width = width;
2984   window->priv->grid_height = height;
2985 }
2986 
2987 
2988 
2989 /**
2990  * terminal_window_has_children:
2991  * @window  : A #TerminalWindow.
2992  **/
2993 gboolean
terminal_window_has_children(TerminalWindow * window)2994 terminal_window_has_children (TerminalWindow *window)
2995 {
2996   return window->priv->n_child_windows != 0;
2997 }
2998 
2999 
3000 
3001 /**
3002  * terminal_window_get_preferences:
3003  * @window  : A #TerminalWindow.
3004  **/
3005 GObject*
terminal_window_get_preferences(TerminalWindow * window)3006 terminal_window_get_preferences (TerminalWindow *window)
3007 {
3008   return G_OBJECT (window->priv->preferences);
3009 }
3010 
3011 
3012 
3013 /**
3014  * terminal_window_get_vbox:
3015  * @window  : A #TerminalWindow.
3016  **/
3017 GtkWidget*
terminal_window_get_vbox(TerminalWindow * window)3018 terminal_window_get_vbox (TerminalWindow *window)
3019 {
3020   return window->priv->vbox;
3021 }
3022 
3023 
3024 
3025 /**
3026  * terminal_window_get_notebook:
3027  * @window  : A #TerminalWindow.
3028  **/
3029 GtkWidget*
terminal_window_get_notebook(TerminalWindow * window)3030 terminal_window_get_notebook (TerminalWindow *window)
3031 {
3032   return window->priv->notebook;
3033 }
3034 
3035 
3036 
3037 /**
3038  * terminal_window_get_preferences_dialog:
3039  * @window  : A #TerminalWindow.
3040  **/
3041 GtkWidget*
terminal_window_get_preferences_dialog(TerminalWindow * window)3042 terminal_window_get_preferences_dialog (TerminalWindow *window)
3043 {
3044   return window->priv->preferences_dialog;
3045 }
3046 
3047 
3048 
3049 /**
3050  * terminal_window_get_action:
3051  * @window      : A #TerminalWindow.
3052  * @action_name : Name of action.
3053  **/
3054 GtkAction*
terminal_window_get_action(TerminalWindow * window,const gchar * action_name)3055 terminal_window_get_action (TerminalWindow *window,
3056                             const gchar    *action_name)
3057 {
3058 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3059   return gtk_action_group_get_action (window->priv->action_group, action_name);
3060 G_GNUC_END_IGNORE_DEPRECATIONS
3061 }
3062 
3063 
3064 
3065 /**
3066  * terminal_window_get_font:
3067  * @window  : A #TerminalWindow.
3068  **/
3069 const gchar*
terminal_window_get_font(TerminalWindow * window)3070 terminal_window_get_font (TerminalWindow *window)
3071 {
3072   return window->priv->font;
3073 }
3074 
3075 
3076 
3077 /**
3078  * terminal_window_set_font:
3079  * @window  : A #TerminalWindow.
3080  **/
3081 void
terminal_window_set_font(TerminalWindow * window,const gchar * font)3082 terminal_window_set_font (TerminalWindow *window,
3083                           const gchar    *font)
3084 {
3085   terminal_return_if_fail (font != NULL);
3086   g_free (window->priv->font);
3087   window->priv->font = g_strdup (font);
3088 }
3089 
3090 
3091 
3092 /**
3093  * terminal_window_get_scrollbar_visibility:
3094  * @window  : A #TerminalWindow.
3095  **/
3096 TerminalVisibility
terminal_window_get_scrollbar_visibility(TerminalWindow * window)3097 terminal_window_get_scrollbar_visibility (TerminalWindow *window)
3098 {
3099   return window->priv->scrollbar_visibility;
3100 }
3101 
3102 
3103 
3104 /**
3105  * terminal_window_set_scrollbar_visibility:
3106  * @window    : A #TerminalWindow.
3107  * @scrollbar : Scrollbar visibility.
3108  **/
3109 void
terminal_window_set_scrollbar_visibility(TerminalWindow * window,TerminalVisibility scrollbar)3110 terminal_window_set_scrollbar_visibility (TerminalWindow     *window,
3111                                           TerminalVisibility  scrollbar)
3112 {
3113   window->priv->scrollbar_visibility = scrollbar;
3114 }
3115 
3116 
3117 
3118 /**
3119  * terminal_window_get_zoom_level:
3120  * @window  : A #TerminalWindow.
3121  **/
3122 TerminalZoomLevel
terminal_window_get_zoom_level(TerminalWindow * window)3123 terminal_window_get_zoom_level (TerminalWindow *window)
3124 {
3125   return window->priv->zoom;
3126 }
3127 
3128 
3129 
3130 /**
3131  * terminal_window_set_zoom_level:
3132  * @window  : A #TerminalWindow.
3133  * @zoom    : Zoom level.
3134  **/
3135 void
terminal_window_set_zoom_level(TerminalWindow * window,TerminalZoomLevel zoom)3136 terminal_window_set_zoom_level (TerminalWindow    *window,
3137                                 TerminalZoomLevel  zoom)
3138 {
3139   window->priv->zoom = zoom;
3140 }
3141 
3142 
3143 
3144 /**
3145  * terminal_window_is_drop_down:
3146  * @window  : A #TerminalWindow.
3147  **/
3148 gboolean
terminal_window_is_drop_down(TerminalWindow * window)3149 terminal_window_is_drop_down (TerminalWindow *window)
3150 {
3151   return window->priv->drop_down != 0;
3152 }
3153 
3154 
3155 
3156 /**
3157  * terminal_window_set_drop_down:
3158  * @window    : A #TerminalWindow.
3159  * @drop_down : Whether the window is drop-down.
3160  **/
3161 void
terminal_window_set_drop_down(TerminalWindow * window,gboolean drop_down)3162 terminal_window_set_drop_down (TerminalWindow *window,
3163                                gboolean        drop_down)
3164 {
3165   window->priv->drop_down = drop_down;
3166 }
3167 
3168 
3169 
3170 /**
3171  * terminal_window_get_menubar_height:
3172  * @window  : A #TerminalWindow.
3173  **/
3174 gint
terminal_window_get_menubar_height(TerminalWindow * window)3175 terminal_window_get_menubar_height (TerminalWindow *window)
3176 {
3177   GtkRequisition req;
3178 
3179   req.height = 0;
3180 
3181   if (window->priv->menubar != NULL && gtk_widget_get_visible (window->priv->menubar))
3182     gtk_widget_get_preferred_size (window->priv->menubar, &req, NULL);
3183 
3184   return req.height;
3185 }
3186 
3187 
3188 
3189 /**
3190  * terminal_window_get_toolbar_height:
3191  * @window  : A #TerminalWindow.
3192  **/
3193 gint
terminal_window_get_toolbar_height(TerminalWindow * window)3194 terminal_window_get_toolbar_height (TerminalWindow *window)
3195 {
3196   GtkRequisition req;
3197 
3198   req.height = 0;
3199 
3200   if (window->priv->toolbar != NULL && gtk_widget_get_visible (window->priv->toolbar))
3201     gtk_widget_get_preferred_size (window->priv->toolbar, &req, NULL);
3202 
3203   return req.height;
3204 }
3205 
3206 
3207 
3208 /**
3209  * terminal_window_rebuild_tabs_menu:
3210  * @window  : A #TerminalWindow.
3211  **/
3212 void
terminal_window_rebuild_tabs_menu(TerminalWindow * window)3213 terminal_window_rebuild_tabs_menu (TerminalWindow *window)
3214 {
3215   gint            npages, n;
3216   GtkWidget      *page;
3217   GSList         *group = NULL;
3218   GtkRadioAction *radio_action;
3219   gchar           name[50], buf[100];
3220   GSList         *lp;
3221   GtkAccelKey     key = {0};
3222 
3223   if (window->priv->tabs_menu_merge_id != 0)
3224     {
3225       /* remove merge id */
3226 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3227       gtk_ui_manager_remove_ui (window->priv->ui_manager, window->priv->tabs_menu_merge_id);
3228 G_GNUC_END_IGNORE_DEPRECATIONS
3229 
3230       /* drop all the old accels from the action group */
3231       for (lp = window->priv->tabs_menu_actions; lp != NULL; lp = lp->next)
3232         {
3233 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3234           gtk_action_group_remove_action (window->priv->action_group, GTK_ACTION (lp->data));
3235 G_GNUC_END_IGNORE_DEPRECATIONS
3236         }
3237 
3238       g_slist_free (window->priv->tabs_menu_actions);
3239       window->priv->tabs_menu_actions = NULL;
3240     }
3241 
3242   /* create a new merge id */
3243 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3244   window->priv->tabs_menu_merge_id = gtk_ui_manager_new_merge_id (window->priv->ui_manager);
3245 G_GNUC_END_IGNORE_DEPRECATIONS
3246   terminal_assert (window->priv->tabs_menu_actions == NULL);
3247 
3248   /* walk the tabs */
3249   npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook));
3250   for (n = 0; n < npages; n++)
3251     {
3252       page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->priv->notebook), n);
3253 
3254       g_snprintf (name, sizeof (name), "goto-tab-%d", n + 1);
3255 
3256       /* create action */
3257 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3258       radio_action = gtk_radio_action_new (name, NULL, NULL, NULL, n);
3259       gtk_action_set_sensitive (GTK_ACTION (radio_action), npages > 1);
3260       g_object_bind_property (G_OBJECT (page), "title",
3261                               G_OBJECT (radio_action), "label",
3262                               G_BINDING_SYNC_CREATE);
3263       gtk_radio_action_set_group (radio_action, group);
3264       group = gtk_radio_action_get_group (radio_action);
3265       gtk_action_group_add_action (window->priv->action_group, GTK_ACTION (radio_action));
3266 G_GNUC_END_IGNORE_DEPRECATIONS
3267       g_signal_connect (G_OBJECT (radio_action), "activate",
3268           G_CALLBACK (terminal_window_action_goto_tab), window->priv->notebook);
3269 
3270       /* connect action to the page so we can active it when a tab is switched */
3271       g_object_set_qdata_full (G_OBJECT (page), tabs_menu_action_quark,
3272                                radio_action, g_object_unref);
3273 
3274       /* set an accelerator path */
3275       g_snprintf (buf, sizeof (buf), "<Actions>/terminal-window/%s", name);
3276       if (gtk_accel_map_lookup_entry (buf, &key) && key.accel_key != 0)
3277         {
3278 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3279           gtk_action_set_accel_path (GTK_ACTION (radio_action), buf);
3280 G_GNUC_END_IGNORE_DEPRECATIONS
3281         }
3282 
3283 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3284       /* add action in the menu */
3285       gtk_ui_manager_add_ui (window->priv->ui_manager, window->priv->tabs_menu_merge_id,
3286                              "/main-menu/tabs-menu/placeholder-tab-items",
3287                              name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
3288       /* allow underscore to be shown */
3289       g_snprintf (buf, sizeof (buf), "/main-menu/tabs-menu/placeholder-tab-items/%s", name);
3290       gtk_menu_item_set_use_underline (GTK_MENU_ITEM (gtk_ui_manager_get_widget (window->priv->ui_manager, buf)), FALSE);
3291 G_GNUC_END_IGNORE_DEPRECATIONS
3292 
3293       if (npages > 1)
3294         {
3295 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3296           /* add to right-click tab menu */
3297           gtk_ui_manager_add_ui (window->priv->ui_manager, window->priv->tabs_menu_merge_id,
3298                                  "/tab-menu/tabs-menu/placeholder-tab-items",
3299                                  name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
3300           /* allow underscore to be shown */
3301           g_snprintf (buf, sizeof (buf), "/tab-menu/tabs-menu/placeholder-tab-items/%s", name);
3302           gtk_menu_item_set_use_underline (GTK_MENU_ITEM (gtk_ui_manager_get_widget (window->priv->ui_manager, buf)), FALSE);
3303 G_GNUC_END_IGNORE_DEPRECATIONS
3304         }
3305 
3306       /* store */
3307       window->priv->tabs_menu_actions = g_slist_prepend (window->priv->tabs_menu_actions, radio_action);
3308     }
3309 }
3310 
3311 
3312 
3313 /**
3314  * terminal_window_action_show_menubar:
3315  * @action  : A toggle action.
3316  * @window  : A #TerminalWindow.
3317  **/
3318 void
terminal_window_action_show_menubar(GtkToggleAction * action,TerminalWindow * window)3319 terminal_window_action_show_menubar (GtkToggleAction *action,
3320                                      TerminalWindow  *window)
3321 {
3322 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3323   gboolean show = gtk_toggle_action_get_active (action);
3324 G_GNUC_END_IGNORE_DEPRECATIONS
3325 
3326   /* don't do anything if the menubar is already in the desired state (shown/hidden) */
3327   if (gtk_widget_is_visible (window->priv->menubar) != show)
3328     {
3329       terminal_window_size_push (window);
3330 
3331       if (show)
3332         gtk_widget_show (window->priv->menubar);
3333       else
3334         gtk_widget_hide (window->priv->menubar);
3335 
3336       terminal_window_size_pop (window);
3337     }
3338 }
3339 
3340 
3341 
3342 /**
3343  * terminal_window_update_tab_key_accels:
3344  * @window          : A #TerminalWindow.
3345  * @tab_key_accels  : A list of Tab key accelerators.
3346  **/
3347 void
terminal_window_update_tab_key_accels(TerminalWindow * window,GSList * tab_key_accels)3348 terminal_window_update_tab_key_accels (TerminalWindow *window,
3349                                        GSList         *tab_key_accels)
3350 {
3351   window->priv->tab_key_accels = tab_key_accels;
3352 }
3353