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
This commit is contained in:
Giovanni Campagna 2011-08-16 14:19:59 +02:00 committed by Colin Walters
parent 167ca75388
commit 5350302b09
4 changed files with 129 additions and 107 deletions

View File

@ -70,8 +70,7 @@ GJS_MIN_VERSION=1.29.18
MUTTER_MIN_VERSION=3.2.1 MUTTER_MIN_VERSION=3.2.1
FOLKS_MIN_VERSION=0.5.2 FOLKS_MIN_VERSION=0.5.2
GTK_MIN_VERSION=3.0.0 GTK_MIN_VERSION=3.0.0
GLIB_MIN_VERSION=2.31.0 GIO_MIN_VERSION=2.31.0
GIO_MIN_VERSION=2.29.10
LIBECAL_MIN_VERSION=2.32.0 LIBECAL_MIN_VERSION=2.32.0
LIBEDATASERVER_MIN_VERSION=1.2.0 LIBEDATASERVER_MIN_VERSION=1.2.0
LIBEDATASERVERUI_MIN_VERSION=2.91.6 LIBEDATASERVERUI_MIN_VERSION=2.91.6
@ -81,9 +80,8 @@ POLKIT_MIN_VERSION=0.100
STARTUP_NOTIFICATION_MIN_VERSION=0.11 STARTUP_NOTIFICATION_MIN_VERSION=0.11
# Collect more than 20 libraries for a prize! # Collect more than 20 libraries for a prize!
PKG_CHECK_MODULES(GNOME_SHELL, glib-2.0 >= $GLIB_MIN_VERSION PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
gio-2.0 >= $GIO_MIN_VERSION libxml-2.0
gio-unix-2.0 dbus-glib-1 libxml-2.0
gtk+-3.0 >= $GTK_MIN_VERSION gtk+-3.0 >= $GTK_MIN_VERSION
folks >= $FOLKS_MIN_VERSION folks >= $FOLKS_MIN_VERSION
libmutter >= $MUTTER_MIN_VERSION libmutter >= $MUTTER_MIN_VERSION

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const DBus = imports.dbus;
const Gdk = imports.gi.Gdk; const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
@ -163,11 +162,6 @@ function start() {
Gio.DesktopAppInfo.set_desktop_env('GNOME'); Gio.DesktopAppInfo.set_desktop_env('GNOME');
shellDBusService = new ShellDBus.GnomeShell(); 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 // Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
// also initialize ShellAppSystem first. ShellAppSystem // also initialize ShellAppSystem first. ShellAppSystem

View File

@ -1,71 +1,70 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DBus = imports.dbus;
const Lang = imports.lang; const Lang = imports.lang;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Config = imports.misc.config; const Config = imports.misc.config;
const ExtensionSystem = imports.ui.extensionSystem; const ExtensionSystem = imports.ui.extensionSystem;
const Main = imports.ui.main; const Main = imports.ui.main;
const GnomeShellIface = { const GnomeShellIface = <interface name="org.gnome.Shell">
name: 'org.gnome.Shell', <method name="Eval">
methods: [{ name: 'Eval', <arg type="s" direction="in" name="script" />
inSignature: 's', <arg type="b" direction="out" name="success" />
outSignature: 'bs' <arg type="s" direction="out" name="result" />
}, </method>
{ name: 'ListExtensions', <method name="ListExtensions">
inSignature: '', <arg type="a{sa{sv}}" direction="out" name="extensions" />
outSignature: 'a{sa{sv}}' </method>
}, <method name="GetExtensionInfo">
{ name: 'GetExtensionInfo', <arg type="s" direction="in" name="extension" />
inSignature: 's', <arg type="a{sv}" direction="out" name="info" />
outSignature: 'a{sv}' </method>
}, <method name="GetExtensionErrors">
{ name: 'GetExtensionErrors', <arg type="s" direction="in" name="extension" />
inSignature: 's', <arg type="as" direction="out" name="errors" />
outSignature: 'as' </method>
}, <method name="ScreenshotArea">
{ name: 'ScreenshotArea', <arg type="i" direction="in" name="x"/>
inSignature: 'iiiis', <arg type="i" direction="in" name="y"/>
outSignature: 'b' <arg type="i" direction="in" name="width"/>
}, <arg type="i" direction="in" name="height"/>
{ name: 'ScreenshotWindow', <arg type="s" direction="in" name="filename"/>
inSignature: 'bs', <arg type="b" direction="out" name="success"/>
outSignature: 'b' </method>
}, <method name="ScreenshotWindow">
{ name: 'Screenshot', <arg type="b" direction="in" name="include_frame"/>
inSignature: 's', <arg type="s" direction="in" name="filename"/>
outSignature: 'b' <arg type="b" direction="out" name="success"/>
}, </method>
{ name: 'EnableExtension', <method name="Screenshot">
inSignature: 's', <arg type="s" direction="in" name="filename"/>
outSignature: '' <arg type="b" direction="out" name="success"/>
}, </method>
{ name: 'DisableExtension', <method name="EnableExtension">
inSignature: 's', <arg type="s" direction="in" name="uuid"/>
outSignature: '' </method>
}, <method name="DisableExtension">
{ name: 'InstallRemoteExtension', <arg type="s" direction="in" name="uuid"/>
inSignature: 'ss', </method>
outSignature: '' <method name="InstallRemoteExtension">
}, <arg type="s" direction="in" name="uuid"/>
{ name: 'UninstallExtension', <arg type="s" direction="in" name="version"/>
inSignature: 's', </method>
outSignature: 'b' <method name="UninstallExtension">
} <arg type="s" direction="in" name="uuid"/>
], <arg type="b" direction="out" name="success"/>
signals: [{ name: 'ExtensionStatusChanged', </method>
inSignature: 'sis' }], <property name="OverviewActive" type="b" access="readwrite" />
properties: [{ name: 'OverviewActive', <property name="ApiVersion" type="i" access="read" />
signature: 'b', <property name="ShellVersion" type="s" access="read" />
access: 'readwrite' }, <signal name="ExtensionStatusChanged">
{ name: 'ApiVersion', <arg type="s" name="uuid"/>
signature: 'i', <arg type="i" name="state"/>
access: 'read' }, <arg type="s" name="error"/>
{ name: 'ShellVersion', </signal>
signature: 's', </interface>;
access: 'read' }]
};
function GnomeShell() { function GnomeShell() {
this._init(); this._init();
@ -73,7 +72,8 @@ function GnomeShell() {
GnomeShell.prototype = { GnomeShell.prototype = {
_init: function() { _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', ExtensionSystem.connect('extension-state-changed',
Lang.bind(this, this._extensionStateChanged)); Lang.bind(this, this._extensionStateChanged));
}, },
@ -156,11 +156,33 @@ GnomeShell.prototype = {
}, },
ListExtensions: function() { 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) { 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) { GetExtensionErrors: function(uuid) {
@ -211,6 +233,3 @@ GnomeShell.prototype = {
[newState.uuid, newState.state, newState.error]); [newState.uuid, newState.state, newState.error]);
} }
}; };
DBus.conformExport(GnomeShell.prototype, GnomeShellIface);

View File

@ -11,7 +11,6 @@
#include <cogl-pango/cogl-pango.h> #include <cogl-pango/cogl-pango.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <clutter/x11/clutter-x11.h> #include <clutter/x11/clutter-x11.h>
#include <dbus/dbus-glib.h>
#include <gdk/gdk.h> #include <gdk/gdk.h>
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
@ -36,35 +35,41 @@ extern GType gnome_shell_plugin_get_type (void);
static gboolean is_gdm_mode = FALSE; static gboolean is_gdm_mode = FALSE;
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
static void static void
shell_dbus_acquire_name (DBusGProxy *bus, shell_dbus_acquire_name (GDBusProxy *bus,
guint32 request_name_flags, guint32 request_name_flags,
guint32 *request_name_result, guint32 *request_name_result,
gchar *name, gchar *name,
gboolean fatal) gboolean fatal)
{ {
GError *error = NULL; GError *error = NULL;
if (!dbus_g_proxy_call (bus, "RequestName", &error, GVariant *request_name_variant;
G_TYPE_STRING, name,
G_TYPE_UINT, request_name_flags, if (!(request_name_variant = g_dbus_proxy_call_sync (bus,
G_TYPE_INVALID, "RequestName",
G_TYPE_UINT, request_name_result, g_variant_new ("(su)", name, request_name_flags),
G_TYPE_INVALID)) 0, /* call flags */
-1, /* timeout */
NULL, /* cancellable */
&error)))
{ {
g_printerr ("failed to acquire %s: %s\n", name, error->message); g_printerr ("failed to acquire org.gnome.Shell: %s\n", error->message);
if (fatal) exit (1);
exit (1);
} }
g_variant_get (request_name_variant, "(u)", request_name_result);
} }
static void static void
shell_dbus_acquire_names (DBusGProxy *bus, shell_dbus_acquire_names (GDBusProxy *bus,
guint32 request_name_flags, guint32 request_name_flags,
gchar *name, gchar *name,
gboolean fatal, ...) G_GNUC_NULL_TERMINATED; gboolean fatal, ...) G_GNUC_NULL_TERMINATED;
static void static void
shell_dbus_acquire_names (DBusGProxy *bus, shell_dbus_acquire_names (GDBusProxy *bus,
guint32 request_name_flags, guint32 request_name_flags,
gchar *name, gchar *name,
gboolean fatal, ...) gboolean fatal, ...)
@ -89,27 +94,32 @@ shell_dbus_acquire_names (DBusGProxy *bus,
static void static void
shell_dbus_init (gboolean replace) shell_dbus_init (gboolean replace)
{ {
DBusGConnection *session; GDBusConnection *session;
DBusGProxy *bus; GDBusProxy *bus;
GError *error = NULL;
guint32 request_name_flags; guint32 request_name_flags;
guint32 request_name_result; guint32 request_name_result;
/* TODO: session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
* 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);
bus = dbus_g_proxy_new_for_name (session, if (error) {
DBUS_SERVICE_DBUS, g_printerr ("Failed to connect to session bus: %s", error->message);
DBUS_PATH_DBUS, exit (1);
DBUS_INTERFACE_DBUS); }
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) if (replace)
request_name_flags |= DBUS_NAME_FLAG_REPLACE_EXISTING; request_name_flags |= DBUS_NAME_FLAG_REPLACE_EXISTING;
shell_dbus_acquire_name (bus, shell_dbus_acquire_name (bus,
request_name_flags, request_name_flags,
&request_name_result, &request_name_result,
@ -117,8 +127,7 @@ shell_dbus_init (gboolean replace)
if (!(request_name_result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER if (!(request_name_result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
|| request_name_result == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER)) || request_name_result == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER))
{ {
g_printerr ("%s already exists on bus and --replace not specified\n", g_printerr (SHELL_DBUS_SERVICE " already exists on bus and --replace not specified\n");
SHELL_DBUS_SERVICE);
exit (1); exit (1);
} }
@ -126,7 +135,8 @@ shell_dbus_init (gboolean replace)
* We always specify REPLACE_EXISTING to ensure we kill off * We always specify REPLACE_EXISTING to ensure we kill off
* the existing service if it was running. * 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, shell_dbus_acquire_names (bus,
request_name_flags, request_name_flags,
/* Also grab org.gnome.Panel to replace any existing panel process */ /* Also grab org.gnome.Panel to replace any existing panel process */
@ -142,6 +152,7 @@ shell_dbus_init (gboolean replace)
&request_name_result, &request_name_result,
"org.gnome.Caribou.Keyboard", FALSE); "org.gnome.Caribou.Keyboard", FALSE);
g_object_unref (bus); g_object_unref (bus);
g_object_unref (session);
} }
static void static void