[gnome-flashback] another big commit (more info in description)



commit 8e79f839eec9a57796688dcdafe0c3fedecbc6e7
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Mon Oct 27 00:18:17 2014 +0200

    another big commit (more info in description)
    
    * Don't create separate application for initialization task. Use
      gnome-flashback with --initialize commandline parameter.
    * Add --replace to allow replace running instance. Mostly for
      debugging purposes.
    * Don't use GtkApplication.

 Makefile.am                             |    1 -
 configure.ac                            |    7 +-
 data/gnome-flashback-init.desktop.in    |    4 +-
 data/gnome-flashback.desktop.in         |    3 +-
 gnome-flashback-init/Makefile.am        |   14 --
 gnome-flashback-init/main.c             |  113 -----------
 gnome-flashback/Makefile.am             |    4 +-
 gnome-flashback/flashback-application.c |  116 +++--------
 gnome-flashback/flashback-application.h |    6 +-
 gnome-flashback/flashback-main.c        |  106 ++++++++++-
 gnome-flashback/flashback-session.c     |  333 +++++++++++++++++++++++++++++++
 gnome-flashback/flashback-session.h     |   56 +++++
 12 files changed, 529 insertions(+), 234 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index ef8a790..70b4140 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,6 @@
 SUBDIRS = \
        data \
        gnome-flashback \
-       gnome-flashback-init \
        po
 
 ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
diff --git a/configure.ac b/configure.ac
index e724ee1..1538ba9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,14 +33,10 @@ CANBERRA_REQUIRED=0.13
 GLIB_REQUIRED=2.39.91
 GSETTINGS_DESKTOP_SCHEMAS_REQUIRED=3.12.0
 
-PKG_CHECK_MODULES(GNOME_FLASHBACK, gtk+-3.0 >= $GTK_REQUIRED)
+PKG_CHECK_MODULES(GNOME_FLASHBACK, gtk+-3.0 >= $GTK_REQUIRED dbus-glib-1)
 AC_SUBST(GNOME_FLASHBACK_CFLAGS)
 AC_SUBST(GNOME_FLASHBACK_LIBS)
 
-PKG_CHECK_MODULES(GNOME_FLASHBACK_INIT, gtk+-3.0 >= $GTK_REQUIRED)
-AC_SUBST(GNOME_FLASHBACK_INIT_CFLAGS)
-AC_SUBST(GNOME_FLASHBACK_INIT_LIBS)
-
 PKG_CHECK_MODULES(END_SESSION_DIALOG, gtk+-3.0 >= $GTK_REQUIRED)
 AC_SUBST(END_SESSION_DIALOG_CFLAGS)
 AC_SUBST(END_SESSION_DIALOG_LIBS)
@@ -79,7 +75,6 @@ gnome-flashback/libend-session-dialog/Makefile
 gnome-flashback/libidle-monitor/Makefile
 gnome-flashback/libsound-applet/Makefile
 gnome-flashback/libsound-applet/gvc/Makefile
-gnome-flashback-init/Makefile
 po/Makefile.in
 ])
 
diff --git a/data/gnome-flashback-init.desktop.in b/data/gnome-flashback-init.desktop.in
index 98df5fd..e07ac22 100644
--- a/data/gnome-flashback-init.desktop.in
+++ b/data/gnome-flashback-init.desktop.in
@@ -1,9 +1,9 @@
 [Desktop Entry]
 Type=Application
 _Name=GNOME Flashback Initialization
-Exec=gnome-flashback-init
+Exec=gnome-flashback --initialize
 OnlyShowIn=GNOME-Flashback;
 NoDisplay=true
 X-GNOME-Autostart-Phase=Initialization
 X-GNOME-Autostart-Notify=true
-X-GNOME-AutoRestart=true
+X-GNOME-AutoRestart=false
diff --git a/data/gnome-flashback.desktop.in b/data/gnome-flashback.desktop.in
index faeecbd..44487fe 100644
--- a/data/gnome-flashback.desktop.in
+++ b/data/gnome-flashback.desktop.in
@@ -1,8 +1,9 @@
 [Desktop Entry]
-_Name=GNOME Flashback
 Type=Application
+_Name=GNOME Flashback
 Exec=gnome-flashback
 OnlyShowIn=GNOME-Flashback;
 NoDisplay=true
 X-GNOME-Autostart-Phase=Desktop
+X-GNOME-Autostart-Notify=true
 X-GNOME-AutoRestart=true
diff --git a/gnome-flashback/Makefile.am b/gnome-flashback/Makefile.am
index 14f3e08..3a10388 100644
--- a/gnome-flashback/Makefile.am
+++ b/gnome-flashback/Makefile.am
@@ -17,7 +17,9 @@ AM_CPPFLAGS = \
 gnome_flashback_SOURCES = \
        flashback-application.c \
        flashback-application.h \
-       flashback-main.c
+       flashback-main.c \
+       flashback-session.c \
+       flashback-session.h
 
 gnome_flashback_LDADD = \
        $(GNOME_FLASHBACK_LIBS) \
diff --git a/gnome-flashback/flashback-application.c b/gnome-flashback/flashback-application.c
index 4e57304..3153128 100644
--- a/gnome-flashback/flashback-application.c
+++ b/gnome-flashback/flashback-application.c
@@ -44,7 +44,7 @@ struct _FlashbackApplicationPrivate {
        GvcApplet                  *applet;
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (FlashbackApplication, flashback_application, GTK_TYPE_APPLICATION);
+G_DEFINE_TYPE_WITH_PRIVATE (FlashbackApplication, flashback_application, G_TYPE_OBJECT);
 
 static void
 flashback_application_settings_changed (GSettings   *settings,
@@ -72,10 +72,7 @@ flashback_application_settings_changed (GSettings   *settings,
                                app->priv->background = desktop_background_new ();
                        }
                } else {
-                       if (app->priv->background) {
-                               g_object_unref (app->priv->background);
-                               app->priv->background = NULL;
-                       }
+                       g_clear_object (&app->priv->background);
                }
        }
 
@@ -85,10 +82,7 @@ flashback_application_settings_changed (GSettings   *settings,
                                app->priv->config = flashback_display_config_new ();
                        }
                } else {
-                       if (app->priv->config) {
-                               g_object_unref (app->priv->config);
-                               app->priv->config = NULL;
-                       }
+                       g_clear_object (&app->priv->config);
                }
        }
 
@@ -98,10 +92,7 @@ flashback_application_settings_changed (GSettings   *settings,
                                app->priv->dialog = flashback_end_session_dialog_new ();
                        }
                } else {
-                       if (app->priv->dialog) {
-                               g_object_unref (app->priv->dialog);
-                               app->priv->dialog = NULL;
-                       }
+                       g_clear_object (&app->priv->dialog);
                }
        }
 
@@ -111,10 +102,7 @@ flashback_application_settings_changed (GSettings   *settings,
                                app->priv->idle_monitor = meta_idle_monitor_dbus_new ();
                        }
                } else {
-                       if (app->priv->idle_monitor) {
-                               g_object_unref (app->priv->idle_monitor);
-                               app->priv->idle_monitor = NULL;
-                       }
+                       g_clear_object (&app->priv->idle_monitor);
                }
        }
 
@@ -124,101 +112,53 @@ flashback_application_settings_changed (GSettings   *settings,
                                app->priv->applet = gvc_applet_new ();
                        }
                } else {
-                       if (app->priv->applet) {
-                               g_object_unref (app->priv->applet);
-                               app->priv->applet = NULL;
-                       }
+                       g_clear_object (&app->priv->applet);
                }
        }
 }
 
 static void
-flashback_application_activate (GApplication *application)
-{
-}
-
-static void
-flashback_application_startup (GApplication *application)
-{
-       FlashbackApplication *app = FLASHBACK_APPLICATION (application);
-
-       G_APPLICATION_CLASS (flashback_application_parent_class)->startup (application);
-
-       bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
-       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-       textdomain (GETTEXT_PACKAGE);
-
-       app->priv->settings = g_settings_new (FLASHBACK_SCHEMA);
-
-       g_signal_connect (app->priv->settings, "changed",
-                         G_CALLBACK (flashback_application_settings_changed), app);
-       flashback_application_settings_changed (app->priv->settings, NULL, app);
-
-       g_application_hold (application);
-}
-
-static void
-flashback_application_shutdown (GApplication *application)
+flashback_application_finalize (GObject *object)
 {
-       FlashbackApplication *app = FLASHBACK_APPLICATION (application);
-
-       if (app->priv->automount) {
-               g_object_unref (app->priv->automount);
-               app->priv->automount = NULL;
-       }
-
-       if (app->priv->background) {
-               g_object_unref (app->priv->background);
-               app->priv->background = NULL;
-       }
-
-       if (app->priv->config) {
-               g_object_unref (app->priv->config);
-               app->priv->config = NULL;
-       }
-
-       if (app->priv->dialog) {
-               g_object_unref (app->priv->dialog);
-               app->priv->dialog = NULL;
-       }
-
-       if (app->priv->idle_monitor) {
-               g_object_unref (app->priv->idle_monitor);
-               app->priv->idle_monitor = NULL;
-       }
+       FlashbackApplication *app = FLASHBACK_APPLICATION (object);
 
+       g_clear_object (&app->priv->background);
+       g_clear_object (&app->priv->config);
+       g_clear_object (&app->priv->dialog);
+       g_clear_object (&app->priv->idle_monitor);
        g_clear_object (&app->priv->applet);
+       g_clear_object (&app->priv->settings);
 
-       if (app->priv->settings) {
-               g_object_unref (app->priv->settings);
-               app->priv->settings = NULL;
-       }
-
-       G_APPLICATION_CLASS (flashback_application_parent_class)->shutdown (application);
+       G_OBJECT_CLASS (flashback_application_parent_class)->finalize (object);
 }
 
 static void
 flashback_application_init (FlashbackApplication *application)
 {
+       FlashbackApplicationPrivate *priv;
+
        application->priv = flashback_application_get_instance_private (application);
+       priv = application->priv;
+
+       priv->settings = g_settings_new (FLASHBACK_SCHEMA);
+
+       g_signal_connect (priv->settings, "changed",
+                         G_CALLBACK (flashback_application_settings_changed), application);
+       flashback_application_settings_changed (priv->settings, NULL, application);
 }
 
 static void
 flashback_application_class_init (FlashbackApplicationClass *class)
 {
-       GApplicationClass *application_class = G_APPLICATION_CLASS (class);
+       GObjectClass *object_class;
+
+       object_class = G_OBJECT_CLASS (class);
 
-       application_class->startup  = flashback_application_startup;
-       application_class->shutdown = flashback_application_shutdown;
-       application_class->activate = flashback_application_activate;
+       object_class->finalize = flashback_application_finalize;
 }
 
 FlashbackApplication *
 flashback_application_new (void)
 {
-       return g_object_new (FLASHBACK_TYPE_APPLICATION,
-                            "application-id", "org.gnome.gnome-flashback",
-                            "flags", G_APPLICATION_FLAGS_NONE,
-                            "register-session", TRUE,
-                            NULL);
+       return g_object_new (FLASHBACK_TYPE_APPLICATION, NULL);
 }
diff --git a/gnome-flashback/flashback-application.h b/gnome-flashback/flashback-application.h
index 32704fb..c1b5653 100644
--- a/gnome-flashback/flashback-application.h
+++ b/gnome-flashback/flashback-application.h
@@ -18,7 +18,7 @@
 #ifndef FLASHBACK_APPLICATION_H
 #define FLASHBACK_APPLICATION_H
 
-#include <gtk/gtk.h>
+#include <glib-object.h>
 
 G_BEGIN_DECLS
 
@@ -34,12 +34,12 @@ typedef struct _FlashbackApplicationClass   FlashbackApplicationClass;
 typedef struct _FlashbackApplicationPrivate FlashbackApplicationPrivate;
 
 struct _FlashbackApplication {
-       GtkApplication               parent;
+       GObject                     parent;
        FlashbackApplicationPrivate *priv;
 };
 
 struct _FlashbackApplicationClass {
-       GtkApplicationClass parent;
+       GObjectClass parent_class;
 };
 
 GType                 flashback_application_get_type (void);
diff --git a/gnome-flashback/flashback-main.c b/gnome-flashback/flashback-main.c
index 67a7521..4a2356c 100644
--- a/gnome-flashback/flashback-main.c
+++ b/gnome-flashback/flashback-main.c
@@ -15,17 +15,113 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <config.h>
+#include <glib-unix.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
 #include "flashback-application.h"
+#include "flashback-session.h"
+
+static gboolean initialize = FALSE;
+static gboolean replace = FALSE;
+
+static GOptionEntry entries[] = {
+       {
+               "initialize", 0, G_OPTION_FLAG_NONE,
+               G_OPTION_ARG_NONE, &initialize,
+               N_("Initialize GNOME Flashback session"),
+               NULL
+       },
+       {
+               "replace", 'r', G_OPTION_FLAG_NONE,
+               G_OPTION_ARG_NONE, &replace,
+               N_("Replace a currently running application"),
+               NULL
+       },
+       {
+               NULL
+       }
+};
+
+static gboolean
+parse_context_options (int *argc, char ***argv)
+{
+       GError *error;
+       GOptionContext *context;
+
+       error = NULL;
+       context = g_option_context_new (NULL);
+
+       g_option_context_add_main_entries (context, entries, NULL);
+       g_option_context_add_group (context, gtk_get_option_group (FALSE));
+
+       if (!g_option_context_parse (context, argc, argv, &error)) {
+               if (error != NULL) {
+                       g_warning ("%s", error->message);
+                       g_error_free (error);
+               }
+
+               return FALSE;
+       }
+
+       g_option_context_free (context);
+
+       return TRUE;
+}
+
+static gboolean
+on_term_signal (gpointer user_data)
+{
+        gtk_main_quit ();
+
+        return FALSE;
+}
+
+static gboolean
+on_int_signal (gpointer user_data)
+{
+        gtk_main_quit ();
+
+        return FALSE;
+}
 
 int
 main (int argc, char *argv[])
 {
-       int status;
        FlashbackApplication *application;
+       FlashbackSession *session;
+
+       g_set_prgname ("gnome-flashback");
+
+       bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+       textdomain (GETTEXT_PACKAGE);
+
+       gtk_init (&argc, &argv);
+
+       g_unix_signal_add (SIGTERM, on_term_signal, NULL);
+       g_unix_signal_add (SIGINT, on_int_signal, NULL);
+
+       if (!parse_context_options (&argc, &argv))
+               return 1;
+
+       session = flashback_session_new (replace);
+       if (session == NULL)
+               return 1;
+
+       if (initialize) {
+               flashback_session_set_environment (session, "XDG_MENU_PREFIX", "gnome-flashback-");
+               flashback_session_register_client (session);
+       } else {
+               application = flashback_application_new ();
+               flashback_session_register_client (session);
+               gtk_main ();
+       }
 
-       application = flashback_application_new ();
-       status = g_application_run (G_APPLICATION (application), argc, argv);
-       g_object_unref (application);
+       if (!initialize)
+               g_object_unref (application);
+       g_object_unref (session);
 
-       return status;
+       return 0;
 }
diff --git a/gnome-flashback/flashback-session.c b/gnome-flashback/flashback-session.c
new file mode 100644
index 0000000..eb01277
--- /dev/null
+++ b/gnome-flashback/flashback-session.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2014 Alberts Muktupāvels
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <dbus/dbus-glib.h>
+#include <gtk/gtk.h>
+
+#include "flashback-session.h"
+
+#define FLASHBACK_DBUS_SERVICE "org.gnome.Flashback"
+
+#define SESSION_MANAGER_NAME      "org.gnome.SessionManager"
+#define SESSION_MANAGER_PATH      "/org/gnome/SessionManager"
+#define SESSION_MANAGER_INTERFACE "org.gnome.SessionManager"
+
+#define SESSION_MANAGER_CLIENT_PRIVATE_INTERFACE "org.gnome.SessionManager.ClientPrivate"
+
+struct _FlashbackSessionPrivate {
+       GDBusConnection *connection;
+       guint            name_lost_id;
+
+       GDBusProxy      *session_manager_proxy;
+
+       gchar           *object_path;
+       GDBusProxy      *client_proxy;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (FlashbackSession, flashback_session, G_TYPE_OBJECT)
+
+static void
+respond_to_end_session (GDBusProxy *proxy)
+{
+       g_dbus_proxy_call (proxy,
+                          "EndSessionResponse",
+                          g_variant_new ("(bs)", TRUE, ""),
+                          G_DBUS_CALL_FLAGS_NONE,
+                          -1,
+                          NULL,
+                          NULL,
+                          NULL);
+}
+
+static void
+flashback_session_client_proxy_signal_cb (GDBusProxy *proxy,
+                                          gchar      *sender_name,
+                                          gchar      *signal_name,
+                                          GVariant   *parameters,
+                                          gpointer    user_data)
+{
+       if (g_str_equal (signal_name, "QueryEndSession"))
+               respond_to_end_session (proxy);
+       else if (g_str_equal (signal_name, "EndSession"))
+               respond_to_end_session (proxy);
+       else if (g_str_equal (signal_name, "Stop"))
+               gtk_main_quit ();
+}
+
+static gboolean
+flashback_session_get_session_manager_proxy (FlashbackSession *session)
+{
+       FlashbackSessionPrivate *priv;
+       GError *error;
+       GDBusProxyFlags flags;
+
+       if (!session)
+               return FALSE;
+
+       priv = session->priv;
+       error = NULL;
+       flags = G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+               G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS;
+
+       priv->session_manager_proxy = g_dbus_proxy_new_sync (priv->connection,
+                                                            flags,
+                                                            NULL,
+                                                            SESSION_MANAGER_NAME,
+                                                            SESSION_MANAGER_PATH,
+                                                            SESSION_MANAGER_INTERFACE,
+                                                            NULL,
+                                                            &error);
+
+       if (error) {
+               g_warning ("Failed to get session manager proxy: %s", error->message);
+               g_error_free (error);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static void
+flashback_session_name_lost (GDBusConnection *connection,
+                             const gchar     *sender_name,
+                             const gchar     *object_path,
+                             const gchar     *interface_name,
+                             const gchar     *signal_name,
+                             GVariant        *parameters,
+                             gpointer         user_data)
+{
+       gtk_main_quit ();
+}
+
+static gboolean
+flashback_session_request_name (FlashbackSession *session,
+                                gboolean          replace)
+{
+       FlashbackSessionPrivate *priv;
+       GBusNameOwnerFlags flags;
+       GError *error;
+       GVariant *result;
+       guint32 reply;
+
+       priv = session->priv;
+       flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
+       error = NULL;
+
+       priv->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+
+       if (error) {
+               g_warning ("Failed to get session bus: %s", error->message);
+               g_error_free (error);
+               return FALSE;
+       }
+
+       if (replace)
+               flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;
+
+       result = g_dbus_connection_call_sync (priv->connection,
+                                             DBUS_SERVICE_DBUS,
+                                             DBUS_PATH_DBUS,
+                                             DBUS_INTERFACE_DBUS,
+                                             "RequestName",
+                                             g_variant_new ("(su)",
+                                                            FLASHBACK_DBUS_SERVICE,
+                                                            flags),
+                                             G_VARIANT_TYPE ("(u)"),
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1,
+                                             NULL,
+                                             &error);
+
+       if (error) {
+               g_warning ("Failed to request name: %s", error->message);
+               g_error_free (error);
+               return FALSE;
+       }
+
+       g_variant_get (result, "(u)", &reply);
+       g_variant_unref (result);
+
+       switch (reply) {
+               case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
+               case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
+                       priv->name_lost_id = g_dbus_connection_signal_subscribe (priv->connection,
+                                                                                DBUS_SERVICE_DBUS,
+                                                                                DBUS_INTERFACE_DBUS,
+                                                                                "NameLost",
+                                                                                DBUS_PATH_DBUS,
+                                                                                FLASHBACK_DBUS_SERVICE,
+                                                                                G_DBUS_SIGNAL_FLAGS_NONE,
+                                                                                (GDBusSignalCallback) 
flashback_session_name_lost,
+                                                                                session,
+                                                                                NULL);
+                       break;
+               case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
+               case DBUS_REQUEST_NAME_REPLY_EXISTS:
+                       g_warning ("Failed to request name: the name already has an owner");
+                       return FALSE;
+               default:
+                       g_warning ("Failed to request name: unhandled reply %u from RequestName", reply);
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+static void
+flashback_session_finalize (GObject *object)
+{
+       FlashbackSession *session;
+       FlashbackSessionPrivate *priv;
+
+       session = FLASHBACK_SESSION (object);
+       priv = session->priv;
+
+       if (priv->object_path != NULL) {
+               g_free (priv->object_path);
+               priv->object_path;
+       }
+
+       g_clear_object (&priv->client_proxy);
+       g_clear_object (&priv->session_manager_proxy);
+
+       if (priv->name_lost_id > 0) {
+               g_dbus_connection_signal_unsubscribe (priv->connection, priv->name_lost_id);
+               priv->name_lost_id = 0;
+       }
+
+       g_clear_object (&priv->connection);
+
+       G_OBJECT_CLASS (flashback_session_parent_class)->finalize (object);
+}
+
+static void
+flashback_session_class_init (FlashbackSessionClass *class)
+{
+       GObjectClass *object_class;
+
+       object_class = G_OBJECT_CLASS (class);
+
+       object_class->finalize = flashback_session_finalize;
+}
+
+static void
+flashback_session_init (FlashbackSession *session)
+{
+       session->priv = flashback_session_get_instance_private (session);
+}
+
+FlashbackSession *
+flashback_session_new (gboolean replace)
+{
+       FlashbackSession *session;
+
+       session = g_object_new (FLASHBACK_TYPE_SESSION, NULL);
+
+       if (!flashback_session_request_name (session, replace))
+               g_clear_object (&session);
+
+       if (!flashback_session_get_session_manager_proxy (session))
+               g_clear_object (&session);
+
+       return session;
+}
+
+gboolean
+flashback_session_set_environment (FlashbackSession *session,
+                                   const gchar      *name,
+                                   const gchar      *value)
+{
+       GError *error;
+       GVariant *parameters;
+       GVariant *res;
+
+       error = NULL;
+       parameters = g_variant_new ("(ss)", name, value);
+       res = g_dbus_proxy_call_sync (session->priv->session_manager_proxy,
+                                     "Setenv",
+                                     parameters,
+                                     G_DBUS_CALL_FLAGS_NONE,
+                                     -1,
+                                     NULL,
+                                     &error);
+
+       if (error) {
+               g_debug ("Failed to set the environment: %s", error->message);
+               g_error_free (error);
+               return FALSE;
+       }
+
+       g_variant_unref (res);
+
+       return TRUE;
+}
+
+gboolean
+flashback_session_register_client (FlashbackSession *session)
+{
+       FlashbackSessionPrivate *priv;
+       GError *error;
+       const gchar *app_id;
+       const gchar *client_startup_id;
+       GVariant *parameters;
+       GVariant *res;
+
+       priv = session->priv;
+       error = NULL;
+       app_id = "gnome-flashback";
+       client_startup_id = g_getenv ("DESKTOP_AUTOSTART_ID");
+
+       parameters = g_variant_new ("(ss)", app_id, client_startup_id ? client_startup_id : "");
+
+       res = g_dbus_proxy_call_sync (priv->session_manager_proxy,
+                                     "RegisterClient",
+                                     parameters,
+                                     G_DBUS_CALL_FLAGS_NONE,
+                                     -1,
+                                     NULL,
+                                     &error);
+
+       if (error) {
+               g_warning ("Failed to register client: %s", error->message);
+               g_error_free (error);
+               return FALSE;
+       }
+
+       g_variant_get (res, "(o)", &priv->object_path);
+       g_variant_unref (res);
+
+       priv->client_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                           G_DBUS_PROXY_FLAGS_NONE,
+                                                           NULL,
+                                                           SESSION_MANAGER_NAME,
+                                                           priv->object_path,
+                                                           SESSION_MANAGER_CLIENT_PRIVATE_INTERFACE,
+                                                           NULL,
+                                                           &error);
+
+       if (error) {
+               g_warning ("Failed to get a client proxy: %s", error->message);
+               g_error_free (error);
+               return FALSE;
+       }
+
+       g_signal_connect (priv->client_proxy, "g-signal",
+                         G_CALLBACK (flashback_session_client_proxy_signal_cb), session);
+
+       return TRUE;
+}
diff --git a/gnome-flashback/flashback-session.h b/gnome-flashback/flashback-session.h
new file mode 100644
index 0000000..cfe9dc8
--- /dev/null
+++ b/gnome-flashback/flashback-session.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 Alberts Muktupāvels
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FLASHBACK_SESSION_H
+#define FLASHBACK_SESSION_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define FLASHBACK_TYPE_SESSION         (flashback_session_get_type ())
+#define FLASHBACK_SESSION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), FLASHBACK_TYPE_SESSION, 
FlashbackSession))
+#define FLASHBACK_IS_SESSION(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), FLASHBACK_TYPE_SESSION))
+#define FLASHBACK_SESSION_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c),    FLASHBACK_TYPE_SESSION, 
FlashbackSessionClass))
+#define FLASHBACK_IS_SESSION_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c),    FLASHBACK_TYPE_SESSION))
+#define FLASHBACK_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  FLASHBACK_TYPE_SESSION, 
FlashbackSessionClass))
+
+typedef struct _FlashbackSession        FlashbackSession;
+typedef struct _FlashbackSessionClass   FlashbackSessionClass;
+typedef struct _FlashbackSessionPrivate FlashbackSessionPrivate;
+
+struct _FlashbackSession {
+       GObject                  parent;
+       FlashbackSessionPrivate *priv;
+};
+
+struct _FlashbackSessionClass {
+       GObjectClass parent_class;
+};
+
+GType             flashback_session_get_type        (void);
+
+FlashbackSession *flashback_session_new             (gboolean          replace);
+
+gboolean          flashback_session_set_environment (FlashbackSession *session,
+                                                     const gchar      *name,
+                                                     const gchar      *value);
+gboolean          flashback_session_register_client (FlashbackSession *session);
+
+G_END_DECLS
+
+#endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]