diff --git a/0001-status-keyboard-Add-a-catch-around-reload-call.patch b/0001-status-keyboard-Add-a-catch-around-reload-call.patch new file mode 100644 index 0000000..fd28223 --- /dev/null +++ b/0001-status-keyboard-Add-a-catch-around-reload-call.patch @@ -0,0 +1,89 @@ +From 01b465beae325c88fe6539303ddbdf1cc1cb80a7 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 16 Aug 2023 18:46:54 -0400 +Subject: [PATCH 1/3] status/keyboard: Add a catch around reload call + +Now that system input settings can get used in the user session +they're getting seen by the tests and the tests are complaining: + +Unhandled promise rejection. To suppress this warning, add an +error handler to your promise chain with .catch() or a try-catch block +around your await expression. + +This commit adds the catch it's asking for. +--- + js/ui/status/keyboard.js | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/js/ui/status/keyboard.js b/js/ui/status/keyboard.js +index 8d98e16de..7277c6d09 100644 +--- a/js/ui/status/keyboard.js ++++ b/js/ui/status/keyboard.js +@@ -171,61 +171,63 @@ class InputSourceSettings extends Signals.EventEmitter { + get mruSources() { + return []; + } + + set mruSources(sourcesList) { + // do nothing + } + + get keyboardOptions() { + return []; + } + + get perWindow() { + return false; + } + } + + class InputSourceSystemSettings extends InputSourceSettings { + constructor() { + super(); + + this._BUS_NAME = 'org.freedesktop.locale1'; + this._BUS_PATH = '/org/freedesktop/locale1'; + this._BUS_IFACE = 'org.freedesktop.locale1'; + this._BUS_PROPS_IFACE = 'org.freedesktop.DBus.Properties'; + + this._layouts = ''; + this._variants = ''; + this._options = ''; + +- this._reload(); ++ this._reload().catch(error => { ++ logError(error, 'Could not reload system input settings'); ++ }); + + Gio.DBus.system.signal_subscribe(this._BUS_NAME, + this._BUS_PROPS_IFACE, + 'PropertiesChanged', + this._BUS_PATH, + null, + Gio.DBusSignalFlags.NONE, + this._reload.bind(this)); + } + + async _reload() { + let props; + try { + const result = await Gio.DBus.system.call( + this._BUS_NAME, + this._BUS_PATH, + this._BUS_PROPS_IFACE, + 'GetAll', + new GLib.Variant('(s)', [this._BUS_IFACE]), + null, Gio.DBusCallFlags.NONE, -1, null); + [props] = result.deepUnpack(); + } catch (e) { + log(`Could not get properties from ${this._BUS_NAME}`); + return; + } + + const layouts = props['X11Layout'].unpack(); + const variants = props['X11Variant'].unpack(); + const options = props['X11Options'].unpack(); + +-- +2.41.0.rc2 + diff --git a/0002-status-keyboard-Load-keyboard-from-system-settings-i.patch b/0002-status-keyboard-Load-keyboard-from-system-settings-i.patch new file mode 100644 index 0000000..c91307b --- /dev/null +++ b/0002-status-keyboard-Load-keyboard-from-system-settings-i.patch @@ -0,0 +1,289 @@ +From 455526804beab00adc7b96d01b7e53355123c3d7 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 16 Aug 2023 11:13:39 -0400 +Subject: [PATCH 2/3] status/keyboard: Load keyboard from system settings if + gsettings unconfigured + +Right now if a user hasn't configured their input sources, the code falls back to +using the current layout on Xorg and the mutter default with wayland. + +This commit changes the code to instead fall back to using the system +default (as configured by localed). +--- + js/ui/status/keyboard.js | 58 +++++++++++++++++++++++++++++++--------- + 1 file changed, 45 insertions(+), 13 deletions(-) + +diff --git a/js/ui/status/keyboard.js b/js/ui/status/keyboard.js +index 7277c6d09..97e35d482 100644 +--- a/js/ui/status/keyboard.js ++++ b/js/ui/status/keyboard.js +@@ -1,54 +1,57 @@ + // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + + import Clutter from 'gi://Clutter'; + import Gio from 'gi://Gio'; + import GLib from 'gi://GLib'; + import GObject from 'gi://GObject'; + import IBus from 'gi://IBus'; + import Meta from 'gi://Meta'; + import Shell from 'gi://Shell'; + import St from 'gi://St'; + import * as Gettext from 'gettext'; + import * as Signals from '../../misc/signals.js'; + + import * as IBusManager from '../../misc/ibusManager.js'; + import * as KeyboardManager from '../../misc/keyboardManager.js'; + import * as Main from '../main.js'; + import * as PopupMenu from '../popupMenu.js'; + import * as PanelMenu from '../panelMenu.js'; + import * as SwitcherPopup from '../switcherPopup.js'; + import * as Util from '../../misc/util.js'; + + export const INPUT_SOURCE_TYPE_XKB = 'xkb'; + export const INPUT_SOURCE_TYPE_IBUS = 'ibus'; + ++const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources'; ++const KEY_INPUT_SOURCES = 'sources'; ++ + export const LayoutMenuItem = GObject.registerClass( + class LayoutMenuItem extends PopupMenu.PopupBaseMenuItem { + _init(displayName, shortName) { + super._init(); + + this.setOrnament(PopupMenu.Ornament.NONE); + + this.label = new St.Label({ + text: displayName, + x_expand: true, + }); + this.indicator = new St.Label({text: shortName}); + this.add_child(this.label); + this.add(this.indicator); + this.label_actor = this.label; + } + }); + + export class InputSource extends Signals.EventEmitter { + constructor(type, id, displayName, shortName, index) { + super(); + + this.type = type; + this.id = id; + this.displayName = displayName; + this._shortName = shortName; + this.index = index; + + this.properties = null; + +@@ -236,166 +239,195 @@ class InputSourceSystemSettings extends InputSourceSettings { + this._layouts = layouts; + this._variants = variants; + this._emitInputSourcesChanged(); + } + if (options !== this._options) { + this._options = options; + this._emitKeyboardOptionsChanged(); + } + } + + get inputSources() { + let sourcesList = []; + let layouts = this._layouts.split(','); + let variants = this._variants.split(','); + + for (let i = 0; i < layouts.length && !!layouts[i]; i++) { + let id = layouts[i]; + if (variants[i]) + id += `+${variants[i]}`; + sourcesList.push({type: INPUT_SOURCE_TYPE_XKB, id}); + } + return sourcesList; + } + + get keyboardOptions() { + return this._options.split(','); + } + } + + class InputSourceSessionSettings extends InputSourceSettings { +- constructor() { ++ constructor(settings) { + super(); + +- this._DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources'; +- this._KEY_INPUT_SOURCES = 'sources'; + this._KEY_MRU_SOURCES = 'mru-sources'; + this._KEY_KEYBOARD_OPTIONS = 'xkb-options'; + this._KEY_PER_WINDOW = 'per-window'; + +- this._settings = new Gio.Settings({schema_id: this._DESKTOP_INPUT_SOURCES_SCHEMA}); +- this._settings.connect(`changed::${this._KEY_INPUT_SOURCES}`, this._emitInputSourcesChanged.bind(this)); ++ this._settings = settings; ++ this._settings.connect(`changed::${KEY_INPUT_SOURCES}`, this._emitInputSourcesChanged.bind(this)); + this._settings.connect(`changed::${this._KEY_KEYBOARD_OPTIONS}`, this._emitKeyboardOptionsChanged.bind(this)); + this._settings.connect(`changed::${this._KEY_PER_WINDOW}`, this._emitPerWindowChanged.bind(this)); + } + + _getSourcesList(key) { + let sourcesList = []; + let sources = this._settings.get_value(key); + let nSources = sources.n_children(); + + for (let i = 0; i < nSources; i++) { + let [type, id] = sources.get_child_value(i).deepUnpack(); + sourcesList.push({type, id}); + } + return sourcesList; + } + + get inputSources() { +- return this._getSourcesList(this._KEY_INPUT_SOURCES); ++ return this._getSourcesList(KEY_INPUT_SOURCES); + } + + get mruSources() { + return this._getSourcesList(this._KEY_MRU_SOURCES); + } + + set mruSources(sourcesList) { + let sources = GLib.Variant.new('a(ss)', sourcesList); + this._settings.set_value(this._KEY_MRU_SOURCES, sources); + } + + get keyboardOptions() { + return this._settings.get_strv(this._KEY_KEYBOARD_OPTIONS); + } + + get perWindow() { + return this._settings.get_boolean(this._KEY_PER_WINDOW); + } + } + + export class InputSourceManager extends Signals.EventEmitter { + constructor() { + super(); + + // All valid input sources currently in the gsettings + // KEY_INPUT_SOURCES list indexed by their index there + this._inputSources = {}; + // All valid input sources currently in the gsettings + // KEY_INPUT_SOURCES list of type INPUT_SOURCE_TYPE_IBUS + // indexed by the IBus ID + this._ibusSources = {}; + + this._currentSource = null; + + // All valid input sources currently in the gsettings + // KEY_INPUT_SOURCES list ordered by most recently used + this._mruSources = []; + this._mruSourcesBackup = null; + this._keybindingAction = + Main.wm.addKeybinding('switch-input-source', + new Gio.Settings({schema_id: 'org.gnome.desktop.wm.keybindings'}), + Meta.KeyBindingFlags.NONE, + Shell.ActionMode.ALL, + this._switchInputSource.bind(this)); + this._keybindingActionBackward = + Main.wm.addKeybinding('switch-input-source-backward', + new Gio.Settings({schema_id: 'org.gnome.desktop.wm.keybindings'}), + Meta.KeyBindingFlags.IS_REVERSED, + Shell.ActionMode.ALL, + this._switchInputSource.bind(this)); +- if (Main.sessionMode.isGreeter) +- this._settings = new InputSourceSystemSettings(); +- else +- this._settings = new InputSourceSessionSettings(); +- this._settings.connect('input-sources-changed', this._inputSourcesChanged.bind(this)); +- this._settings.connect('keyboard-options-changed', this._keyboardOptionsChanged.bind(this)); + + this._xkbInfo = KeyboardManager.getXkbInfo(); + this._keyboardManager = KeyboardManager.getKeyboardManager(); + + this._ibusReady = false; + this._ibusManager = IBusManager.getIBusManager(); + this._ibusManager.connect('ready', this._ibusReadyCallback.bind(this)); + this._ibusManager.connect('properties-registered', this._ibusPropertiesRegistered.bind(this)); + this._ibusManager.connect('property-updated', this._ibusPropertyUpdated.bind(this)); + this._ibusManager.connect('set-content-type', this._ibusSetContentType.bind(this)); + ++ this._inputSettings = new Gio.Settings({schema_id: DESKTOP_INPUT_SOURCES_SCHEMA}); ++ this._setupInputSettings(); ++ + global.display.connect('modifiers-accelerator-activated', this._modifiersSwitcher.bind(this)); + + this._sourcesPerWindow = false; + this._focusWindowNotifyId = 0; +- this._settings.connect('per-window-changed', this._sourcesPerWindowChanged.bind(this)); + this._sourcesPerWindowChanged(); + this._disableIBus = false; + this._reloading = false; + } + ++ _sessionHasNoInputSettings() { ++ return this._inputSettings.get_user_value(KEY_INPUT_SOURCES) === null; ++ } ++ ++ _reloadInputSettings() { ++ const hadNoSessionInputSettings = this._hasNoSessionInputSettings; ++ ++ if (Main.sessionMode.isGreeter) ++ this._hasNoSessionInputSettings = true; ++ else ++ this._hasNoSessionInputSettings = this._sessionHasNoInputSettings(); ++ ++ if (this._settings && hadNoSessionInputSettings === this._hasNoSessionInputSettings) ++ return; ++ ++ this._settings?.disconnectObject(this); ++ ++ if (this._hasNoSessionInputSettings) ++ this._settings = new InputSourceSystemSettings(); ++ else ++ this._settings = new InputSourceSessionSettings(this._inputSettings); ++ ++ this._settings.connectObject('input-sources-changed', this._inputSourcesChanged.bind(this), ++ 'keyboard-options-changed', this._keyboardOptionsChanged.bind(this), ++ 'per-window-changed', this._sourcesPerWindowChanged.bind(this), this); ++ this.reload(); ++ } ++ ++ _setupInputSettings() { ++ if (!Main.sessionMode.isGreeter) ++ this._inputSettings.connect(`changed::${KEY_INPUT_SOURCES}`, this._reloadInputSettings.bind(this)); ++ ++ this._reloadInputSettings(); ++ } ++ + reload() { + this._reloading = true; + this._keyboardManager.setKeyboardOptions(this._settings.keyboardOptions); + this._inputSourcesChanged(); + this._reloading = false; + } + + _ibusReadyCallback(im, ready) { + if (this._ibusReady === ready) + return; + + this._ibusReady = ready; + this._mruSources = []; + this._inputSourcesChanged(); + } + + _modifiersSwitcher() { + let sourceIndexes = Object.keys(this._inputSources); + if (sourceIndexes.length === 0) { + KeyboardManager.releaseKeyboard(); + return true; + } + + let is = this._currentSource; + if (!is) + is = this._inputSources[sourceIndexes[0]]; + + let nextIndex = is.index + 1; + if (nextIndex > sourceIndexes[sourceIndexes.length - 1]) + nextIndex = 0; +-- +2.41.0.rc2 + diff --git a/0003-status-keyboard-Use-gnome-desktop-API-for-getting-de.patch b/0003-status-keyboard-Use-gnome-desktop-API-for-getting-de.patch new file mode 100644 index 0000000..e27d123 --- /dev/null +++ b/0003-status-keyboard-Use-gnome-desktop-API-for-getting-de.patch @@ -0,0 +1,233 @@ +From a2684644e0799fe44180201fa96c4f77137f886f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 16 Aug 2023 14:09:50 -0400 +Subject: [PATCH 3/3] status/keyboard: Use gnome-desktop API for getting + default input sources list + +At the moment, gnome-shell tries to figure out the default input sources +from localed. It fails to take into account the system locale and input +methods. + +This commit switches it to use a new function in gnome-desktop, +gnome_get_default_input_sources, which does most of the heavy +lifting itself, instead. +--- + js/ui/status/keyboard.js | 56 ++++++++++++++++++---------------------- + 1 file changed, 25 insertions(+), 31 deletions(-) + +diff --git a/js/ui/status/keyboard.js b/js/ui/status/keyboard.js +index 97e35d482..8a2f1d2f7 100644 +--- a/js/ui/status/keyboard.js ++++ b/js/ui/status/keyboard.js +@@ -1,57 +1,60 @@ + // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + + import Clutter from 'gi://Clutter'; + import Gio from 'gi://Gio'; + import GLib from 'gi://GLib'; ++import GnomeDesktop from 'gi://GnomeDesktop'; + import GObject from 'gi://GObject'; + import IBus from 'gi://IBus'; + import Meta from 'gi://Meta'; + import Shell from 'gi://Shell'; + import St from 'gi://St'; + import * as Gettext from 'gettext'; + import * as Signals from '../../misc/signals.js'; + + import * as IBusManager from '../../misc/ibusManager.js'; + import * as KeyboardManager from '../../misc/keyboardManager.js'; + import * as Main from '../main.js'; + import * as PopupMenu from '../popupMenu.js'; + import * as PanelMenu from '../panelMenu.js'; + import * as SwitcherPopup from '../switcherPopup.js'; + import * as Util from '../../misc/util.js'; + + export const INPUT_SOURCE_TYPE_XKB = 'xkb'; + export const INPUT_SOURCE_TYPE_IBUS = 'ibus'; + + const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources'; + const KEY_INPUT_SOURCES = 'sources'; + ++Gio._promisify(GnomeDesktop, 'get_default_input_sources'); ++ + export const LayoutMenuItem = GObject.registerClass( + class LayoutMenuItem extends PopupMenu.PopupBaseMenuItem { + _init(displayName, shortName) { + super._init(); + + this.setOrnament(PopupMenu.Ornament.NONE); + + this.label = new St.Label({ + text: displayName, + x_expand: true, + }); + this.indicator = new St.Label({text: shortName}); + this.add_child(this.label); + this.add(this.indicator); + this.label_actor = this.label; + } + }); + + export class InputSource extends Signals.EventEmitter { + constructor(type, id, displayName, shortName, index) { + super(); + + this.type = type; + this.id = id; + this.displayName = displayName; + this._shortName = shortName; + this.index = index; + + this.properties = null; + +@@ -170,125 +173,116 @@ class InputSourceSettings extends Signals.EventEmitter { + get inputSources() { + return []; + } + + get mruSources() { + return []; + } + + set mruSources(sourcesList) { + // do nothing + } + + get keyboardOptions() { + return []; + } + + get perWindow() { + return false; + } + } + + class InputSourceSystemSettings extends InputSourceSettings { + constructor() { + super(); + + this._BUS_NAME = 'org.freedesktop.locale1'; + this._BUS_PATH = '/org/freedesktop/locale1'; + this._BUS_IFACE = 'org.freedesktop.locale1'; + this._BUS_PROPS_IFACE = 'org.freedesktop.DBus.Properties'; + +- this._layouts = ''; +- this._variants = ''; +- this._options = ''; ++ this._inputSourceIds = []; ++ this._inputSourceTypes = []; ++ this._options = []; + + this._reload().catch(error => { + logError(error, 'Could not reload system input settings'); + }); + + Gio.DBus.system.signal_subscribe(this._BUS_NAME, + this._BUS_PROPS_IFACE, + 'PropertiesChanged', + this._BUS_PATH, + null, + Gio.DBusSignalFlags.NONE, + this._reload.bind(this)); + } + + async _reload() { +- let props; ++ let inputSourceIds; ++ let inputSourceTypes; ++ let options; + try { +- const result = await Gio.DBus.system.call( +- this._BUS_NAME, +- this._BUS_PATH, +- this._BUS_PROPS_IFACE, +- 'GetAll', +- new GLib.Variant('(s)', [this._BUS_IFACE]), +- null, Gio.DBusCallFlags.NONE, -1, null); +- [props] = result.deepUnpack(); ++ [inputSourceIds, inputSourceTypes, options] = await GnomeDesktop.get_default_input_sources (null); + } catch (e) { +- log(`Could not get properties from ${this._BUS_NAME}`); ++ logError(e, 'Could not get default input sources'); + return; + } + +- const layouts = props['X11Layout'].unpack(); +- const variants = props['X11Variant'].unpack(); +- const options = props['X11Options'].unpack(); +- +- if (layouts !== this._layouts || +- variants !== this._variants) { +- this._layouts = layouts; +- this._variants = variants; ++ if (inputSourceIds !== this._inputSourceIds || ++ inputSourceTypes !== this._inputSourceTypes) { ++ this._inputSourceIds = inputSourceIds; ++ this._inputSourceTypes = inputSourceTypes; + this._emitInputSourcesChanged(); + } + if (options !== this._options) { + this._options = options; + this._emitKeyboardOptionsChanged(); + } + } + + get inputSources() { +- let sourcesList = []; +- let layouts = this._layouts.split(','); +- let variants = this._variants.split(','); +- +- for (let i = 0; i < layouts.length && !!layouts[i]; i++) { +- let id = layouts[i]; +- if (variants[i]) +- id += `+${variants[i]}`; +- sourcesList.push({type: INPUT_SOURCE_TYPE_XKB, id}); ++ let sourcesList; ++ ++ if (this._inputSourceIds) { ++ sourcesList = this._inputSourceIds.map((id, index) => { ++ return { type: this._inputSourceTypes[index], id }; ++ }); ++ } else { ++ sourcesList = []; + } ++ + return sourcesList; + } + + get keyboardOptions() { +- return this._options.split(','); ++ return this._options; + } + } + + class InputSourceSessionSettings extends InputSourceSettings { + constructor(settings) { + super(); + + this._KEY_MRU_SOURCES = 'mru-sources'; + this._KEY_KEYBOARD_OPTIONS = 'xkb-options'; + this._KEY_PER_WINDOW = 'per-window'; + + this._settings = settings; + this._settings.connect(`changed::${KEY_INPUT_SOURCES}`, this._emitInputSourcesChanged.bind(this)); + this._settings.connect(`changed::${this._KEY_KEYBOARD_OPTIONS}`, this._emitKeyboardOptionsChanged.bind(this)); + this._settings.connect(`changed::${this._KEY_PER_WINDOW}`, this._emitPerWindowChanged.bind(this)); + } + + _getSourcesList(key) { + let sourcesList = []; + let sources = this._settings.get_value(key); + let nSources = sources.n_children(); + + for (let i = 0; i < nSources; i++) { + let [type, id] = sources.get_child_value(i).deepUnpack(); + sourcesList.push({type, id}); + } + return sourcesList; + } + + get inputSources() { +-- +2.41.0.rc2 + diff --git a/gnome-shell.spec b/gnome-shell.spec index c1dc231..1b940d5 100644 --- a/gnome-shell.spec +++ b/gnome-shell.spec @@ -3,6 +3,7 @@ Name: gnome-shell Version: 45~beta.1 Release: %autorelease +Epoch: 1 Summary: Window management and application launching for GNOME License: GPLv2+ @@ -16,8 +17,12 @@ Patch10001: gnome-shell-favourite-apps-firefox.patch # downstream patch to stop trying on configuration errors. Patch40001: 0001-gdm-Work-around-failing-fingerprint-auth.patch +Patch: 0001-status-keyboard-Add-a-catch-around-reload-call.patch +Patch: 0002-status-keyboard-Load-keyboard-from-system-settings-i.patch +Patch: 0003-status-keyboard-Use-gnome-desktop-API-for-getting-de.patch + %define eds_version 3.45.1 -%define gnome_desktop_version 40 +%define gnome_desktop_version 44.0-7 %define glib2_version 2.56.0 %define gobject_introspection_version 1.49.1 %define gjs_version 1.73.1 @@ -43,7 +48,7 @@ BuildRequires: pkgconfig(gcr-4) BuildRequires: pkgconfig(gjs-1.0) >= %{gjs_version} BuildRequires: pkgconfig(gio-2.0) >= %{glib2_version} BuildRequires: pkgconfig(gnome-autoar-0) -BuildRequires: pkgconfig(gnome-desktop-4) +BuildRequires: pkgconfig(gnome-desktop-4) >= %{gnome_desktop_version} BuildRequires: pkgconfig(gobject-introspection-1.0) >= %{gobject_introspection_version} BuildRequires: mesa-libGL-devel BuildRequires: mesa-libEGL-devel