7646 lines
306 KiB
Diff
7646 lines
306 KiB
Diff
From 8e6cb6aec87192acf821dac8a31fc4261a82ce0f Mon Sep 17 00:00:00 2001
|
|
From: Serhii Tereshchenko <serg.partizan@gmail.com>
|
|
Date: Sat, 27 Sep 2025 15:09:29 +0300
|
|
Subject: [PATCH 01/32] test: Add test-case for Keyboard Layout Change using
|
|
Shift+Caps
|
|
|
|
Refs #4346
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4707>
|
|
(cherry picked from commit 9ad80a4aebe4cfba437b44facd2d072ec3507791)
|
|
---
|
|
src/tests/keyboard-map-tests.c | 81 ++++++++++++++++++++++++++++++++++
|
|
1 file changed, 81 insertions(+)
|
|
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index 9b220f81d1..6a547f8cbc 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -186,6 +186,78 @@ meta_test_native_keyboard_map_set_async (void)
|
|
g_signal_handler_disconnect (keymap, keymap_state_changed_handler_id);
|
|
}
|
|
|
|
+static void
|
|
+meta_test_native_keyboard_map_change_layout (void)
|
|
+{
|
|
+ MetaBackend *backend = meta_context_get_backend (test_context);
|
|
+ ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
|
+
|
|
+ g_autoptr (ClutterVirtualInputDevice) virtual_keyboard = NULL;
|
|
+ struct xkb_keymap *xkb_keymap = meta_backend_get_keymap (backend);
|
|
+ struct xkb_keymap *new_xkb_keymap;
|
|
+ gboolean done = FALSE;
|
|
+
|
|
+ virtual_keyboard = clutter_seat_create_virtual_device (seat,
|
|
+ CLUTTER_KEYBOARD_DEVICE);
|
|
+
|
|
+ xkb_keymap_ref (xkb_keymap);
|
|
+
|
|
+ meta_backend_set_keymap_async (backend,
|
|
+ "us,ua",
|
|
+ NULL,
|
|
+ "grp:caps_select",
|
|
+ NULL, NULL,
|
|
+ set_keymap_cb, &done);
|
|
+
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+
|
|
+ new_xkb_keymap = meta_backend_get_keymap (backend);
|
|
+ g_assert_true (new_xkb_keymap != xkb_keymap);
|
|
+ g_assert_cmpuint (xkb_keymap_num_layouts (new_xkb_keymap), ==, 2);
|
|
+ g_assert_cmpstr (xkb_keymap_layout_get_name (new_xkb_keymap, 0),
|
|
+ ==,
|
|
+ "English (US)");
|
|
+ g_assert_cmpstr (xkb_keymap_layout_get_name (new_xkb_keymap, 1),
|
|
+ ==,
|
|
+ "Ukrainian");
|
|
+
|
|
+ xkb_keymap_unref (xkb_keymap);
|
|
+
|
|
+ /* Test layout switching with Caps Lock */
|
|
+ /* First verify we start with layout 0 (English US) */
|
|
+ g_assert_cmpuint (meta_backend_get_keymap_layout_group (backend), ==, 0);
|
|
+
|
|
+ /* Press Shift key */
|
|
+ clutter_virtual_input_device_notify_key (virtual_keyboard,
|
|
+ g_get_monotonic_time (),
|
|
+ KEY_LEFTSHIFT,
|
|
+ CLUTTER_KEY_STATE_PRESSED);
|
|
+
|
|
+ /* Press Caps Lock while Shift is held (Shift+Caps Lock) */
|
|
+ clutter_virtual_input_device_notify_key (virtual_keyboard,
|
|
+ g_get_monotonic_time (),
|
|
+ KEY_CAPSLOCK,
|
|
+ CLUTTER_KEY_STATE_PRESSED);
|
|
+
|
|
+ /* Release Caps Lock */
|
|
+ clutter_virtual_input_device_notify_key (virtual_keyboard,
|
|
+ g_get_monotonic_time (),
|
|
+ KEY_CAPSLOCK,
|
|
+ CLUTTER_KEY_STATE_RELEASED);
|
|
+
|
|
+ /* Release Shift key */
|
|
+ clutter_virtual_input_device_notify_key (virtual_keyboard,
|
|
+ g_get_monotonic_time (),
|
|
+ KEY_LEFTSHIFT,
|
|
+ CLUTTER_KEY_STATE_RELEASED);
|
|
+ meta_flush_input (test_context);
|
|
+ meta_wait_for_update (test_context);
|
|
+
|
|
+ /* Verify that layout switched to Ukrainian (layout 1) */
|
|
+ g_assert_cmpuint (meta_backend_get_keymap_layout_group (backend), ==, 1);
|
|
+}
|
|
+
|
|
static void
|
|
set_keymap_layout_group_cb (GObject *source_object,
|
|
GAsyncResult *result,
|
|
@@ -218,6 +290,13 @@ meta_test_native_keyboard_map_set_layout_index (void)
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
+ done = FALSE;
|
|
+ meta_backend_set_keymap_layout_group_async (backend, 0, NULL,
|
|
+ set_keymap_layout_group_cb,
|
|
+ &done);
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+
|
|
keymap = xkb_keymap_ref (meta_backend_get_keymap (backend));
|
|
g_assert_cmpuint (xkb_keymap_num_layouts (keymap), ==, 2);
|
|
g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 0),
|
|
@@ -353,6 +432,8 @@ init_tests (void)
|
|
{
|
|
g_test_add_func ("/backends/native/keyboard-map/set-async",
|
|
meta_test_native_keyboard_map_set_async);
|
|
+ g_test_add_func ("/backends/native/keyboard-map/change-layout",
|
|
+ meta_test_native_keyboard_map_change_layout);
|
|
g_test_add_func ("/backends/native/keyboard-map/set-layout-index",
|
|
meta_test_native_keyboard_map_set_layout_index);
|
|
g_test_add_func ("/backends/native/keyboard-map/modifiers",
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From d5f19cd112a590206b18dca94fb9aa22381beca8 Mon Sep 17 00:00:00 2001
|
|
From: Sebastian Keller <skeller@gnome.org>
|
|
Date: Thu, 22 Jan 2026 14:39:52 +0100
|
|
Subject: [PATCH 02/32] keymap/native: Use effective instead of locked layout
|
|
group
|
|
|
|
The locked layout group does not take depressed/latched keys into
|
|
consideration, resulting in the layout group not being switched when
|
|
using grp:caps_switch and holding caps lock while typing.
|
|
|
|
Fixes: aeac0f33c2 ("keymap/native: Plumb all modifier state")
|
|
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/4528
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4858>
|
|
(cherry picked from commit f015c1059ff29adc95383aa725afbe50580df020)
|
|
---
|
|
clutter/clutter/clutter-keymap-private.h | 2 +-
|
|
clutter/clutter/clutter-keymap.c | 10 +++++-----
|
|
src/backends/native/meta-keymap-native.c | 8 ++++----
|
|
3 files changed, 10 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/clutter/clutter/clutter-keymap-private.h b/clutter/clutter/clutter-keymap-private.h
|
|
index fbba11980a..047425c05e 100644
|
|
--- a/clutter/clutter/clutter-keymap-private.h
|
|
+++ b/clutter/clutter/clutter-keymap-private.h
|
|
@@ -24,7 +24,7 @@ CLUTTER_EXPORT
|
|
void clutter_keymap_update_state (ClutterKeymap *keymap,
|
|
gboolean caps_lock_state,
|
|
gboolean num_lock_state,
|
|
- xkb_layout_index_t locked_layout_group,
|
|
+ xkb_layout_index_t effective_layout_group,
|
|
xkb_mod_mask_t depressed_mods,
|
|
xkb_mod_mask_t latched_mods,
|
|
xkb_mod_mask_t locked_mods);
|
|
diff --git a/clutter/clutter/clutter-keymap.c b/clutter/clutter/clutter-keymap.c
|
|
index 00bef2933e..8721990f74 100644
|
|
--- a/clutter/clutter/clutter-keymap.c
|
|
+++ b/clutter/clutter/clutter-keymap.c
|
|
@@ -43,7 +43,7 @@ typedef struct _ClutterKeymapPrivate
|
|
xkb_mod_mask_t latched_mods;
|
|
xkb_mod_mask_t locked_mods;
|
|
|
|
- xkb_layout_index_t locked_layout_group;
|
|
+ xkb_layout_index_t effective_layout_group;
|
|
} ClutterKeymapPrivate;
|
|
|
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterKeymap, clutter_keymap,
|
|
@@ -163,7 +163,7 @@ void
|
|
clutter_keymap_update_state (ClutterKeymap *keymap,
|
|
gboolean caps_lock_state,
|
|
gboolean num_lock_state,
|
|
- xkb_layout_index_t locked_layout_group,
|
|
+ xkb_layout_index_t effective_layout_group,
|
|
xkb_mod_mask_t depressed_mods,
|
|
xkb_mod_mask_t latched_mods,
|
|
xkb_mod_mask_t locked_mods)
|
|
@@ -172,13 +172,13 @@ clutter_keymap_update_state (ClutterKeymap *keymap,
|
|
|
|
if (priv->caps_lock_state == caps_lock_state &&
|
|
priv->num_lock_state == num_lock_state &&
|
|
- priv->locked_layout_group == locked_layout_group &&
|
|
+ priv->effective_layout_group == effective_layout_group &&
|
|
priv->depressed_mods == depressed_mods &&
|
|
priv->latched_mods == latched_mods &&
|
|
priv->locked_mods == locked_mods)
|
|
return;
|
|
|
|
- priv->locked_layout_group = locked_layout_group;
|
|
+ priv->effective_layout_group = effective_layout_group;
|
|
priv->depressed_mods = depressed_mods;
|
|
priv->latched_mods = latched_mods;
|
|
priv->locked_mods = locked_mods;
|
|
@@ -222,5 +222,5 @@ clutter_keymap_get_layout_index (ClutterKeymap *keymap)
|
|
{
|
|
ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
|
|
|
- return priv->locked_layout_group;
|
|
+ return priv->effective_layout_group;
|
|
}
|
|
diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c
|
|
index faa4439f57..8d1d804c12 100644
|
|
--- a/src/backends/native/meta-keymap-native.c
|
|
+++ b/src/backends/native/meta-keymap-native.c
|
|
@@ -112,7 +112,7 @@ typedef struct
|
|
xkb_mod_mask_t latched_mods;
|
|
xkb_mod_mask_t locked_mods;
|
|
|
|
- xkb_layout_index_t locked_layout_group;
|
|
+ xkb_layout_index_t effective_layout_group;
|
|
} UpdateLockedModifierStateData;
|
|
|
|
static gboolean
|
|
@@ -135,7 +135,7 @@ update_state_in_main (gpointer user_data)
|
|
clutter_keymap_update_state (CLUTTER_KEYMAP (keymap_native),
|
|
caps_lock_state,
|
|
num_lock_state,
|
|
- data->locked_layout_group,
|
|
+ data->effective_layout_group,
|
|
data->depressed_mods,
|
|
data->latched_mods,
|
|
data->locked_mods);
|
|
@@ -160,8 +160,8 @@ meta_keymap_native_update_in_impl (MetaKeymapNative *keymap_native,
|
|
data->locked_mods =
|
|
xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED);
|
|
|
|
- data->locked_layout_group =
|
|
- xkb_state_serialize_layout (xkb_state, XKB_STATE_LAYOUT_LOCKED);
|
|
+ data->effective_layout_group =
|
|
+ xkb_state_serialize_layout (xkb_state, XKB_STATE_LAYOUT_EFFECTIVE);
|
|
|
|
meta_seat_impl_queue_main_thread_idle (seat_impl,
|
|
update_state_in_main,
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 3b317ede1d9ecbc1c0db490577d1014edf07d193 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Tue, 23 Sep 2025 12:02:15 +0200
|
|
Subject: [PATCH 03/32] build: Fix a file sort order issue
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit ece0c71ca17260f79907de86299343bc442d12a8)
|
|
---
|
|
src/meta/meson.build | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/src/meta/meson.build b/src/meta/meson.build
|
|
index f34ace7439..601b020044 100644
|
|
--- a/src/meta/meson.build
|
|
+++ b/src/meta/meson.build
|
|
@@ -24,8 +24,8 @@ mutter_public_headers = [
|
|
'meta-external-constraint.h',
|
|
'meta-idle-monitor.h',
|
|
'meta-inhibit-shortcuts-dialog.h',
|
|
- 'meta-launch-context.h',
|
|
'meta-later.h',
|
|
+ 'meta-launch-context.h',
|
|
'meta-logical-monitor.h',
|
|
'meta-monitor.h',
|
|
'meta-monitor-manager.h',
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From d2c3ab0a4a89c33ea9115f50df6746b6c1ec1b16 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Mon, 15 Dec 2025 21:39:18 +0100
|
|
Subject: [PATCH 04/32] tests/keyboard-map-tests: Don't leak xkb_keymap
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit c4f7155c900a414a9c45b4d2441c383c82b906b7)
|
|
---
|
|
src/tests/keyboard-map-tests.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index 6a547f8cbc..bca99da74d 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -297,7 +297,7 @@ meta_test_native_keyboard_map_set_layout_index (void)
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
- keymap = xkb_keymap_ref (meta_backend_get_keymap (backend));
|
|
+ keymap = meta_backend_get_keymap (backend);
|
|
g_assert_cmpuint (xkb_keymap_num_layouts (keymap), ==, 2);
|
|
g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 0),
|
|
==,
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From c13eb4351bf2d102f673cb8258233806606de3c5 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Tue, 23 Sep 2025 12:02:54 +0200
|
|
Subject: [PATCH 05/32] meta/backend: Fix include order
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 13f59a7765f8e954d94450d61127c2f029542907)
|
|
---
|
|
src/meta/meta-backend.h | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h
|
|
index 9939f1ae1b..5511acbeec 100644
|
|
--- a/src/meta/meta-backend.h
|
|
+++ b/src/meta/meta-backend.h
|
|
@@ -27,8 +27,8 @@
|
|
#include "clutter/clutter.h"
|
|
#include "meta/meta-dnd.h"
|
|
#include "meta/meta-idle-monitor.h"
|
|
-#include "meta/meta-monitor-manager.h"
|
|
#include "meta/meta-logical-monitor.h"
|
|
+#include "meta/meta-monitor-manager.h"
|
|
#include "meta/meta-orientation-manager.h"
|
|
#include "meta/meta-remote-access-controller.h"
|
|
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 7276f386325234493429eccb49e3e6d3b56ac6ef Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Tue, 23 Sep 2025 12:00:04 +0200
|
|
Subject: [PATCH 06/32] backend: Set keymap using new MetaKeymapDescription
|
|
type
|
|
|
|
This allows moving some logic to a type that centralizes handling of
|
|
describing a keyboard map. It also allows attaching more metadata to the
|
|
keymap which will be useful in the future.
|
|
|
|
The MetaKeymapDescription type is a immutable description of a XKB keyboard
|
|
map. Switching related state, i.e. layout index, is done externally to
|
|
it.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 0ddaddd628d34a6a371340ff9c5c3994f356a749)
|
|
---
|
|
src/backends/meta-backend-private.h | 9 +-
|
|
src/backends/meta-backend.c | 18 ++--
|
|
.../meta-keymap-description-private.h | 27 +++++
|
|
src/backends/meta-keymap-description.c | 101 ++++++++++++++++++
|
|
src/backends/native/meta-backend-native.c | 11 +-
|
|
src/backends/native/meta-seat-native.c | 55 +++++-----
|
|
src/backends/native/meta-seat-native.h | 13 +--
|
|
src/compositor/plugins/default.c | 11 +-
|
|
src/meson.build | 2 +
|
|
src/meta/meson.build | 1 +
|
|
src/meta/meta-backend.h | 14 ++-
|
|
src/meta/meta-keymap-description.h | 44 ++++++++
|
|
src/tests/keyboard-map-tests.c | 41 ++++---
|
|
src/tests/remote-desktop-tests.c | 7 +-
|
|
14 files changed, 267 insertions(+), 87 deletions(-)
|
|
create mode 100644 src/backends/meta-keymap-description-private.h
|
|
create mode 100644 src/backends/meta-keymap-description.c
|
|
create mode 100644 src/meta/meta-keymap-description.h
|
|
|
|
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
|
|
index 096bee25ba..b7d92e6a4c 100644
|
|
--- a/src/backends/meta-backend-private.h
|
|
+++ b/src/backends/meta-backend-private.h
|
|
@@ -124,12 +124,9 @@ struct _MetaBackendClass
|
|
ClutterEventSequence *sequence,
|
|
MetaSequenceState state);
|
|
|
|
- void (* set_keymap_async) (MetaBackend *backend,
|
|
- const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model,
|
|
- GTask *task);
|
|
+ void (* set_keymap_async) (MetaBackend *backend,
|
|
+ MetaKeymapDescription *description,
|
|
+ GTask *task);
|
|
|
|
struct xkb_keymap * (* get_keymap) (MetaBackend *backend);
|
|
|
|
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
|
|
index ff01f58b9e..84e4d4cf25 100644
|
|
--- a/src/backends/meta-backend.c
|
|
+++ b/src/backends/meta-backend.c
|
|
@@ -1775,14 +1775,11 @@ meta_backend_set_keymap_finish (MetaBackend *backend,
|
|
}
|
|
|
|
void
|
|
-meta_backend_set_keymap_async (MetaBackend *backend,
|
|
- const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data)
|
|
+meta_backend_set_keymap_async (MetaBackend *backend,
|
|
+ MetaKeymapDescription *description,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data)
|
|
{
|
|
GTask *task;
|
|
|
|
@@ -1790,10 +1787,7 @@ meta_backend_set_keymap_async (MetaBackend *backend,
|
|
g_task_set_source_tag (task, meta_backend_set_keymap_async);
|
|
|
|
META_BACKEND_GET_CLASS (backend)->set_keymap_async (backend,
|
|
- layouts,
|
|
- variants,
|
|
- options,
|
|
- model,
|
|
+ description,
|
|
task);
|
|
}
|
|
|
|
diff --git a/src/backends/meta-keymap-description-private.h b/src/backends/meta-keymap-description-private.h
|
|
new file mode 100644
|
|
index 0000000000..2e9a6f8e45
|
|
--- /dev/null
|
|
+++ b/src/backends/meta-keymap-description-private.h
|
|
@@ -0,0 +1,27 @@
|
|
+/*
|
|
+ * Copyright (C) 2025 Red Hat
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public License as
|
|
+ * published by the Free Software Foundation; either version 2 of the
|
|
+ * License, or (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "meta/meta-keymap-description.h"
|
|
+
|
|
+void meta_keymap_description_get_rules (MetaKeymapDescription *keymap_description,
|
|
+ char **model,
|
|
+ char **layout,
|
|
+ char **variant,
|
|
+ char **options);
|
|
diff --git a/src/backends/meta-keymap-description.c b/src/backends/meta-keymap-description.c
|
|
new file mode 100644
|
|
index 0000000000..081fcf64d0
|
|
--- /dev/null
|
|
+++ b/src/backends/meta-keymap-description.c
|
|
@@ -0,0 +1,101 @@
|
|
+/*
|
|
+ * Copyright (C) 2025 Red Hat
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public License as
|
|
+ * published by the Free Software Foundation; either version 2 of the
|
|
+ * License, or (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+
|
|
+#include "backends/meta-keymap-description-private.h"
|
|
+
|
|
+#include <glib-object.h>
|
|
+
|
|
+#include "backends/meta-keymap-utils.h"
|
|
+
|
|
+struct _MetaKeymapDescription
|
|
+{
|
|
+ gatomicrefcount ref_count;
|
|
+
|
|
+ char *rules;
|
|
+ char *model;
|
|
+ char *layout;
|
|
+ char *variant;
|
|
+ char *options;
|
|
+};
|
|
+
|
|
+#define DEFAULT_XKB_RULES_FILE "evdev"
|
|
+#define DEFAULT_XKB_MODEL "pc105+inet"
|
|
+
|
|
+G_DEFINE_BOXED_TYPE (MetaKeymapDescription, meta_keymap_description,
|
|
+ meta_keymap_description_ref,
|
|
+ meta_keymap_description_unref)
|
|
+
|
|
+static char *
|
|
+strdup_or_empty (const char *string)
|
|
+{
|
|
+ return string ? g_strdup (string) : g_strdup ("");
|
|
+}
|
|
+
|
|
+MetaKeymapDescription *
|
|
+meta_keymap_description_new_from_rules (const char *model,
|
|
+ const char *layout,
|
|
+ const char *variant,
|
|
+ const char *options)
|
|
+{
|
|
+ MetaKeymapDescription *keymap_description;
|
|
+
|
|
+ keymap_description = g_new0 (MetaKeymapDescription, 1);
|
|
+ g_atomic_ref_count_init (&keymap_description->ref_count);
|
|
+ keymap_description->model = model ? g_strdup (model)
|
|
+ : g_strdup (DEFAULT_XKB_MODEL);
|
|
+ keymap_description->layout = strdup_or_empty (layout);
|
|
+ keymap_description->variant = strdup_or_empty (variant);
|
|
+ keymap_description->options = strdup_or_empty (options);
|
|
+
|
|
+ return keymap_description;
|
|
+}
|
|
+
|
|
+MetaKeymapDescription *
|
|
+meta_keymap_description_ref (MetaKeymapDescription *keymap_description)
|
|
+{
|
|
+ g_atomic_ref_count_inc (&keymap_description->ref_count);
|
|
+ return keymap_description;
|
|
+}
|
|
+
|
|
+void
|
|
+meta_keymap_description_unref (MetaKeymapDescription *keymap_description)
|
|
+{
|
|
+ if (g_atomic_ref_count_dec (&keymap_description->ref_count))
|
|
+ {
|
|
+ g_free (keymap_description->model);
|
|
+ g_free (keymap_description->layout);
|
|
+ g_free (keymap_description->variant);
|
|
+ g_free (keymap_description->options);
|
|
+ g_free (keymap_description);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+meta_keymap_description_get_rules (MetaKeymapDescription *keymap_description,
|
|
+ char **model,
|
|
+ char **layout,
|
|
+ char **variant,
|
|
+ char **options)
|
|
+{
|
|
+ *model = g_strdup (keymap_description->model);
|
|
+ *layout = g_strdup (keymap_description->layout);
|
|
+ *variant = g_strdup (keymap_description->variant);
|
|
+ *options = g_strdup (keymap_description->options);
|
|
+}
|
|
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
|
|
index baca057b34..3e39efb098 100644
|
|
--- a/src/backends/native/meta-backend-native.c
|
|
+++ b/src/backends/native/meta-backend-native.c
|
|
@@ -334,19 +334,16 @@ set_keyboard_map_cb (GObject *source_object,
|
|
}
|
|
|
|
static void
|
|
-meta_backend_native_set_keymap_async (MetaBackend *backend,
|
|
- const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model,
|
|
- GTask *task)
|
|
+meta_backend_native_set_keymap_async (MetaBackend *backend,
|
|
+ MetaKeymapDescription *description,
|
|
+ GTask *task)
|
|
{
|
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
|
ClutterSeat *seat;
|
|
|
|
seat = clutter_backend_get_default_seat (clutter_backend);
|
|
meta_seat_native_set_keyboard_map_async (META_SEAT_NATIVE (seat),
|
|
- layouts, variants, options, model,
|
|
+ description,
|
|
g_task_get_cancellable (task),
|
|
set_keyboard_map_cb,
|
|
task);
|
|
diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c
|
|
index 1d88e1a131..63392531cd 100644
|
|
--- a/src/backends/native/meta-seat-native.c
|
|
+++ b/src/backends/native/meta-seat-native.c
|
|
@@ -29,6 +29,7 @@
|
|
#include "backends/native/meta-seat-native.h"
|
|
|
|
#include "backends/meta-cursor-tracker-private.h"
|
|
+#include "backends/meta-keymap-description-private.h"
|
|
#include "backends/meta-keymap-utils.h"
|
|
#include "backends/native/meta-barrier-native.h"
|
|
#include "backends/native/meta-input-thread.h"
|
|
@@ -36,6 +37,7 @@
|
|
#include "backends/native/meta-virtual-input-device-native.h"
|
|
#include "clutter/clutter-mutter.h"
|
|
#include "core/bell.h"
|
|
+#include "meta/meta-keymap-description.h"
|
|
|
|
#include "meta-private-enum-types.h"
|
|
|
|
@@ -55,13 +57,10 @@ static GParamSpec *props[N_PROPS] = { NULL };
|
|
|
|
G_DEFINE_TYPE (MetaSeatNative, meta_seat_native, CLUTTER_TYPE_SEAT)
|
|
|
|
-static gboolean meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
- const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model,
|
|
- GCancellable *cancellable,
|
|
- GError **error);
|
|
+static gboolean meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
+ MetaKeymapDescription *description,
|
|
+ GCancellable *cancellable,
|
|
+ GError **error);
|
|
|
|
static gboolean
|
|
meta_seat_native_handle_event_post (ClutterSeat *seat,
|
|
@@ -155,6 +154,7 @@ static void
|
|
meta_seat_native_constructed (GObject *object)
|
|
{
|
|
MetaSeatNative *seat = META_SEAT_NATIVE (object);
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
seat->impl = meta_seat_impl_new (seat, seat->seat_id, seat->flags);
|
|
@@ -171,8 +171,12 @@ meta_seat_native_constructed (GObject *object)
|
|
seat->core_pointer = meta_seat_impl_get_pointer (seat->impl);
|
|
seat->core_keyboard = meta_seat_impl_get_keyboard (seat->impl);
|
|
|
|
+ keymap_description = meta_keymap_description_new_from_rules (NULL,
|
|
+ "us",
|
|
+ NULL,
|
|
+ NULL);
|
|
if (!meta_seat_native_set_keyboard_map_sync (seat,
|
|
- "us", "", "", DEFAULT_XKB_MODEL,
|
|
+ keymap_description,
|
|
NULL, &error))
|
|
g_warning ("Failed to set keyboard map: %s", error->message);
|
|
|
|
@@ -583,21 +587,27 @@ set_impl_keyboard_map_cb (GObject *source_object,
|
|
* is pressed when calling this function.
|
|
*/
|
|
void
|
|
-meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
- const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data)
|
|
+meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
+ MetaKeymapDescription *description,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data)
|
|
{
|
|
g_autoptr (GTask) task = NULL;
|
|
struct xkb_keymap *keymap, *impl_keymap;
|
|
+ g_autofree char *layouts = NULL;
|
|
+ g_autofree char *variants = NULL;
|
|
+ g_autofree char *options = NULL;
|
|
+ g_autofree char *model = NULL;
|
|
|
|
task = g_task_new (G_OBJECT (seat), cancellable, callback, user_data);
|
|
g_task_set_source_tag (task, meta_seat_native_set_keyboard_map_async);
|
|
|
|
+ meta_keymap_description_get_rules (description,
|
|
+ &model,
|
|
+ &layouts,
|
|
+ &variants,
|
|
+ &options);
|
|
keymap = create_keymap (layouts, variants, options, model);
|
|
impl_keymap = create_keymap (layouts, variants, options, model);
|
|
|
|
@@ -640,13 +650,10 @@ set_keyboard_map_cb (GObject *source_object,
|
|
}
|
|
|
|
static gboolean
|
|
-meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
- const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model,
|
|
- GCancellable *cancellable,
|
|
- GError **error)
|
|
+meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
+ MetaKeymapDescription *description,
|
|
+ GCancellable *cancellable,
|
|
+ GError **error)
|
|
{
|
|
g_autoptr (GMainContext) main_context = NULL;
|
|
g_autoptr (GMainLoop) main_loop = NULL;
|
|
@@ -660,7 +667,7 @@ meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
g_task_set_task_data (task, main_loop, NULL);
|
|
|
|
meta_seat_native_set_keyboard_map_async (seat_native,
|
|
- layouts, variants, options, model,
|
|
+ description,
|
|
cancellable,
|
|
set_keyboard_map_cb, task);
|
|
g_main_loop_run (main_loop);
|
|
diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h
|
|
index 9f300bad79..e0bd689a07 100644
|
|
--- a/src/backends/native/meta-seat-native.h
|
|
+++ b/src/backends/native/meta-seat-native.h
|
|
@@ -100,14 +100,11 @@ void meta_seat_native_set_device_callbacks (MetaOpenDeviceCallback open_callba
|
|
void meta_seat_native_release_devices (MetaSeatNative *seat);
|
|
void meta_seat_native_reclaim_devices (MetaSeatNative *seat);
|
|
|
|
-void meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
- const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data);
|
|
+void meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
+ MetaKeymapDescription *description,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data);
|
|
|
|
gboolean meta_seat_native_set_keyboard_map_finish (MetaSeatNative *seat_native,
|
|
GAsyncResult *result,
|
|
diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c
|
|
index f5e0684588..094cec07ea 100644
|
|
--- a/src/compositor/plugins/default.c
|
|
+++ b/src/compositor/plugins/default.c
|
|
@@ -364,6 +364,7 @@ init_keymap (MetaDefaultPlugin *self,
|
|
g_autofree char *x11_options = NULL;
|
|
g_autofree char *x11_variant = NULL;
|
|
g_autofree char *x11_model = NULL;
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
|
|
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
|
(G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
|
@@ -414,11 +415,13 @@ init_keymap (MetaDefaultPlugin *self,
|
|
if (!g_variant_lookup (props, "X11Model", "s", &x11_model))
|
|
x11_model = g_strdup ("");
|
|
|
|
+ keymap_description = meta_keymap_description_new_from_rules (x11_model,
|
|
+ x11_layout,
|
|
+ x11_variant,
|
|
+ x11_options);
|
|
+
|
|
meta_backend_set_keymap_async (backend,
|
|
- x11_layout,
|
|
- x11_variant,
|
|
- x11_options,
|
|
- x11_model,
|
|
+ keymap_description,
|
|
NULL, NULL, NULL);
|
|
}
|
|
|
|
diff --git a/src/meson.build b/src/meson.build
|
|
index 159e207153..e7824f502e 100644
|
|
--- a/src/meson.build
|
|
+++ b/src/meson.build
|
|
@@ -243,6 +243,8 @@ mutter_sources = [
|
|
'backends/meta-input-settings-private.h',
|
|
'backends/meta-input-settings-dummy.c',
|
|
'backends/meta-input-settings-dummy.h',
|
|
+ 'backends/meta-keymap-description.c',
|
|
+ 'backends/meta-keymap-description-private.h',
|
|
'backends/meta-keymap-utils.c',
|
|
'backends/meta-keymap-utils.h',
|
|
'backends/meta-logical-monitor.c',
|
|
diff --git a/src/meta/meson.build b/src/meta/meson.build
|
|
index 601b020044..8374441dd2 100644
|
|
--- a/src/meta/meson.build
|
|
+++ b/src/meta/meson.build
|
|
@@ -24,6 +24,7 @@ mutter_public_headers = [
|
|
'meta-external-constraint.h',
|
|
'meta-idle-monitor.h',
|
|
'meta-inhibit-shortcuts-dialog.h',
|
|
+ 'meta-keymap-description.h',
|
|
'meta-later.h',
|
|
'meta-launch-context.h',
|
|
'meta-logical-monitor.h',
|
|
diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h
|
|
index 5511acbeec..74ad2bfebf 100644
|
|
--- a/src/meta/meta-backend.h
|
|
+++ b/src/meta/meta-backend.h
|
|
@@ -27,6 +27,7 @@
|
|
#include "clutter/clutter.h"
|
|
#include "meta/meta-dnd.h"
|
|
#include "meta/meta-idle-monitor.h"
|
|
+#include "meta/meta-keymap-description.h"
|
|
#include "meta/meta-logical-monitor.h"
|
|
#include "meta/meta-monitor-manager.h"
|
|
#include "meta/meta-orientation-manager.h"
|
|
@@ -48,14 +49,11 @@ gboolean meta_backend_set_keymap_finish (MetaBackend *backend,
|
|
GError **error);
|
|
|
|
META_EXPORT
|
|
-void meta_backend_set_keymap_async (MetaBackend *backend,
|
|
- const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data);
|
|
+void meta_backend_set_keymap_async (MetaBackend *backend,
|
|
+ MetaKeymapDescription *description,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data);
|
|
|
|
META_EXPORT
|
|
gboolean meta_backend_set_keymap_layout_group_finish (MetaBackend *backend,
|
|
diff --git a/src/meta/meta-keymap-description.h b/src/meta/meta-keymap-description.h
|
|
new file mode 100644
|
|
index 0000000000..32e9ef6d2d
|
|
--- /dev/null
|
|
+++ b/src/meta/meta-keymap-description.h
|
|
@@ -0,0 +1,44 @@
|
|
+/*
|
|
+ * Copyright 2025 Red Hat
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public License as
|
|
+ * published by the Free Software Foundation; either version 2 of the
|
|
+ * License, or (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <glib-object.h>
|
|
+
|
|
+#include "meta/util.h"
|
|
+
|
|
+typedef struct _MetaKeymapDescription MetaKeymapDescription;
|
|
+
|
|
+#define META_TYPE_KEYMAP_DESCRIPTION (meta_keymap_description_get_type ())
|
|
+
|
|
+META_EXPORT
|
|
+GType meta_keymap_description_get_type (void) G_GNUC_CONST;
|
|
+
|
|
+META_EXPORT
|
|
+MetaKeymapDescription * meta_keymap_description_new_from_rules (const char *model,
|
|
+ const char *layout,
|
|
+ const char *variant,
|
|
+ const char *options);
|
|
+
|
|
+META_EXPORT
|
|
+MetaKeymapDescription * meta_keymap_description_ref (MetaKeymapDescription *keymap_description);
|
|
+
|
|
+META_EXPORT
|
|
+void meta_keymap_description_unref (MetaKeymapDescription *keymap_description);
|
|
+
|
|
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKeymapDescription,
|
|
+ meta_keymap_description_unref);
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index bca99da74d..8d93dababf 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -110,6 +110,7 @@ meta_test_native_keyboard_map_set_async (void)
|
|
1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_ALT);
|
|
ModMaskTuple expected_mods = { alt_mask, 0, 0 };
|
|
ModMaskTuple *expected_mods_ptr = &expected_mods;
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
struct xkb_keymap *new_xkb_keymap;
|
|
gboolean done = FALSE;
|
|
gpointer expected_next_handler;
|
|
@@ -155,11 +156,13 @@ meta_test_native_keyboard_map_set_async (void)
|
|
&expected_next_handler);
|
|
|
|
expected_next_handler = (gpointer) on_keymap_changed;
|
|
- meta_backend_set_keymap_async (backend,
|
|
- "us",
|
|
- "dvorak-alt-intl",
|
|
- NULL, NULL, NULL,
|
|
- set_keymap_cb, &done);
|
|
+ keymap_description =
|
|
+ meta_keymap_description_new_from_rules (NULL,
|
|
+ "us",
|
|
+ "dvorak-alt-intl",
|
|
+ NULL);
|
|
+ meta_backend_set_keymap_async (backend, keymap_description,
|
|
+ NULL, set_keymap_cb, &done);
|
|
|
|
g_assert_true (xkb_keymap == meta_backend_get_keymap (backend));
|
|
|
|
@@ -191,9 +194,9 @@ meta_test_native_keyboard_map_change_layout (void)
|
|
{
|
|
MetaBackend *backend = meta_context_get_backend (test_context);
|
|
ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
|
-
|
|
g_autoptr (ClutterVirtualInputDevice) virtual_keyboard = NULL;
|
|
struct xkb_keymap *xkb_keymap = meta_backend_get_keymap (backend);
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
struct xkb_keymap *new_xkb_keymap;
|
|
gboolean done = FALSE;
|
|
|
|
@@ -202,12 +205,13 @@ meta_test_native_keyboard_map_change_layout (void)
|
|
|
|
xkb_keymap_ref (xkb_keymap);
|
|
|
|
- meta_backend_set_keymap_async (backend,
|
|
- "us,ua",
|
|
- NULL,
|
|
- "grp:caps_select",
|
|
- NULL, NULL,
|
|
- set_keymap_cb, &done);
|
|
+ keymap_description =
|
|
+ meta_keymap_description_new_from_rules (NULL,
|
|
+ "us,ua",
|
|
+ NULL,
|
|
+ "grp:caps_select");
|
|
+ meta_backend_set_keymap_async (backend, keymap_description,
|
|
+ NULL, set_keymap_cb, &done);
|
|
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
@@ -279,14 +283,17 @@ static void
|
|
meta_test_native_keyboard_map_set_layout_index (void)
|
|
{
|
|
MetaBackend *backend = meta_context_get_backend (test_context);
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
gboolean done = FALSE;
|
|
struct xkb_keymap *keymap;
|
|
|
|
- meta_backend_set_keymap_async (backend,
|
|
- "us,se",
|
|
- "dvorak-alt-intl,svdvorak",
|
|
- NULL, NULL, NULL,
|
|
- set_keymap_cb, &done);
|
|
+ keymap_description =
|
|
+ meta_keymap_description_new_from_rules (NULL,
|
|
+ "us,se",
|
|
+ "dvorak-alt-intl,svdvorak",
|
|
+ NULL);
|
|
+ meta_backend_set_keymap_async (backend, keymap_description,
|
|
+ NULL, set_keymap_cb, &done);
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
diff --git a/src/tests/remote-desktop-tests.c b/src/tests/remote-desktop-tests.c
|
|
index d006cecdda..04979afa66 100644
|
|
--- a/src/tests/remote-desktop-tests.c
|
|
+++ b/src/tests/remote-desktop-tests.c
|
|
@@ -70,12 +70,17 @@ remote_desktop_test_client_command (int argc,
|
|
const char *layout = argv[1];
|
|
const char *variant = argv[2];
|
|
g_autoptr (GMainContext) main_context = NULL;
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
gboolean done = FALSE;
|
|
|
|
g_debug ("Switching keyboard layout to %s, %s", layout, variant);
|
|
main_context = g_main_context_new ();
|
|
g_main_context_push_thread_default (main_context);
|
|
- meta_backend_set_keymap_async (backend, layout, variant, "", "",
|
|
+ keymap_description = meta_keymap_description_new_from_rules (NULL,
|
|
+ layout,
|
|
+ variant,
|
|
+ NULL);
|
|
+ meta_backend_set_keymap_async (backend, keymap_description,
|
|
NULL, set_keymap_cb, &done);
|
|
while (!done)
|
|
g_main_context_iteration (main_context, TRUE);
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From d2a5ffe3f926391a80fee07e4a5f1dfc5dd8b033 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 1 Oct 2025 17:14:12 +0200
|
|
Subject: [PATCH 07/32] keymap-description: Add helper for creating xkb_keymap
|
|
instances
|
|
|
|
Will be useful when there are different description sources and not only
|
|
rules based methods of creating a keymap.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 138bffbd16e84143e4d2f3a8db3875a5da5f1bc6)
|
|
---
|
|
.../meta-keymap-description-private.h | 3 ++
|
|
src/backends/meta-keymap-description.c | 37 +++++++++++++++++++
|
|
2 files changed, 40 insertions(+)
|
|
|
|
diff --git a/src/backends/meta-keymap-description-private.h b/src/backends/meta-keymap-description-private.h
|
|
index 2e9a6f8e45..47e2234322 100644
|
|
--- a/src/backends/meta-keymap-description-private.h
|
|
+++ b/src/backends/meta-keymap-description-private.h
|
|
@@ -25,3 +25,6 @@ void meta_keymap_description_get_rules (MetaKeymapDescription *keymap_descripti
|
|
char **layout,
|
|
char **variant,
|
|
char **options);
|
|
+
|
|
+struct xkb_keymap * meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_description,
|
|
+ GError **error);
|
|
diff --git a/src/backends/meta-keymap-description.c b/src/backends/meta-keymap-description.c
|
|
index 081fcf64d0..39af564a0c 100644
|
|
--- a/src/backends/meta-keymap-description.c
|
|
+++ b/src/backends/meta-keymap-description.c
|
|
@@ -99,3 +99,40 @@ meta_keymap_description_get_rules (MetaKeymapDescription *keymap_description,
|
|
*variant = g_strdup (keymap_description->variant);
|
|
*options = g_strdup (keymap_description->options);
|
|
}
|
|
+
|
|
+struct xkb_keymap *
|
|
+meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_description,
|
|
+ GError **error)
|
|
+{
|
|
+ struct xkb_rule_names names;
|
|
+ struct xkb_context *xkb_context;
|
|
+ struct xkb_keymap *xkb_keymap;
|
|
+
|
|
+ names.rules = DEFAULT_XKB_RULES_FILE;
|
|
+ names.model = keymap_description->model;
|
|
+ names.layout = keymap_description->layout;
|
|
+ names.variant = keymap_description->variant;
|
|
+ names.options = keymap_description->options;
|
|
+
|
|
+ xkb_context = meta_create_xkb_context ();
|
|
+ xkb_keymap = xkb_keymap_new_from_names (xkb_context,
|
|
+ &names,
|
|
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
+ xkb_context_unref (xkb_context);
|
|
+
|
|
+ if (!xkb_keymap)
|
|
+ {
|
|
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
+ "Failed to create XKB keymap with "
|
|
+ "rules=%s, model=%s, layout=%s, "
|
|
+ "variant=%s, options=%s",
|
|
+ keymap_description->rules,
|
|
+ keymap_description->model,
|
|
+ keymap_description->layout,
|
|
+ keymap_description->variant,
|
|
+ keymap_description->options);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return xkb_keymap;
|
|
+}
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From dae726791082e3e4b37c720f368c30aaca299ad5 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 1 Oct 2025 17:12:38 +0200
|
|
Subject: [PATCH 08/32] seat/native: Use new xkb_keymap constructor from
|
|
description
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 5fc5f363805e54c7c3fbf890b1539a72438ab9ad)
|
|
---
|
|
.../meta-keymap-description-private.h | 6 ---
|
|
src/backends/meta-keymap-description.c | 13 -----
|
|
src/backends/native/meta-seat-native.c | 51 ++++---------------
|
|
3 files changed, 10 insertions(+), 60 deletions(-)
|
|
|
|
diff --git a/src/backends/meta-keymap-description-private.h b/src/backends/meta-keymap-description-private.h
|
|
index 47e2234322..3cacfe6561 100644
|
|
--- a/src/backends/meta-keymap-description-private.h
|
|
+++ b/src/backends/meta-keymap-description-private.h
|
|
@@ -20,11 +20,5 @@
|
|
|
|
#include "meta/meta-keymap-description.h"
|
|
|
|
-void meta_keymap_description_get_rules (MetaKeymapDescription *keymap_description,
|
|
- char **model,
|
|
- char **layout,
|
|
- char **variant,
|
|
- char **options);
|
|
-
|
|
struct xkb_keymap * meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_description,
|
|
GError **error);
|
|
diff --git a/src/backends/meta-keymap-description.c b/src/backends/meta-keymap-description.c
|
|
index 39af564a0c..cd93c543e3 100644
|
|
--- a/src/backends/meta-keymap-description.c
|
|
+++ b/src/backends/meta-keymap-description.c
|
|
@@ -87,19 +87,6 @@ meta_keymap_description_unref (MetaKeymapDescription *keymap_description)
|
|
}
|
|
}
|
|
|
|
-void
|
|
-meta_keymap_description_get_rules (MetaKeymapDescription *keymap_description,
|
|
- char **model,
|
|
- char **layout,
|
|
- char **variant,
|
|
- char **options)
|
|
-{
|
|
- *model = g_strdup (keymap_description->model);
|
|
- *layout = g_strdup (keymap_description->layout);
|
|
- *variant = g_strdup (keymap_description->variant);
|
|
- *options = g_strdup (keymap_description->options);
|
|
-}
|
|
-
|
|
struct xkb_keymap *
|
|
meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_description,
|
|
GError **error)
|
|
diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c
|
|
index 63392531cd..905fa13ce0 100644
|
|
--- a/src/backends/native/meta-seat-native.c
|
|
+++ b/src/backends/native/meta-seat-native.c
|
|
@@ -513,29 +513,6 @@ meta_seat_native_reclaim_devices (MetaSeatNative *seat)
|
|
seat->released = FALSE;
|
|
}
|
|
|
|
-static struct xkb_keymap *
|
|
-create_keymap (const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model)
|
|
-{
|
|
- struct xkb_rule_names names;
|
|
- struct xkb_keymap *keymap;
|
|
- struct xkb_context *context;
|
|
-
|
|
- names.rules = DEFAULT_XKB_RULES_FILE;
|
|
- names.model = model;
|
|
- names.layout = layouts;
|
|
- names.variant = variants;
|
|
- names.options = options;
|
|
-
|
|
- context = meta_create_xkb_context ();
|
|
- keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
- xkb_context_unref (context);
|
|
-
|
|
- return keymap;
|
|
-}
|
|
-
|
|
gboolean
|
|
meta_seat_native_set_keyboard_map_finish (MetaSeatNative *seat_native,
|
|
GAsyncResult *result,
|
|
@@ -595,30 +572,22 @@ meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
{
|
|
g_autoptr (GTask) task = NULL;
|
|
struct xkb_keymap *keymap, *impl_keymap;
|
|
- g_autofree char *layouts = NULL;
|
|
- g_autofree char *variants = NULL;
|
|
- g_autofree char *options = NULL;
|
|
- g_autofree char *model = NULL;
|
|
+ g_autoptr (GError) error = NULL;
|
|
|
|
task = g_task_new (G_OBJECT (seat), cancellable, callback, user_data);
|
|
g_task_set_source_tag (task, meta_seat_native_set_keyboard_map_async);
|
|
|
|
- meta_keymap_description_get_rules (description,
|
|
- &model,
|
|
- &layouts,
|
|
- &variants,
|
|
- &options);
|
|
- keymap = create_keymap (layouts, variants, options, model);
|
|
- impl_keymap = create_keymap (layouts, variants, options, model);
|
|
-
|
|
+ keymap = meta_keymap_description_create_xkb_keymap (description, &error);
|
|
if (keymap == NULL)
|
|
{
|
|
- g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
- "Unable to load configured keymap: "
|
|
- "rules=%s, model=%s, ""layout=%s, "
|
|
- "variant=%s, options=%s",
|
|
- DEFAULT_XKB_RULES_FILE, model, layouts,
|
|
- variants, options);
|
|
+ g_task_return_error (task, g_steal_pointer (&error));
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ impl_keymap = meta_keymap_description_create_xkb_keymap (description, &error);
|
|
+ if (impl_keymap == NULL)
|
|
+ {
|
|
+ g_task_return_error (task, g_steal_pointer (&error));
|
|
return;
|
|
}
|
|
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 520b5a3d4f46900506a1e0df3cd1dfcf7699a008 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 1 Oct 2025 21:36:32 +0200
|
|
Subject: [PATCH 09/32] keybindings: Create xkb_keymap from keymap description
|
|
|
|
This hides xkb_keymap specific details out of sight.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit e0d847357951f107790c421eb772c7ab89be6834)
|
|
---
|
|
src/core/keybindings.c | 26 ++++++++++++++------------
|
|
1 file changed, 14 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
|
|
index 551a156e50..0f475eae3b 100644
|
|
--- a/src/core/keybindings.c
|
|
+++ b/src/core/keybindings.c
|
|
@@ -30,7 +30,7 @@
|
|
#include "config.h"
|
|
|
|
#include "backends/meta-backend-private.h"
|
|
-#include "backends/meta-keymap-utils.h"
|
|
+#include "backends/meta-keymap-description-private.h"
|
|
#include "backends/meta-logical-monitor-private.h"
|
|
#include "backends/meta-monitor-manager-private.h"
|
|
#include "compositor/compositor-private.h"
|
|
@@ -766,19 +766,21 @@ clear_active_keyboard_layouts (MetaKeyBindingManager *keys)
|
|
static MetaKeyBindingKeyboardLayout
|
|
create_us_layout (void)
|
|
{
|
|
- struct xkb_rule_names names;
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
+ g_autoptr (GError) error = NULL;
|
|
struct xkb_keymap *keymap;
|
|
- struct xkb_context *context;
|
|
|
|
- names.rules = DEFAULT_XKB_RULES_FILE;
|
|
- names.model = DEFAULT_XKB_MODEL;
|
|
- names.layout = "us";
|
|
- names.variant = "";
|
|
- names.options = "";
|
|
-
|
|
- context = meta_create_xkb_context ();
|
|
- keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
- xkb_context_unref (context);
|
|
+ keymap_description = meta_keymap_description_new_from_rules (NULL,
|
|
+ "us",
|
|
+ NULL,
|
|
+ NULL);
|
|
+ keymap = meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
+ &error);
|
|
+ if (!keymap)
|
|
+ {
|
|
+ g_warning ("Failed to create us keybinding layout: %s", error->message);
|
|
+ return (MetaKeyBindingKeyboardLayout) {};
|
|
+ }
|
|
|
|
return (MetaKeyBindingKeyboardLayout) {
|
|
.keymap = keymap,
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 505c26321ac34934eb45c2555090ece23ca751e4 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 1 Oct 2025 21:11:50 +0200
|
|
Subject: [PATCH 10/32] seat/native: Pass keymap description instead of
|
|
xkb_keymap
|
|
|
|
This means the description is available in places it will later be
|
|
useful to have. Right now, there are no functional changes.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 9df69e82ada1dc620c71d12faca3ffb36f9525e9)
|
|
---
|
|
src/backends/native/meta-seat-impl.c | 37 +++++++++++++++++---------
|
|
src/backends/native/meta-seat-impl.h | 10 +++----
|
|
src/backends/native/meta-seat-native.c | 33 ++++++++++-------------
|
|
3 files changed, 44 insertions(+), 36 deletions(-)
|
|
|
|
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
|
|
index 0a6aae3cf0..f89dfc90d9 100644
|
|
--- a/src/backends/native/meta-seat-impl.c
|
|
+++ b/src/backends/native/meta-seat-impl.c
|
|
@@ -35,6 +35,7 @@
|
|
|
|
#include "backends/meta-cursor-tracker-private.h"
|
|
#include "backends/meta-fd-source.h"
|
|
+#include "backends/meta-keymap-description-private.h"
|
|
#include "backends/native/meta-backend-native-private.h"
|
|
#include "backends/native/meta-barrier-native.h"
|
|
#include "backends/native/meta-device-pool.h"
|
|
@@ -3819,16 +3820,28 @@ static gboolean
|
|
set_keyboard_map (GTask *task)
|
|
{
|
|
MetaSeatImpl *seat_impl = g_task_get_source_object (task);
|
|
- struct xkb_keymap *xkb_keymap = g_task_get_task_data (task);
|
|
+ MetaKeymapDescription *keymap_description = g_task_get_task_data (task);
|
|
MetaKeymapNative *keymap;
|
|
+ g_autoptr (GError) error = NULL;
|
|
+ struct xkb_keymap *xkb_keymap;
|
|
+
|
|
+ g_task_set_priority (task, G_PRIORITY_HIGH);
|
|
|
|
keymap = seat_impl->keymap;
|
|
- meta_keymap_native_set_keyboard_map_in_impl (keymap, xkb_keymap);
|
|
|
|
- g_task_set_priority (task, G_PRIORITY_HIGH);
|
|
- g_task_return_boolean (task, TRUE);
|
|
+ xkb_keymap = meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
+ &error);
|
|
+ if (!xkb_keymap)
|
|
+ {
|
|
+ g_prefix_error (&error, "Unable to load configured keymap: ");
|
|
+ g_task_return_error (task, g_steal_pointer (&error));
|
|
+ return G_SOURCE_REMOVE;
|
|
+ }
|
|
+
|
|
+ meta_keymap_native_set_keyboard_map_in_impl (keymap, xkb_keymap);
|
|
|
|
meta_seat_impl_update_xkb_state_in_impl (seat_impl);
|
|
+ g_task_return_boolean (task, TRUE);
|
|
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
@@ -3847,22 +3860,22 @@ set_keyboard_map (GTask *task)
|
|
* is pressed when calling this function.
|
|
*/
|
|
void
|
|
-meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
- struct xkb_keymap *xkb_keymap,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data)
|
|
+meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
+ MetaKeymapDescription *keymap_description,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data)
|
|
{
|
|
GTask *task;
|
|
|
|
g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
|
|
- g_return_if_fail (xkb_keymap != NULL);
|
|
+ g_return_if_fail (keymap_description);
|
|
|
|
task = g_task_new (seat_impl, cancellable, callback, user_data);
|
|
g_task_set_source_tag (task, meta_seat_impl_set_keyboard_map_async);
|
|
g_task_set_task_data (task,
|
|
- xkb_keymap_ref (xkb_keymap),
|
|
- (GDestroyNotify) xkb_keymap_unref);
|
|
+ meta_keymap_description_ref (keymap_description),
|
|
+ (GDestroyNotify) meta_keymap_description_unref);
|
|
meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) set_keyboard_map);
|
|
g_object_unref (task);
|
|
}
|
|
diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h
|
|
index 24d0405062..3637627a67 100644
|
|
--- a/src/backends/native/meta-seat-impl.h
|
|
+++ b/src/backends/native/meta-seat-impl.h
|
|
@@ -189,11 +189,11 @@ gboolean meta_seat_impl_set_keyboard_map_finish (MetaSeatImpl *seat_impl,
|
|
GAsyncResult *result,
|
|
GError **error);
|
|
|
|
-void meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
- struct xkb_keymap *keymap,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data);
|
|
+void meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
+ MetaKeymapDescription *keymap_description,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data);
|
|
|
|
gboolean meta_seat_impl_set_keyboard_layout_index_finish (MetaSeatImpl *seat_impl,
|
|
GAsyncResult *result,
|
|
diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c
|
|
index 905fa13ce0..dc2e6683a4 100644
|
|
--- a/src/backends/native/meta-seat-native.c
|
|
+++ b/src/backends/native/meta-seat-native.c
|
|
@@ -536,6 +536,7 @@ set_impl_keyboard_map_cb (GObject *source_object,
|
|
g_autoptr (GTask) task = G_TASK (user_data);
|
|
g_autoptr (GError) error = NULL;
|
|
MetaSeatNative *seat_native;
|
|
+ MetaKeymapDescription *keymap_description;
|
|
struct xkb_keymap *keymap;
|
|
|
|
if (!meta_seat_impl_set_keyboard_map_finish (seat_impl, result, &error))
|
|
@@ -545,7 +546,14 @@ set_impl_keyboard_map_cb (GObject *source_object,
|
|
}
|
|
|
|
seat_native = META_SEAT_NATIVE (g_task_get_source_object (task));
|
|
- keymap = g_task_get_task_data (task);
|
|
+ keymap_description = g_task_get_task_data (task);
|
|
+ keymap = meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
+ &error);
|
|
+ if (!keymap)
|
|
+ {
|
|
+ g_task_return_error (task, g_steal_pointer (&error));
|
|
+ return;
|
|
+ }
|
|
|
|
g_clear_pointer (&seat_native->xkb_keymap, xkb_keymap_unref);
|
|
seat_native->xkb_keymap = xkb_keymap_ref (keymap);
|
|
@@ -571,33 +579,20 @@ meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
gpointer user_data)
|
|
{
|
|
g_autoptr (GTask) task = NULL;
|
|
- struct xkb_keymap *keymap, *impl_keymap;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
task = g_task_new (G_OBJECT (seat), cancellable, callback, user_data);
|
|
g_task_set_source_tag (task, meta_seat_native_set_keyboard_map_async);
|
|
|
|
- keymap = meta_keymap_description_create_xkb_keymap (description, &error);
|
|
- if (keymap == NULL)
|
|
- {
|
|
- g_task_return_error (task, g_steal_pointer (&error));
|
|
- return;
|
|
- }
|
|
-
|
|
- impl_keymap = meta_keymap_description_create_xkb_keymap (description, &error);
|
|
- if (impl_keymap == NULL)
|
|
- {
|
|
- g_task_return_error (task, g_steal_pointer (&error));
|
|
- return;
|
|
- }
|
|
-
|
|
- g_task_set_task_data (task, keymap, (GDestroyNotify) xkb_keymap_unref);
|
|
+ g_task_set_task_data (task,
|
|
+ meta_keymap_description_ref (description),
|
|
+ (GDestroyNotify) meta_keymap_description_unref);
|
|
|
|
- meta_seat_impl_set_keyboard_map_async (seat->impl, impl_keymap,
|
|
+ meta_seat_impl_set_keyboard_map_async (seat->impl,
|
|
+ description,
|
|
cancellable,
|
|
set_impl_keyboard_map_cb,
|
|
g_object_ref (task));
|
|
- xkb_keymap_unref (impl_keymap);
|
|
}
|
|
|
|
static void
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 248e82f10e7f12b2bb86bc4659d5992c89ea641e Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Mon, 6 Oct 2025 11:41:07 +0200
|
|
Subject: [PATCH 11/32] tests/remote-desktop-tests: Don't use nested context
|
|
when setting keymap
|
|
|
|
This will fail when the keymap related state is set via signals that
|
|
gets emitted from callbacks from the impl thread, that won't know about
|
|
the current thread default context.
|
|
|
|
It should also be harmless, we won't read the next line until the
|
|
function returns, so there should be no risk of re-entry.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 2509ba34aad134ecfc9ad33dcfe939c8dd0bc161)
|
|
---
|
|
src/tests/remote-desktop-tests.c | 6 +-----
|
|
1 file changed, 1 insertion(+), 5 deletions(-)
|
|
|
|
diff --git a/src/tests/remote-desktop-tests.c b/src/tests/remote-desktop-tests.c
|
|
index 04979afa66..a2ce8ce388 100644
|
|
--- a/src/tests/remote-desktop-tests.c
|
|
+++ b/src/tests/remote-desktop-tests.c
|
|
@@ -69,13 +69,10 @@ remote_desktop_test_client_command (int argc,
|
|
MetaBackend *backend = meta_context_get_backend (test_context);
|
|
const char *layout = argv[1];
|
|
const char *variant = argv[2];
|
|
- g_autoptr (GMainContext) main_context = NULL;
|
|
g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
gboolean done = FALSE;
|
|
|
|
g_debug ("Switching keyboard layout to %s, %s", layout, variant);
|
|
- main_context = g_main_context_new ();
|
|
- g_main_context_push_thread_default (main_context);
|
|
keymap_description = meta_keymap_description_new_from_rules (NULL,
|
|
layout,
|
|
variant,
|
|
@@ -83,8 +80,7 @@ remote_desktop_test_client_command (int argc,
|
|
meta_backend_set_keymap_async (backend, keymap_description,
|
|
NULL, set_keymap_cb, &done);
|
|
while (!done)
|
|
- g_main_context_iteration (main_context, TRUE);
|
|
- g_main_context_pop_thread_default (main_context);
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
|
|
return TRUE;
|
|
}
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 60efa23fa5efe2ca105aef4fa21c653beec30f2c Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Thu, 2 Oct 2025 21:49:24 +0200
|
|
Subject: [PATCH 12/32] backend/native: Emit 'keymap-changed' via signal on the
|
|
ClutterKeymap
|
|
|
|
This will allow proper ordering of events (keymap & layout index
|
|
changes) if the index also changes at the same time as the keymap.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit ce7f26e16f5e2e7c4e73e2936818f8b528c1b37d)
|
|
---
|
|
src/backends/native/meta-backend-native.c | 10 +-
|
|
.../native/meta-keymap-native-private.h | 6 +-
|
|
src/backends/native/meta-keymap-native.c | 61 ++++++++-
|
|
src/backends/native/meta-seat-impl.c | 5 +-
|
|
src/backends/native/meta-seat-native.c | 126 +++++++++++++-----
|
|
src/backends/native/meta-seat-native.h | 1 +
|
|
6 files changed, 164 insertions(+), 45 deletions(-)
|
|
|
|
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
|
|
index 3e39efb098..95dbfca41e 100644
|
|
--- a/src/backends/native/meta-backend-native.c
|
|
+++ b/src/backends/native/meta-backend-native.c
|
|
@@ -207,6 +207,7 @@ meta_backend_native_init_post (MetaBackend *backend,
|
|
MetaMonitorManager *monitor_manager =
|
|
meta_backend_get_monitor_manager (backend);
|
|
MetaA11yManager *a11y_manager = meta_backend_get_a11y_manager (backend);
|
|
+ ClutterSeat *seat;
|
|
|
|
g_clear_pointer (&priv->startup_render_devices,
|
|
g_hash_table_unref);
|
|
@@ -225,6 +226,11 @@ meta_backend_native_init_post (MetaBackend *backend,
|
|
"backend", backend,
|
|
NULL);
|
|
|
|
+ seat = meta_backend_get_default_seat (backend);
|
|
+ g_signal_connect_swapped (seat, "keymap-changed",
|
|
+ G_CALLBACK (meta_backend_notify_keymap_changed),
|
|
+ backend);
|
|
+
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -319,7 +325,6 @@ set_keyboard_map_cb (GObject *source_object,
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (source_object);
|
|
g_autoptr (GTask) task = G_TASK (user_data);
|
|
g_autoptr (GError) error = NULL;
|
|
- MetaBackend *backend;
|
|
|
|
if (!meta_seat_native_set_keyboard_map_finish (seat_native, result, &error))
|
|
{
|
|
@@ -327,9 +332,6 @@ set_keyboard_map_cb (GObject *source_object,
|
|
return;
|
|
}
|
|
|
|
- backend = META_BACKEND (g_task_get_source_object (task));
|
|
- meta_backend_notify_keymap_changed (backend);
|
|
-
|
|
g_task_return_boolean (task, TRUE);
|
|
}
|
|
|
|
diff --git a/src/backends/native/meta-keymap-native-private.h b/src/backends/native/meta-keymap-native-private.h
|
|
index 318485a102..2084393d5f 100644
|
|
--- a/src/backends/native/meta-keymap-native-private.h
|
|
+++ b/src/backends/native/meta-keymap-native-private.h
|
|
@@ -25,8 +25,10 @@
|
|
#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h""
|
|
#endif /* META_INPUT_THREAD_H_INSIDE */
|
|
|
|
-void meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
- struct xkb_keymap *xkb_keymap);
|
|
+void meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
+ MetaSeatImpl *seat_impl,
|
|
+ MetaKeymapDescription *keymap_description,
|
|
+ struct xkb_keymap *xkb_keymap);
|
|
|
|
struct xkb_keymap * meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap);
|
|
|
|
diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c
|
|
index 8d1d804c12..770f0cb0d0 100644
|
|
--- a/src/backends/native/meta-keymap-native.c
|
|
+++ b/src/backends/native/meta-keymap-native.c
|
|
@@ -29,6 +29,15 @@ static const char *option_xkb_layout = "us";
|
|
static const char *option_xkb_variant = "";
|
|
static const char *option_xkb_options = "";
|
|
|
|
+enum
|
|
+{
|
|
+ KEYMAP_CHANGED,
|
|
+
|
|
+ N_SIGNALS
|
|
+};
|
|
+
|
|
+static guint signals[N_SIGNALS] = { 0, };
|
|
+
|
|
typedef struct _MetaKeymapNative MetaKeymapNative;
|
|
|
|
struct _MetaKeymapNative
|
|
@@ -68,6 +77,14 @@ meta_keymap_native_class_init (MetaKeymapNativeClass *klass)
|
|
object_class->finalize = meta_keymap_native_finalize;
|
|
|
|
keymap_class->get_direction = meta_keymap_native_get_direction;
|
|
+
|
|
+ signals[KEYMAP_CHANGED] =
|
|
+ g_signal_new ("keymap-changed",
|
|
+ G_TYPE_FROM_CLASS (klass),
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ 0, NULL, NULL, NULL,
|
|
+ G_TYPE_NONE, 1,
|
|
+ META_TYPE_KEYMAP_DESCRIPTION);
|
|
}
|
|
|
|
static void
|
|
@@ -88,14 +105,54 @@ meta_keymap_native_init (MetaKeymapNative *keymap)
|
|
xkb_context_unref (ctx);
|
|
}
|
|
|
|
+typedef struct
|
|
+{
|
|
+ MetaKeymapNative *keymap_native;
|
|
+
|
|
+ MetaKeymapDescription *keymap_description;
|
|
+} UpdateKeymapData;
|
|
+
|
|
+static void
|
|
+update_keymap_data_free (gpointer user_data)
|
|
+{
|
|
+ UpdateKeymapData *data = user_data;
|
|
+
|
|
+ meta_keymap_description_unref (data->keymap_description);
|
|
+ g_free (data);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+update_keymap_in_main (gpointer user_data)
|
|
+{
|
|
+ UpdateKeymapData *data = user_data;
|
|
+ MetaKeymapNative *keymap_native = data->keymap_native;
|
|
+
|
|
+ g_signal_emit (keymap_native, signals[KEYMAP_CHANGED], 0,
|
|
+ data->keymap_description);
|
|
+
|
|
+ return G_SOURCE_REMOVE;
|
|
+}
|
|
+
|
|
void
|
|
-meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
- struct xkb_keymap *xkb_keymap)
|
|
+meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
+ MetaSeatImpl *seat_impl,
|
|
+ MetaKeymapDescription *keymap_description,
|
|
+ struct xkb_keymap *xkb_keymap)
|
|
{
|
|
+ UpdateKeymapData *data;
|
|
+
|
|
g_return_if_fail (xkb_keymap != NULL);
|
|
|
|
g_clear_pointer (&keymap->impl.keymap, xkb_keymap_unref);
|
|
keymap->impl.keymap = xkb_keymap_ref (xkb_keymap);
|
|
+
|
|
+ data = g_new0 (UpdateKeymapData, 1);
|
|
+ data->keymap_native = keymap;
|
|
+ data->keymap_description = meta_keymap_description_ref (keymap_description);
|
|
+
|
|
+ meta_seat_impl_queue_main_thread_idle (seat_impl,
|
|
+ update_keymap_in_main,
|
|
+ data, update_keymap_data_free);
|
|
}
|
|
|
|
struct xkb_keymap *
|
|
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
|
|
index f89dfc90d9..1a54cfe00c 100644
|
|
--- a/src/backends/native/meta-seat-impl.c
|
|
+++ b/src/backends/native/meta-seat-impl.c
|
|
@@ -3838,7 +3838,10 @@ set_keyboard_map (GTask *task)
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
|
|
- meta_keymap_native_set_keyboard_map_in_impl (keymap, xkb_keymap);
|
|
+ meta_keymap_native_set_keyboard_map_in_impl (keymap,
|
|
+ seat_impl,
|
|
+ keymap_description,
|
|
+ xkb_keymap);
|
|
|
|
meta_seat_impl_update_xkb_state_in_impl (seat_impl);
|
|
g_task_return_boolean (task, TRUE);
|
|
diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c
|
|
index dc2e6683a4..9be0bd7ce1 100644
|
|
--- a/src/backends/native/meta-seat-native.c
|
|
+++ b/src/backends/native/meta-seat-native.c
|
|
@@ -55,6 +55,15 @@ enum
|
|
|
|
static GParamSpec *props[N_PROPS] = { NULL };
|
|
|
|
+enum
|
|
+{
|
|
+ KEYMAP_CHANGED,
|
|
+
|
|
+ N_SIGNALS
|
|
+};
|
|
+
|
|
+static guint signals[N_SIGNALS];
|
|
+
|
|
G_DEFINE_TYPE (MetaSeatNative, meta_seat_native, CLUTTER_TYPE_SEAT)
|
|
|
|
static gboolean meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
@@ -150,12 +159,44 @@ keymap_state_changed_cb (MetaSeatNative *seat_native,
|
|
}
|
|
}
|
|
|
|
+static void
|
|
+on_keymap_changed (MetaKeymapNative *keymap_native,
|
|
+ MetaKeymapDescription *keymap_description,
|
|
+ MetaSeatNative *seat_native)
|
|
+{
|
|
+ g_autoptr (GError) error = NULL;
|
|
+ struct xkb_keymap *xkb_keymap;
|
|
+
|
|
+ if (seat_native->keymap_description == keymap_description)
|
|
+ return;
|
|
+
|
|
+ xkb_keymap =
|
|
+ meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
+ &error);
|
|
+ if (!xkb_keymap)
|
|
+ {
|
|
+ g_warning ("Failed to create xkb_keymap for seat: %s", error->message);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ g_clear_pointer (&seat_native->keymap_description,
|
|
+ meta_keymap_description_unref);
|
|
+ seat_native->keymap_description =
|
|
+ meta_keymap_description_ref (keymap_description);
|
|
+
|
|
+ g_clear_pointer (&seat_native->xkb_keymap, xkb_keymap_unref);
|
|
+ seat_native->xkb_keymap = xkb_keymap;
|
|
+
|
|
+ g_signal_emit (seat_native, signals[KEYMAP_CHANGED], 0);
|
|
+}
|
|
+
|
|
static void
|
|
meta_seat_native_constructed (GObject *object)
|
|
{
|
|
MetaSeatNative *seat = META_SEAT_NATIVE (object);
|
|
g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
+ ClutterKeymap *keymap;
|
|
|
|
seat->impl = meta_seat_impl_new (seat, seat->seat_id, seat->flags);
|
|
meta_seat_impl_setup (seat->impl);
|
|
@@ -171,6 +212,10 @@ meta_seat_native_constructed (GObject *object)
|
|
seat->core_pointer = meta_seat_impl_get_pointer (seat->impl);
|
|
seat->core_keyboard = meta_seat_impl_get_keyboard (seat->impl);
|
|
|
|
+ keymap = clutter_seat_get_keymap (CLUTTER_SEAT (seat));
|
|
+ g_signal_connect (keymap, "keymap-changed",
|
|
+ G_CALLBACK (on_keymap_changed), seat);
|
|
+
|
|
keymap_description = meta_keymap_description_new_from_rules (NULL,
|
|
"us",
|
|
NULL,
|
|
@@ -241,6 +286,8 @@ meta_seat_native_dispose (GObject *object)
|
|
{
|
|
MetaSeatNative *seat = META_SEAT_NATIVE (object);
|
|
|
|
+ g_clear_pointer (&seat->keymap_description,
|
|
+ meta_keymap_description_unref);
|
|
g_clear_pointer (&seat->xkb_keymap, xkb_keymap_unref);
|
|
g_clear_object (&seat->core_pointer);
|
|
g_clear_object (&seat->core_keyboard);
|
|
@@ -447,6 +494,13 @@ meta_seat_native_class_init (MetaSeatNativeClass *klass)
|
|
|
|
g_object_class_override_property (object_class, PROP_TOUCH_MODE,
|
|
"touch-mode");
|
|
+
|
|
+ signals[KEYMAP_CHANGED] =
|
|
+ g_signal_new ("keymap-changed",
|
|
+ G_TYPE_FROM_CLASS (klass),
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ 0, NULL, NULL, NULL,
|
|
+ G_TYPE_NONE, 0);
|
|
}
|
|
|
|
static void
|
|
@@ -535,9 +589,6 @@ set_impl_keyboard_map_cb (GObject *source_object,
|
|
MetaSeatImpl *seat_impl = META_SEAT_IMPL (source_object);
|
|
g_autoptr (GTask) task = G_TASK (user_data);
|
|
g_autoptr (GError) error = NULL;
|
|
- MetaSeatNative *seat_native;
|
|
- MetaKeymapDescription *keymap_description;
|
|
- struct xkb_keymap *keymap;
|
|
|
|
if (!meta_seat_impl_set_keyboard_map_finish (seat_impl, result, &error))
|
|
{
|
|
@@ -545,19 +596,6 @@ set_impl_keyboard_map_cb (GObject *source_object,
|
|
return;
|
|
}
|
|
|
|
- seat_native = META_SEAT_NATIVE (g_task_get_source_object (task));
|
|
- keymap_description = g_task_get_task_data (task);
|
|
- keymap = meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
- &error);
|
|
- if (!keymap)
|
|
- {
|
|
- g_task_return_error (task, g_steal_pointer (&error));
|
|
- return;
|
|
- }
|
|
-
|
|
- g_clear_pointer (&seat_native->xkb_keymap, xkb_keymap_unref);
|
|
- seat_native->xkb_keymap = xkb_keymap_ref (keymap);
|
|
-
|
|
g_task_return_boolean (task, TRUE);
|
|
}
|
|
|
|
@@ -579,15 +617,10 @@ meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
gpointer user_data)
|
|
{
|
|
g_autoptr (GTask) task = NULL;
|
|
- g_autoptr (GError) error = NULL;
|
|
|
|
task = g_task_new (G_OBJECT (seat), cancellable, callback, user_data);
|
|
g_task_set_source_tag (task, meta_seat_native_set_keyboard_map_async);
|
|
|
|
- g_task_set_task_data (task,
|
|
- meta_keymap_description_ref (description),
|
|
- (GDestroyNotify) meta_keymap_description_unref);
|
|
-
|
|
meta_seat_impl_set_keyboard_map_async (seat->impl,
|
|
description,
|
|
cancellable,
|
|
@@ -596,20 +629,23 @@ meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
}
|
|
|
|
static void
|
|
-set_keyboard_map_cb (GObject *source_object,
|
|
- GAsyncResult *result,
|
|
- gpointer user_data)
|
|
+sync_set_impl_keyboard_map_cb (GObject *source_object,
|
|
+ GAsyncResult *result,
|
|
+ gpointer user_data)
|
|
{
|
|
- MetaSeatNative *seat_native = META_SEAT_NATIVE (source_object);
|
|
+ MetaSeatImpl *seat_impl = META_SEAT_IMPL (source_object);
|
|
+ g_autoptr (GError) error = NULL;
|
|
GTask *task = G_TASK (user_data);
|
|
GMainLoop *main_loop = g_task_get_task_data (task);
|
|
- g_autoptr (GError) error = NULL;
|
|
|
|
- if (!meta_seat_native_set_keyboard_map_finish (seat_native, result, &error))
|
|
- g_task_return_error (task, error);
|
|
- else
|
|
- g_task_return_boolean (task, TRUE);
|
|
+ if (!meta_seat_impl_set_keyboard_map_finish (seat_impl, result, &error))
|
|
+ {
|
|
+ g_task_return_error (task, g_steal_pointer (&error));
|
|
+ g_main_loop_quit (main_loop);
|
|
+ return;
|
|
+ }
|
|
|
|
+ g_task_return_boolean (task, TRUE);
|
|
g_main_loop_quit (main_loop);
|
|
}
|
|
|
|
@@ -622,22 +658,40 @@ meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
g_autoptr (GMainContext) main_context = NULL;
|
|
g_autoptr (GMainLoop) main_loop = NULL;
|
|
g_autoptr (GTask) task = NULL;
|
|
+ struct xkb_keymap *xkb_keymap;
|
|
|
|
main_context = g_main_context_new ();
|
|
main_loop = g_main_loop_new (main_context, FALSE);
|
|
g_main_context_push_thread_default (main_context);
|
|
|
|
- task = g_task_new (G_OBJECT (seat_native), NULL, NULL, NULL);
|
|
+ task = g_task_new (NULL, NULL, NULL, NULL);
|
|
g_task_set_task_data (task, main_loop, NULL);
|
|
|
|
- meta_seat_native_set_keyboard_map_async (seat_native,
|
|
- description,
|
|
- cancellable,
|
|
- set_keyboard_map_cb, task);
|
|
+ meta_seat_impl_set_keyboard_map_async (seat_native->impl,
|
|
+ description,
|
|
+ cancellable,
|
|
+ sync_set_impl_keyboard_map_cb,
|
|
+ task);
|
|
g_main_loop_run (main_loop);
|
|
g_main_context_pop_thread_default (main_context);
|
|
|
|
- return g_task_propagate_boolean (task, error);
|
|
+ if (!g_task_propagate_boolean (task, error))
|
|
+ return FALSE;
|
|
+
|
|
+ xkb_keymap =
|
|
+ meta_keymap_description_create_xkb_keymap (description,
|
|
+ error);
|
|
+ if (!xkb_keymap)
|
|
+ return FALSE;
|
|
+
|
|
+ g_clear_pointer (&seat_native->xkb_keymap, xkb_keymap_unref);
|
|
+ seat_native->xkb_keymap = xkb_keymap_ref (xkb_keymap);
|
|
+
|
|
+ g_clear_pointer (&seat_native->keymap_description,
|
|
+ meta_keymap_description_unref);
|
|
+ seat_native->keymap_description = meta_keymap_description_ref (description);
|
|
+
|
|
+ return TRUE;
|
|
}
|
|
|
|
/**
|
|
diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h
|
|
index e0bd689a07..fc0663086e 100644
|
|
--- a/src/backends/native/meta-seat-native.h
|
|
+++ b/src/backends/native/meta-seat-native.h
|
|
@@ -50,6 +50,7 @@ struct _MetaSeatNative
|
|
GList *devices;
|
|
struct xkb_keymap *xkb_keymap;
|
|
xkb_layout_index_t xkb_layout_index;
|
|
+ MetaKeymapDescription *keymap_description;
|
|
|
|
ClutterInputDevice *core_pointer;
|
|
ClutterInputDevice *core_keyboard;
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From b024281a74510eaef821cdc6c9bb2f660d1fcae2 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Tue, 9 Dec 2025 22:10:35 +0100
|
|
Subject: [PATCH 13/32] keymap/native: Move out modifier handling to helpers
|
|
|
|
This will make it easier to update modifiers from other places later.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit a2eeb8959e6d3981673fe3d47f909e98877ebcf4)
|
|
---
|
|
src/backends/native/meta-keymap-native.c | 85 +++++++++++++++---------
|
|
1 file changed, 52 insertions(+), 33 deletions(-)
|
|
|
|
diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c
|
|
index 770f0cb0d0..ec69950e0a 100644
|
|
--- a/src/backends/native/meta-keymap-native.c
|
|
+++ b/src/backends/native/meta-keymap-native.c
|
|
@@ -49,6 +49,15 @@ struct _MetaKeymapNative
|
|
} impl;
|
|
};
|
|
|
|
+typedef struct
|
|
+{
|
|
+ xkb_mod_mask_t depressed_mods;
|
|
+ xkb_mod_mask_t latched_mods;
|
|
+ xkb_mod_mask_t locked_mods;
|
|
+
|
|
+ xkb_layout_index_t effective_layout_group;
|
|
+} ModifierState;
|
|
+
|
|
G_DEFINE_TYPE (MetaKeymapNative, meta_keymap_native,
|
|
CLUTTER_TYPE_KEYMAP)
|
|
|
|
@@ -105,6 +114,46 @@ meta_keymap_native_init (MetaKeymapNative *keymap)
|
|
xkb_context_unref (ctx);
|
|
}
|
|
|
|
+static ModifierState
|
|
+calculate_modifier_state (struct xkb_state *xkb_state)
|
|
+{
|
|
+ return (ModifierState) {
|
|
+ .depressed_mods =
|
|
+ xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED),
|
|
+ .latched_mods =
|
|
+ xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED),
|
|
+ .locked_mods =
|
|
+ xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED),
|
|
+ .effective_layout_group =
|
|
+ xkb_state_serialize_layout (xkb_state, XKB_STATE_LAYOUT_EFFECTIVE),
|
|
+ };
|
|
+}
|
|
+
|
|
+static void
|
|
+update_state_from_modifier_state (MetaKeymapNative *keymap_native,
|
|
+ ModifierState *modifier_state)
|
|
+{
|
|
+ gboolean caps_lock_state;
|
|
+ gboolean num_lock_state;
|
|
+
|
|
+ num_lock_state =
|
|
+ !!((modifier_state->latched_mods | modifier_state->locked_mods) &
|
|
+ (1 << xkb_keymap_mod_get_index (keymap_native->impl.keymap,
|
|
+ XKB_MOD_NAME_NUM)));
|
|
+ caps_lock_state =
|
|
+ !!((modifier_state->latched_mods | modifier_state->locked_mods) &
|
|
+ (1 << xkb_keymap_mod_get_index (keymap_native->impl.keymap,
|
|
+ XKB_MOD_NAME_CAPS)));
|
|
+
|
|
+ clutter_keymap_update_state (CLUTTER_KEYMAP (keymap_native),
|
|
+ caps_lock_state,
|
|
+ num_lock_state,
|
|
+ modifier_state->effective_layout_group,
|
|
+ modifier_state->depressed_mods,
|
|
+ modifier_state->latched_mods,
|
|
+ modifier_state->locked_mods);
|
|
+}
|
|
+
|
|
typedef struct
|
|
{
|
|
MetaKeymapNative *keymap_native;
|
|
@@ -165,11 +214,7 @@ typedef struct
|
|
{
|
|
MetaKeymapNative *keymap_native;
|
|
|
|
- xkb_mod_mask_t depressed_mods;
|
|
- xkb_mod_mask_t latched_mods;
|
|
- xkb_mod_mask_t locked_mods;
|
|
-
|
|
- xkb_layout_index_t effective_layout_group;
|
|
+ ModifierState modifier_state;
|
|
} UpdateLockedModifierStateData;
|
|
|
|
static gboolean
|
|
@@ -177,25 +222,8 @@ update_state_in_main (gpointer user_data)
|
|
{
|
|
UpdateLockedModifierStateData *data = user_data;
|
|
MetaKeymapNative *keymap_native = data->keymap_native;
|
|
- gboolean caps_lock_state;
|
|
- gboolean num_lock_state;
|
|
|
|
- num_lock_state =
|
|
- !!((data->latched_mods | data->locked_mods) &
|
|
- (1 << xkb_keymap_mod_get_index (keymap_native->impl.keymap,
|
|
- XKB_MOD_NAME_NUM)));
|
|
- caps_lock_state =
|
|
- !!((data->latched_mods | data->locked_mods) &
|
|
- (1 << xkb_keymap_mod_get_index (keymap_native->impl.keymap,
|
|
- XKB_MOD_NAME_CAPS)));
|
|
-
|
|
- clutter_keymap_update_state (CLUTTER_KEYMAP (keymap_native),
|
|
- caps_lock_state,
|
|
- num_lock_state,
|
|
- data->effective_layout_group,
|
|
- data->depressed_mods,
|
|
- data->latched_mods,
|
|
- data->locked_mods);
|
|
+ update_state_from_modifier_state (keymap_native, &data->modifier_state);
|
|
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
@@ -209,16 +237,7 @@ meta_keymap_native_update_in_impl (MetaKeymapNative *keymap_native,
|
|
|
|
data = g_new0 (UpdateLockedModifierStateData, 1);
|
|
data->keymap_native = keymap_native;
|
|
-
|
|
- data->depressed_mods =
|
|
- xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_DEPRESSED);
|
|
- data->latched_mods =
|
|
- xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LATCHED);
|
|
- data->locked_mods =
|
|
- xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_LOCKED);
|
|
-
|
|
- data->effective_layout_group =
|
|
- xkb_state_serialize_layout (xkb_state, XKB_STATE_LAYOUT_EFFECTIVE);
|
|
+ data->modifier_state = calculate_modifier_state (xkb_state);
|
|
|
|
meta_seat_impl_queue_main_thread_idle (seat_impl,
|
|
update_state_in_main,
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 656d83e985b87b33cc77702502df3b1d65616116 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 1 Oct 2025 21:21:38 +0200
|
|
Subject: [PATCH 14/32] backend: Make set_keymap API also take a layout index
|
|
|
|
This avoids always requiring a second call to a separate function to set
|
|
the layout index, where there is a short period of time where it's
|
|
potentially incorrect.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 50dd36fe3a2f46e43db618a420709dc6fc55373e)
|
|
---
|
|
clutter/clutter/clutter-keymap-private.h | 15 ++--
|
|
clutter/clutter/clutter-keymap.c | 12 ++--
|
|
src/backends/meta-backend-private.h | 1 +
|
|
src/backends/meta-backend.c | 2 +
|
|
src/backends/native/meta-backend-native.c | 2 +
|
|
.../native/meta-keymap-native-private.h | 3 +-
|
|
src/backends/native/meta-keymap-native.c | 35 +++++++---
|
|
src/backends/native/meta-seat-impl.c | 70 +++++++++++++++----
|
|
src/backends/native/meta-seat-impl.h | 1 +
|
|
src/backends/native/meta-seat-native.c | 10 ++-
|
|
src/backends/native/meta-seat-native.h | 1 +
|
|
src/compositor/plugins/default.c | 2 +-
|
|
src/meta/meta-backend.h | 1 +
|
|
src/tests/keyboard-map-tests.c | 6 +-
|
|
src/tests/remote-desktop-tests.c | 2 +-
|
|
15 files changed, 119 insertions(+), 44 deletions(-)
|
|
|
|
diff --git a/clutter/clutter/clutter-keymap-private.h b/clutter/clutter/clutter-keymap-private.h
|
|
index 047425c05e..5b65b880aa 100644
|
|
--- a/clutter/clutter/clutter-keymap-private.h
|
|
+++ b/clutter/clutter/clutter-keymap-private.h
|
|
@@ -21,10 +21,11 @@
|
|
#include "clutter/clutter-keymap.h"
|
|
|
|
CLUTTER_EXPORT
|
|
-void clutter_keymap_update_state (ClutterKeymap *keymap,
|
|
- gboolean caps_lock_state,
|
|
- gboolean num_lock_state,
|
|
- xkb_layout_index_t effective_layout_group,
|
|
- xkb_mod_mask_t depressed_mods,
|
|
- xkb_mod_mask_t latched_mods,
|
|
- xkb_mod_mask_t locked_mods);
|
|
+gboolean clutter_keymap_update_state (ClutterKeymap *keymap,
|
|
+ gboolean caps_lock_state,
|
|
+ gboolean num_lock_state,
|
|
+ xkb_layout_index_t effective_layout_group,
|
|
+ xkb_mod_mask_t depressed_mods,
|
|
+ xkb_mod_mask_t latched_mods,
|
|
+ xkb_mod_mask_t locked_mods,
|
|
+ gboolean emit_signal);
|
|
diff --git a/clutter/clutter/clutter-keymap.c b/clutter/clutter/clutter-keymap.c
|
|
index 8721990f74..4073da4f17 100644
|
|
--- a/clutter/clutter/clutter-keymap.c
|
|
+++ b/clutter/clutter/clutter-keymap.c
|
|
@@ -159,14 +159,15 @@ clutter_keymap_get_direction (ClutterKeymap *keymap)
|
|
return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_direction (keymap);
|
|
}
|
|
|
|
-void
|
|
+gboolean
|
|
clutter_keymap_update_state (ClutterKeymap *keymap,
|
|
gboolean caps_lock_state,
|
|
gboolean num_lock_state,
|
|
xkb_layout_index_t effective_layout_group,
|
|
xkb_mod_mask_t depressed_mods,
|
|
xkb_mod_mask_t latched_mods,
|
|
- xkb_mod_mask_t locked_mods)
|
|
+ xkb_mod_mask_t locked_mods,
|
|
+ gboolean emit_signal)
|
|
{
|
|
ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
|
|
|
@@ -176,7 +177,7 @@ clutter_keymap_update_state (ClutterKeymap *keymap,
|
|
priv->depressed_mods == depressed_mods &&
|
|
priv->latched_mods == latched_mods &&
|
|
priv->locked_mods == locked_mods)
|
|
- return;
|
|
+ return FALSE;
|
|
|
|
priv->effective_layout_group = effective_layout_group;
|
|
priv->depressed_mods = depressed_mods;
|
|
@@ -201,7 +202,10 @@ clutter_keymap_update_state (ClutterKeymap *keymap,
|
|
priv->num_lock_state ? "set" : "unset",
|
|
priv->caps_lock_state ? "set" : "unset");
|
|
|
|
- g_signal_emit (keymap, signals[STATE_CHANGED], 0);
|
|
+ if (emit_signal)
|
|
+ g_signal_emit (keymap, signals[STATE_CHANGED], 0);
|
|
+
|
|
+ return TRUE;
|
|
}
|
|
|
|
void
|
|
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
|
|
index b7d92e6a4c..2cca4caa13 100644
|
|
--- a/src/backends/meta-backend-private.h
|
|
+++ b/src/backends/meta-backend-private.h
|
|
@@ -126,6 +126,7 @@ struct _MetaBackendClass
|
|
|
|
void (* set_keymap_async) (MetaBackend *backend,
|
|
MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
GTask *task);
|
|
|
|
struct xkb_keymap * (* get_keymap) (MetaBackend *backend);
|
|
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
|
|
index 84e4d4cf25..926e94365b 100644
|
|
--- a/src/backends/meta-backend.c
|
|
+++ b/src/backends/meta-backend.c
|
|
@@ -1777,6 +1777,7 @@ meta_backend_set_keymap_finish (MetaBackend *backend,
|
|
void
|
|
meta_backend_set_keymap_async (MetaBackend *backend,
|
|
MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
@@ -1788,6 +1789,7 @@ meta_backend_set_keymap_async (MetaBackend *backend,
|
|
|
|
META_BACKEND_GET_CLASS (backend)->set_keymap_async (backend,
|
|
description,
|
|
+ layout_index,
|
|
task);
|
|
}
|
|
|
|
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
|
|
index 95dbfca41e..ebb95002a1 100644
|
|
--- a/src/backends/native/meta-backend-native.c
|
|
+++ b/src/backends/native/meta-backend-native.c
|
|
@@ -338,6 +338,7 @@ set_keyboard_map_cb (GObject *source_object,
|
|
static void
|
|
meta_backend_native_set_keymap_async (MetaBackend *backend,
|
|
MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
GTask *task)
|
|
{
|
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
|
@@ -346,6 +347,7 @@ meta_backend_native_set_keymap_async (MetaBackend *backend,
|
|
seat = clutter_backend_get_default_seat (clutter_backend);
|
|
meta_seat_native_set_keyboard_map_async (META_SEAT_NATIVE (seat),
|
|
description,
|
|
+ layout_index,
|
|
g_task_get_cancellable (task),
|
|
set_keyboard_map_cb,
|
|
task);
|
|
diff --git a/src/backends/native/meta-keymap-native-private.h b/src/backends/native/meta-keymap-native-private.h
|
|
index 2084393d5f..82d249eda8 100644
|
|
--- a/src/backends/native/meta-keymap-native-private.h
|
|
+++ b/src/backends/native/meta-keymap-native-private.h
|
|
@@ -28,7 +28,8 @@
|
|
void meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
MetaSeatImpl *seat_impl,
|
|
MetaKeymapDescription *keymap_description,
|
|
- struct xkb_keymap *xkb_keymap);
|
|
+ struct xkb_keymap *xkb_keymap,
|
|
+ struct xkb_state *xkb_state);
|
|
|
|
struct xkb_keymap * meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap);
|
|
|
|
diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c
|
|
index ec69950e0a..63f5b4cf29 100644
|
|
--- a/src/backends/native/meta-keymap-native.c
|
|
+++ b/src/backends/native/meta-keymap-native.c
|
|
@@ -129,9 +129,10 @@ calculate_modifier_state (struct xkb_state *xkb_state)
|
|
};
|
|
}
|
|
|
|
-static void
|
|
+static gboolean
|
|
update_state_from_modifier_state (MetaKeymapNative *keymap_native,
|
|
- ModifierState *modifier_state)
|
|
+ ModifierState *modifier_state,
|
|
+ gboolean emit_signal)
|
|
{
|
|
gboolean caps_lock_state;
|
|
gboolean num_lock_state;
|
|
@@ -145,13 +146,14 @@ update_state_from_modifier_state (MetaKeymapNative *keymap_native,
|
|
(1 << xkb_keymap_mod_get_index (keymap_native->impl.keymap,
|
|
XKB_MOD_NAME_CAPS)));
|
|
|
|
- clutter_keymap_update_state (CLUTTER_KEYMAP (keymap_native),
|
|
- caps_lock_state,
|
|
- num_lock_state,
|
|
- modifier_state->effective_layout_group,
|
|
- modifier_state->depressed_mods,
|
|
- modifier_state->latched_mods,
|
|
- modifier_state->locked_mods);
|
|
+ return clutter_keymap_update_state (CLUTTER_KEYMAP (keymap_native),
|
|
+ caps_lock_state,
|
|
+ num_lock_state,
|
|
+ modifier_state->effective_layout_group,
|
|
+ modifier_state->depressed_mods,
|
|
+ modifier_state->latched_mods,
|
|
+ modifier_state->locked_mods,
|
|
+ emit_signal);
|
|
}
|
|
|
|
typedef struct
|
|
@@ -159,6 +161,8 @@ typedef struct
|
|
MetaKeymapNative *keymap_native;
|
|
|
|
MetaKeymapDescription *keymap_description;
|
|
+
|
|
+ ModifierState modifier_state;
|
|
} UpdateKeymapData;
|
|
|
|
static void
|
|
@@ -175,9 +179,16 @@ update_keymap_in_main (gpointer user_data)
|
|
{
|
|
UpdateKeymapData *data = user_data;
|
|
MetaKeymapNative *keymap_native = data->keymap_native;
|
|
+ gboolean state_changed;
|
|
+
|
|
+ state_changed = update_state_from_modifier_state (keymap_native,
|
|
+ &data->modifier_state,
|
|
+ FALSE);
|
|
|
|
g_signal_emit (keymap_native, signals[KEYMAP_CHANGED], 0,
|
|
data->keymap_description);
|
|
+ if (state_changed)
|
|
+ g_signal_emit_by_name (keymap_native, "state-changed");
|
|
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
@@ -186,7 +197,8 @@ void
|
|
meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
MetaSeatImpl *seat_impl,
|
|
MetaKeymapDescription *keymap_description,
|
|
- struct xkb_keymap *xkb_keymap)
|
|
+ struct xkb_keymap *xkb_keymap,
|
|
+ struct xkb_state *xkb_state)
|
|
{
|
|
UpdateKeymapData *data;
|
|
|
|
@@ -197,6 +209,7 @@ meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
|
|
data = g_new0 (UpdateKeymapData, 1);
|
|
data->keymap_native = keymap;
|
|
+ data->modifier_state = calculate_modifier_state (xkb_state);
|
|
data->keymap_description = meta_keymap_description_ref (keymap_description);
|
|
|
|
meta_seat_impl_queue_main_thread_idle (seat_impl,
|
|
@@ -223,7 +236,7 @@ update_state_in_main (gpointer user_data)
|
|
UpdateLockedModifierStateData *data = user_data;
|
|
MetaKeymapNative *keymap_native = data->keymap_native;
|
|
|
|
- update_state_from_modifier_state (keymap_native, &data->modifier_state);
|
|
+ update_state_from_modifier_state (keymap_native, &data->modifier_state, TRUE);
|
|
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
|
|
index 1a54cfe00c..f2ef0d8166 100644
|
|
--- a/src/backends/native/meta-seat-impl.c
|
|
+++ b/src/backends/native/meta-seat-impl.c
|
|
@@ -3670,16 +3670,13 @@ meta_seat_impl_init (MetaSeatImpl *seat_impl)
|
|
seat_impl->barrier_manager = meta_barrier_manager_native_new ();
|
|
}
|
|
|
|
-void
|
|
-meta_seat_impl_update_xkb_state_in_impl (MetaSeatImpl *seat_impl)
|
|
+static void
|
|
+meta_seat_impl_update_xkb_state_in_impl_unlocked (MetaSeatImpl *seat_impl,
|
|
+ struct xkb_keymap *xkb_keymap,
|
|
+ xkb_layout_index_t layout_index)
|
|
{
|
|
xkb_mod_mask_t latched_mods = 0;
|
|
xkb_mod_mask_t locked_mods = 0;
|
|
- struct xkb_keymap *xkb_keymap;
|
|
-
|
|
- g_rw_lock_writer_lock (&seat_impl->state_lock);
|
|
-
|
|
- xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (seat_impl->keymap);
|
|
|
|
if (seat_impl->xkb)
|
|
{
|
|
@@ -3696,15 +3693,29 @@ meta_seat_impl_update_xkb_state_in_impl (MetaSeatImpl *seat_impl)
|
|
0, /* depressed */
|
|
latched_mods,
|
|
locked_mods,
|
|
- 0, 0, seat_impl->layout_idx);
|
|
+ 0, 0, layout_index);
|
|
+
|
|
+ seat_impl->layout_idx = layout_index;
|
|
|
|
update_keyboard_leds (seat_impl);
|
|
|
|
meta_seat_impl_sync_leds_in_impl (seat_impl);
|
|
+}
|
|
+
|
|
+void
|
|
+meta_seat_impl_update_xkb_state_in_impl (MetaSeatImpl *seat_impl)
|
|
+{
|
|
+ struct xkb_keymap *xkb_keymap;
|
|
+
|
|
+ g_rw_lock_writer_lock (&seat_impl->state_lock);
|
|
+
|
|
+ xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (seat_impl->keymap);
|
|
+ meta_seat_impl_update_xkb_state_in_impl_unlocked (seat_impl,
|
|
+ xkb_keymap,
|
|
+ seat_impl->layout_idx);
|
|
meta_keymap_native_update_in_impl (seat_impl->keymap,
|
|
seat_impl,
|
|
seat_impl->xkb);
|
|
-
|
|
g_rw_lock_writer_unlock (&seat_impl->state_lock);
|
|
}
|
|
|
|
@@ -3816,11 +3827,27 @@ meta_seat_impl_set_keyboard_map_finish (MetaSeatImpl *seat_impl,
|
|
return g_task_propagate_boolean (task, error);
|
|
}
|
|
|
|
+typedef struct
|
|
+{
|
|
+ MetaKeymapDescription *keymap_description;
|
|
+ xkb_layout_index_t layout_index;
|
|
+} SetKeymapData;
|
|
+
|
|
+static void
|
|
+set_keymap_data_free (gpointer user_data)
|
|
+{
|
|
+ SetKeymapData *data = user_data;
|
|
+
|
|
+ meta_keymap_description_unref (data->keymap_description);
|
|
+ g_free (data);
|
|
+}
|
|
+
|
|
static gboolean
|
|
set_keyboard_map (GTask *task)
|
|
{
|
|
MetaSeatImpl *seat_impl = g_task_get_source_object (task);
|
|
- MetaKeymapDescription *keymap_description = g_task_get_task_data (task);
|
|
+ SetKeymapData *data = g_task_get_task_data (task);
|
|
+ MetaKeymapDescription *keymap_description = data->keymap_description;
|
|
MetaKeymapNative *keymap;
|
|
g_autoptr (GError) error = NULL;
|
|
struct xkb_keymap *xkb_keymap;
|
|
@@ -3838,12 +3865,21 @@ set_keyboard_map (GTask *task)
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
|
|
+ g_rw_lock_writer_lock (&seat_impl->state_lock);
|
|
+
|
|
+ meta_seat_impl_update_xkb_state_in_impl_unlocked (seat_impl,
|
|
+ xkb_keymap,
|
|
+ data->layout_index);
|
|
+
|
|
meta_keymap_native_set_keyboard_map_in_impl (keymap,
|
|
seat_impl,
|
|
keymap_description,
|
|
- xkb_keymap);
|
|
+ xkb_keymap,
|
|
+ seat_impl->xkb);
|
|
+ xkb_keymap_unref (xkb_keymap);
|
|
+
|
|
+ g_rw_lock_writer_unlock (&seat_impl->state_lock);
|
|
|
|
- meta_seat_impl_update_xkb_state_in_impl (seat_impl);
|
|
g_task_return_boolean (task, TRUE);
|
|
|
|
return G_SOURCE_REMOVE;
|
|
@@ -3865,20 +3901,24 @@ set_keyboard_map (GTask *task)
|
|
void
|
|
meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
MetaKeymapDescription *keymap_description,
|
|
+ xkb_layout_index_t layout_index,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
GTask *task;
|
|
+ SetKeymapData *data;
|
|
|
|
g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
|
|
g_return_if_fail (keymap_description);
|
|
|
|
task = g_task_new (seat_impl, cancellable, callback, user_data);
|
|
g_task_set_source_tag (task, meta_seat_impl_set_keyboard_map_async);
|
|
- g_task_set_task_data (task,
|
|
- meta_keymap_description_ref (keymap_description),
|
|
- (GDestroyNotify) meta_keymap_description_unref);
|
|
+
|
|
+ data = g_new0 (SetKeymapData, 1);
|
|
+ data->keymap_description = meta_keymap_description_ref (keymap_description);
|
|
+ data->layout_index = layout_index;
|
|
+ g_task_set_task_data (task, data, set_keymap_data_free);
|
|
meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) set_keyboard_map);
|
|
g_object_unref (task);
|
|
}
|
|
diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h
|
|
index 3637627a67..4950a19a74 100644
|
|
--- a/src/backends/native/meta-seat-impl.h
|
|
+++ b/src/backends/native/meta-seat-impl.h
|
|
@@ -191,6 +191,7 @@ gboolean meta_seat_impl_set_keyboard_map_finish (MetaSeatImpl *seat_impl,
|
|
|
|
void meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
MetaKeymapDescription *keymap_description,
|
|
+ xkb_layout_index_t layout_index,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data);
|
|
diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c
|
|
index 9be0bd7ce1..921cdb2fc6 100644
|
|
--- a/src/backends/native/meta-seat-native.c
|
|
+++ b/src/backends/native/meta-seat-native.c
|
|
@@ -68,6 +68,7 @@ G_DEFINE_TYPE (MetaSeatNative, meta_seat_native, CLUTTER_TYPE_SEAT)
|
|
|
|
static gboolean meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
GCancellable *cancellable,
|
|
GError **error);
|
|
|
|
@@ -186,6 +187,8 @@ on_keymap_changed (MetaKeymapNative *keymap_native,
|
|
|
|
g_clear_pointer (&seat_native->xkb_keymap, xkb_keymap_unref);
|
|
seat_native->xkb_keymap = xkb_keymap;
|
|
+ seat_native->xkb_layout_index =
|
|
+ clutter_keymap_get_layout_index (CLUTTER_KEYMAP (keymap_native));
|
|
|
|
g_signal_emit (seat_native, signals[KEYMAP_CHANGED], 0);
|
|
}
|
|
@@ -221,7 +224,7 @@ meta_seat_native_constructed (GObject *object)
|
|
NULL,
|
|
NULL);
|
|
if (!meta_seat_native_set_keyboard_map_sync (seat,
|
|
- keymap_description,
|
|
+ keymap_description, 0,
|
|
NULL, &error))
|
|
g_warning ("Failed to set keyboard map: %s", error->message);
|
|
|
|
@@ -612,6 +615,7 @@ set_impl_keyboard_map_cb (GObject *source_object,
|
|
void
|
|
meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
@@ -623,6 +627,7 @@ meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
|
|
meta_seat_impl_set_keyboard_map_async (seat->impl,
|
|
description,
|
|
+ layout_index,
|
|
cancellable,
|
|
set_impl_keyboard_map_cb,
|
|
g_object_ref (task));
|
|
@@ -652,6 +657,7 @@ sync_set_impl_keyboard_map_cb (GObject *source_object,
|
|
static gboolean
|
|
meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
GCancellable *cancellable,
|
|
GError **error)
|
|
{
|
|
@@ -669,6 +675,7 @@ meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
|
|
meta_seat_impl_set_keyboard_map_async (seat_native->impl,
|
|
description,
|
|
+ layout_index,
|
|
cancellable,
|
|
sync_set_impl_keyboard_map_cb,
|
|
task);
|
|
@@ -686,6 +693,7 @@ meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
|
|
g_clear_pointer (&seat_native->xkb_keymap, xkb_keymap_unref);
|
|
seat_native->xkb_keymap = xkb_keymap_ref (xkb_keymap);
|
|
+ seat_native->xkb_layout_index = layout_index;
|
|
|
|
g_clear_pointer (&seat_native->keymap_description,
|
|
meta_keymap_description_unref);
|
|
diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h
|
|
index fc0663086e..2799d895d2 100644
|
|
--- a/src/backends/native/meta-seat-native.h
|
|
+++ b/src/backends/native/meta-seat-native.h
|
|
@@ -103,6 +103,7 @@ void meta_seat_native_reclaim_devices (MetaSeatNative *seat);
|
|
|
|
void meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data);
|
|
diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c
|
|
index 094cec07ea..3ce1e491e1 100644
|
|
--- a/src/compositor/plugins/default.c
|
|
+++ b/src/compositor/plugins/default.c
|
|
@@ -421,7 +421,7 @@ init_keymap (MetaDefaultPlugin *self,
|
|
x11_options);
|
|
|
|
meta_backend_set_keymap_async (backend,
|
|
- keymap_description,
|
|
+ keymap_description, 0,
|
|
NULL, NULL, NULL);
|
|
}
|
|
|
|
diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h
|
|
index 74ad2bfebf..cd93fc9a72 100644
|
|
--- a/src/meta/meta-backend.h
|
|
+++ b/src/meta/meta-backend.h
|
|
@@ -51,6 +51,7 @@ gboolean meta_backend_set_keymap_finish (MetaBackend *backend,
|
|
META_EXPORT
|
|
void meta_backend_set_keymap_async (MetaBackend *backend,
|
|
MetaKeymapDescription *description,
|
|
+ uint32_t layout_index,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data);
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index 8d93dababf..c307c80e83 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -161,7 +161,7 @@ meta_test_native_keyboard_map_set_async (void)
|
|
"us",
|
|
"dvorak-alt-intl",
|
|
NULL);
|
|
- meta_backend_set_keymap_async (backend, keymap_description,
|
|
+ meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
NULL, set_keymap_cb, &done);
|
|
|
|
g_assert_true (xkb_keymap == meta_backend_get_keymap (backend));
|
|
@@ -210,7 +210,7 @@ meta_test_native_keyboard_map_change_layout (void)
|
|
"us,ua",
|
|
NULL,
|
|
"grp:caps_select");
|
|
- meta_backend_set_keymap_async (backend, keymap_description,
|
|
+ meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
NULL, set_keymap_cb, &done);
|
|
|
|
while (!done)
|
|
@@ -292,7 +292,7 @@ meta_test_native_keyboard_map_set_layout_index (void)
|
|
"us,se",
|
|
"dvorak-alt-intl,svdvorak",
|
|
NULL);
|
|
- meta_backend_set_keymap_async (backend, keymap_description,
|
|
+ meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
NULL, set_keymap_cb, &done);
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
diff --git a/src/tests/remote-desktop-tests.c b/src/tests/remote-desktop-tests.c
|
|
index a2ce8ce388..75266a0838 100644
|
|
--- a/src/tests/remote-desktop-tests.c
|
|
+++ b/src/tests/remote-desktop-tests.c
|
|
@@ -77,7 +77,7 @@ remote_desktop_test_client_command (int argc,
|
|
layout,
|
|
variant,
|
|
NULL);
|
|
- meta_backend_set_keymap_async (backend, keymap_description,
|
|
+ meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
NULL, set_keymap_cb, &done);
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From c258b53959ba34625f2fb5913f87dc9bba23a7cb Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 1 Oct 2025 21:35:05 +0200
|
|
Subject: [PATCH 15/32] Add 'sealed fd' type
|
|
|
|
Copied from xdg-desktop-portal, with some unused API skipped. Will be
|
|
used to wrap sealed memfd file descriptors, with a convenient API to
|
|
retrieve the actual data.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 7225cec4ced3bd57614800bc8a938c114a226cad)
|
|
---
|
|
src/core/meta-sealed-fd.c | 175 ++++++++++++++++++++++++++++++++++++++
|
|
src/core/meta-sealed-fd.h | 43 ++++++++++
|
|
src/meson.build | 2 +
|
|
3 files changed, 220 insertions(+)
|
|
create mode 100644 src/core/meta-sealed-fd.c
|
|
create mode 100644 src/core/meta-sealed-fd.h
|
|
|
|
diff --git a/src/core/meta-sealed-fd.c b/src/core/meta-sealed-fd.c
|
|
new file mode 100644
|
|
index 0000000000..57172104a5
|
|
--- /dev/null
|
|
+++ b/src/core/meta-sealed-fd.c
|
|
@@ -0,0 +1,175 @@
|
|
+/*
|
|
+ * Copyright © 2024 GNOME Foundation Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ * Authors:
|
|
+ * Julian Sparber <jsparber@gnome.org>
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+
|
|
+#include "core/meta-sealed-fd.h"
|
|
+
|
|
+#include <errno.h>
|
|
+#include <fcntl.h>
|
|
+#include <gio/gunixfdlist.h>
|
|
+#include <glib/gstdio.h>
|
|
+#include <string.h>
|
|
+#include <sys/mman.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+#define REQUIRED_SEALS (F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SHRINK)
|
|
+
|
|
+struct _MetaSealedFd
|
|
+{
|
|
+ GObject parent_instance;
|
|
+
|
|
+ int fd;
|
|
+};
|
|
+
|
|
+G_DEFINE_FINAL_TYPE (MetaSealedFd, meta_sealed_fd, G_TYPE_OBJECT)
|
|
+
|
|
+static void
|
|
+meta_sealed_fd_finalize (GObject *object)
|
|
+{
|
|
+ MetaSealedFd *sealed_fd = META_SEALED_FD (object);
|
|
+ g_autoptr (GError) error = NULL;
|
|
+
|
|
+ if (!g_clear_fd (&sealed_fd->fd, &error))
|
|
+ g_warning ("Error closing sealed fd: %s", error->message);
|
|
+
|
|
+ G_OBJECT_CLASS (meta_sealed_fd_parent_class)->finalize (object);
|
|
+}
|
|
+
|
|
+static void
|
|
+meta_sealed_fd_class_init (MetaSealedFdClass *klass)
|
|
+{
|
|
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
+
|
|
+ object_class->finalize = meta_sealed_fd_finalize;
|
|
+}
|
|
+
|
|
+static void
|
|
+meta_sealed_fd_init (MetaSealedFd *sealed_fd)
|
|
+{
|
|
+ sealed_fd->fd = -1;
|
|
+}
|
|
+
|
|
+MetaSealedFd *
|
|
+meta_sealed_fd_new_take_memfd (int memfd,
|
|
+ GError **error)
|
|
+{
|
|
+ g_autoptr (MetaSealedFd) sealed_fd = NULL;
|
|
+ g_autofd int fd = g_steal_fd (&memfd);
|
|
+ int saved_errno = -1;
|
|
+ int seals;
|
|
+
|
|
+ g_return_val_if_fail (fd != -1, NULL);
|
|
+
|
|
+ seals = fcntl (fd, F_GET_SEALS);
|
|
+ if (seals == -1)
|
|
+ {
|
|
+ saved_errno = errno;
|
|
+
|
|
+ g_set_error (error,
|
|
+ G_IO_ERROR,
|
|
+ g_io_error_from_errno (saved_errno),
|
|
+ "fcntl F_GET_SEALS: %s", g_strerror (saved_errno));
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ /* If the seal seal is set and some required seal is missing report EPERM error directly */
|
|
+ if ((seals & F_SEAL_SEAL) && (seals & REQUIRED_SEALS) != REQUIRED_SEALS)
|
|
+ saved_errno = EPERM;
|
|
+ else if (fcntl (fd, F_ADD_SEALS, REQUIRED_SEALS) == -1)
|
|
+ saved_errno = errno;
|
|
+
|
|
+ if (saved_errno != -1)
|
|
+ {
|
|
+ g_set_error (error,
|
|
+ G_IO_ERROR,
|
|
+ g_io_error_from_errno (saved_errno),
|
|
+ "fcntl F_ADD_SEALS: %s", g_strerror (saved_errno));
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ sealed_fd = g_object_new (META_TYPE_SEALED_FD, NULL);
|
|
+ sealed_fd->fd = g_steal_fd (&fd);
|
|
+
|
|
+ return g_steal_pointer (&sealed_fd);
|
|
+}
|
|
+
|
|
+MetaSealedFd *
|
|
+meta_sealed_fd_new_from_handle (GVariant *handle,
|
|
+ GUnixFDList *fd_list,
|
|
+ GError **error)
|
|
+{
|
|
+ g_autofd int fd = -1;
|
|
+ int fd_id;
|
|
+
|
|
+ if (!g_variant_is_of_type (handle, G_VARIANT_TYPE_HANDLE))
|
|
+ {
|
|
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
|
|
+ "GVariant is not a file descriptor handle");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (!fd_list)
|
|
+ {
|
|
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
|
|
+ "Invalid file descriptor: index not found (empty list)");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ fd_id = g_variant_get_handle (handle);
|
|
+ if (fd_id >= g_unix_fd_list_get_length (fd_list))
|
|
+ {
|
|
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
|
|
+ "Invalid file descriptor: index not found");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ fd = g_unix_fd_list_get (fd_list, fd_id, error);
|
|
+ if (fd == -1)
|
|
+ return NULL;
|
|
+
|
|
+ return meta_sealed_fd_new_take_memfd (g_steal_fd (&fd), error);
|
|
+}
|
|
+
|
|
+int
|
|
+meta_sealed_fd_get_fd (MetaSealedFd *sealed_fd)
|
|
+{
|
|
+ g_return_val_if_fail (META_IS_SEALED_FD (sealed_fd), -1);
|
|
+
|
|
+ return sealed_fd->fd;
|
|
+}
|
|
+
|
|
+int
|
|
+meta_sealed_fd_dup_fd (MetaSealedFd *sealed_fd)
|
|
+{
|
|
+ g_return_val_if_fail (META_IS_SEALED_FD (sealed_fd), -1);
|
|
+
|
|
+ return dup (sealed_fd->fd);
|
|
+}
|
|
+
|
|
+GBytes *
|
|
+meta_sealed_fd_get_bytes (MetaSealedFd *sealed_fd,
|
|
+ GError **error)
|
|
+{
|
|
+ g_autoptr (GMappedFile) mapped = NULL;
|
|
+
|
|
+ mapped = g_mapped_file_new_from_fd (sealed_fd->fd, FALSE, error);
|
|
+ return g_mapped_file_get_bytes (mapped);
|
|
+}
|
|
diff --git a/src/core/meta-sealed-fd.h b/src/core/meta-sealed-fd.h
|
|
new file mode 100644
|
|
index 0000000000..2721fdddb9
|
|
--- /dev/null
|
|
+++ b/src/core/meta-sealed-fd.h
|
|
@@ -0,0 +1,43 @@
|
|
+/*
|
|
+ * Copyright © 2024 GNOME Foundation Inc.
|
|
+ *
|
|
+ * SPDX-License-Identifier: LGPL-2.1-or-later
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <gio/gio.h>
|
|
+#include <glib-object.h>
|
|
+
|
|
+#define META_TYPE_SEALED_FD (meta_sealed_fd_get_type())
|
|
+G_DECLARE_FINAL_TYPE (MetaSealedFd,
|
|
+ meta_sealed_fd,
|
|
+ META, SEALED_FD,
|
|
+ GObject)
|
|
+
|
|
+MetaSealedFd * meta_sealed_fd_new_take_memfd (int memfd,
|
|
+ GError **error);
|
|
+
|
|
+MetaSealedFd * meta_sealed_fd_new_from_handle (GVariant *handle,
|
|
+ GUnixFDList *fd_list,
|
|
+ GError **error);
|
|
+
|
|
+int meta_sealed_fd_get_fd (MetaSealedFd *sealed_fd);
|
|
+
|
|
+int meta_sealed_fd_dup_fd (MetaSealedFd *sealed_fd);
|
|
+
|
|
+GBytes *meta_sealed_fd_get_bytes (MetaSealedFd *sealed_fd,
|
|
+ GError **error);
|
|
diff --git a/src/meson.build b/src/meson.build
|
|
index e7824f502e..59e8f079c2 100644
|
|
--- a/src/meson.build
|
|
+++ b/src/meson.build
|
|
@@ -373,6 +373,8 @@ mutter_sources = [
|
|
'core/meta-launch-context.c',
|
|
'core/meta-pad-action-mapper.c',
|
|
'core/meta-private-enums.h',
|
|
+ 'core/meta-sealed-fd.c',
|
|
+ 'core/meta-sealed-fd.h',
|
|
'core/meta-selection.c',
|
|
'core/meta-selection-source.c',
|
|
'core/meta-selection-source-memory.c',
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From ab6003a40aa34f95fe8f10ea2e956638163938f8 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 1 Oct 2025 21:41:23 +0200
|
|
Subject: [PATCH 16/32] keymap-description: Add way to create keymap
|
|
description from fd
|
|
|
|
This will be used to set the actual keyboard layout from a sealed memfd
|
|
file descriptor via the remote desktop D-Bus API.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit fcd93d433dddbb79dcc01682d2626e5c47dc9eaf)
|
|
---
|
|
.../meta-keymap-description-private.h | 13 ++
|
|
src/backends/meta-keymap-description.c | 169 +++++++++++++-----
|
|
2 files changed, 137 insertions(+), 45 deletions(-)
|
|
|
|
diff --git a/src/backends/meta-keymap-description-private.h b/src/backends/meta-keymap-description-private.h
|
|
index 3cacfe6561..6504371a6c 100644
|
|
--- a/src/backends/meta-keymap-description-private.h
|
|
+++ b/src/backends/meta-keymap-description-private.h
|
|
@@ -20,5 +20,18 @@
|
|
|
|
#include "meta/meta-keymap-description.h"
|
|
|
|
+#include "core/meta-sealed-fd.h"
|
|
+
|
|
+typedef enum _MetaKeymapDescriptionSource
|
|
+{
|
|
+ META_KEYMAP_DESCRIPTION_SOURCE_RULES,
|
|
+ META_KEYMAP_DESCRIPTION_SOURCE_FD,
|
|
+} MetaKeymapDescriptionSource;
|
|
+
|
|
+MetaKeymapDescription * meta_keymap_description_new_from_fd (MetaSealedFd *sealed_fd,
|
|
+ enum xkb_keymap_format format);
|
|
+
|
|
+MetaKeymapDescriptionSource meta_keymap_description_get_source (MetaKeymapDescription *keymap_description);
|
|
+
|
|
struct xkb_keymap * meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_description,
|
|
GError **error);
|
|
diff --git a/src/backends/meta-keymap-description.c b/src/backends/meta-keymap-description.c
|
|
index cd93c543e3..77d372824e 100644
|
|
--- a/src/backends/meta-keymap-description.c
|
|
+++ b/src/backends/meta-keymap-description.c
|
|
@@ -21,18 +21,30 @@
|
|
#include "backends/meta-keymap-description-private.h"
|
|
|
|
#include <glib-object.h>
|
|
+#include <xkbcommon/xkbregistry.h>
|
|
|
|
#include "backends/meta-keymap-utils.h"
|
|
+#include "core/meta-sealed-fd.h"
|
|
|
|
struct _MetaKeymapDescription
|
|
{
|
|
gatomicrefcount ref_count;
|
|
|
|
- char *rules;
|
|
- char *model;
|
|
- char *layout;
|
|
- char *variant;
|
|
- char *options;
|
|
+ MetaKeymapDescriptionSource source;
|
|
+
|
|
+ union {
|
|
+ struct {
|
|
+ char *rules;
|
|
+ char *model;
|
|
+ char *layout;
|
|
+ char *variant;
|
|
+ char *options;
|
|
+ } rules;
|
|
+ struct {
|
|
+ MetaSealedFd *sealed_fd;
|
|
+ enum xkb_keymap_format format;
|
|
+ } fd;
|
|
+ };
|
|
};
|
|
|
|
#define DEFAULT_XKB_RULES_FILE "evdev"
|
|
@@ -58,11 +70,27 @@ meta_keymap_description_new_from_rules (const char *model,
|
|
|
|
keymap_description = g_new0 (MetaKeymapDescription, 1);
|
|
g_atomic_ref_count_init (&keymap_description->ref_count);
|
|
- keymap_description->model = model ? g_strdup (model)
|
|
- : g_strdup (DEFAULT_XKB_MODEL);
|
|
- keymap_description->layout = strdup_or_empty (layout);
|
|
- keymap_description->variant = strdup_or_empty (variant);
|
|
- keymap_description->options = strdup_or_empty (options);
|
|
+ keymap_description->source = META_KEYMAP_DESCRIPTION_SOURCE_RULES;
|
|
+ keymap_description->rules.model = model ? g_strdup (model)
|
|
+ : g_strdup (DEFAULT_XKB_MODEL);
|
|
+ keymap_description->rules.layout = strdup_or_empty (layout);
|
|
+ keymap_description->rules.variant = strdup_or_empty (variant);
|
|
+ keymap_description->rules.options = strdup_or_empty (options);
|
|
+
|
|
+ return keymap_description;
|
|
+}
|
|
+
|
|
+MetaKeymapDescription *
|
|
+meta_keymap_description_new_from_fd (MetaSealedFd *sealed_fd,
|
|
+ enum xkb_keymap_format format)
|
|
+{
|
|
+ MetaKeymapDescription *keymap_description;
|
|
+
|
|
+ keymap_description = g_new0 (MetaKeymapDescription, 1);
|
|
+ g_atomic_ref_count_init (&keymap_description->ref_count);
|
|
+ keymap_description->source = META_KEYMAP_DESCRIPTION_SOURCE_FD;
|
|
+ g_set_object (&keymap_description->fd.sealed_fd, sealed_fd);
|
|
+ keymap_description->fd.format = format;
|
|
|
|
return keymap_description;
|
|
}
|
|
@@ -79,47 +107,98 @@ meta_keymap_description_unref (MetaKeymapDescription *keymap_description)
|
|
{
|
|
if (g_atomic_ref_count_dec (&keymap_description->ref_count))
|
|
{
|
|
- g_free (keymap_description->model);
|
|
- g_free (keymap_description->layout);
|
|
- g_free (keymap_description->variant);
|
|
- g_free (keymap_description->options);
|
|
+ switch (keymap_description->source)
|
|
+ {
|
|
+ case META_KEYMAP_DESCRIPTION_SOURCE_RULES:
|
|
+ g_free (keymap_description->rules.model);
|
|
+ g_free (keymap_description->rules.layout);
|
|
+ g_free (keymap_description->rules.variant);
|
|
+ g_free (keymap_description->rules.options);
|
|
+ break;
|
|
+ case META_KEYMAP_DESCRIPTION_SOURCE_FD:
|
|
+ g_clear_object (&keymap_description->fd.sealed_fd);
|
|
+ break;
|
|
+ }
|
|
+
|
|
g_free (keymap_description);
|
|
}
|
|
}
|
|
|
|
+MetaKeymapDescriptionSource
|
|
+meta_keymap_description_get_source (MetaKeymapDescription *keymap_description)
|
|
+{
|
|
+ return keymap_description->source;
|
|
+}
|
|
+
|
|
struct xkb_keymap *
|
|
meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_description,
|
|
GError **error)
|
|
{
|
|
- struct xkb_rule_names names;
|
|
- struct xkb_context *xkb_context;
|
|
- struct xkb_keymap *xkb_keymap;
|
|
-
|
|
- names.rules = DEFAULT_XKB_RULES_FILE;
|
|
- names.model = keymap_description->model;
|
|
- names.layout = keymap_description->layout;
|
|
- names.variant = keymap_description->variant;
|
|
- names.options = keymap_description->options;
|
|
-
|
|
- xkb_context = meta_create_xkb_context ();
|
|
- xkb_keymap = xkb_keymap_new_from_names (xkb_context,
|
|
- &names,
|
|
- XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
- xkb_context_unref (xkb_context);
|
|
-
|
|
- if (!xkb_keymap)
|
|
- {
|
|
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
- "Failed to create XKB keymap with "
|
|
- "rules=%s, model=%s, layout=%s, "
|
|
- "variant=%s, options=%s",
|
|
- keymap_description->rules,
|
|
- keymap_description->model,
|
|
- keymap_description->layout,
|
|
- keymap_description->variant,
|
|
- keymap_description->options);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- return xkb_keymap;
|
|
+ switch (keymap_description->source)
|
|
+ {
|
|
+ case META_KEYMAP_DESCRIPTION_SOURCE_RULES:
|
|
+ {
|
|
+ struct xkb_rule_names names;
|
|
+ struct xkb_context *xkb_context;
|
|
+ struct xkb_keymap *xkb_keymap;
|
|
+
|
|
+ names.rules = DEFAULT_XKB_RULES_FILE;
|
|
+ names.model = keymap_description->rules.model;
|
|
+ names.layout = keymap_description->rules.layout;
|
|
+ names.variant = keymap_description->rules.variant;
|
|
+ names.options = keymap_description->rules.options;
|
|
+
|
|
+ xkb_context = meta_create_xkb_context ();
|
|
+ xkb_keymap = xkb_keymap_new_from_names (xkb_context,
|
|
+ &names,
|
|
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
+ xkb_context_unref (xkb_context);
|
|
+
|
|
+ if (!xkb_keymap)
|
|
+ {
|
|
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
+ "Failed to create XKB keymap with "
|
|
+ "rules=%s, model=%s, layout=%s, "
|
|
+ "variant=%s, options=%s",
|
|
+ keymap_description->rules.rules,
|
|
+ keymap_description->rules.model,
|
|
+ keymap_description->rules.layout,
|
|
+ keymap_description->rules.variant,
|
|
+ keymap_description->rules.options);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return xkb_keymap;
|
|
+ }
|
|
+ case META_KEYMAP_DESCRIPTION_SOURCE_FD:
|
|
+ {
|
|
+ g_autoptr (GBytes) keymap_bytes = NULL;
|
|
+ struct xkb_context *xkb_context;
|
|
+ struct xkb_keymap *xkb_keymap;
|
|
+
|
|
+ keymap_bytes =
|
|
+ meta_sealed_fd_get_bytes (keymap_description->fd.sealed_fd, error);
|
|
+ if (!keymap_bytes)
|
|
+ return NULL;
|
|
+
|
|
+ xkb_context = meta_create_xkb_context ();
|
|
+ xkb_keymap =
|
|
+ xkb_keymap_new_from_string (xkb_context,
|
|
+ g_bytes_get_data (keymap_bytes, NULL),
|
|
+ keymap_description->fd.format,
|
|
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
+ xkb_context_unref (xkb_context);
|
|
+
|
|
+ if (!xkb_keymap)
|
|
+ {
|
|
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
+ "Failed to create XKB keymap from file descriptor");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return xkb_keymap;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ g_assert_not_reached ();
|
|
}
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 3e13d05b82513d03a990b8fbb2a146b0d234f7d3 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Thu, 2 Oct 2025 10:09:25 +0200
|
|
Subject: [PATCH 17/32] backend: Add API to get current keymap description
|
|
|
|
This will be used to retrieve information related to the current keymap,
|
|
but not part of the keymap itself. Currently there are no such
|
|
information, but it will be added in the future.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit f2b1c0e8d1bd867f9b62ac0fff5c5a03dd4381df)
|
|
---
|
|
src/backends/meta-backend-private.h | 2 ++
|
|
src/backends/meta-backend.c | 15 +++++++++++++++
|
|
src/backends/native/meta-backend-native.c | 11 +++++++++++
|
|
src/backends/native/meta-seat-native.c | 9 +++++++++
|
|
src/backends/native/meta-seat-native.h | 2 ++
|
|
src/meta/meta-backend.h | 3 +++
|
|
6 files changed, 42 insertions(+)
|
|
|
|
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
|
|
index 2cca4caa13..dccd1116a6 100644
|
|
--- a/src/backends/meta-backend-private.h
|
|
+++ b/src/backends/meta-backend-private.h
|
|
@@ -131,6 +131,8 @@ struct _MetaBackendClass
|
|
|
|
struct xkb_keymap * (* get_keymap) (MetaBackend *backend);
|
|
|
|
+ MetaKeymapDescription * (* get_keymap_description) (MetaBackend *backend);
|
|
+
|
|
xkb_layout_index_t (* get_keymap_layout_group) (MetaBackend *backend);
|
|
|
|
void (* set_keymap_layout_group_async) (MetaBackend *backend,
|
|
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
|
|
index 926e94365b..beaec1f281 100644
|
|
--- a/src/backends/meta-backend.c
|
|
+++ b/src/backends/meta-backend.c
|
|
@@ -1799,6 +1799,21 @@ meta_backend_get_keymap (MetaBackend *backend)
|
|
return META_BACKEND_GET_CLASS (backend)->get_keymap (backend);
|
|
}
|
|
|
|
+/**
|
|
+ * meta_backend_get_keymap_description:
|
|
+ * @backend: a #MetaBackend
|
|
+ * keyboard map description
|
|
+ *
|
|
+ * Gets the description of the current keyboard map.
|
|
+ *
|
|
+ * Returns: (transfer none): The current keymap description.
|
|
+ */
|
|
+MetaKeymapDescription *
|
|
+meta_backend_get_keymap_description (MetaBackend *backend)
|
|
+{
|
|
+ return META_BACKEND_GET_CLASS (backend)->get_keymap_description (backend);
|
|
+}
|
|
+
|
|
xkb_layout_index_t
|
|
meta_backend_get_keymap_layout_group (MetaBackend *backend)
|
|
{
|
|
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
|
|
index ebb95002a1..b2efac59d1 100644
|
|
--- a/src/backends/native/meta-backend-native.c
|
|
+++ b/src/backends/native/meta-backend-native.c
|
|
@@ -364,6 +364,16 @@ meta_backend_native_get_keymap (MetaBackend *backend)
|
|
return meta_seat_native_get_keyboard_map (META_SEAT_NATIVE (seat));
|
|
}
|
|
|
|
+static MetaKeymapDescription *
|
|
+meta_backend_native_get_keymap_description (MetaBackend *backend)
|
|
+{
|
|
+ ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
|
+ ClutterSeat *seat;
|
|
+
|
|
+ seat = clutter_backend_get_default_seat (clutter_backend);
|
|
+ return meta_seat_native_get_keyboard_map_description (META_SEAT_NATIVE (seat));
|
|
+}
|
|
+
|
|
static xkb_layout_index_t
|
|
meta_backend_native_get_keymap_layout_group (MetaBackend *backend)
|
|
{
|
|
@@ -942,6 +952,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
|
|
|
backend_class->set_keymap_async = meta_backend_native_set_keymap_async;
|
|
backend_class->get_keymap = meta_backend_native_get_keymap;
|
|
+ backend_class->get_keymap_description = meta_backend_native_get_keymap_description;
|
|
backend_class->get_keymap_layout_group = meta_backend_native_get_keymap_layout_group;
|
|
backend_class->set_keymap_layout_group_async = meta_backend_native_set_keymap_layout_group_async;
|
|
backend_class->update_stage = meta_backend_native_update_stage;
|
|
diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c
|
|
index 921cdb2fc6..fc849044f9 100644
|
|
--- a/src/backends/native/meta-seat-native.c
|
|
+++ b/src/backends/native/meta-seat-native.c
|
|
@@ -295,6 +295,7 @@ meta_seat_native_dispose (GObject *object)
|
|
g_clear_object (&seat->core_pointer);
|
|
g_clear_object (&seat->core_keyboard);
|
|
g_clear_pointer (&seat->impl, meta_seat_impl_destroy);
|
|
+ g_clear_pointer (&seat->keymap_description, meta_keymap_description_unref);
|
|
g_list_free_full (g_steal_pointer (&seat->devices), g_object_unref);
|
|
g_clear_pointer (&seat->reserved_virtual_slots, g_hash_table_destroy);
|
|
g_clear_pointer (&seat->tablet_cursors, g_hash_table_unref);
|
|
@@ -718,6 +719,14 @@ meta_seat_native_get_keyboard_map (MetaSeatNative *seat)
|
|
return seat->xkb_keymap;
|
|
}
|
|
|
|
+MetaKeymapDescription *
|
|
+meta_seat_native_get_keyboard_map_description (MetaSeatNative *seat_native)
|
|
+{
|
|
+ g_return_val_if_fail (seat_native->keymap_description, NULL);
|
|
+
|
|
+ return seat_native->keymap_description;
|
|
+}
|
|
+
|
|
gboolean
|
|
meta_seat_native_set_keyboard_layout_index_finish (MetaSeatNative *seat_native,
|
|
GAsyncResult *result,
|
|
diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h
|
|
index 2799d895d2..061b580bc2 100644
|
|
--- a/src/backends/native/meta-seat-native.h
|
|
+++ b/src/backends/native/meta-seat-native.h
|
|
@@ -125,6 +125,8 @@ void meta_seat_native_set_keyboard_layout_index_async (MetaSeatNative *seat
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data);
|
|
|
|
+MetaKeymapDescription * meta_seat_native_get_keyboard_map_description (MetaSeatNative *seat_native);
|
|
+
|
|
xkb_layout_index_t meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat);
|
|
|
|
void meta_seat_native_set_keyboard_repeat (MetaSeatNative *seat,
|
|
diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h
|
|
index cd93fc9a72..63dde15575 100644
|
|
--- a/src/meta/meta-backend.h
|
|
+++ b/src/meta/meta-backend.h
|
|
@@ -56,6 +56,9 @@ void meta_backend_set_keymap_async (MetaBackend *backend,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data);
|
|
|
|
+META_EXPORT
|
|
+MetaKeymapDescription * meta_backend_get_keymap_description (MetaBackend *backend);
|
|
+
|
|
META_EXPORT
|
|
gboolean meta_backend_set_keymap_layout_group_finish (MetaBackend *backend,
|
|
GAsyncResult *result,
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 7f512c1d8a6e3222d79756852a20c0d161d145cc Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Thu, 2 Oct 2025 10:30:16 +0200
|
|
Subject: [PATCH 18/32] keymap-description: Provide descriptive names together
|
|
with xkb_keymap
|
|
|
|
These descriptive names are meant to e.g. show in the GNOME Shell input
|
|
source indicator if the keymap is set from something other than GNOME
|
|
Shell itself.
|
|
|
|
Both the short and long names are optional, e.g. not needed by the
|
|
default shell, which doesn't show the current layout, however, will fall
|
|
back on the name from the xkb_keymap itself if not specified.
|
|
|
|
For rules based keymaps, the one creating said keymap can specify both
|
|
the display name and short name, and for the descriptions created for
|
|
serialized keymaps derive them by searching for the short name in the
|
|
XKB registry given the display name.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit f74b640c6ae69338affcc23d9061f8ee73d6fe71)
|
|
---
|
|
meson.build | 1 +
|
|
.../meta-keymap-description-private.h | 2 +
|
|
src/backends/meta-keymap-description.c | 103 +++++++++++++++++-
|
|
src/backends/native/meta-seat-impl.c | 2 +
|
|
src/backends/native/meta-seat-native.c | 4 +
|
|
src/compositor/plugins/default.c | 3 +-
|
|
src/core/keybindings.c | 3 +
|
|
src/meson.build | 1 +
|
|
src/meta/meta-keymap-description.h | 4 +-
|
|
src/tests/keyboard-map-tests.c | 8 +-
|
|
src/tests/remote-desktop-tests.c | 2 +
|
|
11 files changed, 124 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/meson.build b/meson.build
|
|
index f77badb9ae..f508db69ec 100644
|
|
--- a/meson.build
|
|
+++ b/meson.build
|
|
@@ -131,6 +131,7 @@ libadwaita_dep = dependency('libadwaita-1', required: false)
|
|
gmodule_no_export_dep = dependency('gmodule-no-export-2.0', version: glib_req)
|
|
gnome_settings_daemon_dep = dependency('gnome-settings-daemon', required: false)
|
|
xkbcommon_dep = dependency('xkbcommon', version: xkbcommon_req)
|
|
+xkbregistry_dep = dependency('xkbregistry')
|
|
atk_dep = dependency('atk', version: atk_req)
|
|
colord_dep = dependency('colord', version: colord_req)
|
|
lcms2_dep = dependency('lcms2', version: lcms2_req)
|
|
diff --git a/src/backends/meta-keymap-description-private.h b/src/backends/meta-keymap-description-private.h
|
|
index 6504371a6c..3c0d9cc924 100644
|
|
--- a/src/backends/meta-keymap-description-private.h
|
|
+++ b/src/backends/meta-keymap-description-private.h
|
|
@@ -34,4 +34,6 @@ MetaKeymapDescription * meta_keymap_description_new_from_fd (MetaSealedFd
|
|
MetaKeymapDescriptionSource meta_keymap_description_get_source (MetaKeymapDescription *keymap_description);
|
|
|
|
struct xkb_keymap * meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_description,
|
|
+ GStrv *out_display_names,
|
|
+ GStrv *out_short_names,
|
|
GError **error);
|
|
diff --git a/src/backends/meta-keymap-description.c b/src/backends/meta-keymap-description.c
|
|
index 77d372824e..63bd539d57 100644
|
|
--- a/src/backends/meta-keymap-description.c
|
|
+++ b/src/backends/meta-keymap-description.c
|
|
@@ -39,6 +39,8 @@ struct _MetaKeymapDescription
|
|
char *layout;
|
|
char *variant;
|
|
char *options;
|
|
+ GStrv display_names;
|
|
+ GStrv short_names;
|
|
} rules;
|
|
struct {
|
|
MetaSealedFd *sealed_fd;
|
|
@@ -64,7 +66,9 @@ MetaKeymapDescription *
|
|
meta_keymap_description_new_from_rules (const char *model,
|
|
const char *layout,
|
|
const char *variant,
|
|
- const char *options)
|
|
+ const char *options,
|
|
+ GStrv display_names,
|
|
+ GStrv short_names)
|
|
{
|
|
MetaKeymapDescription *keymap_description;
|
|
|
|
@@ -76,6 +80,8 @@ meta_keymap_description_new_from_rules (const char *model,
|
|
keymap_description->rules.layout = strdup_or_empty (layout);
|
|
keymap_description->rules.variant = strdup_or_empty (variant);
|
|
keymap_description->rules.options = strdup_or_empty (options);
|
|
+ keymap_description->rules.display_names = g_strdupv (display_names);
|
|
+ keymap_description->rules.short_names = g_strdupv (short_names);
|
|
|
|
return keymap_description;
|
|
}
|
|
@@ -114,6 +120,8 @@ meta_keymap_description_unref (MetaKeymapDescription *keymap_description)
|
|
g_free (keymap_description->rules.layout);
|
|
g_free (keymap_description->rules.variant);
|
|
g_free (keymap_description->rules.options);
|
|
+ g_strfreev (keymap_description->rules.display_names);
|
|
+ g_strfreev (keymap_description->rules.short_names);
|
|
break;
|
|
case META_KEYMAP_DESCRIPTION_SOURCE_FD:
|
|
g_clear_object (&keymap_description->fd.sealed_fd);
|
|
@@ -130,17 +138,42 @@ meta_keymap_description_get_source (MetaKeymapDescription *keymap_description)
|
|
return keymap_description->source;
|
|
}
|
|
|
|
+static char *
|
|
+maybe_derive_short_name (struct rxkb_context *rxkb_context,
|
|
+ const char *layout_name)
|
|
+{
|
|
+ struct rxkb_layout *rxkb_layout;
|
|
+ if (!layout_name)
|
|
+ return NULL;
|
|
+
|
|
+ for (rxkb_layout = rxkb_layout_first (rxkb_context);
|
|
+ rxkb_layout;
|
|
+ rxkb_layout = rxkb_layout_next (rxkb_layout))
|
|
+ {
|
|
+ if (g_strcmp0 (layout_name,
|
|
+ rxkb_layout_get_description (rxkb_layout)) == 0)
|
|
+ return g_strdup (rxkb_layout_get_brief (rxkb_layout));
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
struct xkb_keymap *
|
|
meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_description,
|
|
+ GStrv *out_display_names,
|
|
+ GStrv *out_short_names,
|
|
GError **error)
|
|
{
|
|
+ g_auto (GStrv) display_names = NULL;
|
|
+ g_auto (GStrv) short_names = NULL;
|
|
+ struct xkb_keymap *xkb_keymap = NULL;
|
|
+
|
|
switch (keymap_description->source)
|
|
{
|
|
case META_KEYMAP_DESCRIPTION_SOURCE_RULES:
|
|
{
|
|
struct xkb_rule_names names;
|
|
struct xkb_context *xkb_context;
|
|
- struct xkb_keymap *xkb_keymap;
|
|
|
|
names.rules = DEFAULT_XKB_RULES_FILE;
|
|
names.model = keymap_description->rules.model;
|
|
@@ -168,13 +201,17 @@ meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_descri
|
|
return NULL;
|
|
}
|
|
|
|
- return xkb_keymap;
|
|
+ if (out_display_names)
|
|
+ display_names = g_strdupv (keymap_description->rules.display_names);
|
|
+ if (out_short_names)
|
|
+ short_names = g_strdupv (keymap_description->rules.short_names);
|
|
+
|
|
+ break;
|
|
}
|
|
case META_KEYMAP_DESCRIPTION_SOURCE_FD:
|
|
{
|
|
g_autoptr (GBytes) keymap_bytes = NULL;
|
|
struct xkb_context *xkb_context;
|
|
- struct xkb_keymap *xkb_keymap;
|
|
|
|
keymap_bytes =
|
|
meta_sealed_fd_get_bytes (keymap_description->fd.sealed_fd, error);
|
|
@@ -196,9 +233,63 @@ meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_descri
|
|
return NULL;
|
|
}
|
|
|
|
- return xkb_keymap;
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
- g_assert_not_reached ();
|
|
+ g_assert (xkb_keymap);
|
|
+
|
|
+ if (out_display_names && !display_names)
|
|
+ {
|
|
+ g_autoptr (GStrvBuilder) display_names_builder = NULL;
|
|
+ xkb_layout_index_t n_layouts, i;
|
|
+
|
|
+ display_names_builder = g_strv_builder_new ();
|
|
+ n_layouts = xkb_keymap_num_layouts (xkb_keymap);
|
|
+ for (i = 0; i < n_layouts; i++)
|
|
+ {
|
|
+ const char *display_name;
|
|
+
|
|
+ display_name = xkb_keymap_layout_get_name (xkb_keymap, i);
|
|
+ g_strv_builder_add (display_names_builder,
|
|
+ display_name ? display_name : "");
|
|
+ }
|
|
+
|
|
+ display_names = g_strv_builder_end (display_names_builder);
|
|
+ }
|
|
+
|
|
+ if (out_short_names && !short_names)
|
|
+ {
|
|
+ g_autoptr (GStrvBuilder) short_names_builder = NULL;
|
|
+ struct rxkb_context *rxkb_context = NULL;
|
|
+
|
|
+ short_names_builder = g_strv_builder_new ();
|
|
+
|
|
+ rxkb_context = rxkb_context_new (RXKB_CONTEXT_LOAD_EXOTIC_RULES);
|
|
+ if (rxkb_context_parse (rxkb_context, "evdev"))
|
|
+ {
|
|
+ xkb_layout_index_t n_layouts, i;
|
|
+
|
|
+ n_layouts = xkb_keymap_num_layouts (xkb_keymap);
|
|
+ for (i = 0; i < n_layouts; i++)
|
|
+ {
|
|
+ g_autofree char *short_name = NULL;
|
|
+
|
|
+ short_name = maybe_derive_short_name (rxkb_context,
|
|
+ display_names[i]);
|
|
+ g_strv_builder_add (short_names_builder,
|
|
+ short_name ? short_name : "");
|
|
+ }
|
|
+
|
|
+ short_names = g_strv_builder_end (short_names_builder);
|
|
+ }
|
|
+ rxkb_context_unref (rxkb_context);
|
|
+ }
|
|
+
|
|
+ if (out_display_names)
|
|
+ *out_display_names = g_steal_pointer (&display_names);
|
|
+ if (out_short_names)
|
|
+ *out_short_names = g_steal_pointer (&short_names);
|
|
+
|
|
+ return xkb_keymap;
|
|
}
|
|
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
|
|
index f2ef0d8166..a5d490d12b 100644
|
|
--- a/src/backends/native/meta-seat-impl.c
|
|
+++ b/src/backends/native/meta-seat-impl.c
|
|
@@ -3857,6 +3857,8 @@ set_keyboard_map (GTask *task)
|
|
keymap = seat_impl->keymap;
|
|
|
|
xkb_keymap = meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
+ NULL,
|
|
+ NULL,
|
|
&error);
|
|
if (!xkb_keymap)
|
|
{
|
|
diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c
|
|
index fc849044f9..5498bac13f 100644
|
|
--- a/src/backends/native/meta-seat-native.c
|
|
+++ b/src/backends/native/meta-seat-native.c
|
|
@@ -173,6 +173,7 @@ on_keymap_changed (MetaKeymapNative *keymap_native,
|
|
|
|
xkb_keymap =
|
|
meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
+ NULL, NULL,
|
|
&error);
|
|
if (!xkb_keymap)
|
|
{
|
|
@@ -222,6 +223,8 @@ meta_seat_native_constructed (GObject *object)
|
|
keymap_description = meta_keymap_description_new_from_rules (NULL,
|
|
"us",
|
|
NULL,
|
|
+ NULL,
|
|
+ NULL,
|
|
NULL);
|
|
if (!meta_seat_native_set_keyboard_map_sync (seat,
|
|
keymap_description, 0,
|
|
@@ -688,6 +691,7 @@ meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
|
|
xkb_keymap =
|
|
meta_keymap_description_create_xkb_keymap (description,
|
|
+ NULL, NULL,
|
|
error);
|
|
if (!xkb_keymap)
|
|
return FALSE;
|
|
diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c
|
|
index 3ce1e491e1..cbce7ab959 100644
|
|
--- a/src/compositor/plugins/default.c
|
|
+++ b/src/compositor/plugins/default.c
|
|
@@ -418,7 +418,8 @@ init_keymap (MetaDefaultPlugin *self,
|
|
keymap_description = meta_keymap_description_new_from_rules (x11_model,
|
|
x11_layout,
|
|
x11_variant,
|
|
- x11_options);
|
|
+ x11_options,
|
|
+ NULL, NULL);
|
|
|
|
meta_backend_set_keymap_async (backend,
|
|
keymap_description, 0,
|
|
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
|
|
index 0f475eae3b..6f879eed8e 100644
|
|
--- a/src/core/keybindings.c
|
|
+++ b/src/core/keybindings.c
|
|
@@ -773,8 +773,11 @@ create_us_layout (void)
|
|
keymap_description = meta_keymap_description_new_from_rules (NULL,
|
|
"us",
|
|
NULL,
|
|
+ NULL,
|
|
+ NULL,
|
|
NULL);
|
|
keymap = meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
+ NULL, NULL,
|
|
&error);
|
|
if (!keymap)
|
|
{
|
|
diff --git a/src/meson.build b/src/meson.build
|
|
index 59e8f079c2..72b70e3199 100644
|
|
--- a/src/meson.build
|
|
+++ b/src/meson.build
|
|
@@ -26,6 +26,7 @@ mutter_pkg_private_deps = [
|
|
gnome_settings_daemon_dep,
|
|
xkbcommon_dep,
|
|
gdk_pixbuf_dep,
|
|
+ xkbregistry_dep,
|
|
libeis_dep,
|
|
libdisplay_info_dep,
|
|
]
|
|
diff --git a/src/meta/meta-keymap-description.h b/src/meta/meta-keymap-description.h
|
|
index 32e9ef6d2d..5140f63b1a 100644
|
|
--- a/src/meta/meta-keymap-description.h
|
|
+++ b/src/meta/meta-keymap-description.h
|
|
@@ -32,7 +32,9 @@ META_EXPORT
|
|
MetaKeymapDescription * meta_keymap_description_new_from_rules (const char *model,
|
|
const char *layout,
|
|
const char *variant,
|
|
- const char *options);
|
|
+ const char *options,
|
|
+ GStrv display_names,
|
|
+ GStrv short_names);
|
|
|
|
META_EXPORT
|
|
MetaKeymapDescription * meta_keymap_description_ref (MetaKeymapDescription *keymap_description);
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index c307c80e83..e1a65214cc 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -160,6 +160,8 @@ meta_test_native_keyboard_map_set_async (void)
|
|
meta_keymap_description_new_from_rules (NULL,
|
|
"us",
|
|
"dvorak-alt-intl",
|
|
+ NULL,
|
|
+ NULL,
|
|
NULL);
|
|
meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
NULL, set_keymap_cb, &done);
|
|
@@ -209,7 +211,9 @@ meta_test_native_keyboard_map_change_layout (void)
|
|
meta_keymap_description_new_from_rules (NULL,
|
|
"us,ua",
|
|
NULL,
|
|
- "grp:caps_select");
|
|
+ "grp:caps_select",
|
|
+ NULL,
|
|
+ NULL);
|
|
meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
NULL, set_keymap_cb, &done);
|
|
|
|
@@ -291,6 +295,8 @@ meta_test_native_keyboard_map_set_layout_index (void)
|
|
meta_keymap_description_new_from_rules (NULL,
|
|
"us,se",
|
|
"dvorak-alt-intl,svdvorak",
|
|
+ NULL,
|
|
+ NULL,
|
|
NULL);
|
|
meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
NULL, set_keymap_cb, &done);
|
|
diff --git a/src/tests/remote-desktop-tests.c b/src/tests/remote-desktop-tests.c
|
|
index 75266a0838..9ebc320bd0 100644
|
|
--- a/src/tests/remote-desktop-tests.c
|
|
+++ b/src/tests/remote-desktop-tests.c
|
|
@@ -76,6 +76,8 @@ remote_desktop_test_client_command (int argc,
|
|
keymap_description = meta_keymap_description_new_from_rules (NULL,
|
|
layout,
|
|
variant,
|
|
+ NULL,
|
|
+ NULL,
|
|
NULL);
|
|
meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
NULL, set_keymap_cb, &done);
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From c01134a4584fad21873333bdbabf06439da9050e Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 1 Oct 2025 15:14:40 +0200
|
|
Subject: [PATCH 19/32] clutter/keymap: Add API to update/get layout names
|
|
|
|
It's up to the backend to set the names, and the getters are
|
|
opportunistic, i.e. will return NULL if none is available.
|
|
|
|
The names comes from the keymap description.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit bafbde3f2c47e224beff9547bf9254f7cff79a17)
|
|
---
|
|
clutter/clutter/clutter-keymap-private.h | 5 ++
|
|
clutter/clutter/clutter-keymap.c | 67 +++++++++++++++++++
|
|
clutter/clutter/clutter-keymap.h | 18 +++++
|
|
.../native/meta-keymap-native-private.h | 4 +-
|
|
src/backends/native/meta-keymap-native.c | 15 ++++-
|
|
src/backends/native/meta-seat-impl.c | 10 ++-
|
|
6 files changed, 114 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/clutter/clutter/clutter-keymap-private.h b/clutter/clutter/clutter-keymap-private.h
|
|
index 5b65b880aa..2b52666bce 100644
|
|
--- a/clutter/clutter/clutter-keymap-private.h
|
|
+++ b/clutter/clutter/clutter-keymap-private.h
|
|
@@ -29,3 +29,8 @@ gboolean clutter_keymap_update_state (ClutterKeymap *keymap,
|
|
xkb_mod_mask_t latched_mods,
|
|
xkb_mod_mask_t locked_mods,
|
|
gboolean emit_signal);
|
|
+
|
|
+CLUTTER_EXPORT
|
|
+void clutter_keymap_update_keymap_names (ClutterKeymap *keymap,
|
|
+ GStrv display_names,
|
|
+ GStrv short_names);
|
|
diff --git a/clutter/clutter/clutter-keymap.c b/clutter/clutter/clutter-keymap.c
|
|
index 4073da4f17..ddcf568f78 100644
|
|
--- a/clutter/clutter/clutter-keymap.c
|
|
+++ b/clutter/clutter/clutter-keymap.c
|
|
@@ -44,6 +44,9 @@ typedef struct _ClutterKeymapPrivate
|
|
xkb_mod_mask_t locked_mods;
|
|
|
|
xkb_layout_index_t effective_layout_group;
|
|
+
|
|
+ GStrv display_names;
|
|
+ GStrv short_names;
|
|
} ClutterKeymapPrivate;
|
|
|
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterKeymap, clutter_keymap,
|
|
@@ -103,6 +106,18 @@ clutter_keymap_set_property (GObject *object,
|
|
}
|
|
}
|
|
|
|
+static void
|
|
+clutter_keymap_finalize (GObject *object)
|
|
+{
|
|
+ ClutterKeymap *keymap = CLUTTER_KEYMAP (object);
|
|
+ ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
|
+
|
|
+ g_clear_pointer (&priv->display_names, g_strfreev);
|
|
+ g_clear_pointer (&priv->short_names, g_strfreev);
|
|
+
|
|
+ G_OBJECT_CLASS (clutter_keymap_parent_class)->finalize (object);
|
|
+}
|
|
+
|
|
static void
|
|
clutter_keymap_class_init (ClutterKeymapClass *klass)
|
|
{
|
|
@@ -110,6 +125,7 @@ clutter_keymap_class_init (ClutterKeymapClass *klass)
|
|
|
|
object_class->get_property = clutter_keymap_get_property;
|
|
object_class->set_property = clutter_keymap_set_property;
|
|
+ object_class->finalize = clutter_keymap_finalize;
|
|
|
|
obj_props[PROP_CAPS_LOCK_STATE] =
|
|
g_param_spec_boolean ("caps-lock-state", NULL, NULL,
|
|
@@ -208,6 +224,19 @@ clutter_keymap_update_state (ClutterKeymap *keymap,
|
|
return TRUE;
|
|
}
|
|
|
|
+void
|
|
+clutter_keymap_update_keymap_names (ClutterKeymap *keymap,
|
|
+ GStrv display_names,
|
|
+ GStrv short_names)
|
|
+{
|
|
+ ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
|
+
|
|
+ g_clear_pointer (&priv->display_names, g_strfreev);
|
|
+ g_clear_pointer (&priv->short_names, g_strfreev);
|
|
+ priv->display_names = g_steal_pointer (&display_names);
|
|
+ priv->short_names = g_steal_pointer (&short_names);
|
|
+}
|
|
+
|
|
void
|
|
clutter_keymap_get_modifier_state (ClutterKeymap *keymap,
|
|
xkb_mod_mask_t *depressed_mods,
|
|
@@ -228,3 +257,41 @@ clutter_keymap_get_layout_index (ClutterKeymap *keymap)
|
|
|
|
return priv->effective_layout_group;
|
|
}
|
|
+
|
|
+const char *
|
|
+clutter_keymap_get_current_display_name (ClutterKeymap *keymap)
|
|
+{
|
|
+ ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
|
+ char *display_name;
|
|
+
|
|
+ if (!priv->display_names)
|
|
+ return NULL;
|
|
+
|
|
+ if (g_strv_length (priv->display_names) <= priv->effective_layout_group)
|
|
+ return NULL;
|
|
+
|
|
+ display_name = priv->display_names[priv->effective_layout_group];
|
|
+ if (g_strcmp0 (display_name, "") == 0)
|
|
+ return NULL;
|
|
+ else
|
|
+ return display_name;
|
|
+}
|
|
+
|
|
+const char *
|
|
+clutter_keymap_get_current_short_name (ClutterKeymap *keymap)
|
|
+{
|
|
+ ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
|
+ char *short_name;
|
|
+
|
|
+ if (!priv->short_names)
|
|
+ return NULL;
|
|
+
|
|
+ if (g_strv_length (priv->display_names) <= priv->effective_layout_group)
|
|
+ return NULL;
|
|
+
|
|
+ short_name = priv->short_names[priv->effective_layout_group];
|
|
+ if (g_strcmp0 (short_name, "") == 0)
|
|
+ return NULL;
|
|
+ else
|
|
+ return short_name;
|
|
+}
|
|
diff --git a/clutter/clutter/clutter-keymap.h b/clutter/clutter/clutter-keymap.h
|
|
index a40a90c823..eb28db39b0 100644
|
|
--- a/clutter/clutter/clutter-keymap.h
|
|
+++ b/clutter/clutter/clutter-keymap.h
|
|
@@ -68,3 +68,21 @@ void clutter_keymap_get_modifier_state (ClutterKeymap *keymap,
|
|
*/
|
|
CLUTTER_EXPORT
|
|
xkb_layout_index_t clutter_keymap_get_layout_index (ClutterKeymap *keymap);
|
|
+
|
|
+/**
|
|
+ * clutter_keymap_get_current_display_name:
|
|
+ * @keymap: A #ClutterKeymap
|
|
+ *
|
|
+ * Returns: (transfer none) (nullable): The display name of the current layout
|
|
+ */
|
|
+CLUTTER_EXPORT
|
|
+const char * clutter_keymap_get_current_display_name (ClutterKeymap *keymap);
|
|
+
|
|
+/**
|
|
+ * clutter_keymap_get_current_short_name:
|
|
+ * @keymap: A #ClutterKeymap
|
|
+ *
|
|
+ * Returns: (transfer none) (nullable): The short name of the current layout
|
|
+ */
|
|
+CLUTTER_EXPORT
|
|
+const char * clutter_keymap_get_current_short_name (ClutterKeymap *keymap);
|
|
diff --git a/src/backends/native/meta-keymap-native-private.h b/src/backends/native/meta-keymap-native-private.h
|
|
index 82d249eda8..e119b91c31 100644
|
|
--- a/src/backends/native/meta-keymap-native-private.h
|
|
+++ b/src/backends/native/meta-keymap-native-private.h
|
|
@@ -29,7 +29,9 @@ void meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
MetaSeatImpl *seat_impl,
|
|
MetaKeymapDescription *keymap_description,
|
|
struct xkb_keymap *xkb_keymap,
|
|
- struct xkb_state *xkb_state);
|
|
+ struct xkb_state *xkb_state,
|
|
+ GStrv display_names,
|
|
+ GStrv short_names);
|
|
|
|
struct xkb_keymap * meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap);
|
|
|
|
diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c
|
|
index 63f5b4cf29..f55b8bd056 100644
|
|
--- a/src/backends/native/meta-keymap-native.c
|
|
+++ b/src/backends/native/meta-keymap-native.c
|
|
@@ -163,6 +163,9 @@ typedef struct
|
|
MetaKeymapDescription *keymap_description;
|
|
|
|
ModifierState modifier_state;
|
|
+
|
|
+ GStrv display_names;
|
|
+ GStrv short_names;
|
|
} UpdateKeymapData;
|
|
|
|
static void
|
|
@@ -171,6 +174,8 @@ update_keymap_data_free (gpointer user_data)
|
|
UpdateKeymapData *data = user_data;
|
|
|
|
meta_keymap_description_unref (data->keymap_description);
|
|
+ g_strfreev (data->display_names);
|
|
+ g_strfreev (data->short_names);
|
|
g_free (data);
|
|
}
|
|
|
|
@@ -181,6 +186,10 @@ update_keymap_in_main (gpointer user_data)
|
|
MetaKeymapNative *keymap_native = data->keymap_native;
|
|
gboolean state_changed;
|
|
|
|
+ clutter_keymap_update_keymap_names (CLUTTER_KEYMAP (keymap_native),
|
|
+ g_steal_pointer (&data->display_names),
|
|
+ g_steal_pointer (&data->short_names));
|
|
+
|
|
state_changed = update_state_from_modifier_state (keymap_native,
|
|
&data->modifier_state,
|
|
FALSE);
|
|
@@ -198,7 +207,9 @@ meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
MetaSeatImpl *seat_impl,
|
|
MetaKeymapDescription *keymap_description,
|
|
struct xkb_keymap *xkb_keymap,
|
|
- struct xkb_state *xkb_state)
|
|
+ struct xkb_state *xkb_state,
|
|
+ GStrv display_names,
|
|
+ GStrv short_names)
|
|
{
|
|
UpdateKeymapData *data;
|
|
|
|
@@ -211,6 +222,8 @@ meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
data->keymap_native = keymap;
|
|
data->modifier_state = calculate_modifier_state (xkb_state);
|
|
data->keymap_description = meta_keymap_description_ref (keymap_description);
|
|
+ data->display_names = g_steal_pointer (&display_names);
|
|
+ data->short_names = g_steal_pointer (&short_names);
|
|
|
|
meta_seat_impl_queue_main_thread_idle (seat_impl,
|
|
update_keymap_in_main,
|
|
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
|
|
index a5d490d12b..8a429dc2ec 100644
|
|
--- a/src/backends/native/meta-seat-impl.c
|
|
+++ b/src/backends/native/meta-seat-impl.c
|
|
@@ -3851,14 +3851,16 @@ set_keyboard_map (GTask *task)
|
|
MetaKeymapNative *keymap;
|
|
g_autoptr (GError) error = NULL;
|
|
struct xkb_keymap *xkb_keymap;
|
|
+ g_auto (GStrv) display_names = NULL;
|
|
+ g_auto (GStrv) short_names = NULL;
|
|
|
|
g_task_set_priority (task, G_PRIORITY_HIGH);
|
|
|
|
keymap = seat_impl->keymap;
|
|
|
|
xkb_keymap = meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
- NULL,
|
|
- NULL,
|
|
+ &display_names,
|
|
+ &short_names,
|
|
&error);
|
|
if (!xkb_keymap)
|
|
{
|
|
@@ -3877,7 +3879,9 @@ set_keyboard_map (GTask *task)
|
|
seat_impl,
|
|
keymap_description,
|
|
xkb_keymap,
|
|
- seat_impl->xkb);
|
|
+ seat_impl->xkb,
|
|
+ g_steal_pointer (&display_names),
|
|
+ g_steal_pointer (&short_names));
|
|
xkb_keymap_unref (xkb_keymap);
|
|
|
|
g_rw_lock_writer_unlock (&seat_impl->state_lock);
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 949bfcc52cae826b15785d462104cc299bbddfd4 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Thu, 2 Oct 2025 10:55:13 +0200
|
|
Subject: [PATCH 20/32] wayland/keyboard: Get the current layout index after
|
|
keymap changes
|
|
|
|
The current layout index will potentially have changed together with the
|
|
keymap, so don't assume it was left unchanged.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit af4ca9a925e87a303a652da13931d4aeed872afc)
|
|
---
|
|
src/wayland/meta-wayland-keyboard.c | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c
|
|
index d7e044c458..451c9d834d 100644
|
|
--- a/src/wayland/meta-wayland-keyboard.c
|
|
+++ b/src/wayland/meta-wayland-keyboard.c
|
|
@@ -159,6 +159,7 @@ static void
|
|
meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
|
|
struct xkb_keymap *keymap)
|
|
{
|
|
+ MetaBackend *backend = backend_from_keyboard (keyboard);
|
|
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
|
|
char *keymap_string;
|
|
size_t keymap_size;
|
|
@@ -198,6 +199,7 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
|
|
|
|
inform_clients_of_new_keymap (keyboard);
|
|
|
|
+ keyboard->xkb_info.group = meta_backend_get_keymap_layout_group (backend);
|
|
notify_modifiers (keyboard);
|
|
}
|
|
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 752d689006a19a573743dd3ae74cb6f39d61ed6d Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Thu, 2 Oct 2025 11:19:07 +0200
|
|
Subject: [PATCH 21/32] backend: Add signals to 'reset' the keymap and layout
|
|
index
|
|
|
|
This allows users of libmutter to fall back on any previously used
|
|
keyboard layout once a locked keymap description is unset.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 6279a85c31710610d551fd71d209dc8cee191f1d)
|
|
---
|
|
src/backends/meta-backend-private.h | 9 ++++
|
|
src/backends/meta-backend.c | 70 +++++++++++++++++++++++++++++
|
|
src/compositor/plugins/default.c | 34 ++++++++++++++
|
|
3 files changed, 113 insertions(+)
|
|
|
|
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
|
|
index dccd1116a6..e3b4c308db 100644
|
|
--- a/src/backends/meta-backend-private.h
|
|
+++ b/src/backends/meta-backend-private.h
|
|
@@ -217,6 +217,15 @@ struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
|
|
META_EXPORT_TEST
|
|
xkb_layout_index_t meta_backend_get_keymap_layout_group (MetaBackend *backend);
|
|
|
|
+gboolean meta_backend_reset_keymap_finish (MetaBackend *backend,
|
|
+ GAsyncResult *result,
|
|
+ GError **error);
|
|
+
|
|
+void meta_backend_reset_keymap_async (MetaBackend *backend,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data);
|
|
+
|
|
gboolean meta_backend_is_lid_closed (MetaBackend *backend);
|
|
|
|
void meta_backend_set_client_pointer_constraint (MetaBackend *backend,
|
|
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
|
|
index beaec1f281..031c0a03cb 100644
|
|
--- a/src/backends/meta-backend.c
|
|
+++ b/src/backends/meta-backend.c
|
|
@@ -122,6 +122,8 @@ enum
|
|
LID_IS_CLOSED_CHANGED,
|
|
GPU_ADDED,
|
|
PREPARE_SHUTDOWN,
|
|
+ RESET_KEYMAP_DESCRIPTION,
|
|
+ RESET_KEYMAP_LAYOUT_INDEX,
|
|
|
|
N_SIGNALS
|
|
};
|
|
@@ -963,6 +965,20 @@ meta_backend_class_init (MetaBackendClass *klass)
|
|
0,
|
|
NULL, NULL, NULL,
|
|
G_TYPE_NONE, 0);
|
|
+ signals[RESET_KEYMAP_DESCRIPTION] =
|
|
+ g_signal_new ("reset-keymap-description",
|
|
+ G_TYPE_FROM_CLASS (klass),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ 0,
|
|
+ g_signal_accumulator_first_wins, NULL, NULL,
|
|
+ META_TYPE_KEYMAP_DESCRIPTION, 0);
|
|
+ signals[RESET_KEYMAP_LAYOUT_INDEX] =
|
|
+ g_signal_new ("reset-keymap-layout-index",
|
|
+ G_TYPE_FROM_CLASS (klass),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ 0,
|
|
+ g_signal_accumulator_first_wins, NULL, NULL,
|
|
+ G_TYPE_UINT, 0);
|
|
}
|
|
|
|
#ifdef HAVE_LOGIND
|
|
@@ -1851,6 +1867,60 @@ meta_backend_set_keymap_layout_group_async (MetaBackend *backend,
|
|
task);
|
|
}
|
|
|
|
+gboolean
|
|
+meta_backend_reset_keymap_finish (MetaBackend *backend,
|
|
+ GAsyncResult *result,
|
|
+ GError **error)
|
|
+{
|
|
+ GTask *task = G_TASK (result);
|
|
+
|
|
+ g_return_val_if_fail (g_task_is_valid (result, backend), FALSE);
|
|
+ g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
|
+ meta_backend_reset_keymap_async, FALSE);
|
|
+
|
|
+ return g_task_propagate_boolean (task, error);
|
|
+}
|
|
+
|
|
+void
|
|
+meta_backend_reset_keymap_async (MetaBackend *backend,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
+ uint32_t layout_index = 0;
|
|
+ GTask *task;
|
|
+
|
|
+ g_signal_emit (backend,
|
|
+ signals[RESET_KEYMAP_DESCRIPTION], 0,
|
|
+ &keymap_description);
|
|
+ g_signal_emit (backend,
|
|
+ signals[RESET_KEYMAP_LAYOUT_INDEX], 0,
|
|
+ &layout_index);
|
|
+
|
|
+ if (!keymap_description)
|
|
+ {
|
|
+ g_warning ("No fallback keymap description available, "
|
|
+ "falling batk to 'us'");
|
|
+ keymap_description =
|
|
+ meta_keymap_description_new_from_rules (NULL,
|
|
+ "us",
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL);
|
|
+ layout_index = 0;
|
|
+ }
|
|
+
|
|
+ task = g_task_new (G_OBJECT (backend), cancellable, callback, user_data);
|
|
+ g_task_set_source_tag (task, meta_backend_reset_keymap_async);
|
|
+
|
|
+ META_BACKEND_GET_CLASS (backend)->set_keymap_async (backend,
|
|
+ keymap_description,
|
|
+ layout_index,
|
|
+ task);
|
|
+}
|
|
+
|
|
/**
|
|
* meta_backend_get_stage:
|
|
* @backend: A #MetaBackend
|
|
diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c
|
|
index cbce7ab959..cc11c2df8a 100644
|
|
--- a/src/compositor/plugins/default.c
|
|
+++ b/src/compositor/plugins/default.c
|
|
@@ -117,6 +117,8 @@ struct _MetaDefaultPluginPrivate
|
|
ClutterActor *desktop2;
|
|
|
|
ClutterActor *background_group;
|
|
+
|
|
+ MetaKeymapDescription *keymap_description;
|
|
};
|
|
|
|
META_PLUGIN_DECLARE_WITH_CODE (MetaDefaultPlugin, meta_default_plugin,
|
|
@@ -149,11 +151,24 @@ typedef struct _DisplayTilePreview
|
|
MtkRectangle tile_rect;
|
|
} DisplayTilePreview;
|
|
|
|
+static void
|
|
+meta_default_plugin_finalize (GObject *object)
|
|
+{
|
|
+ MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (object)->priv;
|
|
+
|
|
+ g_clear_pointer (&priv->keymap_description, meta_keymap_description_unref);
|
|
+
|
|
+ G_OBJECT_CLASS (meta_default_plugin_parent_class)->finalize (object);
|
|
+}
|
|
+
|
|
static void
|
|
meta_default_plugin_class_init (MetaDefaultPluginClass *klass)
|
|
{
|
|
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
MetaPluginClass *plugin_class = META_PLUGIN_CLASS (klass);
|
|
|
|
+ object_class->finalize = meta_default_plugin_finalize;
|
|
+
|
|
plugin_class->start = start;
|
|
plugin_class->map = map;
|
|
plugin_class->minimize = minimize;
|
|
@@ -356,6 +371,7 @@ static void
|
|
init_keymap (MetaDefaultPlugin *self,
|
|
MetaBackend *backend)
|
|
{
|
|
+ MetaDefaultPluginPrivate *priv = self->priv;
|
|
g_autoptr (GError) error = NULL;
|
|
g_autoptr (GDBusProxy) proxy = NULL;
|
|
g_autoptr (GVariant) result = NULL;
|
|
@@ -424,6 +440,9 @@ init_keymap (MetaDefaultPlugin *self,
|
|
meta_backend_set_keymap_async (backend,
|
|
keymap_description, 0,
|
|
NULL, NULL, NULL);
|
|
+
|
|
+
|
|
+ priv->keymap_description = meta_keymap_description_ref (keymap_description);
|
|
}
|
|
|
|
static void
|
|
@@ -433,6 +452,18 @@ prepare_shutdown (MetaBackend *backend,
|
|
kill_switch_workspace (META_PLUGIN (plugin));
|
|
}
|
|
|
|
+static MetaKeymapDescription *
|
|
+on_reset_keymap_description (MetaBackend *backend,
|
|
+ MetaDefaultPlugin *self)
|
|
+{
|
|
+ MetaDefaultPluginPrivate *priv = self->priv;
|
|
+
|
|
+ if (priv->keymap_description)
|
|
+ return meta_keymap_description_ref (priv->keymap_description);
|
|
+ else
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
static void
|
|
start (MetaPlugin *plugin)
|
|
{
|
|
@@ -453,6 +484,9 @@ start (MetaPlugin *plugin)
|
|
|
|
on_monitors_changed (monitor_manager, plugin);
|
|
|
|
+ g_signal_connect (backend, "reset-keymap-description",
|
|
+ G_CALLBACK (on_reset_keymap_description), self);
|
|
+
|
|
g_signal_connect (backend, "prepare-shutdown",
|
|
G_CALLBACK (prepare_shutdown),
|
|
self);
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 74ea326e9b6ceeb9ea42180918fb6422099fd54f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Mon, 15 Dec 2025 13:27:00 +0100
|
|
Subject: [PATCH 22/32] backend: Combine set_keymap() and
|
|
set_keymap_layout_group()
|
|
|
|
We can already skip changing the actual keymap by comparing whether the
|
|
keymap description was replaced by some other one, meaning the the
|
|
layout index only API is redundant.
|
|
|
|
Doing this also allows us to avoid a race condition where one entity
|
|
sets the layout index on a description that was just replaced by another
|
|
entity. This is now resolved by the layout index change replacing also
|
|
the keymap, but in theory this can be now be tweaked, would we want to,
|
|
by adding flags.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 5cc1cd137d88971d289f30f80cde56d991413a92)
|
|
---
|
|
src/backends/meta-backend-private.h | 4 -
|
|
src/backends/meta-backend.c | 31 ----
|
|
src/backends/native/meta-backend-native.c | 49 ------
|
|
src/backends/native/meta-seat-impl.c | 185 +++++++++-------------
|
|
src/backends/native/meta-seat-impl.h | 10 --
|
|
src/backends/native/meta-seat-native.c | 70 --------
|
|
src/backends/native/meta-seat-native.h | 10 --
|
|
src/tests/keyboard-map-tests.c | 29 ++--
|
|
8 files changed, 99 insertions(+), 289 deletions(-)
|
|
|
|
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
|
|
index e3b4c308db..c82d41032d 100644
|
|
--- a/src/backends/meta-backend-private.h
|
|
+++ b/src/backends/meta-backend-private.h
|
|
@@ -135,10 +135,6 @@ struct _MetaBackendClass
|
|
|
|
xkb_layout_index_t (* get_keymap_layout_group) (MetaBackend *backend);
|
|
|
|
- void (* set_keymap_layout_group_async) (MetaBackend *backend,
|
|
- xkb_layout_index_t idx,
|
|
- GTask *task);
|
|
-
|
|
void (* update_stage) (MetaBackend *backend);
|
|
|
|
void (* select_stage_events) (MetaBackend *backend);
|
|
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
|
|
index 031c0a03cb..03ebf27ee4 100644
|
|
--- a/src/backends/meta-backend.c
|
|
+++ b/src/backends/meta-backend.c
|
|
@@ -1836,37 +1836,6 @@ meta_backend_get_keymap_layout_group (MetaBackend *backend)
|
|
return META_BACKEND_GET_CLASS (backend)->get_keymap_layout_group (backend);
|
|
}
|
|
|
|
-gboolean
|
|
-meta_backend_set_keymap_layout_group_finish (MetaBackend *backend,
|
|
- GAsyncResult *result,
|
|
- GError **error)
|
|
-{
|
|
- GTask *task = G_TASK (result);
|
|
-
|
|
- g_return_val_if_fail (g_task_is_valid (result, backend), FALSE);
|
|
- g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
|
- meta_backend_set_keymap_layout_group_async, FALSE);
|
|
-
|
|
- return g_task_propagate_boolean (task, error);
|
|
-}
|
|
-
|
|
-void
|
|
-meta_backend_set_keymap_layout_group_async (MetaBackend *backend,
|
|
- uint32_t idx,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data)
|
|
-{
|
|
- GTask *task;
|
|
-
|
|
- task = g_task_new (G_OBJECT (backend), cancellable, callback, user_data);
|
|
- g_task_set_source_tag (task, meta_backend_set_keymap_layout_group_async);
|
|
-
|
|
- META_BACKEND_GET_CLASS (backend)->set_keymap_layout_group_async (backend,
|
|
- idx,
|
|
- task);
|
|
-}
|
|
-
|
|
gboolean
|
|
meta_backend_reset_keymap_finish (MetaBackend *backend,
|
|
GAsyncResult *result,
|
|
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
|
|
index b2efac59d1..7d68894cb8 100644
|
|
--- a/src/backends/native/meta-backend-native.c
|
|
+++ b/src/backends/native/meta-backend-native.c
|
|
@@ -384,54 +384,6 @@ meta_backend_native_get_keymap_layout_group (MetaBackend *backend)
|
|
return meta_seat_native_get_keyboard_layout_index (META_SEAT_NATIVE (seat));
|
|
}
|
|
|
|
-static void
|
|
-set_layout_index_cb (GObject *source_object,
|
|
- GAsyncResult *result,
|
|
- gpointer user_data)
|
|
-{
|
|
- MetaSeatNative *seat_native = META_SEAT_NATIVE (source_object);
|
|
- g_autoptr (GTask) task = G_TASK (user_data);
|
|
- MetaBackend *backend = META_BACKEND (g_task_get_source_object (task));
|
|
- g_autoptr (GError) error = NULL;
|
|
- gboolean index_changed;
|
|
-
|
|
- index_changed =
|
|
- meta_seat_native_set_keyboard_layout_index_finish (seat_native,
|
|
- result,
|
|
- &error);
|
|
- if (error)
|
|
- {
|
|
- g_task_return_error (task, g_steal_pointer (&error));
|
|
- return;
|
|
- }
|
|
-
|
|
- if (index_changed)
|
|
- {
|
|
- xkb_layout_index_t idx;
|
|
-
|
|
- idx = meta_seat_native_get_keyboard_layout_index (seat_native);
|
|
- meta_backend_notify_keymap_layout_group_changed (backend, idx);
|
|
- }
|
|
-
|
|
- g_task_return_boolean (task, TRUE);
|
|
-}
|
|
-
|
|
-static void
|
|
-meta_backend_native_set_keymap_layout_group_async (MetaBackend *backend,
|
|
- xkb_layout_index_t idx,
|
|
- GTask *task)
|
|
-{
|
|
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
|
- ClutterSeat *seat;
|
|
-
|
|
- seat = clutter_backend_get_default_seat (clutter_backend);
|
|
- meta_seat_native_set_keyboard_layout_index_async (META_SEAT_NATIVE (seat),
|
|
- idx,
|
|
- g_task_get_cancellable (task),
|
|
- set_layout_index_cb,
|
|
- task);
|
|
-}
|
|
-
|
|
static gboolean
|
|
meta_backend_native_is_headless (MetaBackend *backend)
|
|
{
|
|
@@ -954,7 +906,6 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
|
backend_class->get_keymap = meta_backend_native_get_keymap;
|
|
backend_class->get_keymap_description = meta_backend_native_get_keymap_description;
|
|
backend_class->get_keymap_layout_group = meta_backend_native_get_keymap_layout_group;
|
|
- backend_class->set_keymap_layout_group_async = meta_backend_native_set_keymap_layout_group_async;
|
|
backend_class->update_stage = meta_backend_native_update_stage;
|
|
|
|
backend_class->set_pointer_constraint = meta_backend_native_set_pointer_constraint;
|
|
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
|
|
index 8a429dc2ec..7c94a6c5cc 100644
|
|
--- a/src/backends/native/meta-seat-impl.c
|
|
+++ b/src/backends/native/meta-seat-impl.c
|
|
@@ -133,6 +133,8 @@ typedef struct _MetaSeatImplPrivate
|
|
uint32_t last_keysym_time;
|
|
gboolean saw_first_release;
|
|
} a11y;
|
|
+
|
|
+ MetaKeymapDescription *keymap_description;
|
|
} MetaSeatImplPrivate;
|
|
|
|
static void meta_seat_impl_initable_iface_init (GInitableIface *iface);
|
|
@@ -3403,6 +3405,7 @@ static void
|
|
meta_seat_impl_finalize (GObject *object)
|
|
{
|
|
MetaSeatImpl *seat_impl = META_SEAT_IMPL (object);
|
|
+ MetaSeatImplPrivate *priv = meta_seat_impl_get_instance_private (seat_impl);
|
|
|
|
g_assert (!seat_impl->libinput);
|
|
g_assert (!seat_impl->tools);
|
|
@@ -3410,6 +3413,9 @@ meta_seat_impl_finalize (GObject *object)
|
|
|
|
g_free (seat_impl->seat_id);
|
|
|
|
+ g_clear_pointer (&priv->keymap_description,
|
|
+ meta_keymap_description_unref);
|
|
+
|
|
g_rw_lock_clear (&seat_impl->state_lock);
|
|
|
|
G_OBJECT_CLASS (meta_seat_impl_parent_class)->finalize (object);
|
|
@@ -3842,47 +3848,92 @@ set_keymap_data_free (gpointer user_data)
|
|
g_free (data);
|
|
}
|
|
|
|
+static void
|
|
+update_layout_index_unlocked (MetaSeatImpl *seat_impl,
|
|
+ xkb_layout_index_t layout_index)
|
|
+{
|
|
+ xkb_mod_mask_t depressed_mods;
|
|
+ xkb_mod_mask_t latched_mods;
|
|
+ xkb_mod_mask_t locked_mods;
|
|
+ struct xkb_state *state;
|
|
+
|
|
+ state = seat_impl->xkb;
|
|
+
|
|
+ depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED);
|
|
+ latched_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED);
|
|
+ locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED);
|
|
+
|
|
+ xkb_state_update_mask (state,
|
|
+ depressed_mods,
|
|
+ latched_mods,
|
|
+ locked_mods,
|
|
+ 0, 0, layout_index);
|
|
+
|
|
+ seat_impl->layout_idx = layout_index;
|
|
+
|
|
+ meta_seat_impl_sync_leds_in_impl (seat_impl);
|
|
+ meta_keymap_native_update_in_impl (seat_impl->keymap,
|
|
+ seat_impl,
|
|
+ seat_impl->xkb);
|
|
+}
|
|
+
|
|
static gboolean
|
|
set_keyboard_map (GTask *task)
|
|
{
|
|
MetaSeatImpl *seat_impl = g_task_get_source_object (task);
|
|
+ MetaSeatImplPrivate *priv =
|
|
+ meta_seat_impl_get_instance_private (seat_impl);
|
|
SetKeymapData *data = g_task_get_task_data (task);
|
|
MetaKeymapDescription *keymap_description = data->keymap_description;
|
|
MetaKeymapNative *keymap;
|
|
- g_autoptr (GError) error = NULL;
|
|
- struct xkb_keymap *xkb_keymap;
|
|
- g_auto (GStrv) display_names = NULL;
|
|
- g_auto (GStrv) short_names = NULL;
|
|
|
|
g_task_set_priority (task, G_PRIORITY_HIGH);
|
|
|
|
- keymap = seat_impl->keymap;
|
|
-
|
|
- xkb_keymap = meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
- &display_names,
|
|
- &short_names,
|
|
- &error);
|
|
- if (!xkb_keymap)
|
|
- {
|
|
- g_prefix_error (&error, "Unable to load configured keymap: ");
|
|
- g_task_return_error (task, g_steal_pointer (&error));
|
|
- return G_SOURCE_REMOVE;
|
|
- }
|
|
-
|
|
g_rw_lock_writer_lock (&seat_impl->state_lock);
|
|
|
|
- meta_seat_impl_update_xkb_state_in_impl_unlocked (seat_impl,
|
|
- xkb_keymap,
|
|
- data->layout_index);
|
|
+ if (priv->keymap_description != keymap_description)
|
|
+ {
|
|
+ g_autoptr (GError) error = NULL;
|
|
+ g_auto (GStrv) display_names = NULL;
|
|
+ g_auto (GStrv) short_names = NULL;
|
|
+ struct xkb_keymap *xkb_keymap = NULL;
|
|
+
|
|
+ g_clear_pointer (&priv->keymap_description,
|
|
+ meta_keymap_description_unref);
|
|
+ priv->keymap_description =
|
|
+ meta_keymap_description_ref (keymap_description);
|
|
+
|
|
+ xkb_keymap =
|
|
+ meta_keymap_description_create_xkb_keymap (keymap_description,
|
|
+ &display_names,
|
|
+ &short_names,
|
|
+ &error);
|
|
+ if (!xkb_keymap)
|
|
+ {
|
|
+ g_prefix_error (&error, "Unable to load configured keymap: ");
|
|
+ g_task_return_error (task, g_steal_pointer (&error));
|
|
+ g_rw_lock_writer_unlock (&seat_impl->state_lock);
|
|
+ return G_SOURCE_REMOVE;
|
|
+ }
|
|
|
|
- meta_keymap_native_set_keyboard_map_in_impl (keymap,
|
|
- seat_impl,
|
|
- keymap_description,
|
|
- xkb_keymap,
|
|
- seat_impl->xkb,
|
|
- g_steal_pointer (&display_names),
|
|
- g_steal_pointer (&short_names));
|
|
- xkb_keymap_unref (xkb_keymap);
|
|
+ meta_seat_impl_update_xkb_state_in_impl_unlocked (seat_impl,
|
|
+ xkb_keymap,
|
|
+ data->layout_index);
|
|
+
|
|
+ keymap = seat_impl->keymap;
|
|
+ meta_keymap_native_set_keyboard_map_in_impl (keymap,
|
|
+ seat_impl,
|
|
+ keymap_description,
|
|
+ xkb_keymap,
|
|
+ seat_impl->xkb,
|
|
+ g_steal_pointer (&display_names),
|
|
+ g_steal_pointer (&short_names));
|
|
+ xkb_keymap_unref (xkb_keymap);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ update_layout_index_unlocked (seat_impl, data->layout_index);
|
|
+ }
|
|
|
|
g_rw_lock_writer_unlock (&seat_impl->state_lock);
|
|
|
|
@@ -3929,84 +3980,6 @@ meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
g_object_unref (task);
|
|
}
|
|
|
|
-gboolean
|
|
-meta_seat_impl_set_keyboard_layout_index_finish (MetaSeatImpl *seat_impl,
|
|
- GAsyncResult *result,
|
|
- GError **error)
|
|
-{
|
|
- GTask *task = G_TASK (result);
|
|
-
|
|
- g_return_val_if_fail (g_task_is_valid (result, seat_impl), FALSE);
|
|
- g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
|
- meta_seat_impl_set_keyboard_layout_index_async,
|
|
- FALSE);
|
|
-
|
|
- return g_task_propagate_boolean (task, error);
|
|
-}
|
|
-
|
|
-static gboolean
|
|
-set_keyboard_layout_index (GTask *task)
|
|
-{
|
|
- MetaSeatImpl *seat_impl = g_task_get_source_object (task);
|
|
- xkb_layout_index_t idx = GPOINTER_TO_UINT (g_task_get_task_data (task));
|
|
- xkb_mod_mask_t depressed_mods;
|
|
- xkb_mod_mask_t latched_mods;
|
|
- xkb_mod_mask_t locked_mods;
|
|
- struct xkb_state *state;
|
|
-
|
|
- g_rw_lock_writer_lock (&seat_impl->state_lock);
|
|
-
|
|
- state = seat_impl->xkb;
|
|
-
|
|
- depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED);
|
|
- latched_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED);
|
|
- locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED);
|
|
-
|
|
- xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx);
|
|
-
|
|
- seat_impl->layout_idx = idx;
|
|
-
|
|
- g_task_return_boolean (task, TRUE);
|
|
-
|
|
- meta_seat_impl_sync_leds_in_impl (seat_impl);
|
|
- meta_keymap_native_update_in_impl (seat_impl->keymap,
|
|
- seat_impl,
|
|
- seat_impl->xkb);
|
|
-
|
|
- g_rw_lock_writer_unlock (&seat_impl->state_lock);
|
|
-
|
|
- return G_SOURCE_REMOVE;
|
|
-}
|
|
-
|
|
-/**
|
|
- * meta_seat_impl_set_keyboard_layout_index_async: (skip)
|
|
- * @seat_impl: the #ClutterSeat created by the evdev backend
|
|
- * @idx: the xkb layout index to set
|
|
- * @cancellable: a #GCancellable
|
|
- * @callback: callback to call when index has changed
|
|
- * @user_data: user data to pass to the callback
|
|
- *
|
|
- * Sets the xkb layout index on the backend's #xkb_state .
|
|
- */
|
|
-void
|
|
-meta_seat_impl_set_keyboard_layout_index_async (MetaSeatImpl *seat_impl,
|
|
- xkb_layout_index_t idx,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data)
|
|
-{
|
|
- GTask *task;
|
|
-
|
|
- g_return_if_fail (META_IS_SEAT_IMPL (seat_impl));
|
|
-
|
|
- task = g_task_new (seat_impl, cancellable, callback, user_data);
|
|
- g_task_set_source_tag (task, meta_seat_impl_set_keyboard_layout_index_async);
|
|
- g_task_set_task_data (task, GUINT_TO_POINTER (idx), NULL);
|
|
- meta_seat_impl_run_input_task (seat_impl, task,
|
|
- (GSourceFunc) set_keyboard_layout_index);
|
|
- g_object_unref (task);
|
|
-}
|
|
-
|
|
/**
|
|
* meta_seat_impl_set_keyboard_repeat_in_impl:
|
|
* @seat_impl: the #ClutterSeat created by the evdev backend
|
|
diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h
|
|
index 4950a19a74..c4692cac19 100644
|
|
--- a/src/backends/native/meta-seat-impl.h
|
|
+++ b/src/backends/native/meta-seat-impl.h
|
|
@@ -196,16 +196,6 @@ void meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data);
|
|
|
|
-gboolean meta_seat_impl_set_keyboard_layout_index_finish (MetaSeatImpl *seat_impl,
|
|
- GAsyncResult *result,
|
|
- GError **error);
|
|
-
|
|
-void meta_seat_impl_set_keyboard_layout_index_async (MetaSeatImpl *seat_impl,
|
|
- xkb_layout_index_t idx,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data);
|
|
-
|
|
void meta_seat_impl_set_keyboard_repeat_in_impl (MetaSeatImpl *seat_impl,
|
|
gboolean repeat,
|
|
uint32_t delay,
|
|
diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c
|
|
index 5498bac13f..2722b1d970 100644
|
|
--- a/src/backends/native/meta-seat-native.c
|
|
+++ b/src/backends/native/meta-seat-native.c
|
|
@@ -731,76 +731,6 @@ meta_seat_native_get_keyboard_map_description (MetaSeatNative *seat_native)
|
|
return seat_native->keymap_description;
|
|
}
|
|
|
|
-gboolean
|
|
-meta_seat_native_set_keyboard_layout_index_finish (MetaSeatNative *seat_native,
|
|
- GAsyncResult *result,
|
|
- GError **error)
|
|
-{
|
|
- GTask *task = G_TASK (result);
|
|
-
|
|
- g_return_val_if_fail (g_task_is_valid (result, seat_native), FALSE);
|
|
- g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
|
- meta_seat_native_set_keyboard_layout_index_async,
|
|
- FALSE);
|
|
-
|
|
- return g_task_propagate_boolean (task, error);
|
|
-}
|
|
-
|
|
-static void
|
|
-set_seat_impl_layout_index_cb (GObject *source_object,
|
|
- GAsyncResult *result,
|
|
- gpointer user_data)
|
|
-{
|
|
- MetaSeatImpl *seat_impl = META_SEAT_IMPL (source_object);
|
|
- g_autoptr (GTask) task = user_data;
|
|
- MetaSeatNative *seat_native =
|
|
- META_SEAT_NATIVE (g_task_get_source_object (task));
|
|
- g_autoptr (GError) error = NULL;
|
|
- xkb_layout_index_t idx = GPOINTER_TO_UINT (g_task_get_task_data (task));
|
|
- xkb_layout_index_t old_idx;
|
|
-
|
|
- if (!meta_seat_impl_set_keyboard_layout_index_finish (seat_impl,
|
|
- result,
|
|
- &error))
|
|
- {
|
|
- g_task_return_error (task, error);
|
|
- return;
|
|
- }
|
|
-
|
|
- old_idx = seat_native->xkb_layout_index;
|
|
- seat_native->xkb_layout_index = idx;
|
|
-
|
|
- g_task_return_boolean (task, old_idx != idx);
|
|
-}
|
|
-
|
|
-/**
|
|
- * meta_seat_native_set_keyboard_layout_index_async: (skip)
|
|
- * @seat: the #ClutterSeat created by the evdev backend
|
|
- * @idx: the xkb layout index to set
|
|
- *
|
|
- * Sets the xkb layout index on the backend's #xkb_state .
|
|
- */
|
|
-void
|
|
-meta_seat_native_set_keyboard_layout_index_async (MetaSeatNative *seat_native,
|
|
- xkb_layout_index_t idx,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data)
|
|
-{
|
|
- g_autoptr (GTask) task = NULL;
|
|
-
|
|
- g_return_if_fail (META_IS_SEAT_NATIVE (seat_native));
|
|
-
|
|
- task = g_task_new (G_OBJECT (seat_native), cancellable, callback, user_data);
|
|
- g_task_set_source_tag (task, meta_seat_native_set_keyboard_layout_index_async);
|
|
- g_task_set_task_data (task, GUINT_TO_POINTER (idx), NULL);
|
|
-
|
|
- meta_seat_impl_set_keyboard_layout_index_async (seat_native->impl, idx,
|
|
- cancellable,
|
|
- set_seat_impl_layout_index_cb,
|
|
- g_steal_pointer (&task));
|
|
-}
|
|
-
|
|
/**
|
|
* meta_seat_native_get_keyboard_layout_index: (skip)
|
|
*/
|
|
diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h
|
|
index 061b580bc2..7fbe7dd3e7 100644
|
|
--- a/src/backends/native/meta-seat-native.h
|
|
+++ b/src/backends/native/meta-seat-native.h
|
|
@@ -115,16 +115,6 @@ gboolean meta_seat_native_set_keyboard_map_finish (MetaSeatNative *seat_native,
|
|
META_EXPORT_TEST
|
|
struct xkb_keymap * meta_seat_native_get_keyboard_map (MetaSeatNative *seat);
|
|
|
|
-gboolean meta_seat_native_set_keyboard_layout_index_finish (MetaSeatNative *seat_native,
|
|
- GAsyncResult *result,
|
|
- GError **error);
|
|
-
|
|
-void meta_seat_native_set_keyboard_layout_index_async (MetaSeatNative *seat,
|
|
- xkb_layout_index_t idx,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data);
|
|
-
|
|
MetaKeymapDescription * meta_seat_native_get_keyboard_map_description (MetaSeatNative *seat_native);
|
|
|
|
xkb_layout_index_t meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat);
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index e1a65214cc..7d233dbe23 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -275,14 +275,18 @@ set_keymap_layout_group_cb (GObject *source_object,
|
|
gboolean *done = user_data;
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
- g_assert_true (meta_backend_set_keymap_layout_group_finish (backend,
|
|
- result,
|
|
- &error));
|
|
+ g_assert_true (meta_backend_set_keymap_finish (backend, result, &error));
|
|
g_assert_no_error (error);
|
|
|
|
*done = TRUE;
|
|
}
|
|
|
|
+static void
|
|
+trigger_error (const char *message)
|
|
+{
|
|
+ g_error ("%s", message);
|
|
+}
|
|
+
|
|
static void
|
|
meta_test_native_keyboard_map_set_layout_index (void)
|
|
{
|
|
@@ -290,6 +294,7 @@ meta_test_native_keyboard_map_set_layout_index (void)
|
|
g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
gboolean done = FALSE;
|
|
struct xkb_keymap *keymap;
|
|
+ gulong keymap_changed_handler_id;
|
|
|
|
keymap_description =
|
|
meta_keymap_description_new_from_rules (NULL,
|
|
@@ -303,10 +308,15 @@ meta_test_native_keyboard_map_set_layout_index (void)
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
+ keymap_changed_handler_id =
|
|
+ g_signal_connect_swapped (backend,
|
|
+ "keymap-changed",
|
|
+ G_CALLBACK (trigger_error),
|
|
+ (gpointer) "Unexpected keymap-changed emission");
|
|
+
|
|
done = FALSE;
|
|
- meta_backend_set_keymap_layout_group_async (backend, 0, NULL,
|
|
- set_keymap_layout_group_cb,
|
|
- &done);
|
|
+ meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
+ NULL, set_keymap_layout_group_cb, &done);
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
@@ -321,13 +331,14 @@ meta_test_native_keyboard_map_set_layout_index (void)
|
|
|
|
g_assert_cmpuint (meta_backend_get_keymap_layout_group (backend), ==, 0);
|
|
done = FALSE;
|
|
- meta_backend_set_keymap_layout_group_async (backend, 1, NULL,
|
|
- set_keymap_layout_group_cb,
|
|
- &done);
|
|
+ meta_backend_set_keymap_async (backend, keymap_description, 1,
|
|
+ NULL, set_keymap_layout_group_cb, &done);
|
|
g_assert_cmpuint (meta_backend_get_keymap_layout_group (backend), ==, 0);
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
g_assert_cmpuint (meta_backend_get_keymap_layout_group (backend), ==, 1);
|
|
+
|
|
+ g_signal_handler_disconnect (backend, keymap_changed_handler_id);
|
|
}
|
|
|
|
static void
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 47acb440846860210d7b945e34dd87ee2c4ba167 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Thu, 2 Oct 2025 10:56:52 +0200
|
|
Subject: [PATCH 23/32] keymap-description: Add way to 'lock' a keymap
|
|
description
|
|
|
|
This should be interpreted by other entities that tries to set the
|
|
keymap to avoid doing so. It's meant to allow a remote desktop service
|
|
to be in control of the current keymap and keyboard layout.
|
|
|
|
This introduces a concept of keymap description owner. Only the same
|
|
owner can set a new keymap if a current keymap description is locked.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit b1344b5f09d032ee1c44c31ef742b418ce74bb24)
|
|
---
|
|
.../meta-keymap-description-private.h | 21 +++
|
|
src/backends/meta-keymap-description.c | 68 ++++++++
|
|
src/backends/native/meta-seat-impl.c | 13 ++
|
|
src/meta/meta-keymap-description.h | 3 +
|
|
src/tests/keyboard-map-tests.c | 165 ++++++++++++++++++
|
|
5 files changed, 270 insertions(+)
|
|
|
|
diff --git a/src/backends/meta-keymap-description-private.h b/src/backends/meta-keymap-description-private.h
|
|
index 3c0d9cc924..5bf0b25505 100644
|
|
--- a/src/backends/meta-keymap-description-private.h
|
|
+++ b/src/backends/meta-keymap-description-private.h
|
|
@@ -21,6 +21,7 @@
|
|
#include "meta/meta-keymap-description.h"
|
|
|
|
#include "core/meta-sealed-fd.h"
|
|
+#include "core/util-private.h"
|
|
|
|
typedef enum _MetaKeymapDescriptionSource
|
|
{
|
|
@@ -28,6 +29,16 @@ typedef enum _MetaKeymapDescriptionSource
|
|
META_KEYMAP_DESCRIPTION_SOURCE_FD,
|
|
} MetaKeymapDescriptionSource;
|
|
|
|
+typedef struct _MetaKeymapDescriptionOwner MetaKeymapDescriptionOwner;
|
|
+
|
|
+META_EXPORT_TEST
|
|
+MetaKeymapDescriptionOwner * meta_keymap_description_owner_new (void);
|
|
+
|
|
+MetaKeymapDescriptionOwner * meta_keymap_description_owner_ref (MetaKeymapDescriptionOwner *owner);
|
|
+
|
|
+META_EXPORT_TEST
|
|
+void meta_keymap_description_owner_unref (MetaKeymapDescriptionOwner *owner);
|
|
+
|
|
MetaKeymapDescription * meta_keymap_description_new_from_fd (MetaSealedFd *sealed_fd,
|
|
enum xkb_keymap_format format);
|
|
|
|
@@ -37,3 +48,13 @@ struct xkb_keymap * meta_keymap_description_create_xkb_keymap (MetaKeymapDescrip
|
|
GStrv *out_display_names,
|
|
GStrv *out_short_names,
|
|
GError **error);
|
|
+
|
|
+META_EXPORT_TEST
|
|
+void meta_keymap_description_lock (MetaKeymapDescription *keymap_description,
|
|
+ MetaKeymapDescriptionOwner *owner);
|
|
+
|
|
+META_EXPORT_TEST
|
|
+void meta_keymap_description_unlock (MetaKeymapDescription *keymap_description,
|
|
+ MetaKeymapDescriptionOwner *owner);
|
|
+
|
|
+MetaKeymapDescriptionOwner * meta_keymap_description_get_owner (MetaKeymapDescription *keymap_description);
|
|
diff --git a/src/backends/meta-keymap-description.c b/src/backends/meta-keymap-description.c
|
|
index 63bd539d57..b67bcf0a74 100644
|
|
--- a/src/backends/meta-keymap-description.c
|
|
+++ b/src/backends/meta-keymap-description.c
|
|
@@ -26,12 +26,20 @@
|
|
#include "backends/meta-keymap-utils.h"
|
|
#include "core/meta-sealed-fd.h"
|
|
|
|
+struct _MetaKeymapDescriptionOwner
|
|
+{
|
|
+ gatomicrefcount ref_count;
|
|
+};
|
|
+
|
|
struct _MetaKeymapDescription
|
|
{
|
|
gatomicrefcount ref_count;
|
|
|
|
MetaKeymapDescriptionSource source;
|
|
|
|
+ gboolean is_locked;
|
|
+ MetaKeymapDescriptionOwner *owner;
|
|
+
|
|
union {
|
|
struct {
|
|
char *rules;
|
|
@@ -62,6 +70,31 @@ strdup_or_empty (const char *string)
|
|
return string ? g_strdup (string) : g_strdup ("");
|
|
}
|
|
|
|
+MetaKeymapDescriptionOwner *
|
|
+meta_keymap_description_owner_new (void)
|
|
+{
|
|
+ MetaKeymapDescriptionOwner *owner;
|
|
+
|
|
+ owner = g_new0 (MetaKeymapDescriptionOwner, 1);
|
|
+ g_atomic_ref_count_init (&owner->ref_count);
|
|
+
|
|
+ return owner;
|
|
+}
|
|
+
|
|
+MetaKeymapDescriptionOwner *
|
|
+meta_keymap_description_owner_ref (MetaKeymapDescriptionOwner *owner)
|
|
+{
|
|
+ g_atomic_ref_count_inc (&owner->ref_count);
|
|
+ return owner;
|
|
+}
|
|
+
|
|
+void
|
|
+meta_keymap_description_owner_unref (MetaKeymapDescriptionOwner *owner)
|
|
+{
|
|
+ if (g_atomic_ref_count_dec (&owner->ref_count))
|
|
+ g_free (owner);
|
|
+}
|
|
+
|
|
MetaKeymapDescription *
|
|
meta_keymap_description_new_from_rules (const char *model,
|
|
const char *layout,
|
|
@@ -128,6 +161,9 @@ meta_keymap_description_unref (MetaKeymapDescription *keymap_description)
|
|
break;
|
|
}
|
|
|
|
+ g_clear_pointer (&keymap_description->owner,
|
|
+ meta_keymap_description_owner_unref);
|
|
+
|
|
g_free (keymap_description);
|
|
}
|
|
}
|
|
@@ -293,3 +329,35 @@ meta_keymap_description_create_xkb_keymap (MetaKeymapDescription *keymap_descri
|
|
|
|
return xkb_keymap;
|
|
}
|
|
+
|
|
+void
|
|
+meta_keymap_description_lock (MetaKeymapDescription *keymap_description,
|
|
+ MetaKeymapDescriptionOwner *owner)
|
|
+{
|
|
+ g_return_if_fail (!keymap_description->owner);
|
|
+
|
|
+ keymap_description->is_locked = TRUE;
|
|
+ keymap_description->owner = meta_keymap_description_owner_ref (owner);
|
|
+}
|
|
+
|
|
+void
|
|
+meta_keymap_description_unlock (MetaKeymapDescription *keymap_description,
|
|
+ MetaKeymapDescriptionOwner *owner)
|
|
+{
|
|
+ g_return_if_fail (!keymap_description->owner);
|
|
+ g_return_if_fail (!keymap_description->is_locked);
|
|
+
|
|
+ keymap_description->owner = meta_keymap_description_owner_ref (owner);
|
|
+}
|
|
+
|
|
+gboolean
|
|
+meta_keymap_description_is_locked (MetaKeymapDescription *keymap_description)
|
|
+{
|
|
+ return keymap_description->is_locked;
|
|
+}
|
|
+
|
|
+MetaKeymapDescriptionOwner *
|
|
+meta_keymap_description_get_owner (MetaKeymapDescription *keymap_description)
|
|
+{
|
|
+ return keymap_description->owner;
|
|
+}
|
|
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
|
|
index 7c94a6c5cc..ab8e207d16 100644
|
|
--- a/src/backends/native/meta-seat-impl.c
|
|
+++ b/src/backends/native/meta-seat-impl.c
|
|
@@ -3898,6 +3898,19 @@ set_keyboard_map (GTask *task)
|
|
g_auto (GStrv) short_names = NULL;
|
|
struct xkb_keymap *xkb_keymap = NULL;
|
|
|
|
+ if (priv->keymap_description)
|
|
+ {
|
|
+ if (meta_keymap_description_is_locked (priv->keymap_description) &&
|
|
+ meta_keymap_description_get_owner (keymap_description) !=
|
|
+ meta_keymap_description_get_owner (priv->keymap_description))
|
|
+ {
|
|
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
+ "Keymap locked by other owner");
|
|
+ g_rw_lock_writer_unlock (&seat_impl->state_lock);
|
|
+ return G_SOURCE_REMOVE;
|
|
+ }
|
|
+ }
|
|
+
|
|
g_clear_pointer (&priv->keymap_description,
|
|
meta_keymap_description_unref);
|
|
priv->keymap_description =
|
|
diff --git a/src/meta/meta-keymap-description.h b/src/meta/meta-keymap-description.h
|
|
index 5140f63b1a..0f4de5ed2b 100644
|
|
--- a/src/meta/meta-keymap-description.h
|
|
+++ b/src/meta/meta-keymap-description.h
|
|
@@ -42,5 +42,8 @@ MetaKeymapDescription * meta_keymap_description_ref (MetaKeymapDescription *keym
|
|
META_EXPORT
|
|
void meta_keymap_description_unref (MetaKeymapDescription *keymap_description);
|
|
|
|
+META_EXPORT
|
|
+gboolean meta_keymap_description_is_locked (MetaKeymapDescription *keymap_description);
|
|
+
|
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKeymapDescription,
|
|
meta_keymap_description_unref);
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index 7d233dbe23..1bbb87430b 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -21,6 +21,7 @@
|
|
#include <linux/input-event-codes.h>
|
|
|
|
#include "backends/meta-backend-private.h"
|
|
+#include "backends/meta-keymap-description-private.h"
|
|
#include "backends/native/meta-keymap-native.h"
|
|
#include "backends/native/meta-seat-native.h"
|
|
#include "tests/meta-test-utils.h"
|
|
@@ -35,6 +36,12 @@ typedef struct
|
|
|
|
static MetaContext *test_context;
|
|
|
|
+static void
|
|
+set_true_cb (gboolean *value)
|
|
+{
|
|
+ *value = TRUE;
|
|
+}
|
|
+
|
|
static void
|
|
set_keymap_cb (GObject *source_object,
|
|
GAsyncResult *result,
|
|
@@ -50,6 +57,21 @@ set_keymap_cb (GObject *source_object,
|
|
*done = TRUE;
|
|
}
|
|
|
|
+static void
|
|
+set_keymap_expect_error_cb (GObject *source_object,
|
|
+ GAsyncResult *result,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ MetaBackend *backend = META_BACKEND (source_object);
|
|
+ gboolean *done = user_data;
|
|
+ g_autoptr (GError) error = NULL;
|
|
+
|
|
+ g_assert_false (meta_backend_set_keymap_finish (backend, result, &error));
|
|
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
|
|
+
|
|
+ *done = TRUE;
|
|
+}
|
|
+
|
|
static void
|
|
await_mod_mask (MetaKeymapNative *keymap_native,
|
|
ModMaskTuple **awaited_mod_mask)
|
|
@@ -341,6 +363,147 @@ meta_test_native_keyboard_map_set_layout_index (void)
|
|
g_signal_handler_disconnect (backend, keymap_changed_handler_id);
|
|
}
|
|
|
|
+static void
|
|
+meta_test_native_keyboard_map_lock_layout (void)
|
|
+{
|
|
+ MetaBackend *backend = meta_context_get_backend (test_context);
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description1 = NULL;
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description2 = NULL;
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description3 = NULL;
|
|
+ MetaKeymapDescriptionOwner *owner;
|
|
+ gboolean done = FALSE;
|
|
+ gboolean was_signalled;
|
|
+ struct xkb_keymap *keymap;
|
|
+ gulong keymap_changed_handler_id;
|
|
+ gulong keymap_layout_group_changed_handler_id;
|
|
+
|
|
+ owner = meta_keymap_description_owner_new ();
|
|
+
|
|
+ /*
|
|
+ * Set a locking keymap.
|
|
+ */
|
|
+
|
|
+ keymap_description1 =
|
|
+ meta_keymap_description_new_from_rules (NULL,
|
|
+ "us,se",
|
|
+ "dvorak-alt-intl,svdvorak",
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL);
|
|
+ meta_keymap_description_lock (keymap_description1, owner);
|
|
+ meta_backend_set_keymap_async (backend, keymap_description1, 0,
|
|
+ NULL, set_keymap_cb, &done);
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+
|
|
+ keymap = xkb_keymap_ref (meta_backend_get_keymap (backend));
|
|
+ g_assert_cmpuint (xkb_keymap_num_layouts (keymap), ==, 2);
|
|
+ g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 0),
|
|
+ ==,
|
|
+ "English (Dvorak, alt. intl.)");
|
|
+ g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 1),
|
|
+ ==,
|
|
+ "Swedish (Svdvorak)");
|
|
+ g_assert_cmpuint (meta_backend_get_keymap_layout_group (backend), ==, 0);
|
|
+
|
|
+ /*
|
|
+ * Set a new keymap without an owner. Should cause an error and not take
|
|
+ * effect.
|
|
+ */
|
|
+
|
|
+ keymap_changed_handler_id =
|
|
+ g_signal_connect_swapped (backend,
|
|
+ "keymap-changed",
|
|
+ G_CALLBACK (trigger_error),
|
|
+ (gpointer) "Unexpected keymap-changed emission");
|
|
+
|
|
+ keymap_description2 =
|
|
+ meta_keymap_description_new_from_rules (NULL,
|
|
+ "se,us",
|
|
+ "svdvorak,dvorak-alt-intl",
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL);
|
|
+ done = FALSE;
|
|
+ meta_backend_set_keymap_async (backend, keymap_description2, 0,
|
|
+ NULL, set_keymap_expect_error_cb, &done);
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+
|
|
+ g_assert_true (keymap == meta_backend_get_keymap (backend));
|
|
+
|
|
+ /*
|
|
+ * Set the same keymap with a different layout index. Should take effect.
|
|
+ */
|
|
+
|
|
+ was_signalled = FALSE;
|
|
+ keymap_layout_group_changed_handler_id =
|
|
+ g_signal_connect_swapped (backend,
|
|
+ "keymap-layout-group-changed",
|
|
+ G_CALLBACK (set_true_cb),
|
|
+ &was_signalled);
|
|
+
|
|
+ done = FALSE;
|
|
+ meta_backend_set_keymap_async (backend, keymap_description1, 1,
|
|
+ NULL, set_keymap_layout_group_cb, &done);
|
|
+ g_assert_cmpuint (meta_backend_get_keymap_layout_group (backend), ==, 0);
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+ g_assert_cmpuint (meta_backend_get_keymap_layout_group (backend), ==, 1);
|
|
+ g_assert_true (was_signalled);
|
|
+
|
|
+ xkb_keymap_unref (keymap);
|
|
+ g_signal_handler_disconnect (backend, keymap_changed_handler_id);
|
|
+ g_signal_handler_disconnect (backend, keymap_layout_group_changed_handler_id);
|
|
+
|
|
+ /*
|
|
+ * Set another keymap with the same owner. Should take effect.
|
|
+ */
|
|
+
|
|
+ keymap_description3 =
|
|
+ meta_keymap_description_new_from_rules (NULL,
|
|
+ "ua",
|
|
+ "",
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL);
|
|
+ meta_keymap_description_unlock (keymap_description3, owner);
|
|
+ done = FALSE;
|
|
+ meta_backend_set_keymap_async (backend, keymap_description3, 0,
|
|
+ NULL, set_keymap_cb, &done);
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+
|
|
+ keymap = meta_backend_get_keymap (backend);
|
|
+ g_assert_cmpuint (xkb_keymap_num_layouts (keymap), ==, 1);
|
|
+ g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 0),
|
|
+ ==,
|
|
+ "Ukrainian");
|
|
+ g_assert_cmpuint (meta_backend_get_keymap_layout_group (backend), ==, 0);
|
|
+
|
|
+ /*
|
|
+ * Set keymap again without owner. Should take effect.
|
|
+ */
|
|
+
|
|
+ done = FALSE;
|
|
+ meta_backend_set_keymap_async (backend, keymap_description2, 0,
|
|
+ NULL, set_keymap_cb, &done);
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+
|
|
+ keymap = meta_backend_get_keymap (backend);
|
|
+ g_assert_cmpuint (xkb_keymap_num_layouts (keymap), ==, 2);
|
|
+ g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 0),
|
|
+ ==,
|
|
+ "Swedish (Svdvorak)");
|
|
+ g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 1),
|
|
+ ==,
|
|
+ "English (Dvorak, alt. intl.)");
|
|
+ g_assert_cmpuint (meta_backend_get_keymap_layout_group (backend), ==, 0);
|
|
+
|
|
+ meta_keymap_description_owner_unref (owner);
|
|
+}
|
|
+
|
|
static void
|
|
record_modifier_state (ClutterKeymap *keymap,
|
|
ModMaskTuple **expected_mods)
|
|
@@ -460,6 +623,8 @@ init_tests (void)
|
|
meta_test_native_keyboard_map_change_layout);
|
|
g_test_add_func ("/backends/native/keyboard-map/set-layout-index",
|
|
meta_test_native_keyboard_map_set_layout_index);
|
|
+ g_test_add_func ("/backends/native/keyboard-map/lock-layout",
|
|
+ meta_test_native_keyboard_map_lock_layout);
|
|
g_test_add_func ("/backends/native/keyboard-map/modifiers",
|
|
meta_test_native_keyboard_map_modifiers);
|
|
}
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From c5d98a94b453b7b869f9d8cc7a818e9f9698f98e Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Mon, 15 Dec 2025 21:32:31 +0100
|
|
Subject: [PATCH 24/32] backend: Only let owner reset keymap
|
|
|
|
This allows enforcing only the owner of a locked keymap description can
|
|
reset it to something else.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 097ad5b10695cd006e8e50b51df5d6cdcee83eb1)
|
|
---
|
|
src/backends/meta-backend-private.h | 12 +-
|
|
src/backends/meta-backend.c | 11 +-
|
|
.../meta-keymap-description-private.h | 5 +
|
|
src/backends/meta-keymap-description.c | 18 +++
|
|
src/backends/native/meta-seat-impl.c | 2 +
|
|
src/tests/keyboard-map-tests.c | 123 ++++++++++++++++++
|
|
6 files changed, 163 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
|
|
index c82d41032d..8b61738922 100644
|
|
--- a/src/backends/meta-backend-private.h
|
|
+++ b/src/backends/meta-backend-private.h
|
|
@@ -34,6 +34,7 @@
|
|
#include "backends/meta-egl.h"
|
|
#include "backends/meta-input-mapper-private.h"
|
|
#include "backends/meta-input-settings-private.h"
|
|
+#include "backends/meta-keymap-description-private.h"
|
|
#include "backends/meta-monitor-manager-private.h"
|
|
#include "backends/meta-pointer-constraint.h"
|
|
#include "backends/meta-renderer.h"
|
|
@@ -213,14 +214,17 @@ struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
|
|
META_EXPORT_TEST
|
|
xkb_layout_index_t meta_backend_get_keymap_layout_group (MetaBackend *backend);
|
|
|
|
+META_EXPORT_TEST
|
|
gboolean meta_backend_reset_keymap_finish (MetaBackend *backend,
|
|
GAsyncResult *result,
|
|
GError **error);
|
|
|
|
-void meta_backend_reset_keymap_async (MetaBackend *backend,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data);
|
|
+META_EXPORT_TEST
|
|
+void meta_backend_reset_keymap_async (MetaBackend *backend,
|
|
+ MetaKeymapDescriptionOwner *owner,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data);
|
|
|
|
gboolean meta_backend_is_lid_closed (MetaBackend *backend);
|
|
|
|
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
|
|
index 03ebf27ee4..143797213d 100644
|
|
--- a/src/backends/meta-backend.c
|
|
+++ b/src/backends/meta-backend.c
|
|
@@ -1851,10 +1851,11 @@ meta_backend_reset_keymap_finish (MetaBackend *backend,
|
|
}
|
|
|
|
void
|
|
-meta_backend_reset_keymap_async (MetaBackend *backend,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data)
|
|
+meta_backend_reset_keymap_async (MetaBackend *backend,
|
|
+ MetaKeymapDescriptionOwner *owner,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data)
|
|
{
|
|
g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
uint32_t layout_index = 0;
|
|
@@ -1881,6 +1882,8 @@ meta_backend_reset_keymap_async (MetaBackend *backend,
|
|
layout_index = 0;
|
|
}
|
|
|
|
+ meta_keymap_description_reset_owner (keymap_description, owner);
|
|
+
|
|
task = g_task_new (G_OBJECT (backend), cancellable, callback, user_data);
|
|
g_task_set_source_tag (task, meta_backend_reset_keymap_async);
|
|
|
|
diff --git a/src/backends/meta-keymap-description-private.h b/src/backends/meta-keymap-description-private.h
|
|
index 5bf0b25505..f53092cd27 100644
|
|
--- a/src/backends/meta-keymap-description-private.h
|
|
+++ b/src/backends/meta-keymap-description-private.h
|
|
@@ -57,4 +57,9 @@ META_EXPORT_TEST
|
|
void meta_keymap_description_unlock (MetaKeymapDescription *keymap_description,
|
|
MetaKeymapDescriptionOwner *owner);
|
|
|
|
+void meta_keymap_description_reset_owner (MetaKeymapDescription *keymap_description,
|
|
+ MetaKeymapDescriptionOwner *owner);
|
|
+
|
|
MetaKeymapDescriptionOwner * meta_keymap_description_get_owner (MetaKeymapDescription *keymap_description);
|
|
+
|
|
+MetaKeymapDescriptionOwner * meta_keymap_description_resets_owner (MetaKeymapDescription *keymap_description);
|
|
diff --git a/src/backends/meta-keymap-description.c b/src/backends/meta-keymap-description.c
|
|
index b67bcf0a74..60a06fc5da 100644
|
|
--- a/src/backends/meta-keymap-description.c
|
|
+++ b/src/backends/meta-keymap-description.c
|
|
@@ -39,6 +39,7 @@ struct _MetaKeymapDescription
|
|
|
|
gboolean is_locked;
|
|
MetaKeymapDescriptionOwner *owner;
|
|
+ MetaKeymapDescriptionOwner *resets_owner;
|
|
|
|
union {
|
|
struct {
|
|
@@ -163,6 +164,8 @@ meta_keymap_description_unref (MetaKeymapDescription *keymap_description)
|
|
|
|
g_clear_pointer (&keymap_description->owner,
|
|
meta_keymap_description_owner_unref);
|
|
+ g_clear_pointer (&keymap_description->resets_owner,
|
|
+ meta_keymap_description_owner_unref);
|
|
|
|
g_free (keymap_description);
|
|
}
|
|
@@ -350,6 +353,15 @@ meta_keymap_description_unlock (MetaKeymapDescription *keymap_description,
|
|
keymap_description->owner = meta_keymap_description_owner_ref (owner);
|
|
}
|
|
|
|
+void
|
|
+meta_keymap_description_reset_owner (MetaKeymapDescription *keymap_description,
|
|
+ MetaKeymapDescriptionOwner *owner)
|
|
+{
|
|
+ g_clear_pointer (&keymap_description->resets_owner,
|
|
+ meta_keymap_description_owner_unref);
|
|
+ keymap_description->resets_owner = meta_keymap_description_owner_ref (owner);
|
|
+}
|
|
+
|
|
gboolean
|
|
meta_keymap_description_is_locked (MetaKeymapDescription *keymap_description)
|
|
{
|
|
@@ -361,3 +373,9 @@ meta_keymap_description_get_owner (MetaKeymapDescription *keymap_description)
|
|
{
|
|
return keymap_description->owner;
|
|
}
|
|
+
|
|
+MetaKeymapDescriptionOwner *
|
|
+meta_keymap_description_resets_owner (MetaKeymapDescription *keymap_description)
|
|
+{
|
|
+ return keymap_description->resets_owner;
|
|
+}
|
|
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
|
|
index ab8e207d16..2926bab779 100644
|
|
--- a/src/backends/native/meta-seat-impl.c
|
|
+++ b/src/backends/native/meta-seat-impl.c
|
|
@@ -3902,6 +3902,8 @@ set_keyboard_map (GTask *task)
|
|
{
|
|
if (meta_keymap_description_is_locked (priv->keymap_description) &&
|
|
meta_keymap_description_get_owner (keymap_description) !=
|
|
+ meta_keymap_description_get_owner (priv->keymap_description) &&
|
|
+ meta_keymap_description_resets_owner (keymap_description) !=
|
|
meta_keymap_description_get_owner (priv->keymap_description))
|
|
{
|
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index 1bbb87430b..c705562736 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -72,6 +72,36 @@ set_keymap_expect_error_cb (GObject *source_object,
|
|
*done = TRUE;
|
|
}
|
|
|
|
+static void
|
|
+reset_keymap_cb (GObject *source_object,
|
|
+ GAsyncResult *result,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ MetaBackend *backend = META_BACKEND (source_object);
|
|
+ gboolean *done = user_data;
|
|
+ g_autoptr (GError) error = NULL;
|
|
+
|
|
+ g_assert_true (meta_backend_reset_keymap_finish (backend, result, &error));
|
|
+ g_assert_no_error (error);
|
|
+
|
|
+ *done = TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+reset_keymap_expect_error_cb (GObject *source_object,
|
|
+ GAsyncResult *result,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ MetaBackend *backend = META_BACKEND (source_object);
|
|
+ gboolean *done = user_data;
|
|
+ g_autoptr (GError) error = NULL;
|
|
+
|
|
+ g_assert_false (meta_backend_reset_keymap_finish (backend, result, &error));
|
|
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
|
|
+
|
|
+ *done = TRUE;
|
|
+}
|
|
+
|
|
static void
|
|
await_mod_mask (MetaKeymapNative *keymap_native,
|
|
ModMaskTuple **awaited_mod_mask)
|
|
@@ -504,6 +534,97 @@ meta_test_native_keyboard_map_lock_layout (void)
|
|
meta_keymap_description_owner_unref (owner);
|
|
}
|
|
|
|
+static MetaKeymapDescription *
|
|
+on_reset_keymap_description (MetaBackend *backend,
|
|
+ MetaKeymapDescription *keymap_description)
|
|
+{
|
|
+ return meta_keymap_description_ref (keymap_description);
|
|
+}
|
|
+
|
|
+static void
|
|
+meta_test_native_keyboard_map_lock_layout_reset (void)
|
|
+{
|
|
+ MetaBackend *backend = meta_context_get_backend (test_context);
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description1 = NULL;
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description2 = NULL;
|
|
+ MetaKeymapDescriptionOwner *owner;
|
|
+ MetaKeymapDescriptionOwner *other_owner;
|
|
+ gboolean done = FALSE;
|
|
+ gboolean was_signalled = FALSE;
|
|
+ gulong keymap_changed_handler_id;
|
|
+ gulong reset_keymap_handler_id;
|
|
+
|
|
+ owner = meta_keymap_description_owner_new ();
|
|
+ other_owner = meta_keymap_description_owner_new ();
|
|
+
|
|
+ keymap_description1 =
|
|
+ meta_keymap_description_new_from_rules (NULL,
|
|
+ "us,se",
|
|
+ "dvorak-alt-intl,svdvorak",
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL);
|
|
+ meta_keymap_description_lock (keymap_description1, owner);
|
|
+ meta_backend_set_keymap_async (backend, keymap_description1, 0,
|
|
+ NULL, set_keymap_cb, &done);
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+
|
|
+ keymap_changed_handler_id =
|
|
+ g_signal_connect_swapped (backend,
|
|
+ "keymap-changed",
|
|
+ G_CALLBACK (trigger_error),
|
|
+ (gpointer) "Unexpected keymap-changed emission");
|
|
+
|
|
+ keymap_description2 =
|
|
+ meta_keymap_description_new_from_rules (NULL,
|
|
+ "se,us",
|
|
+ "svdvorak,dvorak-alt-intl",
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL);
|
|
+ done = FALSE;
|
|
+ meta_backend_set_keymap_async (backend, keymap_description2, 0,
|
|
+ NULL, set_keymap_expect_error_cb, &done);
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+
|
|
+ reset_keymap_handler_id =
|
|
+ g_signal_connect (backend,
|
|
+ "reset-keymap-description",
|
|
+ G_CALLBACK (on_reset_keymap_description),
|
|
+ keymap_description2);
|
|
+
|
|
+ done = FALSE;
|
|
+ meta_backend_reset_keymap_async (backend, other_owner,
|
|
+ NULL, reset_keymap_expect_error_cb, &done);
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+
|
|
+ g_signal_handler_disconnect (backend, keymap_changed_handler_id);
|
|
+ keymap_changed_handler_id =
|
|
+ g_signal_connect_swapped (backend,
|
|
+ "keymap-changed",
|
|
+ G_CALLBACK (set_true_cb),
|
|
+ &was_signalled);
|
|
+
|
|
+ done = FALSE;
|
|
+ meta_backend_reset_keymap_async (backend, owner,
|
|
+ NULL, reset_keymap_cb, &done);
|
|
+ while (!done)
|
|
+ g_main_context_iteration (NULL, TRUE);
|
|
+
|
|
+ g_assert_true (meta_backend_get_keymap_description (backend) ==
|
|
+ keymap_description2);
|
|
+
|
|
+ g_assert_true (was_signalled);
|
|
+
|
|
+ g_signal_handler_disconnect (backend, keymap_changed_handler_id);
|
|
+ g_signal_handler_disconnect (backend, reset_keymap_handler_id);
|
|
+ meta_keymap_description_owner_unref (owner);
|
|
+ meta_keymap_description_owner_unref (other_owner);
|
|
+}
|
|
+
|
|
static void
|
|
record_modifier_state (ClutterKeymap *keymap,
|
|
ModMaskTuple **expected_mods)
|
|
@@ -625,6 +746,8 @@ init_tests (void)
|
|
meta_test_native_keyboard_map_set_layout_index);
|
|
g_test_add_func ("/backends/native/keyboard-map/lock-layout",
|
|
meta_test_native_keyboard_map_lock_layout);
|
|
+ g_test_add_func ("/backends/native/keyboard-map/lock-layout-reset",
|
|
+ meta_test_native_keyboard_map_lock_layout_reset);
|
|
g_test_add_func ("/backends/native/keyboard-map/modifiers",
|
|
meta_test_native_keyboard_map_modifiers);
|
|
}
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From d62e2aec5b902aa180b3d825bc6348d388b62ce2 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Thu, 2 Oct 2025 11:34:12 +0200
|
|
Subject: [PATCH 25/32] remote-desktop: Allow remote desktop servers to set the
|
|
keyboard layout
|
|
|
|
This allows remote desktop servers to take control of the keyboard
|
|
layout by setting their own keymap. This is meant to for example allow
|
|
using the same keymap in the remote system as in the system where the
|
|
remote desktop client is running.
|
|
|
|
For the time being, if the remote desktop server sets the keymap with a
|
|
'locked' property, it currently breaks the usage of input methods, as
|
|
they currently set what keyboard layout they work with, meaning that if
|
|
they can't override the keyboard layout, they wont work. This is a known
|
|
issue and deliberately not solved right now.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 0b8fae63112331043223f9aa6b234f4a99cd59b0)
|
|
---
|
|
.../org.gnome.Mutter.RemoteDesktop.xml | 100 ++++++
|
|
src/backends/meta-remote-desktop-session.c | 327 +++++++++++++++++-
|
|
2 files changed, 426 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml b/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml
|
|
index 815b1a3625..85cec80a9a 100644
|
|
--- a/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml
|
|
+++ b/data/dbus-interfaces/org.gnome.Mutter.RemoteDesktop.xml
|
|
@@ -367,6 +367,106 @@
|
|
<arg type="h" name="fd" direction="out"/>
|
|
</method>
|
|
|
|
+ <!--
|
|
+ KeymapCapabilities:
|
|
+
|
|
+ Available options:
|
|
+
|
|
+ * ``supported-keymap-types`` (``au``)
|
|
+
|
|
+ Supported keymap types.
|
|
+
|
|
+ Available types:
|
|
+ ``0``: XKB: A keymap specified as a XKB keymap.
|
|
+
|
|
+ * ``supported-xkb-keymap-formats`` (``au``)
|
|
+
|
|
+ Supported XKB keymap formats.
|
|
+
|
|
+ Available formats:
|
|
+ ``1``: XKB_TEXT_V1: XKB text format version 1.
|
|
+ ``2``: XKB_TEXT_V2: XKB text format version 2.
|
|
+
|
|
+ -->
|
|
+ <property name="KeymapCapabilities" type="a{sv}" access="read"/>
|
|
+
|
|
+ <!--
|
|
+ SetKeymap:
|
|
+ @options: Options vararg describing the keymap.
|
|
+
|
|
+ Set the current input source. The type indicates how the input source is
|
|
+ defined.
|
|
+
|
|
+ For possible types, see the ``type`` option in KeyboardLayouts.
|
|
+
|
|
+ Available options:
|
|
+
|
|
+ * ``keymap-type`` (``u``)
|
|
+
|
|
+ The keymap type. Must only use a format listed in
|
|
+ ``supported-keymap-types`` in ``KeymapCapabilities``. Not setting the
|
|
+ keymap type resets the current keymap according to display server
|
|
+ policy.
|
|
+
|
|
+ * ``xkb-keymap-format`` (``u``)
|
|
+
|
|
+ The XKB keymap format. Must only use a format listed in
|
|
+ ``supported-xkb-keymap-formats``` in ``KeymapCapabilites``.
|
|
+
|
|
+ * ``xkb-keymap`` (``h``)
|
|
+
|
|
+ The XKB keymap in the XKB text format version 1. Required when setting
|
|
+ input source with ``XKB``.
|
|
+
|
|
+ * ``xkb-keymap-layout-index`` (``u``)
|
|
+
|
|
+ The initial XKB layout index.
|
|
+
|
|
+ * ``lock-keymap`` (``b``)
|
|
+
|
|
+ Lock the keymap to the specified one. This will result in the
|
|
+ keymap not being changable via the regular methods normally
|
|
+ used within the remote system.
|
|
+
|
|
+ Defaults to false.
|
|
+
|
|
+ -->
|
|
+ <method name="SetKeymap">
|
|
+ <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
|
|
+ <arg name="options" type="a{sv}" direction="in"/>
|
|
+ </method>
|
|
+
|
|
+ <!--
|
|
+ SetKeymapLayoutIndex:
|
|
+ @index: The layout index
|
|
+
|
|
+ Sets the layout group index in the keymap set via SetKeymap. Will only
|
|
+ succeed if the current keymap is one set by the last call to SetKeymap
|
|
+ on this session.
|
|
+ -->
|
|
+ <method name="SetKeymapLayoutIndex">
|
|
+ <arg name="index" type="u" direction="in"/>
|
|
+ </method>
|
|
+
|
|
+ <!--
|
|
+ CurrentKeymap:
|
|
+
|
|
+ Available options:
|
|
+
|
|
+ * ``name`` (``s``)
|
|
+
|
|
+ The name of the current active keymap.
|
|
+
|
|
+ * ``source`` (``u``)
|
|
+
|
|
+ The source of the current active keymap.
|
|
+
|
|
+ Available sources:
|
|
+ ``0``: EXTERNAL: Keymap was configured externally to this session.
|
|
+ ``1``: SESSION: Keymap was configured by this session.
|
|
+ -->
|
|
+ <property name="CurrentKeymap" type="a{sv}" access="read"/>
|
|
+
|
|
</interface>
|
|
|
|
</node>
|
|
diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c
|
|
index bda50e3110..82591bd9e7 100644
|
|
--- a/src/backends/meta-remote-desktop-session.c
|
|
+++ b/src/backends/meta-remote-desktop-session.c
|
|
@@ -31,17 +31,19 @@
|
|
#include <unistd.h>
|
|
#include <xkbcommon/xkbcommon.h>
|
|
|
|
+#include "backends/meta-backend-private.h"
|
|
#include "backends/meta-dbus-session-watcher.h"
|
|
#include "backends/meta-dbus-session-manager.h"
|
|
#include "backends/meta-eis.h"
|
|
+#include "backends/meta-keymap-description-private.h"
|
|
#include "backends/meta-logical-monitor-private.h"
|
|
#include "backends/meta-screen-cast-session.h"
|
|
#include "backends/meta-remote-access-controller-private.h"
|
|
#include "cogl/cogl.h"
|
|
#include "core/display-private.h"
|
|
+#include "core/meta-sealed-fd.h"
|
|
#include "core/meta-selection-private.h"
|
|
#include "core/meta-selection-source-remote.h"
|
|
-#include "meta/meta-backend.h"
|
|
|
|
#include "meta-dbus-remote-desktop.h"
|
|
|
|
@@ -49,6 +51,20 @@
|
|
|
|
#define TRANSFER_REQUEST_CLEANUP_TIMEOUT_MS (s2ms (15))
|
|
|
|
+typedef enum _MetaRemoteDesktopKeymapFormat
|
|
+{
|
|
+ META_REMOTE_DESKTOP_KEYMAP_FORMAT_XKB_V1 = 1,
|
|
+ META_REMOTE_DESKTOP_KEYMAP_FORMAT_XKB_V2 = 2,
|
|
+} MetaRemoteDesktopKeymapFormat;
|
|
+
|
|
+typedef enum _MetaRemoteDesktopKeymapSource
|
|
+{
|
|
+ META_REMOTE_DESKTOP_KEYMAP_SOURCE_EXTERNAL = 0,
|
|
+ META_REMOTE_DESKTOP_KEYMAP_SOURCE_SESSION = 1,
|
|
+} MetaRemoteDesktopKeymapSource;
|
|
+
|
|
+#define SUPPORTED_KEYMAP_FORMATS (1 << META_REMOTE_DESKTOP_KEYMAP_FORMAT_XKB_V1)
|
|
+
|
|
enum
|
|
{
|
|
PROP_0,
|
|
@@ -106,6 +122,14 @@ struct _MetaRemoteDesktopSession
|
|
GHashTable *mapping_ids;
|
|
|
|
gulong monitors_changed_handler_id;
|
|
+ gulong keymap_changed_handler_id;
|
|
+ gulong keymap_layout_group_changed_handler_id;
|
|
+ gulong keymap_state_changed_handler_id;
|
|
+
|
|
+ MetaKeymapDescription *keymap_description;
|
|
+ MetaKeymapDescriptionOwner *keymap_owner;
|
|
+
|
|
+ GCancellable *cancellable;
|
|
};
|
|
|
|
static void initable_init_iface (GInitableIface *iface);
|
|
@@ -475,6 +499,8 @@ meta_remote_desktop_session_close (MetaDbusSession *dbus_session)
|
|
meta_dbus_session_manager_get_backend (session->session_manager);
|
|
MetaMonitorManager *monitor_manager =
|
|
meta_backend_get_monitor_manager (backend);
|
|
+ ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
|
+ ClutterKeymap *keymap = clutter_seat_get_keymap (seat);
|
|
|
|
session->started = FALSE;
|
|
|
|
@@ -491,6 +517,12 @@ meta_remote_desktop_session_close (MetaDbusSession *dbus_session)
|
|
|
|
g_clear_signal_handler (&session->monitors_changed_handler_id,
|
|
monitor_manager);
|
|
+ g_clear_signal_handler (&session->keymap_changed_handler_id,
|
|
+ backend);
|
|
+ g_clear_signal_handler (&session->keymap_layout_group_changed_handler_id,
|
|
+ backend);
|
|
+ g_clear_signal_handler (&session->keymap_state_changed_handler_id,
|
|
+ keymap);
|
|
|
|
g_clear_object (&session->virtual_pointer);
|
|
g_clear_object (&session->virtual_keyboard);
|
|
@@ -1998,6 +2030,276 @@ handle_connect_to_eis (MetaDBusRemoteDesktopSession *skeleton,
|
|
return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
}
|
|
|
|
+static void
|
|
+update_current_keymap (MetaRemoteDesktopSession *session)
|
|
+{
|
|
+ MetaBackend *backend =
|
|
+ meta_dbus_session_manager_get_backend (session->session_manager);
|
|
+ ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
|
+ ClutterKeymap *keymap;
|
|
+ MetaKeymapDescription *keymap_description;
|
|
+ GVariantBuilder builder;
|
|
+ const char *layout_name;
|
|
+ MetaRemoteDesktopKeymapSource source;
|
|
+
|
|
+ keymap = clutter_seat_get_keymap (seat);
|
|
+ keymap_description = meta_backend_get_keymap_description (backend);
|
|
+
|
|
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
|
+
|
|
+ layout_name = clutter_keymap_get_current_display_name (keymap);
|
|
+ if (layout_name)
|
|
+ {
|
|
+ g_variant_builder_add (&builder, "{sv}",
|
|
+ "name", g_variant_new_string (layout_name));
|
|
+ }
|
|
+
|
|
+ if (keymap_description == session->keymap_description)
|
|
+ source = META_REMOTE_DESKTOP_KEYMAP_SOURCE_SESSION;
|
|
+ else
|
|
+ source = META_REMOTE_DESKTOP_KEYMAP_SOURCE_EXTERNAL;
|
|
+ g_variant_builder_add (&builder, "{sv}",
|
|
+ "source", g_variant_new_uint32 (source));
|
|
+
|
|
+ meta_dbus_remote_desktop_session_set_current_keymap (
|
|
+ META_DBUS_REMOTE_DESKTOP_SESSION (session),
|
|
+ g_variant_builder_end (&builder));
|
|
+}
|
|
+
|
|
+typedef struct _SetKeymapData
|
|
+{
|
|
+ MetaRemoteDesktopSession *session;
|
|
+ GDBusMethodInvocation *invocation;
|
|
+} SetKeymapData;
|
|
+
|
|
+static void
|
|
+set_keymap_data_free (gpointer user_data)
|
|
+{
|
|
+ SetKeymapData *data = user_data;
|
|
+
|
|
+ g_free (data);
|
|
+}
|
|
+
|
|
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (SetKeymapData, set_keymap_data_free)
|
|
+
|
|
+static void
|
|
+set_keymap_cb (GObject *source_object,
|
|
+ GAsyncResult *result,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ MetaBackend *backend = META_BACKEND (source_object);
|
|
+ g_autoptr (SetKeymapData) data = user_data;
|
|
+ MetaRemoteDesktopSession *session = data->session;
|
|
+ g_autoptr (GError) error = NULL;
|
|
+
|
|
+ if (!meta_backend_set_keymap_finish (backend, result, &error))
|
|
+ {
|
|
+ g_dbus_method_invocation_return_gerror (data->invocation, error);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ meta_dbus_remote_desktop_session_complete_set_keymap (
|
|
+ META_DBUS_REMOTE_DESKTOP_SESSION (session),
|
|
+ data->invocation,
|
|
+ NULL);
|
|
+
|
|
+ update_current_keymap (session);
|
|
+}
|
|
+
|
|
+static void
|
|
+reset_keymap_cb (GObject *source_object,
|
|
+ GAsyncResult *result,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ MetaBackend *backend = META_BACKEND (source_object);
|
|
+ g_autoptr (SetKeymapData) data = user_data;
|
|
+ MetaRemoteDesktopSession *session = data->session;
|
|
+ g_autoptr (GError) error = NULL;
|
|
+
|
|
+ if (!meta_backend_reset_keymap_finish (backend, result, &error))
|
|
+ {
|
|
+ g_dbus_method_invocation_return_gerror (data->invocation, error);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ g_clear_pointer (&session->keymap_description,
|
|
+ meta_keymap_description_unref);
|
|
+
|
|
+ meta_dbus_remote_desktop_session_complete_set_keymap (
|
|
+ META_DBUS_REMOTE_DESKTOP_SESSION (session),
|
|
+ data->invocation,
|
|
+ NULL);
|
|
+
|
|
+ update_current_keymap (session);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+verify_keymap_format (uint32_t keymap_format)
|
|
+{
|
|
+ switch (keymap_format)
|
|
+ {
|
|
+ case META_REMOTE_DESKTOP_KEYMAP_FORMAT_XKB_V1:
|
|
+ case META_REMOTE_DESKTOP_KEYMAP_FORMAT_XKB_V2:
|
|
+ return TRUE;
|
|
+ }
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+handle_set_keymap (MetaDBusRemoteDesktopSession *skeleton,
|
|
+ GDBusMethodInvocation *invocation,
|
|
+ GUnixFDList *fd_list_in,
|
|
+ GVariant *arg_options)
|
|
+{
|
|
+ MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
|
+ MetaBackend *backend =
|
|
+ meta_dbus_session_manager_get_backend (session->session_manager);
|
|
+ uint32_t keymap_type = UINT32_MAX;
|
|
+ uint32_t keymap_format = UINT32_MAX;
|
|
+ g_autoptr (GError) error = NULL;
|
|
+ g_autoptr (GVariant) keymap_handle = NULL;
|
|
+ g_autoptr (MetaSealedFd) sealed_keymap = NULL;
|
|
+ g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
+ uint32_t layout_index = 0;
|
|
+ gboolean lock_keymap;
|
|
+ SetKeymapData *data;
|
|
+
|
|
+ if (!g_variant_lookup (arg_options, "keymap-type", "u", &keymap_type))
|
|
+ {
|
|
+ data = g_new0 (SetKeymapData, 1);
|
|
+ data->session = session;
|
|
+ data->invocation = invocation;
|
|
+
|
|
+ meta_backend_reset_keymap_async (backend,
|
|
+ session->keymap_owner,
|
|
+ session->cancellable,
|
|
+ reset_keymap_cb,
|
|
+ data);
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
+ }
|
|
+
|
|
+ g_variant_lookup (arg_options, "xkb-keymap-format", "u", &keymap_format);
|
|
+
|
|
+ if (!verify_keymap_format (keymap_format))
|
|
+ {
|
|
+ g_dbus_method_invocation_return_error (invocation,
|
|
+ G_DBUS_ERROR,
|
|
+ G_DBUS_ERROR_INVALID_ARGS,
|
|
+ "Invalid keymap format");
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
+ }
|
|
+
|
|
+ if (!((1 << keymap_format) & SUPPORTED_KEYMAP_FORMATS))
|
|
+ {
|
|
+ g_dbus_method_invocation_return_error (invocation,
|
|
+ G_DBUS_ERROR,
|
|
+ G_DBUS_ERROR_NOT_SUPPORTED,
|
|
+ "Non-supported keymap format");
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
+ }
|
|
+
|
|
+ keymap_handle = g_variant_lookup_value (arg_options, "xkb-keymap",
|
|
+ G_VARIANT_TYPE_HANDLE);
|
|
+ if (!keymap_handle)
|
|
+ {
|
|
+ g_dbus_method_invocation_return_error (invocation,
|
|
+ G_DBUS_ERROR,
|
|
+ G_DBUS_ERROR_FAILED,
|
|
+ "No keymap handle");
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
+ }
|
|
+
|
|
+ sealed_keymap = meta_sealed_fd_new_from_handle (keymap_handle,
|
|
+ fd_list_in,
|
|
+ &error);
|
|
+
|
|
+ g_variant_lookup (arg_options, "xkb-keymap-layout-index", "u", &layout_index);
|
|
+
|
|
+ keymap_description = meta_keymap_description_new_from_fd (sealed_keymap,
|
|
+ keymap_format);
|
|
+ if (g_variant_lookup (arg_options, "lock-keymap", "b", &lock_keymap) &&
|
|
+ lock_keymap)
|
|
+ meta_keymap_description_lock (keymap_description, session->keymap_owner);
|
|
+ else
|
|
+ meta_keymap_description_unlock (keymap_description, session->keymap_owner);
|
|
+
|
|
+ data = g_new0 (SetKeymapData, 1);
|
|
+ data->session = session;
|
|
+ data->invocation = invocation;
|
|
+
|
|
+ g_clear_pointer (&session->keymap_description,
|
|
+ meta_keymap_description_unref);
|
|
+ session->keymap_description =
|
|
+ meta_keymap_description_ref (keymap_description);
|
|
+
|
|
+ meta_backend_set_keymap_async (backend,
|
|
+ keymap_description,
|
|
+ layout_index,
|
|
+ session->cancellable,
|
|
+ set_keymap_cb,
|
|
+ data);
|
|
+
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
+
|
|
+}
|
|
+
|
|
+static void
|
|
+set_keymap_layout_group_cb (GObject *source_object,
|
|
+ GAsyncResult *result,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ MetaBackend *backend = META_BACKEND (source_object);
|
|
+ g_autoptr (SetKeymapData) data = user_data;
|
|
+ g_autoptr (GError) error = NULL;
|
|
+
|
|
+ if (!meta_backend_set_keymap_finish (backend, result, &error))
|
|
+ {
|
|
+ g_dbus_method_invocation_return_gerror (data->invocation, error);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ meta_dbus_remote_desktop_session_complete_set_keymap_layout_index (
|
|
+ META_DBUS_REMOTE_DESKTOP_SESSION (data->session),
|
|
+ data->invocation);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+handle_set_keymap_layout_index (MetaDBusRemoteDesktopSession *skeleton,
|
|
+ GDBusMethodInvocation *invocation,
|
|
+ uint32_t layout_index)
|
|
+{
|
|
+ MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
|
+ MetaBackend *backend =
|
|
+ meta_dbus_session_manager_get_backend (session->session_manager);
|
|
+ MetaKeymapDescription *keymap_description;
|
|
+ SetKeymapData *data;
|
|
+
|
|
+ keymap_description = meta_backend_get_keymap_description (backend);
|
|
+
|
|
+ if (!session->keymap_description ||
|
|
+ keymap_description != session->keymap_description)
|
|
+ {
|
|
+ g_dbus_method_invocation_return_error (invocation,
|
|
+ G_DBUS_ERROR,
|
|
+ G_DBUS_ERROR_FAILED,
|
|
+ "Invalid current keymap");
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
+ }
|
|
+
|
|
+ data = g_new0 (SetKeymapData, 1);
|
|
+ data->session = session;
|
|
+ data->invocation = invocation;
|
|
+
|
|
+ meta_backend_set_keymap_async (backend,
|
|
+ session->keymap_description,
|
|
+ layout_index,
|
|
+ session->cancellable,
|
|
+ set_keymap_layout_group_cb,
|
|
+ data);
|
|
+
|
|
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
|
|
+}
|
|
+
|
|
static gboolean
|
|
meta_remote_desktop_session_initable_init (GInitable *initable,
|
|
GCancellable *cancellable,
|
|
@@ -2029,6 +2331,17 @@ meta_remote_desktop_session_initable_init (GInitable *initable,
|
|
session, "num-lock-state",
|
|
G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
|
|
|
|
+ session->keymap_changed_handler_id =
|
|
+ g_signal_connect_swapped (backend, "keymap-changed",
|
|
+ G_CALLBACK (update_current_keymap), session);
|
|
+ session->keymap_layout_group_changed_handler_id =
|
|
+ g_signal_connect_swapped (backend, "keymap-layout-group-changed",
|
|
+ G_CALLBACK (update_current_keymap), session);
|
|
+ session->keymap_state_changed_handler_id =
|
|
+ g_signal_connect_swapped (keymap, "state-changed",
|
|
+ G_CALLBACK (update_current_keymap), session);
|
|
+ update_current_keymap (session);
|
|
+
|
|
session->mapping_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
|
|
return TRUE;
|
|
@@ -2062,6 +2375,8 @@ meta_remote_desktop_session_init_iface (MetaDBusRemoteDesktopSessionIface *iface
|
|
iface->handle_selection_write_done = handle_selection_write_done;
|
|
iface->handle_selection_read = handle_selection_read;
|
|
iface->handle_connect_to_eis = handle_connect_to_eis;
|
|
+ iface->handle_set_keymap = handle_set_keymap;
|
|
+ iface->handle_set_keymap_layout_index = handle_set_keymap_layout_index;
|
|
}
|
|
|
|
static void
|
|
@@ -2079,6 +2394,9 @@ meta_remote_desktop_session_finalize (GObject *object)
|
|
|
|
g_assert (!meta_remote_desktop_session_is_running (session));
|
|
|
|
+ g_cancellable_cancel (session->cancellable);
|
|
+ g_clear_object (&session->cancellable);
|
|
+
|
|
g_clear_signal_handler (&session->owner_changed_handler_id, selection);
|
|
reset_current_selection_source (session);
|
|
cancel_selection_read (session);
|
|
@@ -2086,6 +2404,9 @@ meta_remote_desktop_session_finalize (GObject *object)
|
|
|
|
g_clear_pointer (&session->mapping_ids, g_hash_table_unref);
|
|
|
|
+ g_clear_pointer (&session->keymap_description, meta_keymap_description_unref);
|
|
+ g_clear_pointer (&session->keymap_owner, meta_keymap_description_owner_unref);
|
|
+
|
|
g_clear_object (&session->handle);
|
|
g_free (session->peer_name);
|
|
g_free (session->session_id);
|
|
@@ -2154,6 +2475,10 @@ meta_remote_desktop_session_init (MetaRemoteDesktopSession *session)
|
|
++global_session_number);
|
|
|
|
session->transfer_requests = g_hash_table_new (NULL, NULL);
|
|
+
|
|
+ session->keymap_owner = meta_keymap_description_owner_new ();
|
|
+
|
|
+ session->cancellable = g_cancellable_new ();
|
|
}
|
|
|
|
static void
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From ec2bd8948e1014325f1c4e247863289666f33d7e Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Mon, 29 Sep 2025 16:36:43 +0200
|
|
Subject: [PATCH 26/32] mdk: Allow mirroring the host keymap in the nested
|
|
instance
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 5a78b12a3579b8c30a43a60f3f344f142db2626c)
|
|
---
|
|
mdk/mdk-context.c | 19 +++++
|
|
mdk/mdk-context.h | 2 +
|
|
mdk/mdk-main-window.ui | 4 +
|
|
mdk/mdk-main.c | 3 +
|
|
mdk/mdk-session.c | 179 +++++++++++++++++++++++++++++++++++++++++
|
|
mdk/meson.build | 1 +
|
|
6 files changed, 208 insertions(+)
|
|
|
|
diff --git a/mdk/mdk-context.c b/mdk/mdk-context.c
|
|
index 38112ab0cb..a358719d53 100644
|
|
--- a/mdk/mdk-context.c
|
|
+++ b/mdk/mdk-context.c
|
|
@@ -36,6 +36,7 @@ enum
|
|
|
|
PROP_EMULATE_TOUCH,
|
|
PROP_INHIBIT_SYSTEM_SHORTCUTS,
|
|
+ PROP_USE_HOST_KEYMAP,
|
|
|
|
N_PROPS
|
|
};
|
|
@@ -67,6 +68,7 @@ struct _MdkContext
|
|
|
|
gboolean emulate_touch;
|
|
gboolean inhibit_system_shortcuts;
|
|
+ gboolean use_host_keymap;
|
|
|
|
GSettings *settings;
|
|
|
|
@@ -324,6 +326,9 @@ mdk_context_set_property (GObject *object,
|
|
case PROP_INHIBIT_SYSTEM_SHORTCUTS:
|
|
context->inhibit_system_shortcuts = g_value_get_boolean (value);
|
|
break;
|
|
+ case PROP_USE_HOST_KEYMAP:
|
|
+ context->use_host_keymap = g_value_get_boolean (value);
|
|
+ break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
@@ -346,6 +351,9 @@ mdk_context_get_property (GObject *object,
|
|
case PROP_INHIBIT_SYSTEM_SHORTCUTS:
|
|
g_value_set_boolean (value, context->inhibit_system_shortcuts);
|
|
break;
|
|
+ case PROP_USE_HOST_KEYMAP:
|
|
+ g_value_set_boolean (value, context->use_host_keymap);
|
|
+ break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
@@ -386,6 +394,11 @@ mdk_context_class_init (MdkContextClass *klass)
|
|
FALSE,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_STATIC_STRINGS);
|
|
+ obj_props[PROP_USE_HOST_KEYMAP] =
|
|
+ g_param_spec_boolean ("use-host-keymap", NULL, NULL,
|
|
+ FALSE,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_STATIC_STRINGS);
|
|
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
|
|
|
signals[READY] = g_signal_new ("ready",
|
|
@@ -593,6 +606,12 @@ mdk_context_get_inhibit_system_shortcuts (MdkContext *context)
|
|
return context->inhibit_system_shortcuts;
|
|
}
|
|
|
|
+gboolean
|
|
+mdk_context_get_use_host_keymap (MdkContext *context)
|
|
+{
|
|
+ return context->use_host_keymap;
|
|
+}
|
|
+
|
|
GPtrArray *
|
|
mdk_context_get_launchers (MdkContext *context)
|
|
{
|
|
diff --git a/mdk/mdk-context.h b/mdk/mdk-context.h
|
|
index 29fb359741..e3f6a519b4 100644
|
|
--- a/mdk/mdk-context.h
|
|
+++ b/mdk/mdk-context.h
|
|
@@ -38,6 +38,8 @@ gboolean mdk_context_get_emulate_touch (MdkContext *context);
|
|
|
|
gboolean mdk_context_get_inhibit_system_shortcuts (MdkContext *context);
|
|
|
|
+gboolean mdk_context_get_use_host_keymap (MdkContext *context);
|
|
+
|
|
GPtrArray * mdk_context_get_launchers (MdkContext *context);
|
|
|
|
void mdk_context_activate_launcher (MdkContext *context,
|
|
diff --git a/mdk/mdk-main-window.ui b/mdk/mdk-main-window.ui
|
|
index b420aa7bd2..a431770366 100644
|
|
--- a/mdk/mdk-main-window.ui
|
|
+++ b/mdk/mdk-main-window.ui
|
|
@@ -13,6 +13,10 @@
|
|
<attribute name="label" translatable="yes">_Inhibit system shortcuts</attribute>
|
|
<attribute name="action">app.toggle_inhibit_system_shortcuts</attribute>
|
|
</item>
|
|
+ <item>
|
|
+ <attribute name="label" translatable="yes">Use host _keymap</attribute>
|
|
+ <attribute name="action">app.toggle_host_keymap</attribute>
|
|
+ </item>
|
|
</submenu>
|
|
</section>
|
|
<section>
|
|
diff --git a/mdk/mdk-main.c b/mdk/mdk-main.c
|
|
index 8e61373616..ff37dad4a2 100644
|
|
--- a/mdk/mdk-main.c
|
|
+++ b/mdk/mdk-main.c
|
|
@@ -237,6 +237,7 @@ main (int argc,
|
|
{ "about", activate_about, NULL, NULL, NULL },
|
|
{ "toggle_emulate_touch", .state = "false", },
|
|
{ "toggle_inhibit_system_shortcuts", .state = "false", },
|
|
+ { "toggle_host_keymap", .state = "false", },
|
|
{ "launch", activate_launch, .parameter_type = "i", },
|
|
{ "edit_launchers", activate_edit_launchers, },
|
|
};
|
|
@@ -257,6 +258,8 @@ main (int argc,
|
|
app->context, "emulate-touch");
|
|
bind_action_to_property (app, "toggle_inhibit_system_shortcuts",
|
|
app->context, "inhibit-system-shortcuts");
|
|
+ bind_action_to_property (app, "toggle_host_keymap",
|
|
+ app->context, "use-host-keymap");
|
|
|
|
g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
|
|
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
|
diff --git a/mdk/mdk-session.c b/mdk/mdk-session.c
|
|
index 43793c8fc5..239d5dacd9 100644
|
|
--- a/mdk/mdk-session.c
|
|
+++ b/mdk/mdk-session.c
|
|
@@ -19,10 +19,13 @@
|
|
|
|
#include "mdk-session.h"
|
|
|
|
+#include <gdk/wayland/gdkwayland.h>
|
|
#include <gio/gio.h>
|
|
#include <glib/gi18n-lib.h>
|
|
#include <glib/gstdio.h>
|
|
#include <libei.h>
|
|
+#include <sys/mman.h>
|
|
+#include <xkbcommon/xkbcommon.h>
|
|
|
|
#include "mdk-context.h"
|
|
#include "mdk-ei.h"
|
|
@@ -41,6 +44,17 @@ typedef enum _MdkScreenCastCursorMode
|
|
MDK_SCREEN_CAST_CURSOR_MODE_METADATA = 2,
|
|
} MdkScreenCastCursorMode;
|
|
|
|
+typedef enum _MdkRemoteDesktopKeymapType
|
|
+{
|
|
+ MDK_REMOTE_DESKTOP_KEYMAP_TYPE_XKB = 0,
|
|
+} MdkRemoteDesktopKeymapType;
|
|
+
|
|
+typedef enum _MdkRemoteDesktopKeymapFormat
|
|
+{
|
|
+ MDK_REMOTE_DESKTOP_KEYMAP_FORMAT_XKB_TEXT_V1 = 1,
|
|
+ MDK_REMOTE_DESKTOP_KEYMAP_FORMAT_XKB_TEXT_V2 = 2,
|
|
+} MdkRemoteDesktopKeymapFormat;
|
|
+
|
|
enum
|
|
{
|
|
PROP_0,
|
|
@@ -73,6 +87,9 @@ struct _MdkSession
|
|
MdkDBusScreenCast *screen_cast_proxy;
|
|
MdkDBusRemoteDesktopSession *remote_desktop_session_proxy;
|
|
MdkDBusScreenCastSession *screen_cast_session_proxy;
|
|
+
|
|
+ struct xkb_keymap *xkb_keymap;
|
|
+ int layout_index;
|
|
};
|
|
|
|
static void
|
|
@@ -89,6 +106,150 @@ on_session_closed (MdkDBusRemoteDesktopSession *remote_desktop_session_proxy,
|
|
g_signal_emit (session, signals[CLOSED], 0);
|
|
}
|
|
|
|
+static void
|
|
+maybe_sync_keymap (MdkSession *session)
|
|
+{
|
|
+ GdkDisplay *display = gdk_display_get_default ();
|
|
+ GdkSeat *seat = gdk_display_get_default_seat (display);
|
|
+ GdkDevice *keyboard = gdk_seat_get_keyboard (seat);
|
|
+ struct xkb_keymap *xkb_keymap;
|
|
+ int layout_index;
|
|
+
|
|
+ if (!mdk_context_get_use_host_keymap (session->context))
|
|
+ {
|
|
+ if (session->xkb_keymap)
|
|
+ {
|
|
+ GVariantBuilder options_builder;
|
|
+
|
|
+ session->xkb_keymap = NULL;
|
|
+
|
|
+ g_variant_builder_init (&options_builder, G_VARIANT_TYPE ("a{sv}"));
|
|
+ mdk_dbus_remote_desktop_session_call_set_keymap (
|
|
+ session->remote_desktop_session_proxy,
|
|
+ g_variant_builder_end (&options_builder),
|
|
+ NULL,
|
|
+ NULL, NULL, NULL);
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!GDK_IS_WAYLAND_DISPLAY (display))
|
|
+ {
|
|
+ g_warning ("Changing keymap not supported when running from X11");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ xkb_keymap = gdk_wayland_device_get_xkb_keymap (keyboard);
|
|
+ layout_index = gdk_device_get_active_layout_index (keyboard);
|
|
+
|
|
+ if (xkb_keymap == session->xkb_keymap &&
|
|
+ layout_index == session->layout_index)
|
|
+ return;
|
|
+
|
|
+ session->layout_index = layout_index;
|
|
+
|
|
+ if (xkb_keymap != session->xkb_keymap)
|
|
+ {
|
|
+ g_autofree char *keymap_serialized = NULL;
|
|
+ g_autofd int fd = -1;
|
|
+ int fd_idx;
|
|
+ size_t keymap_size;
|
|
+ void *keymap_mem;
|
|
+ GVariantBuilder options_builder;
|
|
+ g_autoptr (GUnixFDList) fd_list = NULL;
|
|
+ g_autoptr (GError) error = NULL;
|
|
+
|
|
+ session->xkb_keymap = xkb_keymap;
|
|
+
|
|
+ keymap_serialized = xkb_keymap_get_as_string (xkb_keymap,
|
|
+ XKB_KEYMAP_FORMAT_TEXT_V1);
|
|
+ if (!keymap_serialized)
|
|
+ {
|
|
+ g_warning ("Failed to serialize current keymap.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ fd = memfd_create ("mdk-keymap", MFD_ALLOW_SEALING | MFD_CLOEXEC);
|
|
+ if (fd == -1)
|
|
+ {
|
|
+ g_warning ("Failed to create keymap memfd: %s", g_strerror (errno));
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ keymap_size = strlen (keymap_serialized) + 1;
|
|
+ if (ftruncate (fd, keymap_size) == -1)
|
|
+ {
|
|
+ g_warning ("ftruncate of keymap fd failed: %s", g_strerror (errno));
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ keymap_mem = mmap (NULL, keymap_size, PROT_WRITE, MAP_SHARED, fd, 0);
|
|
+ if (keymap_mem == MAP_FAILED)
|
|
+ {
|
|
+ g_warning ("Failed mmap keymap fd: %s", g_strerror (errno));
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ strcpy (keymap_mem, keymap_serialized);
|
|
+
|
|
+ if (munmap (keymap_mem, keymap_size) == -1)
|
|
+ {
|
|
+ g_warning ("Failed munmap keymap fd: %s", g_strerror (errno));
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ fd_list = g_unix_fd_list_new ();
|
|
+
|
|
+ fd_idx = g_unix_fd_list_append (fd_list, fd, &error);
|
|
+ if (fd_idx == -1)
|
|
+ {
|
|
+ g_warning ("Failed to append file descriptor to fd list: %s",
|
|
+ error->message);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ layout_index = gdk_device_get_active_layout_index (keyboard);
|
|
+
|
|
+ g_variant_builder_init (&options_builder, G_VARIANT_TYPE ("a{sv}"));
|
|
+ g_variant_builder_add (&options_builder, "{sv}",
|
|
+ "keymap-type",
|
|
+ g_variant_new_uint32 (MDK_REMOTE_DESKTOP_KEYMAP_TYPE_XKB));
|
|
+ g_variant_builder_add (&options_builder, "{sv}",
|
|
+ "xkb-keymap-format",
|
|
+ g_variant_new_uint32 (MDK_REMOTE_DESKTOP_KEYMAP_FORMAT_XKB_TEXT_V1));
|
|
+ g_variant_builder_add (&options_builder, "{sv}",
|
|
+ "xkb-keymap",
|
|
+ g_variant_new_handle (fd_idx));
|
|
+ g_variant_builder_add (&options_builder, "{sv}",
|
|
+ "xkb-keymap-layout-index",
|
|
+ g_variant_new_uint32 (layout_index));
|
|
+ g_variant_builder_add (&options_builder, "{sv}",
|
|
+ "lock-keymap",
|
|
+ g_variant_new_boolean (TRUE));
|
|
+
|
|
+ mdk_dbus_remote_desktop_session_call_set_keymap (
|
|
+ session->remote_desktop_session_proxy,
|
|
+ g_variant_builder_end (&options_builder),
|
|
+ fd_list,
|
|
+ NULL, NULL, NULL);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ mdk_dbus_remote_desktop_session_call_set_keymap_layout_index (
|
|
+ session->remote_desktop_session_proxy,
|
|
+ layout_index,
|
|
+ NULL, NULL, NULL);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+on_use_host_keymap_changed (MdkContext *context,
|
|
+ GParamSpec *pspec,
|
|
+ MdkSession *session)
|
|
+{
|
|
+ maybe_sync_keymap (session);
|
|
+}
|
|
+
|
|
static gboolean
|
|
init_session (MdkSession *session,
|
|
GCancellable *cancellable,
|
|
@@ -187,6 +348,12 @@ init_session (MdkSession *session,
|
|
G_CALLBACK (on_session_closed),
|
|
session);
|
|
|
|
+ g_signal_connect_object (session->context,
|
|
+ "notify::use-host-keymap",
|
|
+ G_CALLBACK (on_use_host_keymap_changed),
|
|
+ session,
|
|
+ G_CONNECT_DEFAULT);
|
|
+
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -196,6 +363,9 @@ mdk_session_initable_init (GInitable *initable,
|
|
GError **error)
|
|
{
|
|
MdkSession *session = MDK_SESSION (initable);
|
|
+ GdkDisplay *display = gdk_display_get_default ();
|
|
+ GdkSeat *seat = gdk_display_get_default_seat (display);
|
|
+ GdkDevice *keyboard = gdk_seat_get_keyboard (seat);
|
|
|
|
g_debug ("Initializing session");
|
|
|
|
@@ -230,6 +400,15 @@ mdk_session_initable_init (GInitable *initable,
|
|
error))
|
|
return FALSE;
|
|
|
|
+ g_signal_connect_object (keyboard, "notify::layout-names",
|
|
+ G_CALLBACK (maybe_sync_keymap),
|
|
+ session,
|
|
+ G_CONNECT_SWAPPED);
|
|
+ g_signal_connect_object (keyboard, "notify::active-layout-index",
|
|
+ G_CALLBACK (maybe_sync_keymap),
|
|
+ session,
|
|
+ G_CONNECT_SWAPPED);
|
|
+
|
|
return TRUE;
|
|
}
|
|
|
|
diff --git a/mdk/meson.build b/mdk/meson.build
|
|
index d3e4184ca4..59a39b9c57 100644
|
|
--- a/mdk/meson.build
|
|
+++ b/mdk/meson.build
|
|
@@ -91,6 +91,7 @@ executable('mutter-devkit',
|
|
libpipewire_dep,
|
|
libdrm_dep,
|
|
libei_dep,
|
|
+ xkbcommon_dep,
|
|
],
|
|
install_dir: libexecdir,
|
|
install: true,
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From fc4743e8812280b181ff3097b37ad619c431d24d Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Fri, 3 Oct 2025 15:41:09 +0200
|
|
Subject: [PATCH 27/32] keymap-description: Add 'direct_equal()' API
|
|
|
|
This is meant to be used by Javascript via GI to check whether one
|
|
instance is exactly the same as another, to effectively check if was one
|
|
self that set the keymap description in question.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 3e458cc611026bd4095012c488584b612b85ea4b)
|
|
---
|
|
src/backends/meta-keymap-description.c | 7 +++++++
|
|
src/meta/meta-keymap-description.h | 4 ++++
|
|
2 files changed, 11 insertions(+)
|
|
|
|
diff --git a/src/backends/meta-keymap-description.c b/src/backends/meta-keymap-description.c
|
|
index 60a06fc5da..4d077626df 100644
|
|
--- a/src/backends/meta-keymap-description.c
|
|
+++ b/src/backends/meta-keymap-description.c
|
|
@@ -177,6 +177,13 @@ meta_keymap_description_get_source (MetaKeymapDescription *keymap_description)
|
|
return keymap_description->source;
|
|
}
|
|
|
|
+gboolean
|
|
+meta_keymap_description_direct_equal (MetaKeymapDescription *keymap_description,
|
|
+ MetaKeymapDescription *other)
|
|
+{
|
|
+ return keymap_description == other;
|
|
+}
|
|
+
|
|
static char *
|
|
maybe_derive_short_name (struct rxkb_context *rxkb_context,
|
|
const char *layout_name)
|
|
diff --git a/src/meta/meta-keymap-description.h b/src/meta/meta-keymap-description.h
|
|
index 0f4de5ed2b..d4f9431ef8 100644
|
|
--- a/src/meta/meta-keymap-description.h
|
|
+++ b/src/meta/meta-keymap-description.h
|
|
@@ -45,5 +45,9 @@ void meta_keymap_description_unref (MetaKeymapDescription *keymap_description);
|
|
META_EXPORT
|
|
gboolean meta_keymap_description_is_locked (MetaKeymapDescription *keymap_description);
|
|
|
|
+META_EXPORT
|
|
+gboolean meta_keymap_description_direct_equal (MetaKeymapDescription *keymap_description,
|
|
+ MetaKeymapDescription *other);
|
|
+
|
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKeymapDescription,
|
|
meta_keymap_description_unref);
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From f2c21f79e5587ad1c204dad787bb3de7bd0ba7d2 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Fri, 3 Oct 2025 15:42:19 +0200
|
|
Subject: [PATCH 28/32] tests/keyboard-map-tests: Assert keymap description
|
|
sanity on signal
|
|
|
|
When signalled that the keymap changed, make sure the currently returned
|
|
keymap description is the one that was changed to.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 34f9765e27056ea90b800538c2d77189ece3e810)
|
|
---
|
|
src/tests/keyboard-map-tests.c | 17 +++++++++++++++++
|
|
1 file changed, 17 insertions(+)
|
|
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index c705562736..a26b1a7bf4 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -150,6 +150,14 @@ on_keymap_changed (MetaBackend *backend,
|
|
*expected_next_handler = on_keymap_state_changed;
|
|
}
|
|
|
|
+static void
|
|
+on_keymap_changed2 (MetaBackend *backend,
|
|
+ MetaKeymapDescription *expected_keymap_description)
|
|
+{
|
|
+ g_assert_true (expected_keymap_description ==
|
|
+ meta_backend_get_keymap_description (backend));
|
|
+}
|
|
+
|
|
static void
|
|
meta_test_native_keyboard_map_set_async (void)
|
|
{
|
|
@@ -168,6 +176,7 @@ meta_test_native_keyboard_map_set_async (void)
|
|
gpointer expected_next_handler;
|
|
gulong await_mod_mask_handler_id;
|
|
gulong keymap_changed_handler_id;
|
|
+ gulong keymap_changed_handler_id2;
|
|
gulong keymap_state_changed_handler_id;
|
|
|
|
await_mod_mask_handler_id =
|
|
@@ -215,6 +224,13 @@ meta_test_native_keyboard_map_set_async (void)
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
+
|
|
+ keymap_changed_handler_id2 =
|
|
+ g_signal_connect (backend,
|
|
+ "keymap-changed",
|
|
+ G_CALLBACK (on_keymap_changed2),
|
|
+ keymap_description);
|
|
+
|
|
meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
NULL, set_keymap_cb, &done);
|
|
|
|
@@ -240,6 +256,7 @@ meta_test_native_keyboard_map_set_async (void)
|
|
meta_wait_for_update (test_context);
|
|
|
|
g_signal_handler_disconnect (backend, keymap_changed_handler_id);
|
|
+ g_signal_handler_disconnect (backend, keymap_changed_handler_id2);
|
|
g_signal_handler_disconnect (keymap, keymap_state_changed_handler_id);
|
|
}
|
|
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 2ed2a27f02aed240cc7791b7345d5b7fad5d770c Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 28 Jan 2026 16:48:38 +0100
|
|
Subject: [PATCH 29/32] backend: Harmonize on keymap naming convention
|
|
|
|
Instead of sometimes calling it keyboard map or keymap, harmonize an
|
|
using the term keymap everywhere. One piece of API was renamed to
|
|
get_xkb_keymap() to distinguish between returning a ClutterKeymap, and a
|
|
xkb_keymap.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 2fe20346d03391412c37a54d687c9302eafa61ad)
|
|
---
|
|
src/backends/native/meta-backend-native.c | 24 +++---
|
|
.../native/meta-keymap-native-private.h | 16 ++--
|
|
src/backends/native/meta-keymap-native.c | 16 ++--
|
|
src/backends/native/meta-seat-impl.c | 50 +++++------
|
|
src/backends/native/meta-seat-impl.h | 20 ++---
|
|
src/backends/native/meta-seat-native.c | 84 +++++++++----------
|
|
src/backends/native/meta-seat-native.h | 22 ++---
|
|
.../native/meta-virtual-input-device-native.c | 3 +-
|
|
src/tests/keyboard-map-tests.c | 2 +-
|
|
9 files changed, 119 insertions(+), 118 deletions(-)
|
|
|
|
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
|
|
index 7d68894cb8..66105d6cb4 100644
|
|
--- a/src/backends/native/meta-backend-native.c
|
|
+++ b/src/backends/native/meta-backend-native.c
|
|
@@ -318,15 +318,15 @@ meta_backend_native_get_current_logical_monitor (MetaBackend *backend)
|
|
}
|
|
|
|
static void
|
|
-set_keyboard_map_cb (GObject *source_object,
|
|
- GAsyncResult *result,
|
|
- gpointer user_data)
|
|
+set_keymap_cb (GObject *source_object,
|
|
+ GAsyncResult *result,
|
|
+ gpointer user_data)
|
|
{
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (source_object);
|
|
g_autoptr (GTask) task = G_TASK (user_data);
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
- if (!meta_seat_native_set_keyboard_map_finish (seat_native, result, &error))
|
|
+ if (!meta_seat_native_set_keymap_finish (seat_native, result, &error))
|
|
{
|
|
g_task_return_error (task, g_steal_pointer (&error));
|
|
return;
|
|
@@ -345,12 +345,12 @@ meta_backend_native_set_keymap_async (MetaBackend *backend,
|
|
ClutterSeat *seat;
|
|
|
|
seat = clutter_backend_get_default_seat (clutter_backend);
|
|
- meta_seat_native_set_keyboard_map_async (META_SEAT_NATIVE (seat),
|
|
- description,
|
|
- layout_index,
|
|
- g_task_get_cancellable (task),
|
|
- set_keyboard_map_cb,
|
|
- task);
|
|
+ meta_seat_native_set_keymap_async (META_SEAT_NATIVE (seat),
|
|
+ description,
|
|
+ layout_index,
|
|
+ g_task_get_cancellable (task),
|
|
+ set_keymap_cb,
|
|
+ task);
|
|
|
|
}
|
|
|
|
@@ -361,7 +361,7 @@ meta_backend_native_get_keymap (MetaBackend *backend)
|
|
ClutterSeat *seat;
|
|
|
|
seat = clutter_backend_get_default_seat (clutter_backend);
|
|
- return meta_seat_native_get_keyboard_map (META_SEAT_NATIVE (seat));
|
|
+ return meta_seat_native_get_xkb_keymap (META_SEAT_NATIVE (seat));
|
|
}
|
|
|
|
static MetaKeymapDescription *
|
|
@@ -371,7 +371,7 @@ meta_backend_native_get_keymap_description (MetaBackend *backend)
|
|
ClutterSeat *seat;
|
|
|
|
seat = clutter_backend_get_default_seat (clutter_backend);
|
|
- return meta_seat_native_get_keyboard_map_description (META_SEAT_NATIVE (seat));
|
|
+ return meta_seat_native_get_keymap_description (META_SEAT_NATIVE (seat));
|
|
}
|
|
|
|
static xkb_layout_index_t
|
|
diff --git a/src/backends/native/meta-keymap-native-private.h b/src/backends/native/meta-keymap-native-private.h
|
|
index e119b91c31..326451a282 100644
|
|
--- a/src/backends/native/meta-keymap-native-private.h
|
|
+++ b/src/backends/native/meta-keymap-native-private.h
|
|
@@ -25,15 +25,15 @@
|
|
#error "This header cannot be included directly. Use "backends/native/meta-input-thread.h""
|
|
#endif /* META_INPUT_THREAD_H_INSIDE */
|
|
|
|
-void meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
- MetaSeatImpl *seat_impl,
|
|
- MetaKeymapDescription *keymap_description,
|
|
- struct xkb_keymap *xkb_keymap,
|
|
- struct xkb_state *xkb_state,
|
|
- GStrv display_names,
|
|
- GStrv short_names);
|
|
+void meta_keymap_native_set_keymap_in_impl (MetaKeymapNative *keymap,
|
|
+ MetaSeatImpl *seat_impl,
|
|
+ MetaKeymapDescription *keymap_description,
|
|
+ struct xkb_keymap *xkb_keymap,
|
|
+ struct xkb_state *xkb_state,
|
|
+ GStrv display_names,
|
|
+ GStrv short_names);
|
|
|
|
-struct xkb_keymap * meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap);
|
|
+struct xkb_keymap * meta_keymap_native_get_xkb_keymap_in_impl (MetaKeymapNative *keymap);
|
|
|
|
void meta_keymap_native_update_in_impl (MetaKeymapNative *keymap,
|
|
MetaSeatImpl *seat_impl,
|
|
diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c
|
|
index f55b8bd056..f11fd44866 100644
|
|
--- a/src/backends/native/meta-keymap-native.c
|
|
+++ b/src/backends/native/meta-keymap-native.c
|
|
@@ -203,13 +203,13 @@ update_keymap_in_main (gpointer user_data)
|
|
}
|
|
|
|
void
|
|
-meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
- MetaSeatImpl *seat_impl,
|
|
- MetaKeymapDescription *keymap_description,
|
|
- struct xkb_keymap *xkb_keymap,
|
|
- struct xkb_state *xkb_state,
|
|
- GStrv display_names,
|
|
- GStrv short_names)
|
|
+meta_keymap_native_set_keymap_in_impl (MetaKeymapNative *keymap,
|
|
+ MetaSeatImpl *seat_impl,
|
|
+ MetaKeymapDescription *keymap_description,
|
|
+ struct xkb_keymap *xkb_keymap,
|
|
+ struct xkb_state *xkb_state,
|
|
+ GStrv display_names,
|
|
+ GStrv short_names)
|
|
{
|
|
UpdateKeymapData *data;
|
|
|
|
@@ -231,7 +231,7 @@ meta_keymap_native_set_keyboard_map_in_impl (MetaKeymapNative *keymap,
|
|
}
|
|
|
|
struct xkb_keymap *
|
|
-meta_keymap_native_get_keyboard_map_in_impl (MetaKeymapNative *keymap)
|
|
+meta_keymap_native_get_xkb_keymap_in_impl (MetaKeymapNative *keymap)
|
|
{
|
|
return keymap->impl.keymap;
|
|
}
|
|
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
|
|
index 2926bab779..ca7a9aed5a 100644
|
|
--- a/src/backends/native/meta-seat-impl.c
|
|
+++ b/src/backends/native/meta-seat-impl.c
|
|
@@ -3028,7 +3028,7 @@ meta_seat_impl_set_keyboard_numlock_in_impl (MetaSeatImpl *seat_impl,
|
|
MetaKeymapNative *keymap;
|
|
|
|
keymap = seat_impl->keymap;
|
|
- xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (keymap);
|
|
+ xkb_keymap = meta_keymap_native_get_xkb_keymap_in_impl (keymap);
|
|
|
|
numlock = (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2"));
|
|
|
|
@@ -3180,7 +3180,7 @@ update_keyboard_leds (MetaSeatImpl *seat_impl)
|
|
|
|
G_STATIC_ASSERT (G_N_ELEMENTS (led_map) == N_KEYBOARD_LEDS);
|
|
|
|
- xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (seat_impl->keymap);
|
|
+ xkb_keymap = meta_keymap_native_get_xkb_keymap_in_impl (seat_impl->keymap);
|
|
if (!xkb_keymap)
|
|
return;
|
|
|
|
@@ -3223,7 +3223,7 @@ input_thread (MetaSeatImpl *seat_impl)
|
|
|
|
seat_impl->keymap = g_object_new (META_TYPE_KEYMAP_NATIVE, NULL);
|
|
|
|
- xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (seat_impl->keymap);
|
|
+ xkb_keymap = meta_keymap_native_get_xkb_keymap_in_impl (seat_impl->keymap);
|
|
|
|
if (xkb_keymap)
|
|
{
|
|
@@ -3715,7 +3715,7 @@ meta_seat_impl_update_xkb_state_in_impl (MetaSeatImpl *seat_impl)
|
|
|
|
g_rw_lock_writer_lock (&seat_impl->state_lock);
|
|
|
|
- xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (seat_impl->keymap);
|
|
+ xkb_keymap = meta_keymap_native_get_xkb_keymap_in_impl (seat_impl->keymap);
|
|
meta_seat_impl_update_xkb_state_in_impl_unlocked (seat_impl,
|
|
xkb_keymap,
|
|
seat_impl->layout_idx);
|
|
@@ -3820,15 +3820,15 @@ meta_seat_impl_reclaim_devices (MetaSeatImpl *seat_impl)
|
|
}
|
|
|
|
gboolean
|
|
-meta_seat_impl_set_keyboard_map_finish (MetaSeatImpl *seat_impl,
|
|
- GAsyncResult *result,
|
|
- GError **error)
|
|
+meta_seat_impl_set_keymap_finish (MetaSeatImpl *seat_impl,
|
|
+ GAsyncResult *result,
|
|
+ GError **error)
|
|
{
|
|
GTask *task = G_TASK (result);
|
|
|
|
g_return_val_if_fail (g_task_is_valid (result, seat_impl), FALSE);
|
|
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
|
- meta_seat_impl_set_keyboard_map_async, FALSE);
|
|
+ meta_seat_impl_set_keymap_async, FALSE);
|
|
|
|
return g_task_propagate_boolean (task, error);
|
|
}
|
|
@@ -3878,7 +3878,7 @@ update_layout_index_unlocked (MetaSeatImpl *seat_impl,
|
|
}
|
|
|
|
static gboolean
|
|
-set_keyboard_map (GTask *task)
|
|
+set_keymap (GTask *task)
|
|
{
|
|
MetaSeatImpl *seat_impl = g_task_get_source_object (task);
|
|
MetaSeatImplPrivate *priv =
|
|
@@ -3936,13 +3936,13 @@ set_keyboard_map (GTask *task)
|
|
data->layout_index);
|
|
|
|
keymap = seat_impl->keymap;
|
|
- meta_keymap_native_set_keyboard_map_in_impl (keymap,
|
|
- seat_impl,
|
|
- keymap_description,
|
|
- xkb_keymap,
|
|
- seat_impl->xkb,
|
|
- g_steal_pointer (&display_names),
|
|
- g_steal_pointer (&short_names));
|
|
+ meta_keymap_native_set_keymap_in_impl (keymap,
|
|
+ seat_impl,
|
|
+ keymap_description,
|
|
+ xkb_keymap,
|
|
+ seat_impl->xkb,
|
|
+ g_steal_pointer (&display_names),
|
|
+ g_steal_pointer (&short_names));
|
|
xkb_keymap_unref (xkb_keymap);
|
|
}
|
|
else
|
|
@@ -3958,7 +3958,7 @@ set_keyboard_map (GTask *task)
|
|
}
|
|
|
|
/**
|
|
- * meta_seat_impl_set_keyboard_map_async: (skip)
|
|
+ * meta_seat_impl_set_keymap_async: (skip)
|
|
* @seat_impl: the #ClutterSeat created by the evdev backend
|
|
* @keymap: the new keymap
|
|
* @cancellable: a #GCancellable
|
|
@@ -3971,12 +3971,12 @@ set_keyboard_map (GTask *task)
|
|
* is pressed when calling this function.
|
|
*/
|
|
void
|
|
-meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
- MetaKeymapDescription *keymap_description,
|
|
- xkb_layout_index_t layout_index,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data)
|
|
+meta_seat_impl_set_keymap_async (MetaSeatImpl *seat_impl,
|
|
+ MetaKeymapDescription *keymap_description,
|
|
+ xkb_layout_index_t layout_index,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data)
|
|
{
|
|
GTask *task;
|
|
SetKeymapData *data;
|
|
@@ -3985,13 +3985,13 @@ meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
g_return_if_fail (keymap_description);
|
|
|
|
task = g_task_new (seat_impl, cancellable, callback, user_data);
|
|
- g_task_set_source_tag (task, meta_seat_impl_set_keyboard_map_async);
|
|
+ g_task_set_source_tag (task, meta_seat_impl_set_keymap_async);
|
|
|
|
data = g_new0 (SetKeymapData, 1);
|
|
data->keymap_description = meta_keymap_description_ref (keymap_description);
|
|
data->layout_index = layout_index;
|
|
g_task_set_task_data (task, data, set_keymap_data_free);
|
|
- meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) set_keyboard_map);
|
|
+ meta_seat_impl_run_input_task (seat_impl, task, (GSourceFunc) set_keymap);
|
|
g_object_unref (task);
|
|
}
|
|
|
|
diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h
|
|
index c4692cac19..2a31db19b7 100644
|
|
--- a/src/backends/native/meta-seat-impl.h
|
|
+++ b/src/backends/native/meta-seat-impl.h
|
|
@@ -185,16 +185,16 @@ void meta_seat_impl_reclaim_devices (MetaSeatImpl *seat_impl);
|
|
|
|
struct xkb_state * meta_seat_impl_get_xkb_state_in_impl (MetaSeatImpl *seat_impl);
|
|
|
|
-gboolean meta_seat_impl_set_keyboard_map_finish (MetaSeatImpl *seat_impl,
|
|
- GAsyncResult *result,
|
|
- GError **error);
|
|
-
|
|
-void meta_seat_impl_set_keyboard_map_async (MetaSeatImpl *seat_impl,
|
|
- MetaKeymapDescription *keymap_description,
|
|
- xkb_layout_index_t layout_index,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data);
|
|
+gboolean meta_seat_impl_set_keymap_finish (MetaSeatImpl *seat_impl,
|
|
+ GAsyncResult *result,
|
|
+ GError **error);
|
|
+
|
|
+void meta_seat_impl_set_keymap_async (MetaSeatImpl *seat_impl,
|
|
+ MetaKeymapDescription *keymap_description,
|
|
+ xkb_layout_index_t layout_index,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data);
|
|
|
|
void meta_seat_impl_set_keyboard_repeat_in_impl (MetaSeatImpl *seat_impl,
|
|
gboolean repeat,
|
|
diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c
|
|
index 2722b1d970..dbb0a3534a 100644
|
|
--- a/src/backends/native/meta-seat-native.c
|
|
+++ b/src/backends/native/meta-seat-native.c
|
|
@@ -66,11 +66,11 @@ static guint signals[N_SIGNALS];
|
|
|
|
G_DEFINE_TYPE (MetaSeatNative, meta_seat_native, CLUTTER_TYPE_SEAT)
|
|
|
|
-static gboolean meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
- MetaKeymapDescription *description,
|
|
- xkb_layout_index_t layout_index,
|
|
- GCancellable *cancellable,
|
|
- GError **error);
|
|
+static gboolean meta_seat_native_set_keymap_sync (MetaSeatNative *seat_native,
|
|
+ MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
+ GCancellable *cancellable,
|
|
+ GError **error);
|
|
|
|
static gboolean
|
|
meta_seat_native_handle_event_post (ClutterSeat *seat,
|
|
@@ -226,9 +226,9 @@ meta_seat_native_constructed (GObject *object)
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
- if (!meta_seat_native_set_keyboard_map_sync (seat,
|
|
- keymap_description, 0,
|
|
- NULL, &error))
|
|
+ if (!meta_seat_native_set_keymap_sync (seat,
|
|
+ keymap_description, 0,
|
|
+ NULL, &error))
|
|
g_warning ("Failed to set keyboard map: %s", error->message);
|
|
|
|
if (G_OBJECT_CLASS (meta_seat_native_parent_class)->constructed)
|
|
@@ -575,15 +575,15 @@ meta_seat_native_reclaim_devices (MetaSeatNative *seat)
|
|
}
|
|
|
|
gboolean
|
|
-meta_seat_native_set_keyboard_map_finish (MetaSeatNative *seat_native,
|
|
- GAsyncResult *result,
|
|
- GError **error)
|
|
+meta_seat_native_set_keymap_finish (MetaSeatNative *seat_native,
|
|
+ GAsyncResult *result,
|
|
+ GError **error)
|
|
{
|
|
GTask *task = G_TASK (result);
|
|
|
|
g_return_val_if_fail (g_task_is_valid (result, seat_native), FALSE);
|
|
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) ==
|
|
- meta_seat_native_set_keyboard_map_async, FALSE);
|
|
+ meta_seat_native_set_keymap_async, FALSE);
|
|
|
|
return g_task_propagate_boolean (task, error);
|
|
}
|
|
@@ -597,7 +597,7 @@ set_impl_keyboard_map_cb (GObject *source_object,
|
|
g_autoptr (GTask) task = G_TASK (user_data);
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
- if (!meta_seat_impl_set_keyboard_map_finish (seat_impl, result, &error))
|
|
+ if (!meta_seat_impl_set_keymap_finish (seat_impl, result, &error))
|
|
{
|
|
g_task_return_error (task, g_steal_pointer (&error));
|
|
return;
|
|
@@ -607,7 +607,7 @@ set_impl_keyboard_map_cb (GObject *source_object,
|
|
}
|
|
|
|
/**
|
|
- * meta_seat_native_set_keyboard_map_async: (skip)
|
|
+ * meta_seat_native_set_keymap_async: (skip)
|
|
* @seat: the #ClutterSeat created by the evdev backend
|
|
* @keymap: the new keymap
|
|
*
|
|
@@ -617,24 +617,24 @@ set_impl_keyboard_map_cb (GObject *source_object,
|
|
* is pressed when calling this function.
|
|
*/
|
|
void
|
|
-meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
- MetaKeymapDescription *description,
|
|
- xkb_layout_index_t layout_index,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data)
|
|
+meta_seat_native_set_keymap_async (MetaSeatNative *seat,
|
|
+ MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data)
|
|
{
|
|
g_autoptr (GTask) task = NULL;
|
|
|
|
task = g_task_new (G_OBJECT (seat), cancellable, callback, user_data);
|
|
- g_task_set_source_tag (task, meta_seat_native_set_keyboard_map_async);
|
|
+ g_task_set_source_tag (task, meta_seat_native_set_keymap_async);
|
|
|
|
- meta_seat_impl_set_keyboard_map_async (seat->impl,
|
|
- description,
|
|
- layout_index,
|
|
- cancellable,
|
|
- set_impl_keyboard_map_cb,
|
|
- g_object_ref (task));
|
|
+ meta_seat_impl_set_keymap_async (seat->impl,
|
|
+ description,
|
|
+ layout_index,
|
|
+ cancellable,
|
|
+ set_impl_keyboard_map_cb,
|
|
+ g_object_ref (task));
|
|
}
|
|
|
|
static void
|
|
@@ -647,7 +647,7 @@ sync_set_impl_keyboard_map_cb (GObject *source_object,
|
|
GTask *task = G_TASK (user_data);
|
|
GMainLoop *main_loop = g_task_get_task_data (task);
|
|
|
|
- if (!meta_seat_impl_set_keyboard_map_finish (seat_impl, result, &error))
|
|
+ if (!meta_seat_impl_set_keymap_finish (seat_impl, result, &error))
|
|
{
|
|
g_task_return_error (task, g_steal_pointer (&error));
|
|
g_main_loop_quit (main_loop);
|
|
@@ -659,11 +659,11 @@ sync_set_impl_keyboard_map_cb (GObject *source_object,
|
|
}
|
|
|
|
static gboolean
|
|
-meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
- MetaKeymapDescription *description,
|
|
- xkb_layout_index_t layout_index,
|
|
- GCancellable *cancellable,
|
|
- GError **error)
|
|
+meta_seat_native_set_keymap_sync (MetaSeatNative *seat_native,
|
|
+ MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
+ GCancellable *cancellable,
|
|
+ GError **error)
|
|
{
|
|
g_autoptr (GMainContext) main_context = NULL;
|
|
g_autoptr (GMainLoop) main_loop = NULL;
|
|
@@ -677,12 +677,12 @@ meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
task = g_task_new (NULL, NULL, NULL, NULL);
|
|
g_task_set_task_data (task, main_loop, NULL);
|
|
|
|
- meta_seat_impl_set_keyboard_map_async (seat_native->impl,
|
|
- description,
|
|
- layout_index,
|
|
- cancellable,
|
|
- sync_set_impl_keyboard_map_cb,
|
|
- task);
|
|
+ meta_seat_impl_set_keymap_async (seat_native->impl,
|
|
+ description,
|
|
+ layout_index,
|
|
+ cancellable,
|
|
+ sync_set_impl_keyboard_map_cb,
|
|
+ task);
|
|
g_main_loop_run (main_loop);
|
|
g_main_context_pop_thread_default (main_context);
|
|
|
|
@@ -708,7 +708,7 @@ meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
}
|
|
|
|
/**
|
|
- * meta_seat_native_get_keyboard_map: (skip)
|
|
+ * meta_seat_native_get_keymap: (skip)
|
|
* @seat: the #ClutterSeat created by the evdev backend
|
|
*
|
|
* Retrieves the #xkb_keymap in use by the evdev backend.
|
|
@@ -716,7 +716,7 @@ meta_seat_native_set_keyboard_map_sync (MetaSeatNative *seat_native,
|
|
* Return value: the #xkb_keymap.
|
|
*/
|
|
struct xkb_keymap *
|
|
-meta_seat_native_get_keyboard_map (MetaSeatNative *seat)
|
|
+meta_seat_native_get_xkb_keymap (MetaSeatNative *seat)
|
|
{
|
|
g_return_val_if_fail (META_IS_SEAT_NATIVE (seat), NULL);
|
|
|
|
@@ -724,7 +724,7 @@ meta_seat_native_get_keyboard_map (MetaSeatNative *seat)
|
|
}
|
|
|
|
MetaKeymapDescription *
|
|
-meta_seat_native_get_keyboard_map_description (MetaSeatNative *seat_native)
|
|
+meta_seat_native_get_keymap_description (MetaSeatNative *seat_native)
|
|
{
|
|
g_return_val_if_fail (seat_native->keymap_description, NULL);
|
|
|
|
diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h
|
|
index 7fbe7dd3e7..ce3551d4ad 100644
|
|
--- a/src/backends/native/meta-seat-native.h
|
|
+++ b/src/backends/native/meta-seat-native.h
|
|
@@ -101,21 +101,21 @@ void meta_seat_native_set_device_callbacks (MetaOpenDeviceCallback open_callba
|
|
void meta_seat_native_release_devices (MetaSeatNative *seat);
|
|
void meta_seat_native_reclaim_devices (MetaSeatNative *seat);
|
|
|
|
-void meta_seat_native_set_keyboard_map_async (MetaSeatNative *seat,
|
|
- MetaKeymapDescription *description,
|
|
- xkb_layout_index_t layout_index,
|
|
- GCancellable *cancellable,
|
|
- GAsyncReadyCallback callback,
|
|
- gpointer user_data);
|
|
+void meta_seat_native_set_keymap_async (MetaSeatNative *seat,
|
|
+ MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
+ GCancellable *cancellable,
|
|
+ GAsyncReadyCallback callback,
|
|
+ gpointer user_data);
|
|
|
|
-gboolean meta_seat_native_set_keyboard_map_finish (MetaSeatNative *seat_native,
|
|
- GAsyncResult *result,
|
|
- GError **error);
|
|
+gboolean meta_seat_native_set_keymap_finish (MetaSeatNative *seat_native,
|
|
+ GAsyncResult *result,
|
|
+ GError **error);
|
|
|
|
META_EXPORT_TEST
|
|
-struct xkb_keymap * meta_seat_native_get_keyboard_map (MetaSeatNative *seat);
|
|
+struct xkb_keymap * meta_seat_native_get_xkb_keymap (MetaSeatNative *seat);
|
|
|
|
-MetaKeymapDescription * meta_seat_native_get_keyboard_map_description (MetaSeatNative *seat_native);
|
|
+MetaKeymapDescription * meta_seat_native_get_keymap_description (MetaSeatNative *seat_native);
|
|
|
|
xkb_layout_index_t meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat);
|
|
|
|
diff --git a/src/backends/native/meta-virtual-input-device-native.c b/src/backends/native/meta-virtual-input-device-native.c
|
|
index e33925d7ba..777b4241eb 100644
|
|
--- a/src/backends/native/meta-virtual-input-device-native.c
|
|
+++ b/src/backends/native/meta-virtual-input-device-native.c
|
|
@@ -483,7 +483,8 @@ pick_keycode_for_keyval_in_current_group_in_impl (ClutterVirtualInputDevice *vir
|
|
|
|
seat = clutter_virtual_input_device_get_seat (virtual_device);
|
|
keymap = clutter_seat_get_keymap (seat);
|
|
- xkb_keymap = meta_keymap_native_get_keyboard_map_in_impl (META_KEYMAP_NATIVE (keymap));
|
|
+ xkb_keymap =
|
|
+ meta_keymap_native_get_xkb_keymap_in_impl (META_KEYMAP_NATIVE (keymap));
|
|
state = meta_seat_impl_get_xkb_state_in_impl (seat_native->impl);
|
|
|
|
layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE);
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index a26b1a7bf4..b55dfc0a16 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -670,7 +670,7 @@ meta_test_native_keyboard_map_modifiers (void)
|
|
ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
|
MetaSeatNative *seat_native = META_SEAT_NATIVE (seat);
|
|
struct xkb_keymap *xkb_keymap =
|
|
- meta_seat_native_get_keyboard_map (seat_native);
|
|
+ meta_seat_native_get_xkb_keymap (seat_native);
|
|
xkb_mod_mask_t shift_mask =
|
|
1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_SHIFT);
|
|
xkb_mod_mask_t alt_mask =
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 92e1763f133db6b5909a4989df2ad8c26f2c1fd2 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 28 Jan 2026 22:15:39 +0100
|
|
Subject: [PATCH 30/32] backend: Rename get_keymap() to get_xkb_keymap()
|
|
|
|
This makes it clearer it's not a ClutterKeymap that is returned.
|
|
|
|
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4699>
|
|
(cherry picked from commit 149973014c5abf25c058a081ee6fdab605bed836)
|
|
---
|
|
src/backends/meta-backend-private.h | 4 ++--
|
|
src/backends/meta-backend.c | 4 ++--
|
|
src/backends/meta-eis-client.c | 2 +-
|
|
src/backends/meta-input-capture-session.c | 2 +-
|
|
src/backends/native/meta-backend-native.c | 4 ++--
|
|
src/core/keybindings.c | 4 ++--
|
|
src/tests/keyboard-map-tests.c | 20 ++++++++++----------
|
|
src/wayland/meta-wayland-keyboard.c | 6 ++++--
|
|
8 files changed, 24 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
|
|
index 8b61738922..45c02f2204 100644
|
|
--- a/src/backends/meta-backend-private.h
|
|
+++ b/src/backends/meta-backend-private.h
|
|
@@ -130,7 +130,7 @@ struct _MetaBackendClass
|
|
xkb_layout_index_t layout_index,
|
|
GTask *task);
|
|
|
|
- struct xkb_keymap * (* get_keymap) (MetaBackend *backend);
|
|
+ struct xkb_keymap * (* get_xkb_keymap) (MetaBackend *backend);
|
|
|
|
MetaKeymapDescription * (* get_keymap_description) (MetaBackend *backend);
|
|
|
|
@@ -209,7 +209,7 @@ void meta_backend_finish_touch_sequence (MetaBackend *backend,
|
|
MetaSequenceState state);
|
|
|
|
META_EXPORT_TEST
|
|
-struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
|
|
+struct xkb_keymap * meta_backend_get_xkb_keymap (MetaBackend *backend);
|
|
|
|
META_EXPORT_TEST
|
|
xkb_layout_index_t meta_backend_get_keymap_layout_group (MetaBackend *backend);
|
|
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
|
|
index 143797213d..7c2a520a0d 100644
|
|
--- a/src/backends/meta-backend.c
|
|
+++ b/src/backends/meta-backend.c
|
|
@@ -1810,9 +1810,9 @@ meta_backend_set_keymap_async (MetaBackend *backend,
|
|
}
|
|
|
|
struct xkb_keymap *
|
|
-meta_backend_get_keymap (MetaBackend *backend)
|
|
+meta_backend_get_xkb_keymap (MetaBackend *backend)
|
|
{
|
|
- return META_BACKEND_GET_CLASS (backend)->get_keymap (backend);
|
|
+ return META_BACKEND_GET_CLASS (backend)->get_xkb_keymap (backend);
|
|
}
|
|
|
|
/**
|
|
diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c
|
|
index 167e5ca030..d017c3b09e 100644
|
|
--- a/src/backends/meta-eis-client.c
|
|
+++ b/src/backends/meta-eis-client.c
|
|
@@ -242,7 +242,7 @@ configure_keyboard (MetaEisClient *client,
|
|
eis_device_configure_capability (eis_device, EIS_DEVICE_CAP_KEYBOARD);
|
|
|
|
xkb_keymap =
|
|
- meta_backend_get_keymap (meta_eis_get_backend (client->eis));
|
|
+ meta_backend_get_xkb_keymap (meta_eis_get_backend (client->eis));
|
|
if (!xkb_keymap)
|
|
return;
|
|
|
|
diff --git a/src/backends/meta-input-capture-session.c b/src/backends/meta-input-capture-session.c
|
|
index 67d50c8e8c..15acbe3222 100644
|
|
--- a/src/backends/meta-input-capture-session.c
|
|
+++ b/src/backends/meta-input-capture-session.c
|
|
@@ -244,7 +244,7 @@ ensure_xkb_keymap_file (MetaInputCaptureSession *session,
|
|
if (session->keymap_file)
|
|
return session->keymap_file;
|
|
|
|
- keymap = meta_backend_get_keymap (backend);
|
|
+ keymap = meta_backend_get_xkb_keymap (backend);
|
|
if (!keymap)
|
|
{
|
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
|
|
index 66105d6cb4..15e05a50be 100644
|
|
--- a/src/backends/native/meta-backend-native.c
|
|
+++ b/src/backends/native/meta-backend-native.c
|
|
@@ -355,7 +355,7 @@ meta_backend_native_set_keymap_async (MetaBackend *backend,
|
|
}
|
|
|
|
static struct xkb_keymap *
|
|
-meta_backend_native_get_keymap (MetaBackend *backend)
|
|
+meta_backend_native_get_xkb_keymap (MetaBackend *backend)
|
|
{
|
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
|
ClutterSeat *seat;
|
|
@@ -903,7 +903,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
|
backend_class->get_current_logical_monitor = meta_backend_native_get_current_logical_monitor;
|
|
|
|
backend_class->set_keymap_async = meta_backend_native_set_keymap_async;
|
|
- backend_class->get_keymap = meta_backend_native_get_keymap;
|
|
+ backend_class->get_xkb_keymap = meta_backend_native_get_xkb_keymap;
|
|
backend_class->get_keymap_description = meta_backend_native_get_keymap_description;
|
|
backend_class->get_keymap_layout_group = meta_backend_native_get_keymap_layout_group;
|
|
backend_class->update_stage = meta_backend_native_update_stage;
|
|
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
|
|
index 6f879eed8e..486da03689 100644
|
|
--- a/src/core/keybindings.c
|
|
+++ b/src/core/keybindings.c
|
|
@@ -239,7 +239,7 @@ key_combo_key (MetaResolvedKeyCombo *resolved_combo,
|
|
static void
|
|
reload_modmap (MetaKeyBindingManager *keys)
|
|
{
|
|
- struct xkb_keymap *keymap = meta_backend_get_keymap (keys->backend);
|
|
+ struct xkb_keymap *keymap = meta_backend_get_xkb_keymap (keys->backend);
|
|
struct xkb_state *scratch_state;
|
|
xkb_mod_mask_t scroll_lock_mask;
|
|
xkb_mod_mask_t dummy_mask;
|
|
@@ -800,7 +800,7 @@ reload_active_keyboard_layouts (MetaKeyBindingManager *keys)
|
|
|
|
clear_active_keyboard_layouts (keys);
|
|
|
|
- keymap = meta_backend_get_keymap (keys->backend);
|
|
+ keymap = meta_backend_get_xkb_keymap (keys->backend);
|
|
layout_index = meta_backend_get_keymap_layout_group (keys->backend);
|
|
primary_layout = (MetaKeyBindingKeyboardLayout) {
|
|
.keymap = xkb_keymap_ref (keymap),
|
|
diff --git a/src/tests/keyboard-map-tests.c b/src/tests/keyboard-map-tests.c
|
|
index b55dfc0a16..c31b176c7c 100644
|
|
--- a/src/tests/keyboard-map-tests.c
|
|
+++ b/src/tests/keyboard-map-tests.c
|
|
@@ -165,7 +165,7 @@ meta_test_native_keyboard_map_set_async (void)
|
|
ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
|
ClutterKeymap *keymap = clutter_seat_get_keymap (seat);
|
|
g_autoptr (ClutterVirtualInputDevice) virtual_keyboard = NULL;
|
|
- struct xkb_keymap *xkb_keymap = meta_backend_get_keymap (backend);
|
|
+ struct xkb_keymap *xkb_keymap = meta_backend_get_xkb_keymap (backend);
|
|
xkb_mod_mask_t alt_mask =
|
|
1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_ALT);
|
|
ModMaskTuple expected_mods = { alt_mask, 0, 0 };
|
|
@@ -234,12 +234,12 @@ meta_test_native_keyboard_map_set_async (void)
|
|
meta_backend_set_keymap_async (backend, keymap_description, 0,
|
|
NULL, set_keymap_cb, &done);
|
|
|
|
- g_assert_true (xkb_keymap == meta_backend_get_keymap (backend));
|
|
+ g_assert_true (xkb_keymap == meta_backend_get_xkb_keymap (backend));
|
|
|
|
while (!done || expected_next_handler)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
- new_xkb_keymap = meta_backend_get_keymap (backend);
|
|
+ new_xkb_keymap = meta_backend_get_xkb_keymap (backend);
|
|
g_assert_true (new_xkb_keymap != xkb_keymap);
|
|
g_assert_cmpuint (xkb_keymap_num_layouts (new_xkb_keymap), ==, 1);
|
|
g_assert_cmpstr (xkb_keymap_layout_get_name (new_xkb_keymap, 0),
|
|
@@ -266,7 +266,7 @@ meta_test_native_keyboard_map_change_layout (void)
|
|
MetaBackend *backend = meta_context_get_backend (test_context);
|
|
ClutterSeat *seat = meta_backend_get_default_seat (backend);
|
|
g_autoptr (ClutterVirtualInputDevice) virtual_keyboard = NULL;
|
|
- struct xkb_keymap *xkb_keymap = meta_backend_get_keymap (backend);
|
|
+ struct xkb_keymap *xkb_keymap = meta_backend_get_xkb_keymap (backend);
|
|
g_autoptr (MetaKeymapDescription) keymap_description = NULL;
|
|
struct xkb_keymap *new_xkb_keymap;
|
|
gboolean done = FALSE;
|
|
@@ -289,7 +289,7 @@ meta_test_native_keyboard_map_change_layout (void)
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
- new_xkb_keymap = meta_backend_get_keymap (backend);
|
|
+ new_xkb_keymap = meta_backend_get_xkb_keymap (backend);
|
|
g_assert_true (new_xkb_keymap != xkb_keymap);
|
|
g_assert_cmpuint (xkb_keymap_num_layouts (new_xkb_keymap), ==, 2);
|
|
g_assert_cmpstr (xkb_keymap_layout_get_name (new_xkb_keymap, 0),
|
|
@@ -389,7 +389,7 @@ meta_test_native_keyboard_map_set_layout_index (void)
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
- keymap = meta_backend_get_keymap (backend);
|
|
+ keymap = meta_backend_get_xkb_keymap (backend);
|
|
g_assert_cmpuint (xkb_keymap_num_layouts (keymap), ==, 2);
|
|
g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 0),
|
|
==,
|
|
@@ -443,7 +443,7 @@ meta_test_native_keyboard_map_lock_layout (void)
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
- keymap = xkb_keymap_ref (meta_backend_get_keymap (backend));
|
|
+ keymap = xkb_keymap_ref (meta_backend_get_xkb_keymap (backend));
|
|
g_assert_cmpuint (xkb_keymap_num_layouts (keymap), ==, 2);
|
|
g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 0),
|
|
==,
|
|
@@ -477,7 +477,7 @@ meta_test_native_keyboard_map_lock_layout (void)
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
- g_assert_true (keymap == meta_backend_get_keymap (backend));
|
|
+ g_assert_true (keymap == meta_backend_get_xkb_keymap (backend));
|
|
|
|
/*
|
|
* Set the same keymap with a different layout index. Should take effect.
|
|
@@ -521,7 +521,7 @@ meta_test_native_keyboard_map_lock_layout (void)
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
- keymap = meta_backend_get_keymap (backend);
|
|
+ keymap = meta_backend_get_xkb_keymap (backend);
|
|
g_assert_cmpuint (xkb_keymap_num_layouts (keymap), ==, 1);
|
|
g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 0),
|
|
==,
|
|
@@ -538,7 +538,7 @@ meta_test_native_keyboard_map_lock_layout (void)
|
|
while (!done)
|
|
g_main_context_iteration (NULL, TRUE);
|
|
|
|
- keymap = meta_backend_get_keymap (backend);
|
|
+ keymap = meta_backend_get_xkb_keymap (backend);
|
|
g_assert_cmpuint (xkb_keymap_num_layouts (keymap), ==, 2);
|
|
g_assert_cmpstr (xkb_keymap_layout_get_name (keymap, 0),
|
|
==,
|
|
diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c
|
|
index 451c9d834d..a6329785fd 100644
|
|
--- a/src/wayland/meta-wayland-keyboard.c
|
|
+++ b/src/wayland/meta-wayland-keyboard.c
|
|
@@ -209,7 +209,8 @@ on_keymap_changed (MetaBackend *backend,
|
|
{
|
|
MetaWaylandKeyboard *keyboard = data;
|
|
|
|
- meta_wayland_keyboard_take_keymap (keyboard, meta_backend_get_keymap (backend));
|
|
+ meta_wayland_keyboard_take_keymap (keyboard,
|
|
+ meta_backend_get_xkb_keymap (backend));
|
|
}
|
|
|
|
static void
|
|
@@ -454,7 +455,8 @@ meta_wayland_keyboard_enable (MetaWaylandKeyboard *keyboard)
|
|
g_signal_connect (backend, "keymap-layout-group-changed",
|
|
G_CALLBACK (on_keymap_layout_group_changed), keyboard);
|
|
|
|
- meta_wayland_keyboard_take_keymap (keyboard, meta_backend_get_keymap (backend));
|
|
+ meta_wayland_keyboard_take_keymap (keyboard,
|
|
+ meta_backend_get_xkb_keymap (backend));
|
|
|
|
meta_wayland_keyboard_set_focus (keyboard, seat->input_focus);
|
|
}
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 5f7591a2fd4e362ed50484dceaefec8cddffec56 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Tue, 19 May 2026 23:50:29 +0200
|
|
Subject: [PATCH 31/32] Let X11 backend gracefully handle rules keymap
|
|
descriptions
|
|
|
|
This means ones set from remote desktop servers wont work, but this is
|
|
not supported anyway, so lets not bother.
|
|
---
|
|
.../meta-keymap-description-private.h | 6 ++
|
|
src/backends/meta-keymap-description.c | 24 ++++++++
|
|
src/backends/x11/cm/meta-backend-x11-cm.c | 61 +++++++++----------
|
|
src/backends/x11/meta-backend-x11.c | 6 +-
|
|
src/backends/x11/meta-keymap-x11.c | 3 +-
|
|
.../x11/nested/meta-backend-x11-nested.c | 20 ++----
|
|
6 files changed, 69 insertions(+), 51 deletions(-)
|
|
|
|
diff --git a/src/backends/meta-keymap-description-private.h b/src/backends/meta-keymap-description-private.h
|
|
index f53092cd27..616bc94b2c 100644
|
|
--- a/src/backends/meta-keymap-description-private.h
|
|
+++ b/src/backends/meta-keymap-description-private.h
|
|
@@ -63,3 +63,9 @@ void meta_keymap_description_reset_owner (MetaKeymapDescription *keymap_des
|
|
MetaKeymapDescriptionOwner * meta_keymap_description_get_owner (MetaKeymapDescription *keymap_description);
|
|
|
|
MetaKeymapDescriptionOwner * meta_keymap_description_resets_owner (MetaKeymapDescription *keymap_description);
|
|
+
|
|
+gboolean meta_keymap_description_get_rules (MetaKeymapDescription *keymap_description,
|
|
+ const char **model,
|
|
+ const char **layout,
|
|
+ const char **variant,
|
|
+ const char **options);
|
|
diff --git a/src/backends/meta-keymap-description.c b/src/backends/meta-keymap-description.c
|
|
index 4d077626df..29b1ad2c16 100644
|
|
--- a/src/backends/meta-keymap-description.c
|
|
+++ b/src/backends/meta-keymap-description.c
|
|
@@ -386,3 +386,27 @@ meta_keymap_description_resets_owner (MetaKeymapDescription *keymap_description)
|
|
{
|
|
return keymap_description->resets_owner;
|
|
}
|
|
+
|
|
+gboolean
|
|
+meta_keymap_description_get_rules (MetaKeymapDescription *keymap_description,
|
|
+ const char **model,
|
|
+ const char **layout,
|
|
+ const char **variant,
|
|
+ const char **options)
|
|
+{
|
|
+ switch (keymap_description->source)
|
|
+ {
|
|
+ case META_KEYMAP_DESCRIPTION_SOURCE_RULES:
|
|
+ {
|
|
+ *model = keymap_description->rules.model;
|
|
+ *layout = keymap_description->rules.layout;
|
|
+ *variant = keymap_description->rules.variant;
|
|
+ *options = keymap_description->rules.options;
|
|
+ return TRUE;
|
|
+ }
|
|
+ case META_KEYMAP_DESCRIPTION_SOURCE_FD:
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ g_assert_not_reached ();
|
|
+}
|
|
diff --git a/src/backends/x11/cm/meta-backend-x11-cm.c b/src/backends/x11/cm/meta-backend-x11-cm.c
|
|
index bc8ad6dfe2..18daf62ac1 100644
|
|
--- a/src/backends/x11/cm/meta-backend-x11-cm.c
|
|
+++ b/src/backends/x11/cm/meta-backend-x11-cm.c
|
|
@@ -386,42 +386,42 @@ apply_keymap (MetaBackendX11 *x11)
|
|
}
|
|
|
|
static void
|
|
-meta_backend_x11_cm_set_keymap_async (MetaBackend *backend,
|
|
- const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model,
|
|
- GTask *task)
|
|
+meta_backend_x11_cm_set_keymap_async (MetaBackend *backend,
|
|
+ MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
+ GTask *task)
|
|
{
|
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
|
MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (x11);
|
|
+ Display *xdisplay = meta_backend_x11_get_xdisplay (x11);
|
|
+ const char *models;
|
|
+ const char *layouts;
|
|
+ const char *variants;
|
|
+ const char *options;
|
|
+ gboolean changed = FALSE;
|
|
+
|
|
+ if (!meta_keymap_description_get_rules (description,
|
|
+ &models,
|
|
+ &layouts,
|
|
+ &variants,
|
|
+ &options))
|
|
+ {
|
|
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
+ "X11 backend cant set layout from file descriptor");
|
|
+ g_object_unref (task);
|
|
+ return;
|
|
+ }
|
|
|
|
- g_free (x11_cm->keymap_layouts);
|
|
- x11_cm->keymap_layouts = g_strdup (layouts);
|
|
- g_free (x11_cm->keymap_variants);
|
|
- x11_cm->keymap_variants = g_strdup (variants);
|
|
- g_free (x11_cm->keymap_options);
|
|
- x11_cm->keymap_options = g_strdup (options);
|
|
- g_free (x11_cm->keymap_model);
|
|
- x11_cm->keymap_model = g_strdup (model);
|
|
-
|
|
- apply_keymap (x11);
|
|
+ changed |= g_set_str (&x11_cm->keymap_layouts, layouts);
|
|
+ changed |= g_set_str (&x11_cm->keymap_variants, variants);
|
|
+ changed |= g_set_str (&x11_cm->keymap_options, options);
|
|
+ changed |= g_set_str (&x11_cm->keymap_model, models);
|
|
|
|
- g_task_return_boolean (task, TRUE);
|
|
- g_object_unref (task);
|
|
-}
|
|
-
|
|
-static void
|
|
-meta_backend_x11_cm_set_keymap_layout_group_async (MetaBackend *backend,
|
|
- xkb_layout_index_t idx,
|
|
- GTask *task)
|
|
-{
|
|
- MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
|
- MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (x11);
|
|
- Display *xdisplay = meta_backend_x11_get_xdisplay (x11);
|
|
+ if (changed)
|
|
+ apply_keymap (x11);
|
|
|
|
- x11_cm->locked_group = idx;
|
|
- XkbLockGroup (xdisplay, XkbUseCoreKbd, idx);
|
|
+ x11_cm->locked_group = layout_index;
|
|
+ XkbLockGroup (xdisplay, XkbUseCoreKbd, layout_index);
|
|
|
|
g_task_return_boolean (task, TRUE);
|
|
g_object_unref (task);
|
|
@@ -567,7 +567,6 @@ meta_backend_x11_cm_class_init (MetaBackendX11CmClass *klass)
|
|
backend_class->update_stage = meta_backend_x11_cm_update_stage;
|
|
backend_class->select_stage_events = meta_backend_x11_cm_select_stage_events;
|
|
backend_class->set_keymap_async = meta_backend_x11_cm_set_keymap_async;
|
|
- backend_class->set_keymap_layout_group_async = meta_backend_x11_cm_set_keymap_layout_group_async;
|
|
|
|
backend_x11_class->handle_host_xevent = meta_backend_x11_cm_handle_host_xevent;
|
|
backend_x11_class->translate_device_event = meta_backend_x11_cm_translate_device_event;
|
|
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
|
|
index 9e119f2c93..59fa358d30 100644
|
|
--- a/src/backends/x11/meta-backend-x11.c
|
|
+++ b/src/backends/x11/meta-backend-x11.c
|
|
@@ -876,7 +876,7 @@ meta_backend_x11_get_current_logical_monitor (MetaBackend *backend)
|
|
}
|
|
|
|
static struct xkb_keymap *
|
|
-meta_backend_x11_get_keymap (MetaBackend *backend)
|
|
+meta_backend_x11_get_xkb_keymap (MetaBackend *backend)
|
|
{
|
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
|
@@ -931,7 +931,7 @@ init_xkb_state (MetaBackendX11 *x11)
|
|
int32_t device_id;
|
|
struct xkb_state *state;
|
|
|
|
- keymap = meta_backend_get_keymap (META_BACKEND (x11));
|
|
+ keymap = meta_backend_get_xkb_keymap (META_BACKEND (x11));
|
|
|
|
device_id = xkb_x11_get_core_keyboard_device_id (priv->xcb);
|
|
state = xkb_x11_state_new_from_device (keymap, priv->xcb, device_id);
|
|
@@ -1096,7 +1096,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
|
backend_class->ungrab_keyboard = meta_backend_x11_ungrab_keyboard;
|
|
backend_class->finish_touch_sequence = meta_backend_x11_finish_touch_sequence;
|
|
backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor;
|
|
- backend_class->get_keymap = meta_backend_x11_get_keymap;
|
|
+ backend_class->get_xkb_keymap = meta_backend_x11_get_xkb_keymap;
|
|
backend_class->get_keymap_layout_group = meta_backend_x11_get_keymap_layout_group;
|
|
}
|
|
|
|
diff --git a/src/backends/x11/meta-keymap-x11.c b/src/backends/x11/meta-keymap-x11.c
|
|
index 01107af07c..cdcb69ac45 100644
|
|
--- a/src/backends/x11/meta-keymap-x11.c
|
|
+++ b/src/backends/x11/meta-keymap-x11.c
|
|
@@ -227,7 +227,8 @@ update_modifiers (MetaKeymapX11 *keymap_x11,
|
|
keymap_x11->current_group,
|
|
xkb_event->state.base_mods,
|
|
xkb_event->state.latched_mods,
|
|
- xkb_event->state.locked_mods);
|
|
+ xkb_event->state.locked_mods,
|
|
+ TRUE);
|
|
|
|
if (num_lock_state != old_num_lock_state)
|
|
{
|
|
diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c b/src/backends/x11/nested/meta-backend-x11-nested.c
|
|
index 24377a90be..5cf7fe8667 100644
|
|
--- a/src/backends/x11/nested/meta-backend-x11-nested.c
|
|
+++ b/src/backends/x11/nested/meta-backend-x11-nested.c
|
|
@@ -149,21 +149,10 @@ meta_backend_x11_nested_select_stage_events (MetaBackend *backend)
|
|
}
|
|
|
|
static void
|
|
-meta_backend_x11_nested_set_keymap_async (MetaBackend *backend,
|
|
- const char *layouts,
|
|
- const char *variants,
|
|
- const char *options,
|
|
- const char *model,
|
|
- GTask *task)
|
|
-{
|
|
- g_task_return_boolean (task, TRUE);
|
|
- g_object_unref (task);
|
|
-}
|
|
-
|
|
-static void
|
|
-meta_backend_x11_nested_set_keymap_layout_group_async (MetaBackend *backend,
|
|
- xkb_layout_index_t idx,
|
|
- GTask *task)
|
|
+meta_backend_x11_nested_set_keymap_async (MetaBackend *backend,
|
|
+ MetaKeymapDescription *description,
|
|
+ xkb_layout_index_t layout_index,
|
|
+ GTask *task)
|
|
{
|
|
g_task_return_boolean (task, TRUE);
|
|
g_object_unref (task);
|
|
@@ -292,7 +281,6 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
|
|
backend_class->update_stage = meta_backend_x11_nested_update_stage;
|
|
backend_class->select_stage_events = meta_backend_x11_nested_select_stage_events;
|
|
backend_class->set_keymap_async = meta_backend_x11_nested_set_keymap_async;
|
|
- backend_class->set_keymap_layout_group_async = meta_backend_x11_nested_set_keymap_layout_group_async;
|
|
backend_class->is_lid_closed = meta_backend_x11_nested_is_lid_closed;
|
|
backend_class->set_pointer_constraint = meta_backend_x11_nested_set_pointer_constraint;
|
|
|
|
--
|
|
2.54.0
|
|
|
|
|
|
From 2eea8d03d233a5c20078baaf5fba1aec566ce614 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
Date: Wed, 20 May 2026 00:05:45 +0200
|
|
Subject: [PATCH 32/32] mdk/session: Don't depend on newer GTK
|
|
|
|
A symbol needed for keymap changes doesn't exist in RHEL10, so lets
|
|
build without it, and fall back to using layout index 0.
|
|
---
|
|
mdk/mdk-session.c | 9 +++++++++
|
|
1 file changed, 9 insertions(+)
|
|
|
|
diff --git a/mdk/mdk-session.c b/mdk/mdk-session.c
|
|
index 239d5dacd9..bf253b1b91 100644
|
|
--- a/mdk/mdk-session.c
|
|
+++ b/mdk/mdk-session.c
|
|
@@ -140,7 +140,12 @@ maybe_sync_keymap (MdkSession *session)
|
|
}
|
|
|
|
xkb_keymap = gdk_wayland_device_get_xkb_keymap (keyboard);
|
|
+#if GTK_CHECK_VERSION (4,18,0)
|
|
layout_index = gdk_device_get_active_layout_index (keyboard);
|
|
+#else
|
|
+ g_warning_once ("Only able to set the first layout");
|
|
+ layout_index = 0;
|
|
+#endif
|
|
|
|
if (xkb_keymap == session->xkb_keymap &&
|
|
layout_index == session->layout_index)
|
|
@@ -208,7 +213,11 @@ maybe_sync_keymap (MdkSession *session)
|
|
return;
|
|
}
|
|
|
|
+#if GTK_CHECK_VERSION (4,18,0)
|
|
layout_index = gdk_device_get_active_layout_index (keyboard);
|
|
+#else
|
|
+ layout_index = 0;
|
|
+#endif
|
|
|
|
g_variant_builder_init (&options_builder, G_VARIANT_TYPE ("a{sv}"));
|
|
g_variant_builder_add (&options_builder, "{sv}",
|
|
--
|
|
2.54.0
|
|
|