diff options
| author | Victor Kareh <[email protected]> | 2025-09-05 17:34:36 -0400 |
|---|---|---|
| committer | Victor Kareh <[email protected]> | 2025-09-29 13:25:16 +0000 |
| commit | af0168b6dd83c57bf9f831b2fe2c04e1216bd916 (patch) | |
| tree | 114765618f103ad74704c4ca62272099e89bd2f5 | |
| parent | 29665fe9d62c55100f4a472859c046f3baa35e10 (diff) | |
| download | pluma-af0168b6dd83c57bf9f831b2fe2c04e1216bd916.tar.bz2 pluma-af0168b6dd83c57bf9f831b2fe2c04e1216bd916.tar.xz | |
Use GtkApplication and GtkApplicationWindow
Instead of using GtkWindow, we create a PlumaApplication that inherits
from GtkApplication. This is the initial groundwork for deprecating
a bunch of old GTK functions (like GtkActions).
| -rw-r--r-- | pluma/Makefile.am | 2 | ||||
| -rw-r--r-- | pluma/pluma-app.c | 5 | ||||
| -rw-r--r-- | pluma/pluma-application.c | 272 | ||||
| -rw-r--r-- | pluma/pluma-application.h | 82 | ||||
| -rw-r--r-- | pluma/pluma-session.c | 4 | ||||
| -rw-r--r-- | pluma/pluma-window.c | 8 | ||||
| -rw-r--r-- | pluma/pluma-window.h | 4 | ||||
| -rw-r--r-- | pluma/pluma.c | 92 |
8 files changed, 386 insertions, 83 deletions
diff --git a/pluma/Makefile.am b/pluma/Makefile.am index 24e52728..cb51086e 100644 --- a/pluma/Makefile.am +++ b/pluma/Makefile.am @@ -66,6 +66,7 @@ NOINST_H_FILES = \ INST_H_FILES = \ pluma-app.h \ pluma-app-activatable.h \ + pluma-application.h \ pluma-commands.h \ pluma-debug.h \ pluma-document.h \ @@ -99,6 +100,7 @@ header_DATA = \ libpluma_c_files = \ pluma-app.c \ pluma-app-activatable.c \ + pluma-application.c \ pluma-close-button.c \ pluma-commands-documents.c \ pluma-commands-edit.c \ diff --git a/pluma/pluma-app.c b/pluma/pluma-app.c index 5060ec97..5fc6da4b 100644 --- a/pluma/pluma-app.c +++ b/pluma/pluma-app.c @@ -489,7 +489,10 @@ window_destroy (PlumaWindow *window, save_page_setup (app); save_print_settings (app); - gtk_main_quit (); + /* Exit the application when no windows remain */ + GApplication *app = g_application_get_default (); + if (app) + g_application_quit (app); } } diff --git a/pluma/pluma-application.c b/pluma/pluma-application.c new file mode 100644 index 00000000..228c163b --- /dev/null +++ b/pluma/pluma-application.c @@ -0,0 +1,272 @@ +/* + * pluma-application.c + * This file is part of pluma + * + * Copyright (C) 2025 MATE Developers + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <locale.h> +#include <glib/gi18n.h> + +#include "pluma-application.h" +#include "pluma-debug.h" +#include "pluma-dirs.h" +#include "pluma-plugins-engine.h" +#include "pluma-session.h" +#include "pluma-settings.h" +#include "pluma-app.h" +#include "pluma-window.h" +#include "pluma-commands.h" + +#include "eggdesktopfile.h" + +#ifndef ENABLE_GVFS_METADATA +#include "pluma-metadata-manager.h" +#endif + +struct _PlumaApplicationPrivate +{ + /* command line */ + gint line_position; + gchar *encoding_charset; + gboolean new_window_option; + gboolean new_document_option; + GSList *file_list; + + /* Application state */ + gboolean session_restored; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (PlumaApplication, pluma_application, GTK_TYPE_APPLICATION) + +static void pluma_application_free_command_line_data (PlumaApplication *app); + +static void +pluma_application_activate (GApplication *application) +{ + PlumaApp *app; + PlumaWindow *window; + gboolean restored = FALSE; + + pluma_debug_message (DEBUG_APP, "PlumaApplication activate"); + + /* Chain up to parent */ + G_APPLICATION_CLASS (pluma_application_parent_class)->activate (application); + + if (pluma_session_is_restored ()) + restored = pluma_session_load (); + + if (!restored) + { + PlumaApplication *pluma_app = PLUMA_APPLICATION (application); + PlumaApplicationPrivate *priv = pluma_app->priv; + + pluma_debug_message (DEBUG_APP, "Get default app"); + app = pluma_app_get_default (); + + pluma_debug_message (DEBUG_APP, "Create main window"); + window = pluma_app_create_window (app, NULL); + gtk_application_add_window (GTK_APPLICATION (application), GTK_WINDOW (window)); + gtk_widget_set_size_request (GTK_WIDGET (window), 250, 250); + + if (priv->file_list != NULL) + { + const PlumaEncoding *encoding = NULL; + + if (priv->encoding_charset) + encoding = pluma_encoding_get_from_charset (priv->encoding_charset); + + pluma_debug_message (DEBUG_APP, "Load files"); + _pluma_cmd_load_files_from_prompt (window, + priv->file_list, + encoding, + priv->line_position); + } + else + { + pluma_debug_message (DEBUG_APP, "Create tab"); + pluma_window_create_tab (window, TRUE); + } + + if (priv->new_document_option) + pluma_window_create_tab (window, TRUE); + + pluma_debug_message (DEBUG_APP, "Show window"); + gtk_widget_show (GTK_WIDGET (window)); + + pluma_application_free_command_line_data (pluma_app); + } +} + +static void +pluma_application_startup (GApplication *application) +{ + pluma_debug_message (DEBUG_APP, "PlumaApplication startup"); + + /* Chain up to parent first */ + G_APPLICATION_CLASS (pluma_application_parent_class)->startup (application); + + /* Most initialization is done in main() before GtkApplication starts */ + /* Only do the minimal setup here that needs to happen in the GtkApplication context */ + + pluma_debug_message (DEBUG_APP, "Set icon"); + gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), + PLUMA_DATADIR "/icons"); + + /* Set the associated .desktop file */ + egg_set_desktop_file (DATADIR "/applications/pluma.desktop"); + + /* Init plugins engine */ + pluma_debug_message (DEBUG_APP, "Init plugins"); + pluma_plugins_engine_get_default (); + + /* Initialize session management */ + pluma_debug_message (DEBUG_APP, "Init session manager"); + pluma_session_init (); +} + +static void +pluma_application_shutdown (GApplication *application) +{ + pluma_debug_message (DEBUG_APP, "PlumaApplication shutdown"); + + pluma_settings_unref_singleton (); + +#ifndef ENABLE_GVFS_METADATA + pluma_metadata_manager_shutdown (); +#endif + + /* Chain up to parent */ + G_APPLICATION_CLASS (pluma_application_parent_class)->shutdown (application); +} + +static void +pluma_application_free_command_line_data (PlumaApplication *app) +{ + PlumaApplicationPrivate *priv = app->priv; + + if (priv->file_list) + { + g_slist_free_full (priv->file_list, g_object_unref); + priv->file_list = NULL; + } + + g_free (priv->encoding_charset); + priv->encoding_charset = NULL; + + priv->new_window_option = FALSE; + priv->new_document_option = FALSE; + priv->line_position = 0; +} + + +static int +pluma_application_command_line (GApplication *application, + GApplicationCommandLine *command_line) +{ + pluma_debug_message (DEBUG_APP, "PlumaApplication command_line"); + + /* Command line parsing is already done in main() before GtkApplication starts */ + /* Just activate the application to handle the parsed data */ + g_application_activate (application); + + return 0; +} + +static void +pluma_application_finalize (GObject *object) +{ + PlumaApplication *app = PLUMA_APPLICATION (object); + + pluma_debug_message (DEBUG_APP, "PlumaApplication finalize"); + + pluma_application_free_command_line_data (app); + + /* Chain up to parent */ + G_OBJECT_CLASS (pluma_application_parent_class)->finalize (object); +} + +static void +pluma_application_class_init (PlumaApplicationClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GApplicationClass *application_class = G_APPLICATION_CLASS (klass); + + object_class->finalize = pluma_application_finalize; + + application_class->activate = pluma_application_activate; + application_class->startup = pluma_application_startup; + application_class->shutdown = pluma_application_shutdown; + application_class->command_line = pluma_application_command_line; +} + +static void +pluma_application_init (PlumaApplication *application) +{ + pluma_debug_message (DEBUG_APP, "PlumaApplication init"); + + application->priv = pluma_application_get_instance_private (application); +} + +void +pluma_application_set_command_line_options (PlumaApplication *app, + gint line_pos, + const gchar *encoding, + gboolean new_window, + gboolean new_document, + GSList *file_list) +{ + PlumaApplicationPrivate *priv = app->priv; + + pluma_application_free_command_line_data (app); + + priv->line_position = line_pos; + priv->new_window_option = new_window; + priv->new_document_option = new_document; + priv->encoding_charset = g_strdup (encoding); + + if (file_list) + { + GSList *l; + for (l = file_list; l != NULL; l = l->next) + { + priv->file_list = g_slist_prepend (priv->file_list, g_object_ref (l->data)); + } + priv->file_list = g_slist_reverse (priv->file_list); + } + + if (priv->encoding_charset && + (pluma_encoding_get_from_charset (priv->encoding_charset) == NULL)) + { + g_free (priv->encoding_charset); + priv->encoding_charset = NULL; + } +} + +PlumaApplication * +pluma_application_new (void) +{ + return g_object_new (PLUMA_TYPE_APPLICATION, + "application-id", "org.mate.Pluma", + "flags", G_APPLICATION_HANDLES_OPEN | G_APPLICATION_HANDLES_COMMAND_LINE, + NULL); +} diff --git a/pluma/pluma-application.h b/pluma/pluma-application.h new file mode 100644 index 00000000..d0329657 --- /dev/null +++ b/pluma/pluma-application.h @@ -0,0 +1,82 @@ +/* + * pluma-application.h + * This file is part of pluma + * + * Copyright (C) 2025 MATE Developers + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __PLUMA_APPLICATION_H__ +#define __PLUMA_APPLICATION_H__ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +/* + * Type checking and casting macros + */ +#define PLUMA_TYPE_APPLICATION (pluma_application_get_type()) +#define PLUMA_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PLUMA_TYPE_APPLICATION, PlumaApplication)) +#define PLUMA_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PLUMA_TYPE_APPLICATION, PlumaApplicationClass)) +#define PLUMA_IS_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PLUMA_TYPE_APPLICATION)) +#define PLUMA_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PLUMA_TYPE_APPLICATION)) +#define PLUMA_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PLUMA_TYPE_APPLICATION, PlumaApplicationClass)) + +/* Private structure type */ +typedef struct _PlumaApplicationPrivate PlumaApplicationPrivate; + +/* + * Main object structure + */ +typedef struct _PlumaApplication PlumaApplication; + +struct _PlumaApplication +{ + GtkApplication parent_instance; + + /*< private > */ + PlumaApplicationPrivate *priv; +}; + +/* + * Class definition + */ +typedef struct _PlumaApplicationClass PlumaApplicationClass; + +struct _PlumaApplicationClass +{ + GtkApplicationClass parent_class; +}; + +/* + * Public methods + */ +GType pluma_application_get_type (void) G_GNUC_CONST; + +PlumaApplication *pluma_application_new (void); + +void pluma_application_set_command_line_options (PlumaApplication *app, + gint line_pos, + const gchar *encoding, + gboolean new_window, + gboolean new_document, + GSList *file_list); + +G_END_DECLS + +#endif /* __PLUMA_APPLICATION_H__ */ diff --git a/pluma/pluma-session.c b/pluma/pluma-session.c index 1caa8fe5..7fa3af67 100644 --- a/pluma/pluma-session.c +++ b/pluma/pluma-session.c @@ -392,7 +392,9 @@ client_quit_cb (EggSMClient *client, gpointer data) pluma_debug_message (DEBUG_FILE, "Unref pluma_app_server: DONE"); #endif - gtk_main_quit (); + GApplication *app = g_application_get_default (); + if (app) + g_application_quit (app); } /** diff --git a/pluma/pluma-window.c b/pluma/pluma-window.c index f141ccb9..7a12bdd1 100644 --- a/pluma/pluma-window.c +++ b/pluma/pluma-window.c @@ -95,7 +95,7 @@ enum TARGET_URI_LIST = 100 }; -G_DEFINE_TYPE_WITH_PRIVATE (PlumaWindow, pluma_window, GTK_TYPE_WINDOW) +G_DEFINE_TYPE_WITH_PRIVATE (PlumaWindow, pluma_window, GTK_TYPE_APPLICATION_WINDOW) static void recent_manager_changed (GtkRecentManager *manager, PlumaWindow *window); @@ -3010,7 +3010,7 @@ fullscreen_controls_build (PlumaWindow *window) priv->fullscreen_controls = gtk_window_new (GTK_WINDOW_POPUP); gtk_window_set_transient_for (GTK_WINDOW (priv->fullscreen_controls), - &window->window); + GTK_WINDOW (&window->window)); /* popup toolbar */ toolbar = gtk_ui_manager_get_widget (priv->manager, "/FullscreenToolBar"); @@ -4655,7 +4655,7 @@ _pluma_window_fullscreen (PlumaWindow *window) return; /* Go to fullscreen mode and hide bars */ - gtk_window_fullscreen (&window->window); + gtk_window_fullscreen (GTK_WINDOW (&window->window)); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->priv->notebook), FALSE); g_signal_connect (window->priv->notebook, "notify::show-tabs", G_CALLBACK (hide_notebook_tabs_on_fullscreen), window); @@ -4688,7 +4688,7 @@ _pluma_window_unfullscreen (PlumaWindow *window) return; /* Unfullscreen and show bars */ - gtk_window_unfullscreen (&window->window); + gtk_window_unfullscreen (GTK_WINDOW (&window->window)); g_signal_handlers_disconnect_by_func (window->priv->notebook, hide_notebook_tabs_on_fullscreen, window); diff --git a/pluma/pluma-window.h b/pluma/pluma-window.h index c7133c5f..5b9ae841 100644 --- a/pluma/pluma-window.h +++ b/pluma/pluma-window.h @@ -71,7 +71,7 @@ typedef struct _PlumaWindow PlumaWindow; struct _PlumaWindow { - GtkWindow window; + GtkApplicationWindow window; /*< private > */ PlumaWindowPrivate *priv; @@ -84,7 +84,7 @@ typedef struct _PlumaWindowClass PlumaWindowClass; struct _PlumaWindowClass { - GtkWindowClass parent_class; + GtkApplicationWindowClass parent_class; /* Signals */ void (* tab_added) (PlumaWindow *window, diff --git a/pluma/pluma.c b/pluma/pluma.c index b3ccf468..9a359ddd 100644 --- a/pluma/pluma.c +++ b/pluma/pluma.c @@ -48,6 +48,7 @@ #endif #include "pluma-app.h" +#include "pluma-application.h" #include "pluma-commands.h" #include "pluma-debug.h" #include "pluma-dirs.h" @@ -502,11 +503,9 @@ int main (int argc, char *argv[]) { GOptionContext *context; - PlumaPluginsEngine *engine; - PlumaWindow *window; - PlumaApp *app; - gboolean restored = FALSE; + PlumaApplication *application; GError *error = NULL; + int status; /* Setup debugging */ pluma_debug_init (); @@ -541,6 +540,8 @@ main (int argc, char *argv[]) g_option_context_free (context); + pluma_get_command_line_data (); + pluma_debug_message (DEBUG_APP, "Create bacon connection"); connection = bacon_message_connection_new ("pluma"); @@ -551,8 +552,6 @@ main (int argc, char *argv[]) { pluma_debug_message (DEBUG_APP, "I'm a client"); - pluma_get_command_line_data (); - send_bacon_message (); free_command_line_data (); @@ -580,78 +579,21 @@ main (int argc, char *argv[]) g_warning ("Cannot create the 'pluma' connection."); } - pluma_debug_message (DEBUG_APP, "Set icon"); - gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), - PLUMA_DATADIR "/icons"); - - /* Set the associated .desktop file */ - egg_set_desktop_file (DATADIR "/applications/pluma.desktop"); - - /* Init plugins engine */ - pluma_debug_message (DEBUG_APP, "Init plugins"); - engine = pluma_plugins_engine_get_default (); - - /* Initialize session management */ - pluma_debug_message (DEBUG_APP, "Init session manager"); - pluma_session_init (); - - if (pluma_session_is_restored ()) - restored = pluma_session_load (); + /* Only the server reaches this point - now use GtkApplication */ + application = pluma_application_new (); - if (!restored) - { - pluma_debug_message (DEBUG_APP, "Analyze command line data"); - pluma_get_command_line_data (); - - pluma_debug_message (DEBUG_APP, "Get default app"); - app = pluma_app_get_default (); - - pluma_debug_message (DEBUG_APP, "Create main window"); - window = pluma_app_create_window (app, NULL); - gtk_widget_set_size_request (GTK_WIDGET (window), 250, 250); - - if (file_list != NULL) - { - const PlumaEncoding *encoding = NULL; + /* Send parsed command line data to application */ + pluma_application_set_command_line_options (application, + line_position, + encoding_charset, + new_window_option, + new_document_option, + file_list); - if (encoding_charset) - encoding = pluma_encoding_get_from_charset (encoding_charset); - - pluma_debug_message (DEBUG_APP, "Load files"); - _pluma_cmd_load_files_from_prompt (window, - file_list, - encoding, - line_position); - } - else - { - pluma_debug_message (DEBUG_APP, "Create tab"); - pluma_window_create_tab (window, TRUE); - } - - pluma_debug_message (DEBUG_APP, "Show window"); - gtk_widget_show (GTK_WIDGET (window)); - - free_command_line_data (); - } - - pluma_debug_message (DEBUG_APP, "Start gtk-main"); - - gtk_main(); + status = g_application_run (G_APPLICATION (application), argc, argv); + g_object_unref (application); bacon_message_connection_free (connection); - /* We kept the original engine reference here. So let's unref it to - * finalize it properly. - */ - g_object_unref (engine); - - pluma_settings_unref_singleton (); - -#ifndef ENABLE_GVFS_METADATA - pluma_metadata_manager_shutdown (); -#endif - - return EXIT_SUCCESS; + return status; } - |
