keyboard: Add a way to use the OSK on shell chrome in wayland sessions

libcaribou was designed to generate X events which works under wayland
sessions for X clients but obviously doesn't work for wayland clients
and for shell chrome.

This patch adds a simple caribou display adapter which inherits from
its X display adapter and allows us to continue to work for X clients
and at the same time makes the OSK work on shell text entries by
sending key events directly to the focused text actor.

Making the OSK work for wayland clients requires much bigger changes
at various levels in the stack and either not using libcaribou or
re-working it substantially so that's left for future work.

https://bugzilla.gnome.org/show_bug.cgi?id=747274
This commit is contained in:
Rui Matos 2015-04-03 00:18:07 +02:00
parent a0868bac6b
commit 5afd04781c
3 changed files with 40 additions and 0 deletions

View File

@ -184,6 +184,10 @@ const Keyboard = new Lang.Class({
this._daemonProxy = null; this._daemonProxy = null;
this._lastDeviceId = null; this._lastDeviceId = null;
if (Meta.is_wayland_compositor() &&
Caribou.DisplayAdapter.set_default)
Caribou.DisplayAdapter.set_default(new ShellWaylandAdapter());
Meta.get_backend().connect('last-device-changed', Lang.bind(this, Meta.get_backend().connect('last-device-changed', Lang.bind(this,
function (backend, deviceId) { function (backend, deviceId) {
let manager = Clutter.DeviceManager.get_default(); let manager = Clutter.DeviceManager.get_default();
@ -725,3 +729,24 @@ const KeyboardSource = new Lang.Class({
this._keyboard.show(Main.layoutManager.bottomIndex); this._keyboard.show(Main.layoutManager.bottomIndex);
} }
}); });
const ShellWaylandAdapter = new Lang.Class({
Name: 'ShellWaylandAdapter',
Extends: Caribou.XAdapter,
vfunc_keyval_press: function(keyval) {
let focus = global.stage.get_key_focus();
if (focus instanceof Clutter.Text)
Shell.util_text_insert_keyval(focus, keyval);
else
this.parent(keyval);
},
vfunc_keyval_release: function(keyval) {
let focus = global.stage.get_key_focus();
if (focus instanceof Clutter.Text)
return; // do nothing
else
this.parent(keyval);
},
});

View File

@ -391,3 +391,15 @@ shell_util_need_background_refresh (void)
return FALSE; return FALSE;
} }
void
shell_util_text_insert_keyval (ClutterActor *actor,
guint keyval)
{
ClutterEvent event = { 0 };
event.type = CLUTTER_KEY_PRESS;
event.key.keyval = keyval;
clutter_actor_event (actor, &event, FALSE);
}

View File

@ -47,6 +47,9 @@ void shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker,
gboolean shell_util_need_background_refresh (void); gboolean shell_util_need_background_refresh (void);
void shell_util_text_insert_keyval (ClutterActor *actor,
guint keyval);
G_END_DECLS G_END_DECLS
#endif /* __SHELL_UTIL_H__ */ #endif /* __SHELL_UTIL_H__ */