+
+ /* We could possibly have been D-Bus activated as a result of incoming
+ * requests on either the application or actiongroup interfaces.
+ * Because of how GDBus dispatches messages, we need to ensure that
+ * both of those things are registered before we attempt to request
+ * our name.
+ *
+ * The action group need not be populated yet, as long as it happens
+ * before we return to the mainloop. The reason for that is because
+ * GDBus does the check to make sure the object exists from the worker
+ * thread but doesn't actually dispatch the action invocation until we
+ * hit the mainloop in this thread. There is also no danger of
+ * receiving 'activate' or 'open' signals until after 'startup' runs,
+ * for the same reason.
+ */
+ impl->object_id = g_dbus_connection_register_object (impl->session_bus, impl->object_path,
+ org_gtk_Application, &vtable, impl, NULL, error);
+
+ if (impl->object_id == 0)
+ return FALSE;
+
+ impl->fdo_object_id = g_dbus_connection_register_object (impl->session_bus, impl->object_path,
+ org_freedesktop_Application, &vtable, impl, NULL, error);
+
+ if (impl->fdo_object_id == 0)
+ return FALSE;
+
+ impl->actions_id = g_dbus_connection_export_action_group (impl->session_bus, impl->object_path,
+ impl->exported_actions, error);
+
+ if (impl->actions_id == 0)
+ return FALSE;
+
+ if (!app_class->dbus_register (impl->app,
+ impl->session_bus,
+ impl->object_path,
+ error))
+ return FALSE;
+
+ if (impl->bus_name == NULL)
+ {
+ /* If this is a non-unique application then it is sufficient to
+ * have our object paths registered. We can return now.
+ *
+ * Note: non-unique applications always act as primary-instance.
+ */
+ impl->primary = TRUE;
+ return TRUE;
+ }
+
+ /* If this is a unique application then we need to attempt to own
+ * the well-known name and fall back to remote mode (!is_primary)
+ * in the case that we can't do that.
+ */
+ /* DBUS_NAME_FLAG_DO_NOT_QUEUE: 0x4 */
+ reply = g_dbus_connection_call_sync (impl->session_bus, "org.freedesktop.DBus", "/org/freedesktop/DBus",
+ "org.freedesktop.DBus", "RequestName",
+ g_variant_new ("(su)", impl->bus_name, 0x4), G_VARIANT_TYPE ("(u)"),
+ 0, -1, cancellable, error);
+
+ if (reply == NULL)
+ return FALSE;
+
+ g_variant_get (reply, "(u)", &rval);
+ g_variant_unref (reply);
+
+ /* DBUS_REQUEST_NAME_REPLY_EXISTS: 3 */
+ impl->primary = (rval != 3);
+
+ return TRUE;
+}
+
+/* Stop doing the things that the primary instance does.
+ *
+ * This should be called if attempting to become the primary instance
+ * failed (in order to clean up any partial success) and should also
+ * be called when freeing the GApplication.
+ *
+ * It is safe to call this multiple times.
+ */
+static void
+g_application_impl_stop_primary (GApplicationImpl *impl)
+{
+ GApplicationClass *app_class = G_APPLICATION_GET_CLASS (impl->app);
+
+ app_class->dbus_unregister (impl->app,
+ impl->session_bus,
+ impl->object_path);
+
+ if (impl->object_id)
+ {
+ g_dbus_connection_unregister_object (impl->session_bus, impl->object_id);
+ impl->object_id = 0;
+ }
+
+ if (impl->fdo_object_id)
+ {
+ g_dbus_connection_unregister_object (impl->session_bus, impl->fdo_object_id);
+ impl->fdo_object_id = 0;
+ }
+
+ if (impl->actions_id)
+ {
+ g_dbus_connection_unexport_action_group (impl->session_bus, impl->actions_id);
+ impl->actions_id = 0;
+ }
+
+ if (impl->primary && impl->bus_name)