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:
parent
167ca75388
commit
5350302b09
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
|
||||||
|
|
||||||
|
69
src/main.c
69
src/main.c
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user