[gnome-shell] keyboard: Avoid runtime dependency on the Caribou daemon
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] keyboard: Avoid runtime dependency on the Caribou daemon
- Date: Mon, 15 May 2017 12:51:51 +0000 (UTC)
commit aecd1c126a4606af0b460d4168299792e862e4d5
Author: Carlos Garnacho <carlosg gnome org>
Date: Mon Jan 16 16:21:01 2017 +0100
keyboard: Avoid runtime dependency on the Caribou daemon
The caribou daemon only gives us focus tracking, which is almost 1:1 with
our own FocusCaretTracker implementation. This means we can entirely
replace the Caribou daemon inside gnome-shell, reducing the Caribou
dependency to just libcaribou, and more specifically the
CaribouKeyboardModel we pull the keyboard models from.
As we still need underneath a CaribouDisplayAdapter to drive the keyboard,
reuse the wayland one, which has been renamed to make it look generic, plus
it will use the virtual input device API from mutter/clutter.
https://bugzilla.gnome.org/show_bug.cgi?id=777342
js/ui/keyboard.js | 170 ++++++++++++++++++++++++++++++++---------------------
1 files changed, 102 insertions(+), 68 deletions(-)
---
diff --git a/js/ui/keyboard.js b/js/ui/keyboard.js
index 4af1f1a..dbe4ffa 100644
--- a/js/ui/keyboard.js
+++ b/js/ui/keyboard.js
@@ -1,5 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+const FocusCaretTracker = imports.ui.focusCaretTracker;
+const Atspi = imports.gi.Atspi;
const Caribou = imports.gi.Caribou;
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
@@ -25,42 +27,6 @@ const KEYBOARD_TYPE = 'keyboard-type';
const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
const SHOW_KEYBOARD = 'screen-keyboard-enabled';
-const CARIBOU_BUS_NAME = 'org.gnome.Caribou.Daemon';
-const CARIBOU_OBJECT_PATH = '/org/gnome/Caribou/Daemon';
-
-const CaribouKeyboardIface = '<node> \
-<interface name="org.gnome.Caribou.Keyboard"> \
-<method name="Show"> \
- <arg type="u" direction="in" /> \
-</method> \
-<method name="Hide"> \
- <arg type="u" direction="in" /> \
-</method> \
-<method name="SetCursorLocation"> \
- <arg type="i" direction="in" /> \
- <arg type="i" direction="in" /> \
- <arg type="i" direction="in" /> \
- <arg type="i" direction="in" /> \
-</method> \
-<method name="SetEntryLocation"> \
- <arg type="i" direction="in" /> \
- <arg type="i" direction="in" /> \
- <arg type="i" direction="in" /> \
- <arg type="i" direction="in" /> \
-</method> \
-<property name="Name" access="read" type="s" /> \
-</interface> \
-</node>';
-
-const CaribouDaemonIface = '<node> \
-<interface name="org.gnome.Caribou.Daemon"> \
-<method name="Run" /> \
-<method name="Quit" /> \
-</interface> \
-</node>';
-
-const CaribouDaemonProxy = Gio.DBusProxy.makeProxyWrapper(CaribouDaemonIface);
-
const Key = new Lang.Class({
Name: 'Key',
@@ -188,19 +154,22 @@ const Key = new Lang.Class({
Signals.addSignalMethods(Key.prototype);
const Keyboard = new Lang.Class({
- // HACK: we can't set Name, because it collides with Name dbus property
- // Name: 'Keyboard',
+ Name: 'Keyboard',
_init: function () {
- this._impl = Gio.DBusExportedObject.wrapJSObject(CaribouKeyboardIface, this);
- this._impl.export(Gio.DBus.session, '/org/gnome/Caribou/Keyboard');
-
this.actor = null;
this._focusInTray = false;
this._focusInExtendedKeys = false;
this._timestamp = global.display.get_current_time_roundtrip();
+ this._focusCaretTracker = new FocusCaretTracker.FocusCaretTracker();
+ this._focusCaretTracker.connect('focus-changed', Lang.bind(this, this._onFocusChanged));
+ this._focusCaretTracker.connect('caret-moved', Lang.bind(this, this._onCaretMoved));
+ this._currentAccessible = null;
+ this._caretTrackingEnabled = false;
+ this._updateCaretPositionId = 0;
+
this._keyboardSettings = new Gio.Settings({ schema_id: KEYBOARD_SCHEMA });
this._keyboardSettings.connect('changed', Lang.bind(this, this._sync));
this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
@@ -208,9 +177,7 @@ const Keyboard = new Lang.Class({
this._daemonProxy = null;
this._lastDeviceId = null;
- if (Meta.is_wayland_compositor() &&
- Caribou.DisplayAdapter.set_default)
- Caribou.DisplayAdapter.set_default(new ShellWaylandAdapter());
+ Caribou.DisplayAdapter.set_default(new LocalAdapter());
Meta.get_backend().connect('last-device-changed', Lang.bind(this,
function (backend, deviceId) {
@@ -240,6 +207,93 @@ const Keyboard = new Lang.Class({
this._redraw();
},
+ _setCaretTrackerEnabled: function (enabled) {
+ if (this._caretTrackingEnabled == enabled)
+ return;
+
+ this._caretTrackingEnabled = enabled;
+
+ if (enabled) {
+ this._focusCaretTracker.registerFocusListener();
+ this._focusCaretTracker.registerCaretListener();
+ } else {
+ this._focusCaretTracker.deregisterFocusListener();
+ this._focusCaretTracker.deregisterCaretListener();
+ }
+ },
+
+ _updateCaretPosition: function (accessible) {
+ if (this._updateCaretPositionId)
+ GLib.source_remove(this._updateCaretPositionId);
+ this._updateCaretPositionId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, Lang.bind(this, function() {
+ this._updateCaretPositionId = 0;
+
+ let currentWindow = global.screen.get_display().focus_window;
+ if (!currentWindow)
+ return GLib.SOURCE_REMOVE;
+
+ let windowRect = currentWindow.get_frame_rect();
+ let text = accessible.get_text_iface();
+ let component = accessible.get_component_iface();
+
+ try {
+ let caretOffset = text.get_caret_offset();
+ let caretRect = text.get_character_extents(caretOffset, Atspi.CoordType.WINDOW);
+ let focusRect = component.get_extents(Atspi.CoordType.WINDOW);
+
+ caretRect.x += windowRect.x;
+ caretRect.y += windowRect.y;
+ focusRect.x += windowRect.x;
+ focusRect.y += windowRect.y;
+
+ if (caretRect.width == 0 && caretRect.height == 0)
+ caretRect = focusRect;
+
+ this.SetEntryLocation(focusRect.x, focusRect.y, focusRect.width, focusRect.height);
+ this.SetCursorLocation(caretRect.x, caretRect.y, caretRect.width, caretRect.height);
+ } catch (e) {
+ log('Error updating caret position for OSK: ' + e.message);
+ }
+
+ return GLib.SOURCE_REMOVE;
+ }));
+
+ GLib.Source.set_name_by_id(this._updateCaretPositionId, '[gnome-shell] this._updateCaretPosition');
+ },
+
+ _focusIsTextEntry: function (accessible) {
+ try {
+ let role = accessible.get_role();
+ let stateSet = accessible.get_state_set();
+ return stateSet.contains(Atspi.StateType.EDITABLE) || role == Atspi.Role.TERMINAL;
+ } catch (e) {
+ log('Error determining accessible role: ' + e.message);
+ return false;
+ }
+ },
+
+ _onFocusChanged: function (caretTracker, event) {
+ let accessible = event.source;
+ if (!this._focusIsTextEntry(accessible))
+ return;
+
+ let focused = event.detail1 != 0;
+ if (focused) {
+ this._currentAccessible = accessible;
+ this._updateCaretPosition(accessible);
+ this.Show(this._timestamp);
+ } else if (this._currentAccessible == accessible) {
+ this._currentAccessible = null;
+ this.Hide(this._timestamp);
+ }
+ },
+
+ _onCaretMoved: function (caretTracker, event) {
+ let accessible = event.source;
+ if (this._currentAccessible == accessible)
+ this._updateCaretPosition(accessible);
+ },
+
_lastDeviceIsTouchscreen: function () {
if (!this._lastDeviceId)
return false;
@@ -262,6 +316,8 @@ const Keyboard = new Lang.Class({
this._keyboard.keyboard_type == this._keyboardSettings.get_string(KEYBOARD_TYPE))
return;
+ this._setCaretTrackerEnabled(this._enableKeyboard);
+
if (this._keyboard)
this._destroyKeyboard();
@@ -297,23 +353,6 @@ const Keyboard = new Lang.Class({
},
_setupKeyboard: function() {
- if (!this._daemonProxy) {
- this._daemonProxy = new CaribouDaemonProxy(Gio.DBus.session, CARIBOU_BUS_NAME,
- CARIBOU_OBJECT_PATH,
- Lang.bind(this, function(proxy, error) {
- if (error) {
- log(error.message);
- return;
- }
- }));
- }
- this._daemonProxy.RunRemote(function (result, error) {
- if (error) {
- log(error.message);
- return;
- }
- });
-
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
Main.layoutManager.keyboardBox.add_actor(this.actor);
Main.layoutManager.trackChrome(this.actor);
@@ -685,7 +724,6 @@ const Keyboard = new Lang.Class({
this._showIdleId = 0;
},
- // D-Bus methods
Show: function(timestamp) {
if (!this._enableKeyboard)
return;
@@ -727,10 +765,6 @@ const Keyboard = new Lang.Class({
// this._setLocation(x, y);
},
-
- get Name() {
- return 'gnome-shell';
- }
});
const KeyboardSource = new Lang.Class({
@@ -754,8 +788,8 @@ const KeyboardSource = new Lang.Class({
}
});
-const ShellWaylandAdapter = new Lang.Class({
- Name: 'ShellWaylandAdapter',
+const LocalAdapter = new Lang.Class({
+ Name: 'LocalAdapter',
Extends: Caribou.XAdapter,
_init: function () {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]