[gnome-shell] shellDBus: Add methods to handle key grabs
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] shellDBus: Add methods to handle key grabs
- Date: Fri, 1 Mar 2013 15:56:46 +0000 (UTC)
commit 81e01b6f88ce55bee8d55e83adaa5522d7c08c87
Author: Florian Müllner <fmuellner gnome org>
Date: Sat Aug 11 23:11:37 2012 +0200
shellDBus: Add methods to handle key grabs
Expose Mutter's external grab API on the bus, so gnome-settings-daemon
can refer keygrabbing to the shell.
https://bugzilla.gnome.org/show_bug.cgi?id=643111
js/ui/shellDBus.js | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 109 insertions(+), 1 deletions(-)
---
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
index 6aaa2f0..6657b35 100644
--- a/js/ui/shellDBus.js
+++ b/js/ui/shellDBus.js
@@ -1,14 +1,16 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
-const Lang = imports.lang;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
+const Lang = imports.lang;
+const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Config = imports.misc.config;
const ExtensionSystem = imports.ui.extensionSystem;
const ExtensionDownloader = imports.ui.extensionDownloader;
const ExtensionUtils = imports.misc.extensionUtils;
+const Hash = imports.misc.hash;
const Main = imports.ui.main;
const Screenshot = imports.ui.screenshot;
@@ -18,6 +20,23 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
<arg type="b" direction="out" name="success" />
<arg type="s" direction="out" name="result" />
</method>
+<method name="GrabAccelerator">
+ <arg type="s" direction="in" name="accelerator"/>
+ <arg type="u" direction="in" name="flags"/>
+ <arg type="u" direction="out" name="action"/>
+</method>
+<method name="GrabAccelerators">
+ <arg type="a(su)" direction="in" name="accelerators"/>
+ <arg type="au" direction="out" name="actions"/>
+</method>
+<method name="UngrabAccelerator">
+ <arg type="u" direction="in" name="action"/>
+ <arg type="b" direction="out" name="success"/>
+</method>
+<signal name="AcceleratorActivated">
+ <arg name="action" type="u" />
+ <arg name="deviceid" type="u" />
+</signal>
<property name="Mode" type="s" access="read" />
<property name="OverviewActive" type="b" access="readwrite" />
<property name="ShellVersion" type="s" access="read" />
@@ -49,6 +68,14 @@ const GnomeShell = new Lang.Class({
this._extensionsService = new GnomeShellExtensions();
this._screenshotService = new Screenshot.ScreenshotService();
+
+ this._grabbedAccelerators = new Hash.Map();
+ this._grabbers = new Hash.Map();
+
+ global.display.connect('accelerator-activated', Lang.bind(this,
+ function(display, action, deviceid) {
+ this._emitAcceleratorActivated(action, deviceid);
+ }));
},
/**
@@ -84,6 +111,87 @@ const GnomeShell = new Lang.Class({
return [success, returnValue];
},
+ GrabAcceleratorAsync: function(params, invocation) {
+ let [accel, flags] = params;
+ let sender = invocation.get_sender();
+ let bindingAction = this._grabAcceleratorForSender(accel, flags, sender);
+ return invocation.return_value(GLib.Variant.new('(u)', [bindingAction]));
+ },
+
+ GrabAcceleratorsAsync: function(params, invocation) {
+ let [accels] = params;
+ let sender = invocation.get_sender();
+ let bindingActions = [];
+ for (let i = 0; i < accels.length; i++) {
+ let [accel, flags] = accels[i];
+ bindingActions.push(this._grabAcceleratorForSender(accel, flags, sender));
+ }
+ return invocation.return_value(GLib.Variant.new('(au)', [bindingActions]));
+ },
+
+ UngrabAcceleratorAsync: function(params, invocation) {
+ let [action] = params;
+ let grabbedBy = this._grabbedAccelerators.get(action);
+ if (invocation.get_sender() != grabbedBy)
+ return invocation.return_value(GLib.Variant.new('(b)', [false]));
+
+ let ungrabSucceeded = global.display.ungrab_accelerator(action);
+ if (ungrabSucceeded)
+ this._grabbedAccelerators.delete(action);
+ return invocation.return_value(GLib.Variant.new('(b)', [ungrabSucceeded]));
+ },
+
+ _emitAcceleratorActivated: function(action, deviceid) {
+ let destination = this._grabbedAccelerators.get(action);
+ if (!destination)
+ return;
+
+ let connection = this._dbusImpl.get_connection();
+ let info = this._dbusImpl.get_info();
+ connection.emit_signal(destination,
+ this._dbusImpl.get_object_path(),
+ info ? info.name : null,
+ 'AcceleratorActivated',
+ GLib.Variant.new('(uu)', [action, deviceid]));
+ },
+
+ _grabAcceleratorForSender: function(accelerator, flags, sender) {
+ let bindingAction = global.display.grab_accelerator(accelerator);
+ if (bindingAction == Meta.KeyBindingAction.NONE)
+ return Meta.KeyBindingAction.NONE;
+
+ let bindingName = Meta.external_binding_name_for_action(bindingAction);
+ Main.wm.allowKeybinding(bindingName, flags);
+
+ this._grabbedAccelerators.set(bindingAction, sender);
+
+ if (!this._grabbers.has(sender)) {
+ let id = Gio.bus_watch_name(Gio.BusType.SESSION, sender, 0, null,
+ Lang.bind(this, this._onGrabberBusNameVanished));
+ this._grabbers.set(sender, id);
+ }
+
+ return bindingAction;
+ },
+
+ _ungrabAccelerator: function(action) {
+ let ungrabSucceeded = global.display.ungrab_accelerator(action);
+ if (ungrabSucceeded)
+ this._grabbedAccelerators.delete(action);
+ },
+
+ _onGrabberBusNameVanished: function(connection, name) {
+ let grabs = this._grabbedAccelerators.items();
+ for (let i = 0; i < grabs.length; i++) {
+ let [action, sender] = grabs[i];
+ if (sender == name)
+ this._ungrabAccelerator(action);
+ }
+ Gio.bus_unwatch_name(this._grabbers.get(name));
+ this._grabbers.delete(name);
+ },
+
+
Mode: global.session_mode,
get OverviewActive() {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]