diff options
| author | mbkma <[email protected]> | 2026-02-01 08:12:15 +0100 |
|---|---|---|
| committer | mbkma <[email protected]> | 2026-02-02 00:11:25 +0100 |
| commit | f03c3fa5d195bd26232a5a4a1a1d761b2187a6b7 (patch) | |
| tree | 5fce2241d3424d66874c69fa57d86c844d5008a6 /src | |
| parent | 72e82009ab236c2edb16827905b0aeb5bfc61a11 (diff) | |
| download | mate-terminal-application.tar.bz2 mate-terminal-application.tar.xz | |
port to GtkApplicationapplication
Diffstat (limited to 'src')
| -rw-r--r-- | src/meson.build | 2 | ||||
| -rw-r--r-- | src/terminal-accels.c | 108 | ||||
| -rw-r--r-- | src/terminal-accels.h | 3 | ||||
| -rw-r--r-- | src/terminal-actions.c | 603 | ||||
| -rw-r--r-- | src/terminal-actions.h | 85 | ||||
| -rw-r--r-- | src/terminal-app.c | 343 | ||||
| -rw-r--r-- | src/terminal-app.h | 12 | ||||
| -rw-r--r-- | src/terminal-encoding.c | 2 | ||||
| -rw-r--r-- | src/terminal-window.c | 86 | ||||
| -rw-r--r-- | src/terminal-window.h | 10 | ||||
| -rw-r--r-- | src/terminal.c | 538 |
11 files changed, 1121 insertions, 671 deletions
diff --git a/src/meson.build b/src/meson.build index a8cd1b1..67748d1 100644 --- a/src/meson.build +++ b/src/meson.build @@ -36,6 +36,8 @@ sources = [ 'terminal.c', 'terminal-accels.c', 'terminal-accels.h', + 'terminal-actions.c', + 'terminal-actions.h', 'terminal-app.c', 'terminal-app.h', 'terminal-close-button.h', diff --git a/src/terminal-accels.c b/src/terminal-accels.c index 06b35e4..f2fa795 100644 --- a/src/terminal-accels.c +++ b/src/terminal-accels.c @@ -379,6 +379,7 @@ static gboolean binding_from_value (GVariant *value, GdkModifierType *accelerator_mods); static gboolean sync_idle_cb (gpointer data); +static void update_gaction_accel_for_key (const gchar *gsettings_key); static guint sync_idle_id = 0; static GtkAccelGroup *notification_group = NULL; @@ -578,6 +579,9 @@ keys_change_notify (GSettings *settings, if (edit_keys_store) gtk_tree_model_foreach (GTK_TREE_MODEL (edit_keys_store), update_model_foreach, key_entry); + /* Also update GAction accelerator if this key has one */ + update_gaction_accel_for_key (key); + g_variant_unref(val); } @@ -1091,3 +1095,107 @@ done: gtk_window_set_transient_for (GTK_WINDOW (edit_keys_dialog), transient_parent); gtk_window_present (GTK_WINDOW (edit_keys_dialog)); } + +/* GAction accelerator mapping + * Maps GSettings keys to GAction names for gtk_application_set_accels_for_action + */ +typedef struct { + const char *gsettings_key; + const char *action_name; +} GActionAccelEntry; + +static const char * +get_gaction_name_for_gsettings_key (const gchar *gsettings_key); + +static void +update_gaction_accel_for_key (const gchar *gsettings_key) +{ + GApplication *app; + const char *action_name; + char *binding; + const char *accels[2] = { NULL, NULL }; + + app = g_application_get_default (); + if (!GTK_IS_APPLICATION (app)) + return; + + action_name = get_gaction_name_for_gsettings_key (gsettings_key); + if (!action_name) + return; + + binding = g_settings_get_string (settings_keybindings, gsettings_key); + + if (binding && *binding && g_strcmp0 (binding, "disabled") != 0) + accels[0] = binding; + + gtk_application_set_accels_for_action (GTK_APPLICATION (app), action_name, accels); + + g_free (binding); +} + +static const GActionAccelEntry gaction_accels[] = { + { KEY_NEW_TAB, "win.new-tab" }, + { KEY_NEW_WINDOW, "app.new-window" }, + { KEY_CLOSE_TAB, "win.close-tab" }, + { KEY_CLOSE_WINDOW, "win.close-window" }, + { KEY_COPY, "win.copy" }, + { KEY_PASTE, "win.paste" }, + { KEY_SELECT_ALL, "win.select-all" }, + { KEY_FULL_SCREEN, "win.fullscreen" }, + { KEY_TOGGLE_MENUBAR, "win.menubar" }, + { KEY_PREV_TAB, "win.prev-tab" }, + { KEY_NEXT_TAB, "win.next-tab" }, + { KEY_MOVE_TAB_LEFT, "win.move-tab-left" }, + { KEY_MOVE_TAB_RIGHT, "win.move-tab-right" }, + { KEY_SEARCH_FIND_NEXT, "win.find-next" }, + { KEY_SEARCH_FIND_PREVIOUS, "win.find-prev" }, + { KEY_RESET, "win.reset" }, + { KEY_RESET_AND_CLEAR, "win.reset-clear" }, + { KEY_HELP, "app.help" }, +}; + +static const char * +get_gaction_name_for_gsettings_key (const gchar *gsettings_key) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (gaction_accels); i++) + { + if (g_strcmp0 (gaction_accels[i].gsettings_key, gsettings_key) == 0) + return gaction_accels[i].action_name; + } + + return NULL; +} + +void +terminal_accels_set_gaction_accels (GtkApplication *app) +{ + guint i; + + g_return_if_fail (GTK_IS_APPLICATION (app)); + g_return_if_fail (settings_keybindings != NULL); + + for (i = 0; i < G_N_ELEMENTS (gaction_accels); i++) + { + const GActionAccelEntry *entry = &gaction_accels[i]; + char *binding; + const char *accels[2] = { NULL, NULL }; + + binding = g_settings_get_string (settings_keybindings, entry->gsettings_key); + + /* Check if binding is valid (not empty, not "disabled") */ + if (binding && *binding && g_strcmp0 (binding, "disabled") != 0) + { + accels[0] = binding; + gtk_application_set_accels_for_action (app, entry->action_name, accels); + } + else + { + /* Set empty accelerator list (clears any existing) */ + gtk_application_set_accels_for_action (app, entry->action_name, accels); + } + + g_free (binding); + } +} diff --git a/src/terminal-accels.h b/src/terminal-accels.h index 4fddc2f..00fb8cb 100644 --- a/src/terminal-accels.h +++ b/src/terminal-accels.h @@ -29,6 +29,9 @@ void terminal_accels_init (void); void terminal_accels_shutdown (void); +/* Set up accelerators for GActions */ +void terminal_accels_set_gaction_accels (GtkApplication *app); + void terminal_edit_keys_dialog_show (GtkWindow *transient_parent); G_END_DECLS diff --git a/src/terminal-actions.c b/src/terminal-actions.c new file mode 100644 index 0000000..0afc1f4 --- /dev/null +++ b/src/terminal-actions.c @@ -0,0 +1,603 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include <string.h> +#include <gtk/gtk.h> +#include <vte/vte.h> + +#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); +} diff --git a/src/terminal-actions.h b/src/terminal-actions.h new file mode 100644 index 0000000..05d0dba --- /dev/null +++ b/src/terminal-actions.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2012-2021 MATE Developers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef TERMINAL_ACTIONS_H +#define TERMINAL_ACTIONS_H + +#include <gio/gio.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +/* Initialize application-level actions */ +void terminal_actions_init_app (GtkApplication *app); + +/* Initialize window-level actions */ +void terminal_actions_init_window (GtkApplicationWindow *window); + +/* Action name definitions for accelerator binding */ + +/* Application-level actions (prefix: app.) */ +#define TERMINAL_ACTION_QUIT "quit" +#define TERMINAL_ACTION_NEW_WINDOW "new-window" +#define TERMINAL_ACTION_PREFERENCES "preferences" +#define TERMINAL_ACTION_HELP "help" +#define TERMINAL_ACTION_ABOUT "about" + +/* Window-level actions (prefix: win.) */ +#define TERMINAL_ACTION_NEW_TAB "new-tab" +#define TERMINAL_ACTION_NEW_PROFILE "new-profile" +#define TERMINAL_ACTION_SAVE_CONTENTS "save-contents" +#define TERMINAL_ACTION_CLOSE_TAB "close-tab" +#define TERMINAL_ACTION_CLOSE_WINDOW "close-window" + +#define TERMINAL_ACTION_COPY "copy" +#define TERMINAL_ACTION_PASTE "paste" +#define TERMINAL_ACTION_PASTE_URIS "paste-uris" +#define TERMINAL_ACTION_SELECT_ALL "select-all" +#define TERMINAL_ACTION_PROFILES "profiles" +#define TERMINAL_ACTION_KEYBINDINGS "keybindings" +#define TERMINAL_ACTION_CURRENT_PROFILE "current-profile" + +#define TERMINAL_ACTION_ZOOM_IN "zoom-in" +#define TERMINAL_ACTION_ZOOM_OUT "zoom-out" +#define TERMINAL_ACTION_ZOOM_NORMAL "zoom-normal" +#define TERMINAL_ACTION_FULLSCREEN "fullscreen" +#define TERMINAL_ACTION_MENUBAR "menubar" + +#define TERMINAL_ACTION_FIND "find" +#define TERMINAL_ACTION_FIND_NEXT "find-next" +#define TERMINAL_ACTION_FIND_PREV "find-prev" +#define TERMINAL_ACTION_FIND_CLEAR "find-clear" + +#define TERMINAL_ACTION_SET_TITLE "set-title" +#define TERMINAL_ACTION_RESET "reset" +#define TERMINAL_ACTION_RESET_CLEAR "reset-clear" +#define TERMINAL_ACTION_ADD_ENCODING "add-encoding" + +#define TERMINAL_ACTION_PREV_TAB "prev-tab" +#define TERMINAL_ACTION_NEXT_TAB "next-tab" +#define TERMINAL_ACTION_MOVE_TAB_LEFT "move-tab-left" +#define TERMINAL_ACTION_MOVE_TAB_RIGHT "move-tab-right" +#define TERMINAL_ACTION_DETACH_TAB "detach-tab" + +#define TERMINAL_ACTION_PREV_PROFILE "prev-profile" +#define TERMINAL_ACTION_NEXT_PROFILE "next-profile" + +G_END_DECLS + +#endif /* TERMINAL_ACTIONS_H */ diff --git a/src/terminal-app.c b/src/terminal-app.c index 831f42f..58e71bc 100644 --- a/src/terminal-app.c +++ b/src/terminal-app.c @@ -32,6 +32,7 @@ #include "terminal-debug.h" #include "terminal-app.h" #include "terminal-accels.h" +#include "terminal-actions.h" #include "terminal-screen.h" #include "terminal-screen-container.h" #include "terminal-window.h" @@ -70,22 +71,18 @@ * */ -GSettings *settings_global; - struct _TerminalAppClass { - GObjectClass parent_class; + GtkApplicationClass parent_class; - void (* quit) (TerminalApp *app); void (* profile_list_changed) (TerminalApp *app); void (* encoding_list_changed) (TerminalApp *app); }; struct _TerminalApp { - GObject parent_instance; + GtkApplication parent_instance; - GList *windows; GtkWidget *new_profile_dialog; GtkWidget *manage_profiles_dialog; GtkWidget *manage_profiles_list; @@ -94,6 +91,7 @@ struct _TerminalApp GtkWidget *manage_profiles_delete_button; GtkWidget *manage_profiles_default_menu; + GSettings *settings_global; GSettings *settings_font; GHashTable *profiles; @@ -120,7 +118,6 @@ enum enum { - QUIT, PROFILE_LIST_CHANGED, ENCODING_LIST_CHANGED, LAST_SIGNAL @@ -140,8 +137,6 @@ enum SOURCE_SESSION = 1 }; -static TerminalApp *global_app = NULL; - #define MONOSPACE_FONT_SCHEMA "org.mate.interface" #define MONOSPACE_FONT_KEY "monospace-font-name" #define DEFAULT_MONOSPACE_FONT ("Monospace 10") @@ -157,6 +152,9 @@ static TerminalApp *global_app = NULL; #define ENCODING_LIST_KEY "active-encodings" +/* Define the type - inherits from GtkApplication */ +G_DEFINE_TYPE (TerminalApp, terminal_app, GTK_TYPE_APPLICATION) + /* two following functions were copied from libmate-desktop to get rid * of dependency on it * @@ -323,16 +321,6 @@ profiles_lookup_by_visible_name_foreach (gpointer key, info->result = value; } -static void -terminal_window_destroyed (TerminalWindow *window, - TerminalApp *app) -{ - app->windows = g_list_remove (app->windows, window); - - if (app->windows == NULL) - g_signal_emit (app, signals[QUIT], 0); -} - static TerminalProfile * terminal_app_create_profile (TerminalApp *app, const char *name) @@ -361,7 +349,7 @@ terminal_app_create_profile (TerminalApp *app, } static void -terminal_app_delete_profile (TerminalProfile *profile) +terminal_app_delete_profile (TerminalApp *app, TerminalProfile *profile) { const char *profile_name; char *profile_dir; @@ -370,7 +358,7 @@ terminal_app_delete_profile (TerminalProfile *profile) profile_name = terminal_profile_get_property_string (profile, TERMINAL_PROFILE_NAME); profile_dir = g_strconcat (CONF_PROFILE_PREFIX, profile_name, "/", NULL); - gsettings_remove_all_from_strv (settings_global, PROFILE_LIST_KEY, profile_name); + gsettings_remove_all_from_strv (app->settings_global, PROFILE_LIST_KEY, profile_name); /* And remove the profile directory */ DConfClient *client = dconf_client_new (); @@ -548,7 +536,7 @@ profile_combo_box_changed_cb (GtkWidget *widget, if (!profile) return; - g_settings_set_string (settings_global, DEFAULT_PROFILE_KEY, + g_settings_set_string (app->settings_global, DEFAULT_PROFILE_KEY, terminal_profile_get_property_string (profile, TERMINAL_PROFILE_NAME)); /* Even though the GSettings change notification does this, it happens too late. @@ -629,12 +617,16 @@ profile_list_delete_confirm_response_cb (GtkWidget *dialog, int response) { TerminalProfile *profile; + TerminalApp *app; profile = TERMINAL_PROFILE (g_object_get_data (G_OBJECT (dialog), "profile")); g_assert (profile != NULL); if (response == GTK_RESPONSE_ACCEPT) - terminal_app_delete_profile (profile); + { + app = terminal_app_get (); + terminal_app_delete_profile (app, profile); + } gtk_widget_destroy (dialog); } @@ -682,7 +674,7 @@ profile_list_delete_button_clicked_cb (GtkWidget *button, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, - _("Delete profile ā%sā?"), + _("Delete profile \"%s\"?"), terminal_profile_get_property_string (selected_profile, TERMINAL_PROFILE_VISIBLE_NAME)); mate_dialog_add_button (GTK_DIALOG (dialog), @@ -1145,7 +1137,7 @@ new_profile_response_cb (GtkWidget *new_profile_dialog, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, - _("You already have a profile called ā%sā. Do you want to create another profile with the same name?"), name); + _("You already have a profile called \"%s\". Do you want to create another profile with the same name?"), name); /* Alternative button order was set automatically by GtkMessageDialog */ retval = gtk_dialog_run (GTK_DIALOG (confirm_dialog)); gtk_widget_destroy (confirm_dialog); @@ -1163,7 +1155,7 @@ new_profile_response_cb (GtkWidget *new_profile_dialog, new_profile /* adopts the refcount */); /* And now save the new profile name to GSettings */ - gsettings_append_strv (settings_global, + gsettings_append_strv (app->settings_global, PROFILE_LIST_KEY, new_profile_name); @@ -1389,18 +1381,19 @@ static void terminal_app_client_quit_cb (EggSMClient *client, TerminalApp *app) { - g_signal_emit (app, signals[QUIT], 0); + g_application_quit (G_APPLICATION (app)); } #endif /* HAVE_SMCLIENT */ -/* Class implementation */ - -G_DEFINE_TYPE (TerminalApp, terminal_app, G_TYPE_OBJECT) +/* GtkApplication vfuncs */ static void -terminal_app_init (TerminalApp *app) +terminal_app_startup (GApplication *application) { - global_app = app; + TerminalApp *app = TERMINAL_APP (application); + + /* Chain up */ + G_APPLICATION_CLASS (terminal_app_parent_class)->startup (application); gtk_window_set_default_icon_name (MATE_TERMINAL_ICON_NAME); @@ -1412,20 +1405,20 @@ terminal_app_init (TerminalApp *app) app->encodings = terminal_encodings_get_builtins (); - settings_global = g_settings_new (CONF_GLOBAL_SCHEMA); + app->settings_global = g_settings_new (CONF_GLOBAL_SCHEMA); app->settings_font = g_settings_new (MONOSPACE_FONT_SCHEMA); - g_signal_connect (settings_global, + g_signal_connect (app->settings_global, "changed::" PROFILE_LIST_KEY, G_CALLBACK(terminal_app_profile_list_notify_cb), app); - g_signal_connect (settings_global, + g_signal_connect (app->settings_global, "changed::" DEFAULT_PROFILE_KEY, G_CALLBACK(terminal_app_default_profile_notify_cb), app); - g_signal_connect (settings_global, + g_signal_connect (app->settings_global, "changed::" ENCODING_LIST_KEY, G_CALLBACK(terminal_app_encoding_list_notify_cb), app); @@ -1435,33 +1428,33 @@ terminal_app_init (TerminalApp *app) G_CALLBACK(terminal_app_system_font_notify_cb), app); - g_signal_connect (settings_global, + g_signal_connect (app->settings_global, "changed::" ENABLE_MNEMONICS_KEY, G_CALLBACK(terminal_app_enable_mnemonics_notify_cb), app); - g_signal_connect (settings_global, + g_signal_connect (app->settings_global, "changed::" ENABLE_MENU_BAR_ACCEL_KEY, G_CALLBACK(terminal_app_enable_menu_accels_notify_cb), app); /* Load the settings */ - terminal_app_profile_list_notify_cb (settings_global, + terminal_app_profile_list_notify_cb (app->settings_global, PROFILE_LIST_KEY, app); - terminal_app_default_profile_notify_cb (settings_global, + terminal_app_default_profile_notify_cb (app->settings_global, DEFAULT_PROFILE_KEY, app); - terminal_app_encoding_list_notify_cb (settings_global, + terminal_app_encoding_list_notify_cb (app->settings_global, ENCODING_LIST_KEY, app); terminal_app_system_font_notify_cb (app->settings_font, MONOSPACE_FONT_KEY, app); - terminal_app_enable_menu_accels_notify_cb (settings_global, + terminal_app_enable_menu_accels_notify_cb (app->settings_global, ENABLE_MENU_BAR_ACCEL_KEY, app); - terminal_app_enable_mnemonics_notify_cb (settings_global, + terminal_app_enable_mnemonics_notify_cb (app->settings_global, ENABLE_MNEMONICS_KEY, app); @@ -1471,73 +1464,182 @@ terminal_app_init (TerminalApp *app) terminal_accels_init (); -#ifdef HAVE_SMCLIENT - EggSMClient *sm_client; - char *desktop_file; + /* Initialize application-level GActions */ + terminal_actions_init_app (GTK_APPLICATION (app)); - desktop_file = g_build_filename (TERM_DATADIR, - "applications", - PACKAGE ".desktop", - NULL); - egg_set_desktop_file_without_defaults (desktop_file); - g_free (desktop_file); + /* Set up accelerators for GActions */ + terminal_accels_set_gaction_accels (GTK_APPLICATION (app)); - sm_client = egg_sm_client_get (); - g_signal_connect (sm_client, "save-state", - G_CALLBACK (terminal_app_save_state_cb), app); - g_signal_connect (sm_client, "quit", - G_CALLBACK (terminal_app_client_quit_cb), app); +#ifdef HAVE_SMCLIENT + { + EggSMClient *sm_client; + char *desktop_file; + + desktop_file = g_build_filename (TERM_DATADIR, + "applications", + PACKAGE ".desktop", + NULL); + egg_set_desktop_file_without_defaults (desktop_file); + g_free (desktop_file); + + sm_client = egg_sm_client_get (); + g_signal_connect (sm_client, "save-state", + G_CALLBACK (terminal_app_save_state_cb), app); + g_signal_connect (sm_client, "quit", + G_CALLBACK (terminal_app_client_quit_cb), app); + } #endif /* HAVE_SMCLIENT */ } static void -terminal_app_finalize (GObject *object) +terminal_app_activate (GApplication *application) { - TerminalApp *app = TERMINAL_APP (object); + TerminalApp *app = TERMINAL_APP (application); + GList *windows; + + /* If we have windows, just present the first one */ + windows = gtk_application_get_windows (GTK_APPLICATION (app)); + if (windows != NULL) + { + gtk_window_present (GTK_WINDOW (windows->data)); + return; + } + + /* Otherwise create a new window with default profile */ + TerminalWindow *window; + TerminalProfile *profile; + + window = terminal_app_new_window (app, gdk_screen_get_default ()); + profile = terminal_app_get_profile_for_new_term (app); + + terminal_app_new_terminal (app, window, profile, + NULL, NULL, NULL, NULL, 1.0); + + gtk_window_present (GTK_WINDOW (window)); +} + +static int +terminal_app_command_line (GApplication *application, + GApplicationCommandLine *command_line) +{ + TerminalApp *app = TERMINAL_APP (application); + TerminalOptions *options = NULL; + GError *error = NULL; + int argc; + char **argv; + const char *working_directory; + const char *startup_id; + gboolean allow_resume; + + argv = g_application_command_line_get_arguments (command_line, &argc); + working_directory = g_application_command_line_get_cwd (command_line); + startup_id = g_application_command_line_getenv (command_line, "DESKTOP_STARTUP_ID"); + + /* Determine if we're resuming from session */ + allow_resume = g_application_command_line_get_is_remote (command_line) == FALSE; + + options = terminal_options_parse (working_directory, + NULL, /* display_name - get from environment */ + startup_id, + NULL, /* envv - we get it from command line */ + TRUE, /* remote args */ + TRUE, /* do_not_use_factory */ + &argc, &argv, + &error, + NULL); + + if (options == NULL) + { + g_application_command_line_printerr (command_line, + _("Failed to parse arguments: %s\n"), + error->message); + g_error_free (error); + g_strfreev (argv); + return EXIT_FAILURE; + } + + if (!terminal_app_handle_options (app, options, allow_resume, &error)) + { + g_application_command_line_printerr (command_line, + "Error handling options: %s\n", + error->message); + g_error_free (error); + terminal_options_free (options); + g_strfreev (argv); + return EXIT_FAILURE; + } + + terminal_options_free (options); + g_strfreev (argv); + + return EXIT_SUCCESS; +} + +static void +terminal_app_shutdown (GApplication *application) +{ + TerminalApp *app = TERMINAL_APP (application); #ifdef HAVE_SMCLIENT - EggSMClient *sm_client; + { + EggSMClient *sm_client; - sm_client = egg_sm_client_get (); - g_signal_handlers_disconnect_matched (sm_client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, app); + sm_client = egg_sm_client_get (); + g_signal_handlers_disconnect_matched (sm_client, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, app); + } #endif /* HAVE_SMCLIENT */ - g_signal_handlers_disconnect_by_func (settings_global, + g_signal_handlers_disconnect_by_func (app->settings_global, G_CALLBACK(terminal_app_profile_list_notify_cb), app); - g_signal_handlers_disconnect_by_func (settings_global, + g_signal_handlers_disconnect_by_func (app->settings_global, G_CALLBACK(terminal_app_default_profile_notify_cb), app); - g_signal_handlers_disconnect_by_func (settings_global, + g_signal_handlers_disconnect_by_func (app->settings_global, G_CALLBACK(terminal_app_encoding_list_notify_cb), app); g_signal_handlers_disconnect_by_func (app->settings_font, G_CALLBACK(terminal_app_system_font_notify_cb), app); - g_signal_handlers_disconnect_by_func (settings_global, + g_signal_handlers_disconnect_by_func (app->settings_global, G_CALLBACK(terminal_app_enable_menu_accels_notify_cb), app); - g_signal_handlers_disconnect_by_func (settings_global, + g_signal_handlers_disconnect_by_func (app->settings_global, G_CALLBACK(terminal_app_enable_mnemonics_notify_cb), app); - g_object_unref (settings_global); - g_object_unref (app->settings_font); + g_clear_object (&app->settings_global); + g_clear_object (&app->settings_font); g_free (app->default_profile_id); + app->default_profile_id = NULL; g_hash_table_destroy (app->profiles); + app->profiles = NULL; g_hash_table_destroy (app->encodings); + app->encodings = NULL; - pango_font_description_free (app->system_font_desc); + if (app->system_font_desc) + { + pango_font_description_free (app->system_font_desc); + app->system_font_desc = NULL; + } terminal_accels_shutdown (); - G_OBJECT_CLASS (terminal_app_parent_class)->finalize (object); + /* Chain up */ + G_APPLICATION_CLASS (terminal_app_parent_class)->shutdown (application); +} + +/* GObject vfuncs */ - global_app = NULL; +static void +terminal_app_finalize (GObject *object) +{ + /* Most cleanup is done in shutdown */ + G_OBJECT_CLASS (terminal_app_parent_class)->finalize (object); } static void @@ -1583,11 +1685,11 @@ terminal_app_set_property (GObject *object, { case PROP_ENABLE_MENU_BAR_ACCEL: app->enable_menu_accels = g_value_get_boolean (value); - g_settings_set_boolean (settings_global, ENABLE_MENU_BAR_ACCEL_KEY, app->enable_menu_accels); + g_settings_set_boolean (app->settings_global, ENABLE_MENU_BAR_ACCEL_KEY, app->enable_menu_accels); break; case PROP_ENABLE_MNEMONICS: app->enable_mnemonics = g_value_get_boolean (value); - g_settings_set_boolean (settings_global, ENABLE_MNEMONICS_KEY, app->enable_mnemonics); + g_settings_set_boolean (app->settings_global, ENABLE_MNEMONICS_KEY, app->enable_mnemonics); break; case PROP_DEFAULT_PROFILE: case PROP_SYSTEM_FONT: @@ -1599,30 +1701,19 @@ terminal_app_set_property (GObject *object, } static void -terminal_app_real_quit (TerminalApp *app) -{ - gtk_main_quit(); -} - -static void terminal_app_class_init (TerminalAppClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + GApplicationClass *application_class = G_APPLICATION_CLASS (klass); object_class->finalize = terminal_app_finalize; object_class->get_property = terminal_app_get_property; object_class->set_property = terminal_app_set_property; - klass->quit = terminal_app_real_quit; - - signals[QUIT] = - g_signal_new (I_("quit"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TerminalAppClass, quit), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + application_class->startup = terminal_app_startup; + application_class->activate = terminal_app_activate; + application_class->command_line = terminal_app_command_line; + application_class->shutdown = terminal_app_shutdown; signals[PROFILE_LIST_CHANGED] = g_signal_new (I_("profile-list-changed"), @@ -1671,28 +1762,32 @@ terminal_app_class_init (TerminalAppClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); } +static void +terminal_app_init (TerminalApp *app) +{ + /* Initialization is done in startup vfunc */ +} + /* Public API */ TerminalApp* terminal_app_get (void) { - if (global_app == NULL) - { - g_object_new (TERMINAL_TYPE_APP, NULL); - g_assert (global_app != NULL); - } + GApplication *app; - return global_app; + app = g_application_get_default (); + if (app != NULL && TERMINAL_IS_APP (app)) + return TERMINAL_APP (app); + + return NULL; } -void -terminal_app_shutdown (void) +GSettings* +terminal_app_get_global_settings (TerminalApp *app) { - if (global_app == NULL) - return; + g_return_val_if_fail (TERMINAL_IS_APP (app), NULL); - g_object_unref (global_app); - g_assert (global_app == NULL); + return app->settings_global; } /** @@ -1881,9 +1976,7 @@ terminal_app_new_window (TerminalApp *app, window = terminal_window_new (); - app->windows = g_list_append (app->windows, window); - g_signal_connect (window, "destroy", - G_CALLBACK (terminal_window_destroyed), app); + gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (window)); if (screen) gtk_window_set_screen (GTK_WINDOW (window), screen); @@ -1948,23 +2041,35 @@ terminal_app_get_current_window (TerminalApp *app, GdkScreen *from_screen, int workspace) { - GList *res = NULL; + GList *windows; + GList *res; TerminalWindow *ret = NULL; - if (app->windows == NULL) - return NULL; + windows = gtk_application_get_windows (GTK_APPLICATION (app)); + if (windows == NULL) + return NULL; - res = g_list_last (app->windows); + res = g_list_last (windows); g_assert (from_screen != NULL); while (res) { int win_workspace; + + if (!TERMINAL_IS_WINDOW (res->data)) + { + res = g_list_previous (res); + continue; + } + if (gtk_window_get_screen(GTK_WINDOW(res->data)) != from_screen) - continue; + { + res = g_list_previous (res); + continue; + } - win_workspace = terminal_app_get_workspace_for_window(res->data); + win_workspace = terminal_app_get_workspace_for_window(TERMINAL_WINDOW(res->data)); /* Same workspace or if the window is set to show up on all workspaces */ if (win_workspace == workspace || win_workspace == -1) @@ -2060,7 +2165,7 @@ terminal_app_get_encodings (TerminalApp *app) * * Ensures there's a #TerminalEncoding for @charset available. */ -TerminalEncoding * + TerminalEncoding * terminal_app_ensure_encoding (TerminalApp *app, const char *charset) { @@ -2111,6 +2216,7 @@ void terminal_app_save_config (TerminalApp *app, GKeyFile *key_file) { + GList *windows; GList *lw; guint n = 0; GPtrArray *window_names_array; @@ -2122,13 +2228,18 @@ terminal_app_save_config (TerminalApp *app, g_key_file_set_integer (key_file, TERMINAL_CONFIG_GROUP, TERMINAL_CONFIG_PROP_VERSION, TERMINAL_CONFIG_VERSION); g_key_file_set_integer (key_file, TERMINAL_CONFIG_GROUP, TERMINAL_CONFIG_PROP_COMPAT_VERSION, TERMINAL_CONFIG_COMPAT_VERSION); - window_names_array = g_ptr_array_sized_new (g_list_length (app->windows) + 1); + windows = gtk_application_get_windows (GTK_APPLICATION (app)); + window_names_array = g_ptr_array_sized_new (g_list_length (windows) + 1); - for (lw = app->windows; lw != NULL; lw = lw->next) + for (lw = windows; lw != NULL; lw = lw->next) { - TerminalWindow *window = TERMINAL_WINDOW (lw->data); + TerminalWindow *window; char *group; + if (!TERMINAL_IS_WINDOW (lw->data)) + continue; + + window = TERMINAL_WINDOW (lw->data); group = g_strdup_printf ("Window%u", n++); g_ptr_array_add (window_names_array, group); diff --git a/src/terminal-app.h b/src/terminal-app.h index ebb78c1..98b15fa 100644 --- a/src/terminal-app.h +++ b/src/terminal-app.h @@ -73,7 +73,10 @@ G_BEGIN_DECLS #define TERMINAL_APP_ENABLE_MNEMONICS "enable-mnemonics" #define TERMINAL_APP_SYSTEM_FONT "system-font" -/* TerminalApp */ +/* Application ID for GtkApplication */ +#define TERMINAL_APPLICATION_ID "org.mate.Terminal" + +/* TerminalApp - now inherits from GtkApplication */ #define TERMINAL_TYPE_APP (terminal_app_get_type ()) #define TERMINAL_APP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TERMINAL_TYPE_APP, TerminalApp)) @@ -84,14 +87,15 @@ G_BEGIN_DECLS typedef struct _TerminalAppClass TerminalAppClass; typedef struct _TerminalApp TerminalApp; - -extern GSettings *settings_global; +typedef struct _TerminalAppPrivate TerminalAppPrivate; GType terminal_app_get_type (void); +/* Get the application instance - now uses g_application_get_default() internally */ TerminalApp* terminal_app_get (void); -void terminal_app_shutdown (void); +/* Get GSettings for global settings */ +GSettings* terminal_app_get_global_settings (TerminalApp *app); gboolean terminal_app_handle_options (TerminalApp *app, TerminalOptions *options, diff --git a/src/terminal-encoding.c b/src/terminal-encoding.c index a470c99..c132985 100644 --- a/src/terminal-encoding.c +++ b/src/terminal-encoding.c @@ -302,7 +302,7 @@ update_active_encodings_gsettings (void) strings = g_array_append_val (strings, id_string); } - g_settings_set_strv (settings_global, "active-encodings", (const gchar **) strings->data); + g_settings_set_strv (terminal_app_get_global_settings (terminal_app_get ()), "active-encodings", (const gchar **) strings->data); g_array_free (strings, TRUE); g_slist_foreach (list, (GFunc) terminal_encoding_unref, NULL); diff --git a/src/terminal-window.c b/src/terminal-window.c index 75e5fd8..12fe9de 100644 --- a/src/terminal-window.c +++ b/src/terminal-window.c @@ -30,6 +30,7 @@ #include <gdk/gdkkeysyms.h> #include "terminal-accels.h" +#include "terminal-actions.h" #include "terminal-app.h" #include "terminal-debug.h" #include "terminal-encoding.h" @@ -45,8 +46,6 @@ #include "skey-popup.h" #endif -static gboolean detach_tab = FALSE; - struct _TerminalWindowPrivate { GtkActionGroup *action_group; @@ -162,10 +161,10 @@ static gboolean terminal_window_focus_in_event (GtkWidget *widget, static gboolean notebook_button_press_cb (GtkWidget *notebook, GdkEventButton *event, - GSettings *settings); + gpointer user_data); static gboolean window_key_press_cb (GtkWidget *notebook, GdkEventKey *event, - GSettings *settings); + gpointer user_data); static gboolean notebook_popup_menu_cb (GtkWidget *notebook, TerminalWindow *window); static void notebook_page_selected_callback (GtkWidget *notebook, @@ -269,7 +268,7 @@ sync_screen_icon_title (TerminalScreen *screen, GParamSpec *psepc, TerminalWindow *window); -G_DEFINE_TYPE_WITH_PRIVATE (TerminalWindow, terminal_window, GTK_TYPE_WINDOW) +G_DEFINE_TYPE_WITH_PRIVATE (TerminalWindow, terminal_window, GTK_TYPE_APPLICATION_WINDOW) /* Menubar mnemonics & accel settings handling */ @@ -2260,6 +2259,9 @@ terminal_window_init (TerminalWindow *window) priv = window->priv = terminal_window_get_instance_private (window); + /* Initialize GAction for this window */ + terminal_actions_init_window (GTK_APPLICATION_WINDOW (window)); + g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK(terminal_window_delete_event), NULL); @@ -2294,9 +2296,9 @@ terminal_window_init (TerminalWindow *window) gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE); gtk_notebook_set_group_name (GTK_NOTEBOOK (priv->notebook), I_("mate-terminal-window")); g_signal_connect (priv->notebook, "button-press-event", - G_CALLBACK (notebook_button_press_cb), settings_global); + G_CALLBACK (notebook_button_press_cb), NULL); g_signal_connect (window, "key-press-event", - G_CALLBACK (window_key_press_cb), settings_global); + G_CALLBACK (window_key_press_cb), NULL); g_signal_connect (priv->notebook, "popup-menu", G_CALLBACK (notebook_popup_menu_cb), window); g_signal_connect_after (priv->notebook, "switch-page", @@ -2727,9 +2729,10 @@ terminal_window_add_screen (TerminalWindow *window, TRUE); } -void -terminal_window_remove_screen (TerminalWindow *window, - TerminalScreen *screen) +static void +remove_screen_internal (TerminalWindow *window, + TerminalScreen *screen, + gboolean detach) { TerminalWindowPrivate *priv = window->priv; TerminalScreenContainer *screen_container; @@ -2739,18 +2742,22 @@ terminal_window_remove_screen (TerminalWindow *window, update_tab_visibility (window, -1); screen_container = terminal_screen_container_get_from_screen (screen); - if (detach_tab) - { + if (detach) gtk_notebook_detach_tab (GTK_NOTEBOOK (priv->notebook), GTK_WIDGET (screen_container)); - detach_tab = FALSE; - } else gtk_container_remove (GTK_CONTAINER (priv->notebook), GTK_WIDGET (screen_container)); } void +terminal_window_remove_screen (TerminalWindow *window, + TerminalScreen *screen) +{ + remove_screen_internal (window, screen, FALSE); +} + +void terminal_window_move_screen (TerminalWindow *source_window, TerminalWindow *dest_window, TerminalScreen *screen, @@ -2775,9 +2782,7 @@ terminal_window_move_screen (TerminalWindow *source_window, g_object_ref_sink (screen_container); g_object_ref_sink (screen); - detach_tab = TRUE; - - terminal_window_remove_screen (source_window, screen); + remove_screen_internal (source_window, screen, TRUE); /* Now we can safely remove the screen from the container and let the container die */ gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (GTK_WIDGET (screen))), GTK_WIDGET (screen)); @@ -3034,11 +3039,12 @@ terminal_window_get_active (TerminalWindow *window) static gboolean notebook_button_press_cb (GtkWidget *widget, GdkEventButton *event, - GSettings *settings) + gpointer user_data) { TerminalWindow *window = TERMINAL_WINDOW (gtk_widget_get_toplevel (widget)); TerminalWindowPrivate *priv = window->priv; GtkNotebook *notebook = GTK_NOTEBOOK (widget); + GSettings *settings = terminal_app_get_global_settings (terminal_app_get ()); GtkWidget *tab; GtkWidget *menu; GtkAction *action; @@ -3122,8 +3128,9 @@ notebook_button_press_cb (GtkWidget *widget, static gboolean window_key_press_cb (GtkWidget *widget, GdkEventKey *event, - GSettings *settings) + gpointer user_data) { + GSettings *settings = terminal_app_get_global_settings (terminal_app_get ()); if (g_settings_get_boolean (settings, "ctrl-tab-switch-tabs") && event->state & GDK_CONTROL_MASK) { @@ -3732,7 +3739,7 @@ confirm_close_window_or_tab (TerminalWindow *window, int n_tabs; char *confirm_msg; - if (!g_settings_get_boolean (settings_global, "confirm-window-close")) + if (!g_settings_get_boolean (terminal_app_get_global_settings (terminal_app_get ()), "confirm-window-close")) return FALSE; if (screen) @@ -4622,6 +4629,45 @@ terminal_window_get_ui_manager (TerminalWindow *window) return priv->ui_manager; } +/* Public wrapper functions for GAction callbacks */ + +void +terminal_window_show_find_dialog (TerminalWindow *window) +{ + g_return_if_fail (TERMINAL_IS_WINDOW (window)); + search_find_callback (NULL, window); +} + +void +terminal_window_show_set_title_dialog (TerminalWindow *window) +{ + g_return_if_fail (TERMINAL_IS_WINDOW (window)); + terminal_set_title_callback (NULL, window); +} + +void +terminal_window_detach_screen (TerminalWindow *window, TerminalScreen *screen) +{ + g_return_if_fail (TERMINAL_IS_WINDOW (window)); + g_return_if_fail (TERMINAL_IS_SCREEN (screen)); + tabs_detach_tab_callback (NULL, window); +} + +void +terminal_window_show_about_dialog (GtkWindow *parent) +{ + if (parent && TERMINAL_IS_WINDOW (parent)) + help_about_callback (NULL, TERMINAL_WINDOW (parent)); + else + { + /* Create a temporary window for the about dialog */ + GtkApplication *app = GTK_APPLICATION (g_application_get_default ()); + GList *windows = gtk_application_get_windows (app); + if (windows) + help_about_callback (NULL, TERMINAL_WINDOW (windows->data)); + } +} + void terminal_window_save_state (TerminalWindow *window, GKeyFile *key_file, diff --git a/src/terminal-window.h b/src/terminal-window.h index 86b8e28..659f2ee 100644 --- a/src/terminal-window.h +++ b/src/terminal-window.h @@ -39,14 +39,14 @@ typedef struct _TerminalWindowPrivate TerminalWindowPrivate; struct _TerminalWindow { - GtkWindow parent_instance; + GtkApplicationWindow parent_instance; TerminalWindowPrivate *priv; }; struct _TerminalWindowClass { - GtkWindowClass parent_class; + GtkApplicationWindowClass parent_class; }; @@ -110,6 +110,12 @@ terminal_window_update_copy_selection (TerminalScreen *screen, TerminalWindow *terminal_window_get_latest_focused (TerminalWindow *window1, TerminalWindow *window2); +/* Public functions for GAction callbacks */ +void terminal_window_show_find_dialog (TerminalWindow *window); +void terminal_window_show_set_title_dialog (TerminalWindow *window); +void terminal_window_detach_screen (TerminalWindow *window, TerminalScreen *screen); +void terminal_window_show_about_dialog (GtkWindow *parent); + G_END_DECLS #endif /* TERMINAL_WINDOW_H */ diff --git a/src/terminal.c b/src/terminal.c index 7909fdf..c9a044b 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -38,431 +38,15 @@ #include "eggsmclient.h" #endif /* HAVE_SMCLIENT */ -#include "terminal-accels.h" #include "terminal-app.h" #include "terminal-debug.h" #include "terminal-intl.h" -#include "terminal-options.h" -#include "terminal-util.h" - -#define TERMINAL_FACTORY_SERVICE_NAME_PREFIX "org.mate.Terminal.Display" -#define TERMINAL_FACTORY_SERVICE_PATH "/org/mate/Terminal/Factory" -#define TERMINAL_FACTORY_INTERFACE_NAME "org.mate.Terminal.Factory" - -static char * -ay_to_string (GVariant *variant, - GError **error) -{ - gsize len; - const char *data; - - data = g_variant_get_fixed_array (variant, &len, sizeof (char)); - if (len == 0) - return NULL; - - /* Make sure there are no embedded NULs */ - if (memchr (data, '\0', len) != NULL) - { - g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, - "String is shorter than claimed"); - return NULL; - } - - return g_strndup (data, len); -} - -static char ** -ay_to_strv (GVariant *variant, - int *argc) -{ - GPtrArray *argv; - const char *data, *nullbyte; - gsize data_len; - gssize len; - - data = g_variant_get_fixed_array (variant, &data_len, sizeof (char)); - if (data_len == 0 || data_len > G_MAXSSIZE) - { - if (argc != NULL) - *argc = 0; - return NULL; - } - - argv = g_ptr_array_new (); - - len = data_len; - do - { - gssize string_len; - - nullbyte = memchr (data, '\0', len); - - string_len = nullbyte ? (gssize) (nullbyte - data) : len; - g_ptr_array_add (argv, g_strndup (data, string_len)); - - len -= string_len + 1; - data += string_len + 1; - } - while (len > 0); - - if (argc) - *argc = argv->len; - - /* NULL terminate */ - g_ptr_array_add (argv, NULL); - return (char **) g_ptr_array_free (argv, FALSE); -} - -static GVariant * -string_to_ay (const char *string) -{ - gsize len; - char *data; - - len = strlen (string); - data = g_strndup (string, len); - - return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, len, TRUE, g_free, data); -} - -typedef struct -{ - char *factory_name; - TerminalOptions *options; - int exit_code; - char **argv; - int argc; -} OwnData; - -static void -method_call_cb (GDBusConnection *connection, - const char *sender, - const char *object_path, - const char *interface_name, - const char *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) -{ - if (g_strcmp0 (method_name, "HandleArguments") == 0) - { - TerminalOptions *options = NULL; - GVariant *v_wd, *v_display, *v_sid, *v_envv, *v_argv; - char *working_directory = NULL, *display_name = NULL, *startup_id = NULL; - int initial_workspace = -1; - char **envv = NULL, **argv = NULL; - int argc; - GError *error = NULL; - - g_variant_get (parameters, "(@ay@ay@ay@ayi@ay)", - &v_wd, &v_display, &v_sid, &v_envv, &initial_workspace, &v_argv); - - working_directory = ay_to_string (v_wd, &error); - if (error) - goto out; - display_name = ay_to_string (v_display, &error); - if (error) - goto out; - startup_id = ay_to_string (v_sid, &error); - if (error) - goto out; - envv = ay_to_strv (v_envv, NULL); - argv = ay_to_strv (v_argv, &argc); - - _terminal_debug_print (TERMINAL_DEBUG_FACTORY, - "Factory invoked with working-dir='%s' display='%s' startup-id='%s'" - "workspace='%d'\n", - working_directory ? working_directory : "(null)", - display_name ? display_name : "(null)", - startup_id ? startup_id : "(null)", - initial_workspace); - - options = terminal_options_parse (working_directory, - display_name, - startup_id, - envv, - TRUE, - TRUE, - &argc, &argv, - &error, - NULL); - - if (options != NULL) - { - options->initial_workspace = initial_workspace; - - terminal_app_handle_options (terminal_app_get (), options, FALSE /* no resume */, &error); - terminal_options_free (options); - } - -out: - g_variant_unref (v_wd); - g_free (working_directory); - g_variant_unref (v_display); - g_free (display_name); - g_variant_unref (v_sid); - g_free (startup_id); - g_variant_unref (v_envv); - g_strfreev (envv); - g_variant_unref (v_argv); - g_strfreev (argv); - - if (error == NULL) - { - g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); - } - else - { - g_dbus_method_invocation_return_gerror (invocation, error); - g_error_free (error); - } - } -} - -static void -bus_acquired_cb (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - static const char dbus_introspection_xml[] = - "<node name='/org/mate/Terminal'>" - "<interface name='org.mate.Terminal.Factory'>" - "<method name='HandleArguments'>" - "<arg type='ay' name='working_directory' direction='in' />" - "<arg type='ay' name='display_name' direction='in' />" - "<arg type='ay' name='startup_id' direction='in' />" - "<arg type='ay' name='environment' direction='in' />" - "<arg type='i' name='workspace' direction='in' />" - "<arg type='ay' name='arguments' direction='in' />" - "</method>" - "</interface>" - "</node>"; - - static const GDBusInterfaceVTable interface_vtable = - { - method_call_cb, - NULL, - NULL, - { 0 } - }; - - OwnData *data = (OwnData *) user_data; - GDBusNodeInfo *introspection_data; - guint registration_id; - GError *error = NULL; - - _terminal_debug_print (TERMINAL_DEBUG_FACTORY, - "Bus %s acquired\n", name); - - introspection_data = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL); - g_assert (introspection_data != NULL); - - registration_id = g_dbus_connection_register_object (connection, - TERMINAL_FACTORY_SERVICE_PATH, - introspection_data->interfaces[0], - &interface_vtable, - NULL, NULL, - &error); - g_dbus_node_info_unref (introspection_data); - - if (registration_id == 0) - { - g_printerr ("Failed to register object: %s\n", error->message); - g_error_free (error); - data->exit_code = EXIT_FAILURE; - gtk_main_quit (); - } -} - -static void -name_acquired_cb (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - OwnData *data = (OwnData *) user_data; - GError *error = NULL; - - _terminal_debug_print (TERMINAL_DEBUG_FACTORY, - "Acquired the name %s on the session bus\n", name); - - if (data->options == NULL) - { - /* Name re-acquired!? */ - g_assert_not_reached (); - } - - if (!terminal_app_handle_options (terminal_app_get (), data->options, TRUE /* do resume */, &error)) - { - g_printerr ("Failed to handle options: %s\n", error->message); - g_error_free (error); - data->exit_code = EXIT_FAILURE; - gtk_main_quit (); - } - - terminal_options_free (data->options); - data->options = NULL; -} - -static void -name_lost_cb (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - OwnData *data = (OwnData *) user_data; - GError *error = NULL; - char **envv; - int i; - GVariantBuilder builder; - GVariant *value; - GString *string; - char *s; - gsize len; - - _terminal_debug_print (TERMINAL_DEBUG_FACTORY, - "Lost the name %s on the session bus\n", name); - - /* Couldn't get the connection? No way to continue! */ - if (connection == NULL) - { - data->exit_code = EXIT_FAILURE; - gtk_main_quit (); - return; - } - - if (data->options == NULL) - { - /* Already handled */ - data->exit_code = EXIT_SUCCESS; - gtk_main_quit (); - return; - } - - _terminal_debug_print (TERMINAL_DEBUG_FACTORY, - "Forwarding arguments to existing instance\n"); - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ayayayayiay)")); - - g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->default_working_dir)); - g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->display_name)); - g_variant_builder_add (&builder, "@ay", string_to_ay (data->options->startup_id)); - - string = g_string_new (NULL); - envv = g_get_environ (); - for (i = 0; envv[i]; ++i) - { - if (i > 0) - g_string_append_c (string, '\0'); - - g_string_append (string, envv[i]); - } - g_strfreev (envv); - - len = string->len; - s = g_string_free (string, FALSE); - g_variant_builder_add (&builder, "@ay", - g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s)); - - g_variant_builder_add (&builder, "@i", g_variant_new_int32 (data->options->initial_workspace)); - - string = g_string_new (NULL); - - for (i = 0; i < data->argc; ++i) - { - if (i > 0) - g_string_append_c (string, '\0'); - g_string_append (string, data->argv[i]); - } - - len = string->len; - s = g_string_free (string, FALSE); - g_variant_builder_add (&builder, "@ay", - g_variant_new_from_data (G_VARIANT_TYPE ("ay"), s, len, TRUE, g_free, s)); - - value = g_dbus_connection_call_sync (connection, - data->factory_name, - TERMINAL_FACTORY_SERVICE_PATH, - TERMINAL_FACTORY_INTERFACE_NAME, - "HandleArguments", - g_variant_builder_end (&builder), - G_VARIANT_TYPE ("()"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (value == NULL) - { - g_printerr ("Failed to forward arguments: %s\n", error->message); - g_error_free (error); - data->exit_code = EXIT_FAILURE; - gtk_main_quit (); - } - else - { - g_variant_unref (value); - data->exit_code = EXIT_SUCCESS; - } - - terminal_options_free (data->options); - data->options = NULL; - - gtk_main_quit (); -} - -static char * -get_factory_name_for_display (const char *display_name) -{ - GString *name; - const char *p; - - name = g_string_sized_new (strlen (TERMINAL_FACTORY_SERVICE_NAME_PREFIX) + strlen (display_name) + 1 /* NUL */); - g_string_append (name, TERMINAL_FACTORY_SERVICE_NAME_PREFIX); - - for (p = display_name; *p; ++p) - { - if (g_ascii_isalnum (*p)) - g_string_append_c (name, *p); - else - g_string_append_c (name, '_'); - } - - _terminal_debug_print (TERMINAL_DEBUG_FACTORY, - "Factory name is \"%s\"\n", name->str); - - return g_string_free (name, FALSE); -} - -static int -get_initial_workspace (void) -{ - int ret = -1; - GdkWindow *window; - guchar *data = NULL; - GdkAtom atom; - GdkAtom cardinal_atom; - - window = gdk_get_default_root_window(); - - atom = gdk_atom_intern_static_string ("_NET_CURRENT_DESKTOP"); - cardinal_atom = gdk_atom_intern_static_string ("CARDINAL"); - - if (gdk_property_get (window, atom, cardinal_atom, 0, 8, FALSE, NULL, NULL, NULL, &data)) { - ret = *(int *)data; - g_free (data); - } - return ret; -} int main (int argc, char **argv) { - int i; - char **argv_copy; - int argc_copy; - const char *startup_id, *home_dir; - TerminalOptions *options; - GError *error = NULL; - char *working_directory; - int ret = EXIT_SUCCESS; + TerminalApp *app; + int ret; setlocale (LC_ALL, ""); @@ -472,120 +56,18 @@ main (int argc, char **argv) _terminal_debug_init (); - /* Make a NULL-terminated copy since we may need it later */ - argv_copy = g_new (char *, argc + 1); - for (i = 0; i < argc; ++i) - argv_copy [i] = argv [i]; - argv_copy [i] = NULL; - argc_copy = argc; - - startup_id = g_getenv ("DESKTOP_STARTUP_ID"); - - working_directory = g_get_current_dir (); - - /* Now change directory to $HOME so we don't prevent unmounting, e.g. if the - * factory is started by caja-open-terminal. See bug #565328. - * On failure back to /. - */ - home_dir = g_get_home_dir (); - if (home_dir == NULL || chdir (home_dir) < 0) - if (chdir ("/") < 0) - g_warning ("Could not change working directory."); - - options = terminal_options_parse (working_directory, - NULL, - startup_id, - NULL, - FALSE, - FALSE, - &argc, &argv, - &error, -#ifdef HAVE_SMCLIENT - gtk_get_option_group (TRUE), - egg_sm_client_get_option_group (), -#endif /* HAVE_SMCLIENT */ - NULL); - g_free (working_directory); - - if (options == NULL) - { - g_printerr (_("Failed to parse arguments: %s\n"), error->message); - g_error_free (error); - exit (EXIT_FAILURE); - } - g_set_application_name (_("Terminal")); - /* Unset the these env variables, so they doesn't end up - * in the factory's env and thus in the terminals' envs. - */ - g_unsetenv ("DESKTOP_STARTUP_ID"); - g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE_PID"); - g_unsetenv ("GIO_LAUNCHED_DESKTOP_FILE"); - - if (options->startup_id == NULL) - { - options->startup_id = g_strdup_printf ("_TIME%" G_GINT64_FORMAT, - g_get_monotonic_time () / 1000); - } - - gdk_init (&argc, &argv); - const char *display_name = gdk_display_get_name (gdk_display_get_default ()); - options->display_name = g_strdup (display_name); - - if (options->use_factory) - { - OwnData *data; - guint owner_id; - - data = g_new (OwnData, 1); - data->factory_name = get_factory_name_for_display (display_name); - data->options = options; - data->exit_code = -1; - data->argv = argv_copy; - data->argc = argc_copy; - - gtk_init(&argc, &argv); - options->initial_workspace = get_initial_workspace (); - - owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, - data->factory_name, - G_BUS_NAME_OWNER_FLAGS_NONE, - bus_acquired_cb, - name_acquired_cb, - name_lost_cb, - data, NULL); - - gtk_main (); - - ret = data->exit_code; - g_bus_unown_name (owner_id); - - g_free (data->factory_name); - g_free (data); - - } - else - { - gtk_init(&argc, &argv); - terminal_app_handle_options (terminal_app_get (), options, TRUE /* allow resume */, &error); - terminal_options_free (options); - - if (error == NULL) - { - gtk_main (); - } - else - { - g_printerr ("Error handling options: %s\n", error->message); - g_error_free (error); - ret = EXIT_FAILURE; - } - } + /* Create the GtkApplication */ + app = g_object_new (TERMINAL_TYPE_APP, + "application-id", TERMINAL_APPLICATION_ID, + "flags", G_APPLICATION_HANDLES_COMMAND_LINE, + NULL); - terminal_app_shutdown (); + /* Run the application */ + ret = g_application_run (G_APPLICATION (app), argc, argv); - g_free (argv_copy); + g_object_unref (app); return ret; } |
