No key control of the input method candidate window on SearchController
Affected version
Provide at least the following information:
- OS: Fedora 40
- Affected GNOME Shell version: 46
- Does this issue appear in XOrg and/or Wayland: XOrg and Wayland
- Does this issue happen without extensions: Yes
Bug summary
Currently, SearchController takes over key control from the input method even when the input method shows preedit text and, optionally, a candidate window if there are characters in the text area. As a result, users cannot select a candidate using cursor keys and confirm the selection with the Enter key as usual.
Steps to reproduce
- Type at least one character in the 'Type to search' box.
- Continue typing more characters and trigger the input method to show the preedit text and candidate window.
What happened
Users cannot select candidates using the keyboard because SearchController captures the keyboard events.
Relevant logs, screenshots, screencasts etc.
The following screenshots depict the situation where key control is not available:
ibus-typing-booster
withibus-hiragana
withOne way to address this issue is by processing keyboard events after the input method in SearchController. In this scenario, the 'activate' signal must be handled separately.
--- a/js/ui/searchController.js
+++ b/js/ui/searchController.js
@@ -54,7 +54,11 @@ export const SearchController = GObject.registerClass({
this._text = this._entry.clutter_text;
this._text.connect('text-changed', this._onTextChanged.bind(this));
- this._text.connect('key-press-event', this._onKeyPress.bind(this));
+ this._text.connect_after('key-press-event', this._onKeyPress.bind(this));
+ this._text.connect('activate', () => {
+ if (this._searchActive)
+ this._searchResults.activateDefault();
+ });
this._text.connect('key-focus-in', () => {
this._searchResults.highlightDefault(true);
});
@@ -299,9 +303,6 @@ export const SearchController = GObject.registerClass({
} else if (symbol === arrowNext && this._text.cursor_position === -1) {
this._searchResults.navigateFocus(nextDirection);
return Clutter.EVENT_STOP;
- } else if (symbol === Clutter.KEY_Return || symbol === Clutter.KEY_KP_Enter) {
- this._searchResults.activateDefault();
- return Clutter.EVENT_STOP;
}
}
return Clutter.EVENT_PROPAGATE;
Another approach is by propagating keyboard events unconditionally from SearchController if the input method shows preedit text. If a function similar to gtk_im_context_filter_keypress() can be used here, it would be better.
--- a/js/ui/searchController.js
+++ b/js/ui/searchController.js
@@ -269,6 +269,9 @@ export const SearchController = GObject.registerClass({
}
_onKeyPress(entry, event) {
+ if (Main.inputMethod.hasPreedit())
+ return Clutter.EVENT_PROPAGATE;
+
let symbol = event.get_key_symbol();
if (symbol === Clutter.KEY_Escape) {
if (this._isActivated()) {