[totem] Port Totem to new GApplication code
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [totem] Port Totem to new GApplication code
- Date: Fri, 29 Oct 2010 16:21:08 +0000 (UTC)
commit d818ea98b280d62e8c150ea3cc3fac1744c4d439
Author: Bastien Nocera <hadess hadess net>
Date: Fri Oct 29 17:10:22 2010 +0100
Port Totem to new GApplication code
This cleans up Totem's initialisation, and cleans up its
command-line handling.
We do use one hack to handle window creation and command-line
handling in the same function, as some of Totem's functionality
requires knowing about the command-line.
This however breaks activating the application via D-Bus.
src/totem-options.c | 107 +++++++----------------
src/totem-options.h | 3 +-
src/totem-private.h | 2 +-
src/totem.c | 237 +++++++++++++++++++++++----------------------------
4 files changed, 141 insertions(+), 208 deletions(-)
---
diff --git a/src/totem-options.c b/src/totem-options.c
index cbe346d..77ece31 100644
--- a/src/totem-options.c
+++ b/src/totem-options.c
@@ -44,7 +44,7 @@ option_version_cb (const gchar *option_name,
exit (0);
}
-
+
const GOptionEntry all_options[] = {
{"debug", '\0', 0, G_OPTION_ARG_NONE, &optionstate.debug, N_("Enable debug"), NULL},
{"play-pause", '\0', 0, G_OPTION_ARG_NONE, &optionstate.playpause, N_("Play/Pause"), NULL},
@@ -62,7 +62,6 @@ const GOptionEntry all_options[] = {
{"quit", '\0', 0, G_OPTION_ARG_NONE, &optionstate.quit, N_("Quit"), NULL},
{"enqueue", '\0', 0, G_OPTION_ARG_NONE, &optionstate.enqueue, N_("Enqueue"), NULL},
{"replace", '\0', 0, G_OPTION_ARG_NONE, &optionstate.replace, N_("Replace"), NULL},
- {"no-existing-session", '\0', 0, G_OPTION_ARG_NONE, &optionstate.notconnectexistingsession, N_("Don't connect to an already-running instance"), NULL},
{"seek", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_INT64, &optionstate.seek, N_("Seek"), NULL},
/* Translators: help for a (hidden) command line option to specify (the zero-based index of) a playlist entry to start playing once Totem's finished loading */
{"playlist-idx", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_DOUBLE, &optionstate.playlistidx, N_("Playlist index"), NULL},
@@ -74,7 +73,7 @@ const GOptionEntry all_options[] = {
void
totem_options_process_late (Totem *totem, const TotemCmdLineOptions *options)
{
- if (options->togglecontrols)
+ if (options->togglecontrols)
totem_action_toggle_controls (totem);
/* Handle --playlist-idx */
@@ -85,20 +84,6 @@ totem_options_process_late (Totem *totem, const TotemCmdLineOptions *options)
}
void
-totem_options_register_remote_commands (Totem *totem)
-{
- GEnumClass *klass;
- guint i;
-
- klass = (GEnumClass *) g_type_class_ref (TOTEM_TYPE_REMOTE_COMMAND);
- for (i = TOTEM_REMOTE_COMMAND_UNKNOWN + 1; i < klass->n_values; i++) {
- const GEnumValue *val = g_enum_get_value (klass, i);
- g_application_add_action (G_APPLICATION (totem->app), val->value_name, val->value_nick);
- }
- g_type_class_unref (klass);
-}
-
-void
totem_options_process_early (Totem *totem, const TotemCmdLineOptions* options)
{
if (options->quit) {
@@ -110,156 +95,126 @@ totem_options_process_early (Totem *totem, const TotemCmdLineOptions* options)
g_settings_set_boolean (totem->settings, "debug", options->debug);
}
-static char *
-totem_get_action_for_command (const TotemRemoteCommand command)
-{
- GEnumClass *klass;
- char *name;
-
- klass = g_type_class_ref (TOTEM_TYPE_REMOTE_COMMAND);
- name = g_strdup (g_enum_get_value (klass, command)->value_name);
- g_type_class_unref (klass);
-
- return name;
-}
-
-#define UPDATE_ACTION(action, command) \
- do { \
- g_free ((action)); \
- (action) = totem_get_action_for_command ((command)); \
- } while (0)
-
void
-totem_options_process_for_server (GApplication *app,
- const TotemCmdLineOptions* options)
+totem_options_process_for_server (Totem *totem,
+ const TotemCmdLineOptions *options)
{
- gchar *action = NULL;
+ TotemRemoteCommand action;
GList *commands, *l;
int i;
commands = NULL;
- UPDATE_ACTION (action, TOTEM_REMOTE_COMMAND_REPLACE);
+ action = TOTEM_REMOTE_COMMAND_REPLACE;
/* Are we quitting ? */
if (options->quit) {
- g_application_invoke_action (G_APPLICATION (app),
- totem_get_action_for_command (TOTEM_REMOTE_COMMAND_QUIT),
- NULL);
+ totem_action_remote (totem, TOTEM_REMOTE_COMMAND_QUIT, NULL);
return;
}
/* Then handle the things that modify the playlist */
if (options->replace && options->enqueue) {
- /* FIXME translate that */
- g_warning ("Can't enqueue and replace at the same time");
+ g_warning (_("Can't enqueue and replace at the same time"));
} else if (options->replace) {
- UPDATE_ACTION (action, TOTEM_REMOTE_COMMAND_REPLACE);
+ action = TOTEM_REMOTE_COMMAND_REPLACE;
} else if (options->enqueue) {
- UPDATE_ACTION (action, TOTEM_REMOTE_COMMAND_ENQUEUE);
+ action = TOTEM_REMOTE_COMMAND_ENQUEUE;
}
/* Send the files to enqueue */
for (i = 0; options->filenames && options->filenames[i] != NULL; i++) {
- GVariant *data;
+ const char *filename;
char *full_path;
- GVariantBuilder builder;
- full_path = totem_create_full_path (options->filenames[i]);
+ filename = options->filenames[i];
+ full_path = totem_create_full_path (filename);
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
- g_variant_builder_add (&builder, "{sv}",
- "url", g_variant_new_string (full_path ? full_path : options->filenames[i]));
- data = g_variant_builder_end (&builder);
+ g_message ("filename %s", filename);
+ g_message ("full_path %s", full_path);
- g_application_invoke_action (G_APPLICATION (app), action, data);
+ totem_action_remote (totem, action, full_path ? full_path : filename);
g_free (full_path);
- g_variant_unref (data);
/* Even if the default action is replace, we only want to replace with the
first file. After that, we enqueue. */
if (i == 0) {
- UPDATE_ACTION (action, TOTEM_REMOTE_COMMAND_ENQUEUE);
+ action = TOTEM_REMOTE_COMMAND_ENQUEUE;
}
}
if (options->playpause) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_PLAYPAUSE));
}
if (options->play) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_PLAY));
}
if (options->pause) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_PAUSE));
}
if (options->next) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_NEXT));
}
if (options->previous) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_PREVIOUS));
}
if (options->seekfwd) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_SEEK_FORWARD));
}
if (options->seekbwd) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_SEEK_BACKWARD));
}
if (options->volumeup) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_VOLUME_UP));
}
if (options->volumedown) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_VOLUME_DOWN));
}
if (options->mute) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_MUTE));
}
if (options->fullscreen) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_FULLSCREEN));
}
if (options->togglecontrols) {
- commands = g_list_append (commands, totem_get_action_for_command
+ commands = g_list_append (commands, GINT_TO_POINTER
(TOTEM_REMOTE_COMMAND_TOGGLE_CONTROLS));
}
/* No commands, no files, show ourselves */
if (commands == NULL && options->filenames == NULL) {
- g_application_invoke_action (G_APPLICATION (app),
- totem_get_action_for_command (TOTEM_REMOTE_COMMAND_SHOW),
- NULL);
+ totem_action_remote (totem, TOTEM_REMOTE_COMMAND_SHOW, NULL);
return;
}
/* Send commands */
for (l = commands; l != NULL; l = l->next) {
- g_application_invoke_action (G_APPLICATION (app), l->data, NULL);
+ totem_action_remote (totem, GPOINTER_TO_INT (l->data), NULL);
}
- g_free (action);
g_list_foreach (commands, (GFunc) g_free, NULL);
g_list_free (commands);
}
-#undef UPDATE_ACTION
-
diff --git a/src/totem-options.h b/src/totem-options.h
index a8cbed7..8d59583 100644
--- a/src/totem-options.h
+++ b/src/totem-options.h
@@ -47,7 +47,6 @@ typedef struct {
gboolean quit;
gboolean enqueue;
gboolean replace;
- gboolean notconnectexistingsession;
gdouble playlistidx;
gint64 seek;
gchar **filenames;
@@ -61,7 +60,7 @@ void totem_options_process_early (Totem *totem,
const TotemCmdLineOptions* options);
void totem_options_process_late (Totem *totem,
const TotemCmdLineOptions* options);
-void totem_options_process_for_server (GApplication *app,
+void totem_options_process_for_server (Totem *totem,
const TotemCmdLineOptions* options);
G_END_DECLS
diff --git a/src/totem-private.h b/src/totem-private.h
index 653bac1..8abed90 100644
--- a/src/totem-private.h
+++ b/src/totem-private.h
@@ -158,7 +158,7 @@ struct _TotemObject {
gint64 seek_to;
TotemPlaylist *playlist;
GSettings *settings;
- GApplication *app;
+ GtkApplication *app;
TotemStates state;
TotemOpenLocation *open_location;
gboolean remember_position;
diff --git a/src/totem.c b/src/totem.c
index 2cc6198..1ce9b80 100644
--- a/src/totem.c
+++ b/src/totem.c
@@ -51,6 +51,8 @@
#include "totem-sidebar.h"
#include "video-utils.h"
+static gboolean startup_called = FALSE;
+
static void
long_action (void)
{
@@ -58,47 +60,6 @@ long_action (void)
gtk_main_iteration ();
}
-static void
-totem_action_handler (GApplication *app,
- gchar *name,
- GVariant *platform_data,
- gpointer user_data)
-{
- GEnumClass *klass;
- const GEnumValue *enum_value;
- char *url = NULL;
- TotemRemoteCommand command;
-
- /* GApplication requires the platform_data to be of type a{sv}. */
- if (platform_data) {
- GVariantIter iter;
- GVariant *value;
- const char *key;
-
- g_variant_iter_init (&iter, platform_data);
- while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) {
- if (g_strcmp0 (key, "url") == 0) {
- url = g_variant_dup_string (value, NULL);
- g_variant_unref (value);
- break;
- }
- g_variant_unref (value);
- }
- }
-
- klass = g_type_class_ref (TOTEM_TYPE_REMOTE_COMMAND);
-
- enum_value = g_enum_get_value_by_name (klass, name);
- if (!enum_value)
- return;
- command = enum_value->value;
-
- g_type_class_unref (klass);
-
- totem_action_remote (TOTEM_OBJECT (user_data), command, url);
- g_free (url);
-}
-
/* Debug log message handler: discards debug messages unless Totem is run with TOTEM_DEBUG=1.
* If we're building in the source tree, enable debug messages by default. */
static void
@@ -116,93 +77,16 @@ debug_handler (const char *log_domain,
g_log_default_handler (log_domain, log_level, message, NULL);
}
-int
-main (int argc, char **argv)
+static void
+app_init (Totem *totem, char **argv)
{
- Totem *totem;
- GSettings *settings;
- GError *error = NULL;
- GOptionContext *context;
- GOptionGroup *baconoptiongroup;
- GtkSettings *gtk_settings;
char *sidebar_pageid;
- bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
-
-#ifdef GDK_WINDOWING_X11
- if (XInitThreads () == 0)
- {
- gtk_init (&argc, &argv);
- g_set_application_name (_("Totem Movie Player"));
- totem_action_error_and_exit (_("Could not initialize the thread-safe libraries."), _("Verify your system installation. Totem will now exit."), NULL);
- }
-#endif
-
- g_thread_init (NULL);
- g_type_init ();
-
- /* Handle command line arguments */
- context = g_option_context_new (N_("- Play movies and songs"));
- baconoptiongroup = bacon_video_widget_get_option_group();
- g_option_context_add_main_entries (context, all_options, GETTEXT_PACKAGE);
- g_option_context_set_translation_domain(context, GETTEXT_PACKAGE);
- g_option_context_add_group (context, baconoptiongroup);
-
- g_option_context_add_group (context, gtk_get_option_group (TRUE));
- totem_session_add_options (context);
- if (g_option_context_parse (context, &argc, &argv, &error) == FALSE) {
- g_print (_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
- error->message, argv[0]);
- g_error_free (error);
- g_option_context_free (context);
- totem_action_exit (NULL);
- }
- g_option_context_free (context);
-
- g_set_application_name (_("Totem Movie Player"));
- gtk_window_set_default_icon_name ("totem");
- g_setenv("PULSE_PROP_media.role", "video", TRUE);
-
- gtk_settings = gtk_settings_get_default ();
- g_object_set (G_OBJECT (gtk_settings), "gtk-application-prefer-dark-theme", TRUE, NULL);
-
- settings = g_settings_new (TOTEM_GSETTINGS_SCHEMA);
- if (settings == NULL) {
- totem_action_error_and_exit (_("Totem could not initialize the configuration engine."),
- _("Make sure that GNOME is properly installed."), NULL);
- }
+ /* Settings */
+ totem->settings = g_settings_new (TOTEM_GSETTINGS_SCHEMA);
/* Debug log handling */
- g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, (GLogFunc) debug_handler, settings);
-
- /* Build the main Totem object */
- totem = g_object_new (TOTEM_TYPE_OBJECT, NULL);
- totem->settings = settings;
-
- /* IPC stuff */
- if (optionstate.notconnectexistingsession == FALSE) {
- /* FIXME should be GtkApplication */
- totem->app = g_initable_new (G_TYPE_APPLICATION,
- NULL,
- NULL,
- "application-id", "org.gnome.Totem",
- "argv", g_variant_new_bytestring_array ((const gchar * const*) argv, argc),
- "default-quit", FALSE,
- NULL);
-
- if (g_application_is_remote (G_APPLICATION (totem->app))) {
- totem_options_process_for_server (G_APPLICATION (totem->app), &optionstate);
- gdk_notify_startup_complete ();
- totem_action_exit (totem);
- } else {
- totem_options_register_remote_commands (totem);
- totem_options_process_early (totem, &optionstate);
- }
- } else {
- totem_options_process_early (totem, &optionstate);
- }
+ g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, (GLogFunc) debug_handler, totem->settings);
/* Main window */
totem->xml = totem_interface_load ("totem.ui", TRUE, NULL, totem);
@@ -210,8 +94,6 @@ main (int argc, char **argv)
totem_action_exit (NULL);
totem->win = GTK_WIDGET (gtk_builder_get_object (totem->xml, "totem_main_window"));
- /* FIXME should be enabled
- gtk_application_add_window (totem->app, GTK_WINDOW (totem->win)); */
/* Menubar */
totem_ui_manager_setup (totem);
@@ -289,12 +171,109 @@ main (int argc, char **argv)
if (optionstate.fullscreen == FALSE)
gdk_window_set_cursor (gtk_widget_get_window (totem->win), NULL);
- if (totem->app != NULL) {
- g_signal_connect (G_APPLICATION (totem->app), "action-with-data",
- G_CALLBACK (totem_action_handler), totem);
+ gtk_window_set_application (GTK_WINDOW (totem->win), totem->app);
+}
+
+static void
+app_startup (GApplication *application,
+ Totem *totem)
+{
+ /* We don't do anything here, as we need to know the options
+ * when we set everything up.
+ * Note that this will break D-Bus activation of the application */
+ startup_called = TRUE;
+}
+
+static int
+app_command_line (GApplication *app,
+ GApplicationCommandLine *command_line,
+ Totem *totem)
+{
+ GOptionContext *context;
+ GOptionGroup *baconoptiongroup;
+ GError *error = NULL;
+ int argc;
+ char **argv;
+
+ argv = g_application_command_line_get_arguments (command_line, &argc);
+
+ /* Options parsing */
+ context = g_option_context_new (N_("- Play movies and songs"));
+ baconoptiongroup = bacon_video_widget_get_option_group();
+ g_option_context_add_main_entries (context, all_options, GETTEXT_PACKAGE);
+ g_option_context_set_translation_domain(context, GETTEXT_PACKAGE);
+ g_option_context_add_group (context, baconoptiongroup);
+
+ g_option_context_add_group (context, gtk_get_option_group (TRUE));
+ /* Only add session options to the server process */
+ if (startup_called != FALSE)
+ totem_session_add_options (context);
+ if (g_option_context_parse (context, &argc, &argv, &error) == FALSE) {
+ g_print (_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
+ error->message, argv[0]);
+ g_error_free (error);
+ g_option_context_free (context);
+ return 1;
+ }
+ g_option_context_free (context);
+
+ /* Don't create another window if we're remote.
+ * We can't use g_application_get_is_remote() because it's not registered yet */
+ if (startup_called != FALSE) {
+ app_init (totem, argv);
+ startup_called = FALSE;
+ } else {
+ gtk_window_present_with_time (GTK_WINDOW (totem->win), GDK_CURRENT_TIME);
+ }
+
+ /* Now do something with it */
+ totem_options_process_for_server (totem, &optionstate);
+
+ g_strfreev (argv);
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ Totem *totem;
+ GtkSettings *gtk_settings;
+
+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+#ifdef GDK_WINDOWING_X11
+ if (XInitThreads () == 0)
+ {
+ gtk_init (&argc, &argv);
+ g_set_application_name (_("Totem Movie Player"));
+ totem_action_error_and_exit (_("Could not initialize the thread-safe libraries."), _("Verify your system installation. Totem will now exit."), NULL);
}
+#endif
+
+ g_thread_init (NULL);
+ g_type_init ();
+ gtk_init (&argc, &argv);
+
+ g_set_application_name (_("Totem Movie Player"));
+ gtk_window_set_default_icon_name ("totem");
+ g_setenv("PULSE_PROP_media.role", "video", TRUE);
+
+ gtk_settings = gtk_settings_get_default ();
+ g_object_set (G_OBJECT (gtk_settings), "gtk-application-prefer-dark-theme", TRUE, NULL);
+
+
+ /* Build the main Totem object */
+ totem = g_object_new (TOTEM_TYPE_OBJECT, NULL);
+
+ totem->app = gtk_application_new ("org.gnome.Totem", G_APPLICATION_HANDLES_COMMAND_LINE);
+ g_signal_connect (G_OBJECT (totem->app), "startup",
+ G_CALLBACK (app_startup), totem);
+ g_signal_connect (G_OBJECT (totem->app), "command-line",
+ G_CALLBACK (app_command_line), totem);
- gtk_main ();
+ g_application_run (G_APPLICATION (totem->app), argc, argv);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]