[totem] Port Totem to new GApplication code



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]