diff --git a/js/ui/main.js b/js/ui/main.js index 62eea850d..e0a095360 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -1,6 +1,7 @@ /* -*- mode: js2; js2-basic-offset: 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; @@ -15,6 +16,7 @@ const Overview = imports.ui.overview; const Panel = imports.ui.panel; const RunDialog = imports.ui.runDialog; const LookingGlass = imports.ui.lookingGlass; +const ShellDBus = imports.ui.shellDBus; const Sidebar = imports.ui.sidebar; const Tweener = imports.ui.tweener; const WindowManager = imports.ui.windowManager; @@ -30,6 +32,7 @@ let runDialog = null; let lookingGlass = null; let wm = null; let recorder = null; +let shellDBusService = null; let modalCount = 0; let modalActorFocusStack = []; @@ -42,6 +45,12 @@ function start() { Gio.DesktopAppInfo.set_desktop_env("GNOME"); global.grab_dbus_service(); + 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(); Tweener.init(); diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js new file mode 100644 index 000000000..1d998efff --- /dev/null +++ b/js/ui/shellDBus.js @@ -0,0 +1,72 @@ +/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ + +const DBus = imports.dbus; +const Lang = imports.lang; +const Shell = imports.gi.Shell; +const Mainloop = imports.mainloop; + +const Main = imports.ui.main; + +const GnomeShellIface = { + name: "org.gnome.Shell", + methods: [{ name: "Eval", + inSignature: "s", + outSignature: "bs" + } + ], + signals: [], + properties: [{ name: "OverviewActive", + signature: "b", + access: "readwrite" }] +}; + +function GnomeShell() { + this._init(); +} + +GnomeShell.prototype = { + _init: function() { + DBus.session.exportObject('/org/gnome/Shell', this); + }, + + /** + * Eval: + * @code: A string containing JavaScript code + * + * This function executes arbitrary code in the main + * loop, and returns a boolean success and + * JSON representation of the object as a string. + * + * If evaluation completes without throwing an exception, + * then the return value will be [true, JSON.stringify(result)]. + * If evaluation fails, then the return value will be + * [false, JSON.stringify(exception)]; + * + */ + Eval: function(code) { + let returnValue; + let success; + try { + returnValue = JSON.stringify(eval(code)); + success = true; + } catch (e) { + returnValue = JSON.stringify(e); + success = false; + } + return [success, returnValue]; + }, + + get OverviewActive() { + return Main.overview.visible; + }, + + set OverviewActive(visible) { + if (visible) + Main.overview.show(); + else + Main.overview.hide(); + } +}; + +DBus.conformExport(GnomeShell.prototype, GnomeShellIface); +