ibusManager: Add OSK completion mode
This mode changes the current IBus engine to ibus-typing-booster under the rug (i.e. no changes in keyboard status menu) for any XKB engine selected. In order to make it useful for the currently selected language, the typing-booster dictionary is changed to the current XKB layout language. And since the OSK has its own emoji panel, typing-boosters own emoji completion is disabled. These changes only apply as long as the OSK panel is shown, reverting to the original engine and typing-booster configuration after it is hidden. This in theory also caters for users that do have ibus-typing-booster enabled as an input source. The final effect is text prediction for the language that is being typed, according to the OSK layout, given that ibus-typing-booster and the relevant hunspell dictionaries are used. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2278>
This commit is contained in:
parent
3c538fc7e2
commit
b210b2de72
@ -22,6 +22,13 @@ _checkIBusVersion(1, 5, 2);
|
||||
let _ibusManager = null;
|
||||
const IBUS_SYSTEMD_SERVICE = 'org.freedesktop.IBus.session.GNOME.service';
|
||||
|
||||
const TYPING_BOOSTER_ENGINE = 'typing-booster';
|
||||
const IBUS_TYPING_BOOSTER_SCHEMA = 'org.freedesktop.ibus.engine.typing-booster';
|
||||
const KEY_EMOJIPREDICTIONS = 'emojipredictions';
|
||||
const KEY_DICTIONARY = 'dictionary';
|
||||
const KEY_INLINECOMPLETION = 'inlinecompletion';
|
||||
const KEY_INPUTMETHOD = 'inputmethod';
|
||||
|
||||
function _checkIBusVersion(requiredMajor, requiredMinor, requiredMicro) {
|
||||
if ((IBus.MAJOR_VERSION > requiredMajor) ||
|
||||
(IBus.MAJOR_VERSION == requiredMajor && IBus.MINOR_VERSION > requiredMinor) ||
|
||||
@ -304,9 +311,12 @@ var IBusManager = class extends Signals.EventEmitter {
|
||||
}
|
||||
|
||||
preloadEngines(ids) {
|
||||
if (!this._ibus || ids.length == 0)
|
||||
if (!this._ibus || !this._ready)
|
||||
return;
|
||||
|
||||
if (!ids.includes(TYPING_BOOSTER_ENGINE))
|
||||
ids.push(TYPING_BOOSTER_ENGINE);
|
||||
|
||||
if (this._preloadEnginesId != 0) {
|
||||
GLib.source_remove(this._preloadEnginesId);
|
||||
this._preloadEnginesId = 0;
|
||||
@ -326,4 +336,54 @@ var IBusManager = class extends Signals.EventEmitter {
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
setCompletionEnabled(enabled) {
|
||||
/* Needs typing-booster available */
|
||||
if (!this._engines.has(TYPING_BOOSTER_ENGINE))
|
||||
return false;
|
||||
/* Can do only on xkb engines */
|
||||
if (enabled && !this._currentEngineName.startsWith('xkb:'))
|
||||
return false;
|
||||
|
||||
if (this._oskCompletion === enabled)
|
||||
return true;
|
||||
|
||||
this._oskCompletion = enabled;
|
||||
let settings =
|
||||
new Gio.Settings({schema_id: IBUS_TYPING_BOOSTER_SCHEMA});
|
||||
|
||||
if (enabled) {
|
||||
this._preOskState = {
|
||||
'engine': this._currentEngineName,
|
||||
'emoji': settings.get_value(KEY_EMOJIPREDICTIONS),
|
||||
'langs': settings.get_value(KEY_DICTIONARY),
|
||||
'completion': settings.get_value(KEY_INLINECOMPLETION),
|
||||
'inputMethod': settings.get_value(KEY_INPUTMETHOD),
|
||||
};
|
||||
settings.reset(KEY_EMOJIPREDICTIONS);
|
||||
|
||||
const removeEncoding = l => l.replace(/\..*/, '');
|
||||
const removeDups = (l, pos, arr) => {
|
||||
return !pos || arr[pos - 1] !== l;
|
||||
};
|
||||
settings.set_string(
|
||||
KEY_DICTIONARY,
|
||||
GLib.get_language_names().map(removeEncoding)
|
||||
.sort().filter(removeDups).join(','));
|
||||
|
||||
settings.reset(KEY_INLINECOMPLETION);
|
||||
settings.set_string(KEY_INPUTMETHOD, 'NoIME');
|
||||
this.setEngine(TYPING_BOOSTER_ENGINE);
|
||||
} else if (this._preOskState) {
|
||||
const {engine, emoji, langs, completion, inputMethod} =
|
||||
this._preOskState;
|
||||
this._preOskState = null;
|
||||
this.setEngine(engine);
|
||||
settings.set_value(KEY_EMOJIPREDICTIONS, emoji);
|
||||
settings.set_value(KEY_DICTIONARY, langs);
|
||||
settings.set_value(KEY_INLINECOMPLETION, completion);
|
||||
settings.set_value(KEY_INPUTMETHOD, inputMethod);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -315,4 +315,11 @@ var InputMethod = GObject.registerClass({
|
||||
hasPreedit() {
|
||||
return this._preeditVisible && this._preeditStr !== '' && this._preeditStr !== null;
|
||||
}
|
||||
|
||||
handleVirtualKey(keyval) {
|
||||
this._context.process_key_event_async(
|
||||
keyval, 0, 0, -1, null, null);
|
||||
this._context.process_key_event_async(
|
||||
keyval, 0, IBus.ModifierType.RELEASE_MASK, -1, null, null);
|
||||
}
|
||||
});
|
||||
|
@ -1497,7 +1497,14 @@ var Keyboard = GObject.registerClass({
|
||||
|
||||
if (key.action !== 'modifier') {
|
||||
button.connect('commit', (actor, keyval, str) => {
|
||||
if (this._modifiers.length === 0 && str !== '' &&
|
||||
keyval && this._oskCompletionEnabled) {
|
||||
Main.inputMethod.handleVirtualKey(keyval);
|
||||
return;
|
||||
}
|
||||
|
||||
if (str === '' || !Main.inputMethod.currentFocus ||
|
||||
(keyval && this._oskCompletionEnabled) ||
|
||||
this._modifiers.size > 0 ||
|
||||
!this._keyboardController.commitString(str, true)) {
|
||||
if (keyval !== 0) {
|
||||
@ -1865,6 +1872,8 @@ var Keyboard = GObject.registerClass({
|
||||
return;
|
||||
}
|
||||
|
||||
this._oskCompletionEnabled =
|
||||
IBusManager.getIBusManager().setCompletionEnabled(true);
|
||||
this._clearKeyboardRestTimer();
|
||||
|
||||
if (immediate) {
|
||||
@ -1899,6 +1908,8 @@ var Keyboard = GObject.registerClass({
|
||||
if (!this._keyboardVisible)
|
||||
return;
|
||||
|
||||
IBusManager.getIBusManager().setCompletionEnabled(false);
|
||||
this._oskCompletionEnabled = false;
|
||||
this._clearKeyboardRestTimer();
|
||||
|
||||
if (immediate) {
|
||||
|
Loading…
Reference in New Issue
Block a user