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