From a2684644e0799fe44180201fa96c4f77137f886f Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
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

