summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Kareh <[email protected]>2025-09-05 17:34:36 -0400
committerVictor Kareh <[email protected]>2025-09-29 13:25:16 +0000
commitaf0168b6dd83c57bf9f831b2fe2c04e1216bd916 (patch)
tree114765618f103ad74704c4ca62272099e89bd2f5
parent29665fe9d62c55100f4a472859c046f3baa35e10 (diff)
downloadpluma-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.am2
-rw-r--r--pluma/pluma-app.c5
-rw-r--r--pluma/pluma-application.c272
-rw-r--r--pluma/pluma-application.h82
-rw-r--r--pluma/pluma-session.c4
-rw-r--r--pluma/pluma-window.c8
-rw-r--r--pluma/pluma-window.h4
-rw-r--r--pluma/pluma.c92
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;
}
-