File: Rework-keyboard-handling-to-layouts-ibus-handling.patch

package info (click to toggle)
budgie-desktop 10.7.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 13,560 kB
  • sloc: ansic: 8,439; xml: 844; sh: 126; makefile: 42
file content (305 lines) | stat: -rw-r--r-- 9,046 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
Forwarded: https://github.com/BuddiesOfBudgie/budgie-desktop/pull/168
Authord: David Mohammed <fossfreedom@ubuntu.com>
Last-Update: 2023-02-23
Description: [PATCH] Rework keyboard handling to layouts & ibus handling always
 works on logon

---
 src/wm/ibus.vala     |   4 +-
 src/wm/keyboard.vala | 130 +++++++++++++++++++++++++++++++++++++------
 src/wm/wm.vala       |   5 +-
 3 files changed, 115 insertions(+), 24 deletions(-)

--- a/src/wm/ibus.vala
+++ b/src/wm/ibus.vala
@@ -53,7 +53,7 @@
 			this.engines = new HashTable<string,weak IBus.EngineDesc>(str_hash, str_equal);
 
 			/* Get the bus */
-			bus = new IBus.Bus();
+			bus = new IBus.Bus.async();
 
 			/* Hook up basic signals */
 			bus.connected.connect(this.ibus_connected);
--- a/src/wm/keyboard.vala
+++ b/src/wm/keyboard.vala
@@ -55,8 +55,11 @@
 		}
 	}
 
-	public class KeyboardManager : GLib.Object {
-		public unowned Budgie.BudgieWM? wm { construct set ; public get; }
+	public class KeyboardManager : Object {
+		unowned Budgie.BudgieWM? wm;
+		static KeyboardManager? instance;
+		static VariantType sources_variant_type;
+
 		private Gnome.XkbInfo? xkb;
 		string[] options = {};
 
@@ -73,20 +76,49 @@
 		/* Guard ourselves from any future potential derps */
 		private bool is_keyboard_held = false;
 
-		public KeyboardManager(Budgie.BudgieWM? wm) {
-			Object(wm: wm);
+		public static void init (Budgie.BudgieWM? wm) {
+			if (instance != null)
+				return;
+
+			instance = new KeyboardManager (wm);
 
-			xkb = new Gnome.XkbInfo();
+			var display = wm.get_display();
+			display.modifiers_accelerator_activated.connect (instance.handle_modifiers_accelerator_activated);
+		}
+
+		static construct {
+			sources_variant_type = new VariantType ("a(ss)");
+		}
+
+		KeyboardManager (Budgie.BudgieWM? wm) {
+			Object ();
+			this.wm = wm;
+
+			/* Hook into GNOME defaults */
+			var schema = new Settings("org.gnome.desktop.wm.keybindings");
+			wm.get_display().add_keybinding("switch-input-source", schema, Meta.KeyBindingFlags.NONE, switch_input_source);
+			wm.get_display().add_keybinding("switch-input-source-backward", schema, Meta.KeyBindingFlags.NONE, switch_input_source_backward);
+		}
 
+		construct {
+			var schema = GLib.SettingsSchemaSource.get_default ().lookup ("org.gnome.desktop.input-sources", true);
+			if (schema == null)
+				return;
+
+			settings = new GLib.Settings.full (schema, null, null);
+			Signal.connect (settings, "changed", (Callback) set_keyboard_layout, this);
+
+			set_keyboard_layout ("current");
+
+			xkb = new Gnome.XkbInfo();
 			/* Only hook things up when ibus is setup, whether it failed or not */
 			ibus_manager = new IBusManager(this);
 			ibus_manager.ready.connect(on_ibus_ready);
 			ibus_manager.do_init();
 		}
 
+		[CCode (instance_pos = -1)]
 		private void on_ibus_ready() {
-			settings = new Settings("org.gnome.desktop.input-sources");
-
 			/* Special handling of the current source. */
 			sig_id = settings.changed["current"].connect(on_current_source_changed);
 
@@ -95,10 +127,12 @@
 
 			on_settings_changed("xkb-options");
 			on_settings_changed("sources");
+			on_settings_changed("current");
 		}
 
 		public delegate void KeyHandlerFunc(Meta.Display display, Meta.Window? window, Clutter.KeyEvent? event, Meta.KeyBinding binding);
 
+		[CCode (instance_pos = -1)]
 		void switch_input_source(Meta.Display display,
 								Meta.Window? window, Clutter.KeyEvent? event,
 								Meta.KeyBinding binding) {
@@ -111,6 +145,7 @@
 			this.apply_ibus();
 		}
 
+		[CCode (instance_pos = -1)]
 		void switch_input_source_backward(Meta.Display display,
 										Meta.Window? window, Clutter.KeyEvent? event,
 										Meta.KeyBinding binding) {
@@ -123,15 +158,7 @@
 			this.apply_ibus();
 		}
 
-		public void hook_extra() {
-			var display = wm.get_display();
-
-			/* Hook into GNOME defaults */
-			var schema = new Settings("org.gnome.desktop.wm.keybindings");
-			display.add_keybinding("switch-input-source", schema, Meta.KeyBindingFlags.NONE, switch_input_source);
-			display.add_keybinding("switch-input-source-backward", schema, Meta.KeyBindingFlags.NONE, switch_input_source_backward);
-		}
-
+		[CCode (instance_pos = -1)]
 		void on_settings_changed(string key) {
 			switch (key) {
 				case "sources":
@@ -142,12 +169,16 @@
 					/* Update our xkb-options */
 					this.options = settings.get_strv(key);
 					break;
+				case "current":
+					set_keyboard_layout(key);
+					break;
 				default:
-					return;
+					break;
 			}
 		}
 
 		/* Reset InputSource list and produce something consumable by xkb */
+		[CCode (instance_pos = -1)]
 		void update_sources() {
 			sources = new Array<InputSource>();
 
@@ -200,6 +231,7 @@
 		}
 
 		/* Apply our given layout groups to mutter */
+		[CCode (instance_pos = -1)]
 		void apply_layout_group() {
 			unowned InputSource? source;
 			string[] layouts = {};
@@ -220,6 +252,7 @@
 		}
 
 		/* Apply an indexed layout, i.e. 0 for now */
+		[CCode (instance_pos = -1)]
 		void apply_layout(uint idx) {
 			if (idx > sources.length) {
 				idx = 0;
@@ -230,9 +263,10 @@
 			ctx.get_backend().lock_layout_group(idx);
 			/* Send this off to gsettings so that clients know what our idx is */
 			this.write_source_index(idx);
-		}
 
+		}
 
+		[CCode (instance_pos = -1)]
 		void update_fallback() {
 			string? type = null;
 			string? id = null;
@@ -268,16 +302,19 @@
 		/**
 		* Update the index in gsettings so that clients know the current
 		*/
+		[CCode (instance_pos = -1)]
 		private void write_source_index(uint index) {
 			SignalHandler.block(this.settings, this.sig_id);
 			this.settings.set_uint("current", index);
 			this.settings.apply();
+			this.set_keyboard_layout("current");
 			SignalHandler.unblock(this.settings, this.sig_id);
 		}
 
 		/**
 		* Someone else changed the current source, do somethin' about it
 		*/
+		[CCode (instance_pos = -1)]
 		private void on_current_source_changed() {
 			uint new_source = this.settings.get_uint("current");
 			this.hold_keyboard();
@@ -288,6 +325,7 @@
 		/**
 		* Apply the ibus engine and then release the keyboard
 		*/
+		[CCode (instance_pos = -1)]
 		private void apply_ibus() {
 			string engine_name;
 			InputSource? current = sources.index(current_source);
@@ -302,6 +340,7 @@
 		/**
 		* Unfreeze the keyboard
 		*/
+		[CCode (instance_pos = -1)]
 		public void release_keyboard() {
 			if (!is_keyboard_held) {
 				return;
@@ -313,6 +352,7 @@
 		/**
 		* Freeze the keyboard so we don't loose input events
 		*/
+		[CCode (instance_pos = -1)]
 		public void hold_keyboard() {
 			if (is_keyboard_held) {
 				return;
@@ -320,5 +360,61 @@
 			wm.get_display().freeze_keyboard(wm.get_display().get_current_time());
 			is_keyboard_held = true;
 		}
+
+		[CCode (instance_pos = -1)]
+		bool handle_modifiers_accelerator_activated (Meta.Display display) {
+			display.ungrab_keyboard (display.get_current_time ());
+
+			var sources = settings.get_value ("sources");
+			if (!sources.is_of_type (sources_variant_type))
+				return true;
+
+			var n_sources = (uint) sources.n_children ();
+			if (n_sources < 2)
+				return true;
+
+			var current = settings.get_uint ("current");
+			settings.set_uint ("current", (current + 1) % n_sources);
+
+			return true;
+		}
+
+		[CCode (instance_pos = -1)]
+		void set_keyboard_layout (string key) {
+			if (!(key == "current" || key == "sources" || key == "xkb-options"))
+				return;
+
+			string layout = "us", variant = "", options = "";
+
+			var sources = settings.get_value ("sources");
+			if (!sources.is_of_type (sources_variant_type))
+				return;
+
+			var current = settings.get_uint ("current");
+			unowned string? type = null, name = null;
+			if (sources.n_children () > current)
+				sources.get_child (current, "(&s&s)", out type, out name);
+			if (type == "xkb") {
+				string[] arr = name.split ("+", 2);
+				layout = arr[0];
+				variant = arr[1] ?? "";
+			} else {
+				return;  //We do not want to change the current xkb layout here when using ibus.
+			}
+
+			var xkb_options = settings.get_strv ("xkb-options");
+			if (xkb_options.length > 0)
+				options = string.joinv (",", xkb_options);
+
+			// Needed to make common keybindings work on non-latin layouts
+			if (layout != "us" || variant != "") {
+				layout = layout + ",us";
+				variant = variant + ",";
+			}
+
+			Meta.Display display = wm.get_display();
+			Meta.Context ctx = display.get_context();
+			ctx.get_backend ().set_keymap (layout, variant, options);
+		}
 	}
 }
--- a/src/wm/wm.vala
+++ b/src/wm/wm.vala
@@ -156,8 +156,6 @@
 
 		private Meta.BackgroundGroup? background_group;
 
-		private KeyboardManager? keyboard = null;
-
 		Settings? settings = null;
 		Settings? gnome_desktop_prefs = null;
 		RavenRemote? raven_proxy = null;
@@ -654,8 +652,7 @@
 			display_group.show();
 			stage.show();
 
-			keyboard = new KeyboardManager(this);
-			keyboard.hook_extra();
+			KeyboardManager.init(this);
 
 			display.get_workspace_manager().override_workspace_layout(Meta.DisplayCorner.TOPLEFT, false, 1, -1);