/* * Copyright (C) 2012-2021 MATE Developers * * Mate-terminal is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Mate-terminal is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "terminal-actions.h" #include "terminal-app.h" #include "terminal-intl.h" #include "terminal-screen.h" #include "terminal-util.h" #include "terminal-window.h" /* * Application-level action callbacks */ static void action_quit (GSimpleAction *action, GVariant *parameter, gpointer user_data) { GtkApplication *app = GTK_APPLICATION (user_data); GList *windows; /* Close all windows - this will trigger quit */ windows = gtk_application_get_windows (app); while (windows) { GtkWidget *window = GTK_WIDGET (windows->data); windows = windows->next; gtk_widget_destroy (window); } } static void action_new_window (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalApp *app = TERMINAL_APP (user_data); TerminalWindow *window; TerminalProfile *profile; profile = terminal_app_get_profile_for_new_term (app); if (!profile) return; window = terminal_app_new_window (app, gdk_screen_get_default ()); terminal_app_new_terminal (app, window, profile, NULL, NULL, NULL, NULL, 1.0); gtk_window_present (GTK_WINDOW (window)); } static void action_preferences (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalApp *app = TERMINAL_APP (user_data); GtkWindow *parent = NULL; GList *windows; windows = gtk_application_get_windows (GTK_APPLICATION (app)); if (windows) parent = GTK_WINDOW (windows->data); terminal_app_manage_profiles (app, parent); } static void action_help (GSimpleAction *action, GVariant *parameter, gpointer user_data) { GtkApplication *app = GTK_APPLICATION (user_data); GtkWindow *parent = NULL; GList *windows; windows = gtk_application_get_windows (app); if (windows) parent = GTK_WINDOW (windows->data); terminal_util_show_help (NULL, parent); } /* Application action entries */ static const GActionEntry app_actions[] = { { TERMINAL_ACTION_QUIT, action_quit, NULL, NULL, NULL }, { TERMINAL_ACTION_NEW_WINDOW, action_new_window, NULL, NULL, NULL }, { TERMINAL_ACTION_PREFERENCES, action_preferences, NULL, NULL, NULL }, { TERMINAL_ACTION_HELP, action_help, NULL, NULL, NULL }, }; /* * Window-level action callbacks */ static TerminalWindow * get_terminal_window (gpointer user_data) { if (TERMINAL_IS_WINDOW (user_data)) return TERMINAL_WINDOW (user_data); return NULL; } static void action_new_tab (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalApp *app = terminal_app_get (); TerminalProfile *profile = terminal_app_get_profile_for_new_term (app); if (profile) { TerminalScreen *screen = terminal_window_get_active (window); char *working_dir = NULL; if (screen) working_dir = terminal_screen_get_current_dir_with_fallback (screen); terminal_app_new_terminal (app, window, profile, NULL, NULL, working_dir, screen ? terminal_screen_get_initial_environment (screen) : NULL, 1.0); g_free (working_dir); } } static void action_close_tab (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) terminal_window_remove_screen (window, screen); } static void action_close_window (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; gtk_widget_destroy (GTK_WIDGET (window)); } static void action_copy (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) vte_terminal_copy_clipboard_format (VTE_TERMINAL (screen), VTE_FORMAT_TEXT); } static void action_paste (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) vte_terminal_paste_clipboard (VTE_TERMINAL (screen)); } static void action_select_all (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) vte_terminal_select_all (VTE_TERMINAL (screen)); } static void action_fullscreen (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; GVariant *state = g_action_get_state (G_ACTION (action)); gboolean active = g_variant_get_boolean (state); g_simple_action_set_state (action, g_variant_new_boolean (!active)); if (!active) gtk_window_fullscreen (GTK_WINDOW (window)); else gtk_window_unfullscreen (GTK_WINDOW (window)); g_variant_unref (state); } static void action_menubar (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; GVariant *state = g_action_get_state (G_ACTION (action)); gboolean visible = g_variant_get_boolean (state); g_simple_action_set_state (action, g_variant_new_boolean (!visible)); terminal_window_set_menubar_visible (window, !visible); g_variant_unref (state); } static void action_prev_tab (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; GtkWidget *notebook = terminal_window_get_notebook (window); if (notebook) { int page = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); if (page > 0) gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), page - 1); else { int n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), n_pages - 1); } } } static void action_next_tab (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; GtkWidget *notebook = terminal_window_get_notebook (window); if (notebook) { int page = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); int n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); if (page < n_pages - 1) gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), page + 1); else gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0); } } static void action_move_tab_left (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; GtkWidget *notebook = terminal_window_get_notebook (window); if (notebook) { int page = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); if (page > 0) { GtkWidget *child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), page); gtk_notebook_reorder_child (GTK_NOTEBOOK (notebook), child, page - 1); } } } static void action_move_tab_right (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; GtkWidget *notebook = terminal_window_get_notebook (window); if (notebook) { int page = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); int n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); if (page < n_pages - 1) { GtkWidget *child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), page); gtk_notebook_reorder_child (GTK_NOTEBOOK (notebook), child, page + 1); } } } static void action_find_next (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) vte_terminal_search_find_next (VTE_TERMINAL (screen)); } static void action_find_prev (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) vte_terminal_search_find_previous (VTE_TERMINAL (screen)); } static void action_reset (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) vte_terminal_reset (VTE_TERMINAL (screen), TRUE, FALSE); } static void action_reset_clear (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) vte_terminal_reset (VTE_TERMINAL (screen), TRUE, TRUE); } static void action_new_profile (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); TerminalApp *app = terminal_app_get (); terminal_app_new_profile (app, terminal_app_get_profile_for_new_term (app), window ? GTK_WINDOW (window) : NULL); } static void action_keybindings (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); TerminalApp *app = terminal_app_get (); terminal_app_edit_keybindings (app, window ? GTK_WINDOW (window) : NULL); } static void action_current_profile (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalApp *app = terminal_app_get (); TerminalScreen *screen = terminal_window_get_active (window); if (screen) { TerminalProfile *profile = terminal_screen_get_profile (screen); if (profile) terminal_app_edit_profile (app, profile, GTK_WINDOW (window), NULL); } } static void action_zoom_in (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) { double zoom = vte_terminal_get_font_scale (VTE_TERMINAL (screen)); vte_terminal_set_font_scale (VTE_TERMINAL (screen), zoom * 1.1); terminal_window_update_size (window, screen, TRUE); } } static void action_zoom_out (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) { double zoom = vte_terminal_get_font_scale (VTE_TERMINAL (screen)); vte_terminal_set_font_scale (VTE_TERMINAL (screen), zoom / 1.1); terminal_window_update_size (window, screen, TRUE); } } static void action_zoom_normal (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) { vte_terminal_set_font_scale (VTE_TERMINAL (screen), 1.0); terminal_window_update_size (window, screen, TRUE); } } static void action_find (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; terminal_window_show_find_dialog (window); } static void action_set_title (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; terminal_window_show_set_title_dialog (window); } static void action_detach_tab (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); if (!window) return; TerminalScreen *screen = terminal_window_get_active (window); if (screen) terminal_window_detach_screen (window, screen); } static void action_about (GSimpleAction *action, GVariant *parameter, gpointer user_data) { TerminalWindow *window = get_terminal_window (user_data); GtkWindow *parent = window ? GTK_WINDOW (window) : NULL; terminal_window_show_about_dialog (parent); } /* Window action entries */ static const GActionEntry win_actions[] = { { TERMINAL_ACTION_NEW_TAB, action_new_tab, NULL, NULL, NULL }, { TERMINAL_ACTION_NEW_PROFILE, action_new_profile, NULL, NULL, NULL }, { TERMINAL_ACTION_CLOSE_TAB, action_close_tab, NULL, NULL, NULL }, { TERMINAL_ACTION_CLOSE_WINDOW, action_close_window, NULL, NULL, NULL }, { TERMINAL_ACTION_COPY, action_copy, NULL, NULL, NULL }, { TERMINAL_ACTION_PASTE, action_paste, NULL, NULL, NULL }, { TERMINAL_ACTION_SELECT_ALL, action_select_all, NULL, NULL, NULL }, { TERMINAL_ACTION_KEYBINDINGS, action_keybindings, NULL, NULL, NULL }, { TERMINAL_ACTION_CURRENT_PROFILE, action_current_profile, NULL, NULL, NULL }, { TERMINAL_ACTION_ZOOM_IN, action_zoom_in, NULL, NULL, NULL }, { TERMINAL_ACTION_ZOOM_OUT, action_zoom_out, NULL, NULL, NULL }, { TERMINAL_ACTION_ZOOM_NORMAL, action_zoom_normal, NULL, NULL, NULL }, { TERMINAL_ACTION_FULLSCREEN, action_fullscreen, NULL, "false", NULL }, { TERMINAL_ACTION_MENUBAR, action_menubar, NULL, "true", NULL }, { TERMINAL_ACTION_FIND, action_find, NULL, NULL, NULL }, { TERMINAL_ACTION_FIND_NEXT, action_find_next, NULL, NULL, NULL }, { TERMINAL_ACTION_FIND_PREV, action_find_prev, NULL, NULL, NULL }, { TERMINAL_ACTION_SET_TITLE, action_set_title, NULL, NULL, NULL }, { TERMINAL_ACTION_RESET, action_reset, NULL, NULL, NULL }, { TERMINAL_ACTION_RESET_CLEAR, action_reset_clear, NULL, NULL, NULL }, { TERMINAL_ACTION_PREV_TAB, action_prev_tab, NULL, NULL, NULL }, { TERMINAL_ACTION_NEXT_TAB, action_next_tab, NULL, NULL, NULL }, { TERMINAL_ACTION_MOVE_TAB_LEFT, action_move_tab_left, NULL, NULL, NULL }, { TERMINAL_ACTION_MOVE_TAB_RIGHT, action_move_tab_right, NULL, NULL, NULL }, { TERMINAL_ACTION_DETACH_TAB, action_detach_tab, NULL, NULL, NULL }, { "about", action_about, NULL, NULL, NULL }, }; /* * Public API */ void terminal_actions_init_app (GtkApplication *app) { g_return_if_fail (GTK_IS_APPLICATION (app)); g_action_map_add_action_entries (G_ACTION_MAP (app), app_actions, G_N_ELEMENTS (app_actions), app); } void terminal_actions_init_window (GtkApplicationWindow *window) { g_return_if_fail (GTK_IS_APPLICATION_WINDOW (window)); g_action_map_add_action_entries (G_ACTION_MAP (window), win_actions, G_N_ELEMENTS (win_actions), window); }