diff options
Diffstat (limited to 'src/terminal-app.c')
| -rw-r--r-- | src/terminal-app.c | 343 |
1 files changed, 227 insertions, 116 deletions
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); |
