From 5350302b09ddbbfa98091a943ae878c9aaf9eb6e Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 16 Aug 2011 14:19:59 +0200 Subject: [PATCH] Port to new GDBus bindings in gjs Rewrite code acquiring dbus names so that it uses GDBus, and rewrite ShellDBus so that it is exposed on the GDBus connection. Ports of the other objects will follow. https://bugzilla.gnome.org/show_bug.cgi?id=648651 --- configure.ac | 8 +-- js/ui/main.js | 6 -- js/ui/shellDBus.js | 151 +++++++++++++++++++++++++-------------------- src/main.c | 71 ++++++++++++--------- 4 files changed, 129 insertions(+), 107 deletions(-) diff --git a/configure.ac b/configure.ac index a0fc33827..1304baae9 100644 --- a/configure.ac +++ b/configure.ac @@ -70,8 +70,7 @@ GJS_MIN_VERSION=1.29.18 MUTTER_MIN_VERSION=3.2.1 FOLKS_MIN_VERSION=0.5.2 GTK_MIN_VERSION=3.0.0 -GLIB_MIN_VERSION=2.31.0 -GIO_MIN_VERSION=2.29.10 +GIO_MIN_VERSION=2.31.0 LIBECAL_MIN_VERSION=2.32.0 LIBEDATASERVER_MIN_VERSION=1.2.0 LIBEDATASERVERUI_MIN_VERSION=2.91.6 @@ -81,9 +80,8 @@ POLKIT_MIN_VERSION=0.100 STARTUP_NOTIFICATION_MIN_VERSION=0.11 # Collect more than 20 libraries for a prize! -PKG_CHECK_MODULES(GNOME_SHELL, glib-2.0 >= $GLIB_MIN_VERSION - gio-2.0 >= $GIO_MIN_VERSION - gio-unix-2.0 dbus-glib-1 libxml-2.0 +PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION + libxml-2.0 gtk+-3.0 >= $GTK_MIN_VERSION folks >= $FOLKS_MIN_VERSION libmutter >= $MUTTER_MIN_VERSION diff --git a/js/ui/main.js b/js/ui/main.js index e08de3df8..6bd5f59dc 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -1,7 +1,6 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- const Clutter = imports.gi.Clutter; -const DBus = imports.dbus; const Gdk = imports.gi.Gdk; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; @@ -163,11 +162,6 @@ function start() { Gio.DesktopAppInfo.set_desktop_env('GNOME'); shellDBusService = new ShellDBus.GnomeShell(); - // Force a connection now; dbus.js will do this internally - // if we use its name acquisition stuff but we aren't right - // now; to do so we'd need to convert from its async calls - // back into sync ones. - DBus.session.flush(); // Ensure ShellWindowTracker and ShellAppUsage are initialized; this will // also initialize ShellAppSystem first. ShellAppSystem diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js index 4f81c53a9..5a00a34f3 100644 --- a/js/ui/shellDBus.js +++ b/js/ui/shellDBus.js @@ -1,71 +1,70 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- -const DBus = imports.dbus; const Lang = imports.lang; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; const Config = imports.misc.config; const ExtensionSystem = imports.ui.extensionSystem; const Main = imports.ui.main; -const GnomeShellIface = { - name: 'org.gnome.Shell', - methods: [{ name: 'Eval', - inSignature: 's', - outSignature: 'bs' - }, - { name: 'ListExtensions', - inSignature: '', - outSignature: 'a{sa{sv}}' - }, - { name: 'GetExtensionInfo', - inSignature: 's', - outSignature: 'a{sv}' - }, - { name: 'GetExtensionErrors', - inSignature: 's', - outSignature: 'as' - }, - { name: 'ScreenshotArea', - inSignature: 'iiiis', - outSignature: 'b' - }, - { name: 'ScreenshotWindow', - inSignature: 'bs', - outSignature: 'b' - }, - { name: 'Screenshot', - inSignature: 's', - outSignature: 'b' - }, - { name: 'EnableExtension', - inSignature: 's', - outSignature: '' - }, - { name: 'DisableExtension', - inSignature: 's', - outSignature: '' - }, - { name: 'InstallRemoteExtension', - inSignature: 'ss', - outSignature: '' - }, - { name: 'UninstallExtension', - inSignature: 's', - outSignature: 'b' - } - ], - signals: [{ name: 'ExtensionStatusChanged', - inSignature: 'sis' }], - properties: [{ name: 'OverviewActive', - signature: 'b', - access: 'readwrite' }, - { name: 'ApiVersion', - signature: 'i', - access: 'read' }, - { name: 'ShellVersion', - signature: 's', - access: 'read' }] -}; +const GnomeShellIface = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +; function GnomeShell() { this._init(); @@ -73,7 +72,8 @@ function GnomeShell() { GnomeShell.prototype = { _init: function() { - DBus.session.exportObject('/org/gnome/Shell', this); + this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this); + this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell'); ExtensionSystem.connect('extension-state-changed', Lang.bind(this, this._extensionStateChanged)); }, @@ -156,11 +156,33 @@ GnomeShell.prototype = { }, ListExtensions: function() { - return ExtensionSystem.extensionMeta; + let out; + for (let uuid in ExtensionSystem.extensionMeta) { + let dbusObj = this.GetExtensionInfo(uuid); + out[uuid] = dbusObj; + } + return out; }, GetExtensionInfo: function(uuid) { - return ExtensionSystem.extensionMeta[uuid] || {}; + let meta = ExtensionSystem.extensionMeta[uuid] || {}; + let out; + for (let key in meta) { + let val = meta[key]; + let type; + switch (typeof val) { + case 'object': + throw Error('Extension had a nested object in the metadata. This is not supported'); + case 'string': + type = 's'; + break; + case 'number': + type = 'd'; + break; + } + out[key] = GLib.Variant.new(type, val); + } + return out; }, GetExtensionErrors: function(uuid) { @@ -211,6 +233,3 @@ GnomeShell.prototype = { [newState.uuid, newState.state, newState.error]); } }; - -DBus.conformExport(GnomeShell.prototype, GnomeShellIface); - diff --git a/src/main.c b/src/main.c index d8cdff5b2..6cc66f83d 100644 --- a/src/main.c +++ b/src/main.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -36,35 +35,41 @@ extern GType gnome_shell_plugin_get_type (void); static gboolean is_gdm_mode = FALSE; +#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 +#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 + static void -shell_dbus_acquire_name (DBusGProxy *bus, +shell_dbus_acquire_name (GDBusProxy *bus, guint32 request_name_flags, guint32 *request_name_result, gchar *name, gboolean fatal) { GError *error = NULL; - if (!dbus_g_proxy_call (bus, "RequestName", &error, - G_TYPE_STRING, name, - G_TYPE_UINT, request_name_flags, - G_TYPE_INVALID, - G_TYPE_UINT, request_name_result, - G_TYPE_INVALID)) + GVariant *request_name_variant; + + if (!(request_name_variant = g_dbus_proxy_call_sync (bus, + "RequestName", + g_variant_new ("(su)", name, request_name_flags), + 0, /* call flags */ + -1, /* timeout */ + NULL, /* cancellable */ + &error))) { - g_printerr ("failed to acquire %s: %s\n", name, error->message); - if (fatal) - exit (1); + g_printerr ("failed to acquire org.gnome.Shell: %s\n", error->message); + exit (1); } + g_variant_get (request_name_variant, "(u)", request_name_result); } static void -shell_dbus_acquire_names (DBusGProxy *bus, +shell_dbus_acquire_names (GDBusProxy *bus, guint32 request_name_flags, gchar *name, gboolean fatal, ...) G_GNUC_NULL_TERMINATED; static void -shell_dbus_acquire_names (DBusGProxy *bus, +shell_dbus_acquire_names (GDBusProxy *bus, guint32 request_name_flags, gchar *name, gboolean fatal, ...) @@ -89,27 +94,32 @@ shell_dbus_acquire_names (DBusGProxy *bus, static void shell_dbus_init (gboolean replace) { - DBusGConnection *session; - DBusGProxy *bus; + GDBusConnection *session; + GDBusProxy *bus; + GError *error = NULL; guint32 request_name_flags; guint32 request_name_result; - /* TODO: - * In the future we should use GDBus for this. However, in - * order to do that, we need to port all of the JavaScript - * code. Otherwise, the name will be claimed on the wrong - * connection. - */ - session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL); + session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); - bus = dbus_g_proxy_new_for_name (session, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); + if (error) { + g_printerr ("Failed to connect to session bus: %s", error->message); + exit (1); + } - request_name_flags = DBUS_NAME_FLAG_DO_NOT_QUEUE | DBUS_NAME_FLAG_ALLOW_REPLACEMENT; + bus = g_dbus_proxy_new_sync (session, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* interface info */ + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + NULL, /* cancellable */ + &error); + + request_name_flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; if (replace) request_name_flags |= DBUS_NAME_FLAG_REPLACE_EXISTING; + shell_dbus_acquire_name (bus, request_name_flags, &request_name_result, @@ -117,8 +127,7 @@ shell_dbus_init (gboolean replace) if (!(request_name_result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER || request_name_result == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER)) { - g_printerr ("%s already exists on bus and --replace not specified\n", - SHELL_DBUS_SERVICE); + g_printerr (SHELL_DBUS_SERVICE " already exists on bus and --replace not specified\n"); exit (1); } @@ -126,7 +135,8 @@ shell_dbus_init (gboolean replace) * We always specify REPLACE_EXISTING to ensure we kill off * the existing service if it was running. */ - request_name_flags |= DBUS_NAME_FLAG_REPLACE_EXISTING; + request_name_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; + shell_dbus_acquire_names (bus, request_name_flags, /* Also grab org.gnome.Panel to replace any existing panel process */ @@ -142,6 +152,7 @@ shell_dbus_init (gboolean replace) &request_name_result, "org.gnome.Caribou.Keyboard", FALSE); g_object_unref (bus); + g_object_unref (session); } static void