Fix keyboard layouts getting out of sync in anaconda
This commit is contained in:
parent
c93b840f9c
commit
fc46cee8bd
116
0001-gobject-utils-Log-when-executing-deferred-tasks.patch
Normal file
116
0001-gobject-utils-Log-when-executing-deferred-tasks.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From ab8482bab7981321f0f2fbd401907ac34028bb1a Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Tue, 20 Apr 2021 09:27:01 -0400
|
||||
Subject: [PATCH 1/4] gobject-utils: Log when executing deferred tasks
|
||||
|
||||
At the moment, the code defers execution until "later" in
|
||||
various parts of the code to ensure a flood of related events
|
||||
doesn't lead to a flood of duplicated work.
|
||||
|
||||
But, its on the called code to log at the moment.
|
||||
|
||||
This commit adds logging to the generic part of the code to
|
||||
for clarity.
|
||||
---
|
||||
compositor/kiosk-gobject-utils.c | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/compositor/kiosk-gobject-utils.c b/compositor/kiosk-gobject-utils.c
|
||||
index a0dfcd8..c38db7e 100644
|
||||
--- a/compositor/kiosk-gobject-utils.c
|
||||
+++ b/compositor/kiosk-gobject-utils.c
|
||||
@@ -1,83 +1,87 @@
|
||||
#include "config.h"
|
||||
#include "kiosk-gobject-utils.h"
|
||||
|
||||
#define COALESCE_INTERVAL 250 /* milliseconds */
|
||||
|
||||
static void
|
||||
on_task_wait_complete (GObject *self,
|
||||
GTask *task)
|
||||
{
|
||||
KioskObjectCallback callback;
|
||||
gpointer user_data;
|
||||
gboolean completed;
|
||||
g_autofree char *data_key = NULL;
|
||||
|
||||
+ g_debug ("KioskGObjectUtils: Executing deferred task '%s'", g_task_get_name (task));
|
||||
+
|
||||
callback = g_object_get_data (G_OBJECT (task), "callback");
|
||||
user_data = g_object_get_data (G_OBJECT (task), "user-data");
|
||||
|
||||
completed = g_task_propagate_boolean (task, NULL);
|
||||
|
||||
if (completed) {
|
||||
callback (self, user_data);
|
||||
}
|
||||
|
||||
data_key = g_strdup_printf ("kiosk-gobject-utils-%p-%p-task",
|
||||
callback, user_data);
|
||||
|
||||
g_object_set_data (G_OBJECT (self), data_key, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_coalesce_timeout (GTask *task)
|
||||
{
|
||||
if (!g_task_return_error_if_cancelled (task)) {
|
||||
g_task_return_boolean (task, TRUE);
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
kiosk_gobject_utils_queue_defer_callback (GObject *self,
|
||||
const char *name,
|
||||
GCancellable *cancellable,
|
||||
KioskObjectCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autofree char *data_key = NULL;
|
||||
g_autoptr (GSource) timeout_source = NULL;
|
||||
GTask *task;
|
||||
|
||||
g_return_if_fail (G_IS_OBJECT (self));
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
data_key = g_strdup_printf ("kiosk-gobject-utils-%p-%p-task",
|
||||
callback, user_data);
|
||||
|
||||
task = g_object_get_data (G_OBJECT (self), data_key);
|
||||
|
||||
if (task != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
timeout_source = g_timeout_source_new (COALESCE_INTERVAL);
|
||||
|
||||
- if (name != NULL) {
|
||||
- g_source_set_name (timeout_source, name);
|
||||
- }
|
||||
-
|
||||
task = g_task_new (self,
|
||||
cancellable,
|
||||
(GAsyncReadyCallback) on_task_wait_complete,
|
||||
NULL);
|
||||
+
|
||||
+ if (name != NULL) {
|
||||
+ g_task_set_name (task, name);
|
||||
+ g_debug ("KioskGObjectUtils: Deferring task '%s' for %dms", name, COALESCE_INTERVAL);
|
||||
+ }
|
||||
+
|
||||
g_task_attach_source (task, timeout_source, G_SOURCE_FUNC (on_coalesce_timeout));
|
||||
|
||||
g_object_set_data (G_OBJECT (task), "callback", callback);
|
||||
g_object_set_data (G_OBJECT (task), "user-data", user_data);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (self),
|
||||
data_key,
|
||||
task,
|
||||
(GDestroyNotify)
|
||||
g_object_unref);
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 83e38979f48829d4498b2df6ea62aafa34c1975b Mon Sep 17 00:00:00 2001
|
||||
From f553708a756682d625f51e7c0f3d2a31f39442bb Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Thu, 15 Apr 2021 14:39:55 -0400
|
||||
Subject: [PATCH 2/4] input-sources-manager: Fix overzealous rename mistake
|
||||
@ -184,5 +184,5 @@ index 58d7a4c..a1a4cfa 100644
|
||||
old_input_source_group = kiosk_input_sources_manager_get_selected_input_source_group (self);
|
||||
|
||||
--
|
||||
2.31.1
|
||||
2.30.2
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From db59d653751018f9b79c2a38a996fc7f0692d6b5 Mon Sep 17 00:00:00 2001
|
||||
From a944f0d27a42028ec18edb17f65957780c400104 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Thu, 15 Apr 2021 13:28:00 -0400
|
||||
Subject: [PATCH 1/4] compositor: Add signal for reporting X server events
|
||||
Subject: [PATCH 3/4] compositor: Add signal for reporting X server events
|
||||
|
||||
The keyboard layout handling code currently doesn't notice
|
||||
when the keyboard layout is changed using libxklavier, out from
|
||||
@ -225,5 +225,5 @@ index dad7776..14f5de3 100644
|
||||
|
||||
return KIOSK_SERVICE (self->service);
|
||||
--
|
||||
2.31.1
|
||||
2.30.2
|
||||
|
@ -1,219 +0,0 @@
|
||||
From 60e52b132e9957452004c85a0999b37a2e46ff55 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Thu, 15 Apr 2021 14:41:41 -0400
|
||||
Subject: [PATCH 3/4] input-sources-manager: Add function to load input sources
|
||||
from strings
|
||||
|
||||
kiosk_input_sources_manager_set_input_sources_from_system_settings
|
||||
currently has code to load fetch the strings from localed and then
|
||||
use them.
|
||||
|
||||
This commit moves the "use them" part to its own function so it can
|
||||
be reused in a subsequent commit for something else.
|
||||
---
|
||||
compositor/kiosk-input-sources-manager.c | 73 ++++++++++++++++--------
|
||||
1 file changed, 48 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/compositor/kiosk-input-sources-manager.c b/compositor/kiosk-input-sources-manager.c
|
||||
index a1a4cfa..4b4ef62 100644
|
||||
--- a/compositor/kiosk-input-sources-manager.c
|
||||
+++ b/compositor/kiosk-input-sources-manager.c
|
||||
@@ -793,147 +793,170 @@ kiosk_input_sources_manager_add_layout (KioskInputSourcesManager *self,
|
||||
input_source_group = kiosk_input_sources_manager_add_new_input_source_group (self, options);
|
||||
}
|
||||
|
||||
mapping_full = !kiosk_input_source_group_add_layout (input_source_group, xkb_layout, xkb_variant);
|
||||
|
||||
if (mapping_full) {
|
||||
g_debug ("KioskInputSourcesManager: Keyboard mapping full, starting another one");
|
||||
|
||||
input_source_group = kiosk_input_sources_manager_add_new_input_source_group (self, options);
|
||||
|
||||
kiosk_input_source_group_add_layout (input_source_group, xkb_layout, xkb_variant);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kiosk_input_sources_manager_add_input_engine (KioskInputSourcesManager *self,
|
||||
const char *engine_name,
|
||||
const char *options)
|
||||
{
|
||||
KioskInputSourceGroup *input_source_group = NULL;
|
||||
|
||||
g_debug ("KioskInputSourcesManager: Adding input engine '%s'", engine_name);
|
||||
|
||||
input_source_group = kiosk_input_sources_manager_add_new_input_source_group (self, options);
|
||||
|
||||
kiosk_input_source_group_set_input_engine (input_source_group, engine_name);
|
||||
kiosk_input_source_group_set_options (input_source_group, options);
|
||||
}
|
||||
|
||||
|
||||
-gboolean
|
||||
-kiosk_input_sources_manager_set_input_sources_from_system_configuration (KioskInputSourcesManager *self)
|
||||
+static gboolean
|
||||
+kiosk_input_sources_manager_set_input_sources_from_strings (KioskInputSourcesManager *self,
|
||||
+ const char *layouts_string,
|
||||
+ const char *variants_string,
|
||||
+ const char *options_string)
|
||||
{
|
||||
KioskInputSourceGroup *old_input_source_group;
|
||||
g_autofree char *old_input_engine = NULL;
|
||||
g_autofree char *old_selected_layout = NULL;
|
||||
|
||||
- const char *layouts_string = NULL;
|
||||
g_auto (GStrv) layouts = NULL;
|
||||
size_t number_of_layouts = 0;
|
||||
|
||||
- const char *variants_string = NULL;
|
||||
g_auto (GStrv) variants = NULL;
|
||||
size_t number_of_variants = 0;
|
||||
|
||||
- const char *options = NULL;
|
||||
size_t i, j;
|
||||
|
||||
- gboolean input_source_group_active;
|
||||
+ gboolean input_sources_active;
|
||||
|
||||
g_return_val_if_fail (KIOSK_IS_INPUT_SOURCES_MANAGER (self), FALSE);
|
||||
|
||||
- if (self->locale_proxy == NULL) {
|
||||
- return FALSE;
|
||||
- }
|
||||
-
|
||||
- g_debug ("KioskInputSourcesManager: Setting keymap from system configuration");
|
||||
-
|
||||
- layouts_string = sd_locale1_get_x11_layout (self->locale_proxy);
|
||||
- g_debug ("KioskInputSourcesManager: System layout is '%s'", layouts_string);
|
||||
-
|
||||
layouts = g_strsplit (layouts_string, ",", -1);
|
||||
number_of_layouts = g_strv_length (layouts);
|
||||
|
||||
- options = sd_locale1_get_x11_options (self->locale_proxy);
|
||||
- g_debug ("KioskInputSourcesManager: System layout options are '%s'", options);
|
||||
-
|
||||
- variants_string = sd_locale1_get_x11_variant (self->locale_proxy);
|
||||
- g_debug ("KioskInputSourcesManager: System layout variant is '%s'", variants_string);
|
||||
variants = g_strsplit (variants_string, ",", -1);
|
||||
number_of_variants = g_strv_length (variants);
|
||||
|
||||
if (number_of_layouts < number_of_variants) {
|
||||
g_debug ("KioskInputSourcesManager: There is a layout variant mismatch");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
old_input_source_group = kiosk_input_sources_manager_get_selected_input_source_group (self);
|
||||
|
||||
if (old_input_source_group != NULL) {
|
||||
old_input_engine = g_strdup (kiosk_input_source_group_get_input_engine (old_input_source_group));
|
||||
old_selected_layout = kiosk_input_source_group_get_selected_layout (old_input_source_group);
|
||||
}
|
||||
|
||||
kiosk_input_sources_manager_clear_input_sources (self);
|
||||
|
||||
for (i = 0, j = 0; layouts[i] != NULL; i++) {
|
||||
char *id = NULL;
|
||||
const char *layout = layouts[i];
|
||||
const char *variant = "";
|
||||
|
||||
if (variants[j] != NULL) {
|
||||
variant = variants[j++];
|
||||
}
|
||||
|
||||
if (variant[0] == '\0') {
|
||||
id = g_strdup (layout);
|
||||
} else {
|
||||
id = g_strdup_printf ("%s+%s", layout, variant);
|
||||
}
|
||||
|
||||
- kiosk_input_sources_manager_add_layout (self, id, options);
|
||||
+ kiosk_input_sources_manager_add_layout (self, id, options_string);
|
||||
}
|
||||
|
||||
- input_source_group_active = activate_best_available_input_source_group (self, old_input_engine, old_selected_layout);
|
||||
+ input_sources_active = activate_best_available_input_source_group (self, old_input_engine, old_selected_layout);
|
||||
|
||||
- if (!input_source_group_active) {
|
||||
+ if (!input_sources_active) {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ sync_dbus_service (self);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+gboolean
|
||||
+kiosk_input_sources_manager_set_input_sources_from_system_configuration (KioskInputSourcesManager *self)
|
||||
+{
|
||||
+ const char *layouts_string = NULL;
|
||||
+ const char *variants_string = NULL;
|
||||
+ const char *options = NULL;
|
||||
+
|
||||
+ gboolean input_sources_active;
|
||||
+
|
||||
+ g_return_val_if_fail (KIOSK_IS_INPUT_SOURCES_MANAGER (self), FALSE);
|
||||
+
|
||||
+ if (self->locale_proxy == NULL) {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ g_debug ("KioskInputSourcesManager: Setting keymap from system configuration");
|
||||
+
|
||||
+ layouts_string = sd_locale1_get_x11_layout (self->locale_proxy);
|
||||
+ g_debug ("KioskInputSourcesManager: System layout is '%s'", layouts_string);
|
||||
+
|
||||
+ options = sd_locale1_get_x11_options (self->locale_proxy);
|
||||
+ g_debug ("KioskInputSourcesManager: System layout options are '%s'", options);
|
||||
+
|
||||
+ variants_string = sd_locale1_get_x11_variant (self->locale_proxy);
|
||||
+ g_debug ("KioskInputSourcesManager: System layout variant is '%s'", variants_string);
|
||||
+
|
||||
+ input_sources_active = kiosk_input_sources_manager_set_input_sources_from_strings (self, layouts_string, variants_string, options);
|
||||
+
|
||||
+ if (!input_sources_active) {
|
||||
const char * const *locales;
|
||||
|
||||
locales = sd_locale1_get_locale (self->locale_proxy);
|
||||
- input_source_group_active = kiosk_input_sources_manager_set_input_sources_from_locales (self, locales, options);
|
||||
+ input_sources_active = kiosk_input_sources_manager_set_input_sources_from_locales (self, locales, options);
|
||||
}
|
||||
|
||||
sync_dbus_service (self);
|
||||
self->overriding_configuration = FALSE;
|
||||
|
||||
- if (!input_source_group_active) {
|
||||
+ if (!input_sources_active) {
|
||||
g_debug ("KioskInputSourcesManager: System has no valid configured input sources");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_session_input_configuration_changed (KioskInputSourcesManager *self)
|
||||
{
|
||||
g_debug ("KioskInputSourcesManager: Session input sources configuration changed");
|
||||
|
||||
if (self->overriding_configuration) {
|
||||
g_debug ("KioskInputSourcesManager: Ignoring change, because keymap is overriden");
|
||||
return;
|
||||
}
|
||||
|
||||
kiosk_input_sources_manager_set_input_sources_from_session_configuration (self);
|
||||
}
|
||||
|
||||
static void
|
||||
on_session_input_sources_setting_changed (KioskInputSourcesManager *self)
|
||||
{
|
||||
kiosk_gobject_utils_queue_defer_callback (G_OBJECT (self),
|
||||
"[kiosk-input-sources-manager] on_session_input_configuration_changed",
|
||||
self->cancellable,
|
||||
KIOSK_OBJECT_CALLBACK (on_session_input_configuration_changed),
|
||||
NULL);
|
||||
}
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,29 +1,100 @@
|
||||
From c99306e0efcf3113d592bc963b4dfac6504b724d Mon Sep 17 00:00:00 2001
|
||||
From 5b23d5f86f554373d4207d4f95c50bc86892e634 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Thu, 15 Apr 2021 14:43:17 -0400
|
||||
Subject: [PATCH 4/4] wip! Better support libxklavier
|
||||
Subject: [PATCH 4/4] input-sources-manager: Support libxklavier managed
|
||||
keyboard layouts
|
||||
|
||||
Mutter currently doesn't allow libxklavier to change the group out from
|
||||
Mutter currently doesn't allow libxklavier to change the layout out from
|
||||
under it.
|
||||
|
||||
This commit fixes that, but also makes sure that current layout state
|
||||
stays in sync with X server state.
|
||||
This commit fixes that on X being careful to make sure the current layout
|
||||
state, as gnome-kiosk sees it, stays in sync with X server state.
|
||||
---
|
||||
compositor/kiosk-input-source-group.c | 17 +
|
||||
compositor/kiosk-input-source-group.c | 47 +-
|
||||
compositor/kiosk-input-source-group.h | 5 +-
|
||||
compositor/kiosk-input-sources-manager.c | 142 ++++++
|
||||
compositor/kiosk-x-keyboard-manager.c | 579 +++++++++++++++++++++++
|
||||
compositor/kiosk-x-keyboard-manager.h | 22 +
|
||||
compositor/kiosk-input-sources-manager.c | 143 ++++++
|
||||
compositor/kiosk-input-sources-manager.h | 2 +
|
||||
compositor/kiosk-x-keyboard-manager.c | 565 +++++++++++++++++++++++
|
||||
compositor/kiosk-x-keyboard-manager.h | 29 ++
|
||||
meson.build | 1 +
|
||||
6 files changed, 765 insertions(+), 1 deletion(-)
|
||||
7 files changed, 786 insertions(+), 6 deletions(-)
|
||||
create mode 100644 compositor/kiosk-x-keyboard-manager.c
|
||||
create mode 100644 compositor/kiosk-x-keyboard-manager.h
|
||||
|
||||
diff --git a/compositor/kiosk-input-source-group.c b/compositor/kiosk-input-source-group.c
|
||||
index a0c924e..6e2712f 100644
|
||||
index a0c924e..c33ca05 100644
|
||||
--- a/compositor/kiosk-input-source-group.c
|
||||
+++ b/compositor/kiosk-input-source-group.c
|
||||
@@ -213,60 +213,66 @@ kiosk_input_source_group_set_input_engine (KioskInputSourceGroup *self,
|
||||
@@ -1,67 +1,67 @@
|
||||
#include "config.h"
|
||||
#include "kiosk-input-source-group.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
|
||||
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||
#include <libgnome-desktop/gnome-languages.h>
|
||||
#include <libgnome-desktop/gnome-xkb-info.h>
|
||||
|
||||
#include "kiosk-gobject-utils.h"
|
||||
#include "kiosk-input-sources-manager.h"
|
||||
|
||||
#define KIOSK_INPUT_SOURCE_GROUP_MAX_LAYOUTS 3
|
||||
|
||||
struct _KioskInputSourceGroup
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
/* weak references */
|
||||
KioskInputSourcesManager *input_sources_manager;
|
||||
KioskInputEngineManager *input_engine_manager;
|
||||
+ KioskXKeyboardManager *x_keyboard_manager;
|
||||
|
||||
/* strong references */
|
||||
char *input_engine_name;
|
||||
GPtrArray *layouts;
|
||||
GPtrArray *variants;
|
||||
char *options;
|
||||
|
||||
/* state */
|
||||
xkb_layout_index_t layout_index;
|
||||
};
|
||||
-
|
||||
enum
|
||||
{
|
||||
PROP_INPUT_SOURCES_MANAGER = 1,
|
||||
NUMBER_OF_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *kiosk_input_source_group_properties[NUMBER_OF_PROPERTIES] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE (KioskInputSourceGroup, kiosk_input_source_group, G_TYPE_OBJECT)
|
||||
|
||||
static void kiosk_input_source_group_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *param_spec);
|
||||
static void kiosk_input_source_group_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *param_spec);
|
||||
|
||||
static void kiosk_input_source_group_constructed (GObject *object);
|
||||
static void kiosk_input_source_group_dispose (GObject *object);
|
||||
|
||||
KioskInputSourceGroup *
|
||||
kiosk_input_source_group_new (KioskInputSourcesManager *input_sources_manager)
|
||||
{
|
||||
GObject *object;
|
||||
|
||||
object = g_object_new (KIOSK_TYPE_INPUT_SOURCE_GROUP,
|
||||
"input-sources-manager", input_sources_manager,
|
||||
NULL);
|
||||
@@ -213,121 +213,156 @@ kiosk_input_source_group_set_input_engine (KioskInputSourceGroup *self,
|
||||
const char *engine_name)
|
||||
{
|
||||
g_debug ("KioskInputSourceGroup: Setting input engine to '%s'", engine_name);
|
||||
@ -66,6 +137,8 @@ index a0c924e..6e2712f 100644
|
||||
size_t number_of_layouts;
|
||||
g_autofree char *layouts = NULL;
|
||||
g_autofree char *variants = NULL;
|
||||
+ gboolean keymap_already_set = FALSE;
|
||||
+ gboolean layout_group_already_locked = FALSE;
|
||||
|
||||
g_debug ("KioskInputSourceGroup: Activating input source");
|
||||
|
||||
@ -90,16 +163,36 @@ index a0c924e..6e2712f 100644
|
||||
if (!activated) {
|
||||
g_debug ("KioskInputSourceGroup: Could not activate input engine '%s'", self->input_engine_name);
|
||||
return FALSE;
|
||||
@@ -274,60 +280,71 @@ kiosk_input_source_group_activate (KioskInputSourceGroup *self)
|
||||
}
|
||||
} else {
|
||||
kiosk_input_engine_manager_activate_engine (self->input_engine_manager, NULL);
|
||||
}
|
||||
|
||||
g_debug ("KioskInputSourceGroup: Setting keyboard mapping to [%s] (%s) [%s]",
|
||||
layouts, variants, self->options);
|
||||
- g_debug ("KioskInputSourceGroup: Setting keyboard mapping to [%s] (%s) [%s]",
|
||||
- layouts, variants, self->options);
|
||||
+ if (self->x_keyboard_manager != NULL) {
|
||||
+ keymap_already_set = kiosk_x_keyboard_manager_keymap_is_active (self->x_keyboard_manager, (const char * const *) self->layouts->pdata, (const char * const *) self->variants->pdata, self->options);
|
||||
+ layout_group_already_locked = kiosk_x_keyboard_manager_layout_group_is_locked (self->x_keyboard_manager, self->layout_index);
|
||||
|
||||
meta_backend_set_keymap (meta_get_backend (), layouts, variants, self->options);
|
||||
meta_backend_lock_layout_group (meta_get_backend (), self->layout_index);
|
||||
- meta_backend_set_keymap (meta_get_backend (), layouts, variants, self->options);
|
||||
- meta_backend_lock_layout_group (meta_get_backend (), self->layout_index);
|
||||
+ }
|
||||
+
|
||||
+ if (!keymap_already_set) {
|
||||
+ g_debug ("KioskInputSourceGroup: Setting keyboard mapping to [%s] (%s) [%s]",
|
||||
+ layouts, variants, self->options);
|
||||
+
|
||||
+ meta_backend_set_keymap (meta_get_backend (), layouts, variants, self->options);
|
||||
+ }
|
||||
+
|
||||
+ if (!layout_group_already_locked) {
|
||||
+ g_debug ("KioskInputSourceGroup: Locking layout to index %d", self->layout_index);
|
||||
+ meta_backend_lock_layout_group (meta_get_backend (), self->layout_index);
|
||||
+ }
|
||||
+
|
||||
+ if (keymap_already_set && layout_group_already_locked) {
|
||||
+ g_debug ("KioskInputSourceGroup: Input source already active");
|
||||
+ }
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -162,6 +255,58 @@ index a0c924e..6e2712f 100644
|
||||
void
|
||||
kiosk_input_source_group_switch_to_first_layout (KioskInputSourceGroup *self)
|
||||
{
|
||||
@@ -492,49 +527,51 @@ kiosk_input_source_group_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *param_spec)
|
||||
{
|
||||
switch (property_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, param_spec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
kiosk_input_source_group_init (KioskInputSourceGroup *self)
|
||||
{
|
||||
g_debug ("KioskInputSourceGroup: Initializing");
|
||||
|
||||
self->layouts = g_ptr_array_new_full (KIOSK_INPUT_SOURCE_GROUP_MAX_LAYOUTS + 1, g_free);
|
||||
self->variants = g_ptr_array_new_full (KIOSK_INPUT_SOURCE_GROUP_MAX_LAYOUTS + 1, g_free);
|
||||
|
||||
g_ptr_array_add (self->layouts, NULL);
|
||||
g_ptr_array_add (self->variants, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
kiosk_input_source_group_constructed (GObject *object)
|
||||
{
|
||||
KioskInputSourceGroup *self = KIOSK_INPUT_SOURCE_GROUP (object);
|
||||
|
||||
G_OBJECT_CLASS (kiosk_input_source_group_parent_class)->constructed (object);
|
||||
|
||||
g_set_weak_pointer (&self->input_engine_manager, kiosk_input_sources_manager_get_input_engine_manager (self->input_sources_manager));
|
||||
+ g_set_weak_pointer (&self->x_keyboard_manager, kiosk_input_sources_manager_get_x_keyboard_manager (self->input_sources_manager));
|
||||
}
|
||||
|
||||
static void
|
||||
kiosk_input_source_group_dispose (GObject *object)
|
||||
{
|
||||
KioskInputSourceGroup *self = KIOSK_INPUT_SOURCE_GROUP (object);
|
||||
|
||||
g_debug ("KioskInputSourceGroup: Disposing");
|
||||
|
||||
g_clear_pointer (&self->options, g_free);
|
||||
|
||||
g_clear_pointer (&self->variants, g_ptr_array_unref);
|
||||
g_clear_pointer (&self->layouts, g_ptr_array_unref);
|
||||
|
||||
+ g_clear_weak_pointer (&self->x_keyboard_manager);
|
||||
g_clear_weak_pointer (&self->input_engine_manager);
|
||||
g_clear_weak_pointer (&self->input_sources_manager);
|
||||
|
||||
G_OBJECT_CLASS (kiosk_input_source_group_parent_class)->dispose (object);
|
||||
}
|
||||
diff --git a/compositor/kiosk-input-source-group.h b/compositor/kiosk-input-source-group.h
|
||||
index cec8b2f..d255da4 100644
|
||||
--- a/compositor/kiosk-input-source-group.h
|
||||
@ -210,10 +355,10 @@ index cec8b2f..d255da4 100644
|
||||
gboolean kiosk_input_source_group_switch_to_previous_layout (KioskInputSourceGroup *input_sources);
|
||||
G_END_DECLS
|
||||
diff --git a/compositor/kiosk-input-sources-manager.c b/compositor/kiosk-input-sources-manager.c
|
||||
index 4b4ef62..c6c8c91 100644
|
||||
index a1a4cfa..7bb67b0 100644
|
||||
--- a/compositor/kiosk-input-sources-manager.c
|
||||
+++ b/compositor/kiosk-input-sources-manager.c
|
||||
@@ -1,83 +1,88 @@
|
||||
@@ -1,83 +1,85 @@
|
||||
#include "config.h"
|
||||
#include "kiosk-input-sources-manager.h"
|
||||
|
||||
@ -227,9 +372,6 @@ index 4b4ef62..c6c8c91 100644
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/meta-plugin.h>
|
||||
+#include <meta/meta-x11-display.h>
|
||||
+
|
||||
+#include <X11/Xatom.h>
|
||||
|
||||
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||
#include <libgnome-desktop/gnome-languages.h>
|
||||
@ -302,7 +444,74 @@ index 4b4ef62..c6c8c91 100644
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *param_spec);
|
||||
@@ -1363,60 +1368,189 @@ on_input_engine_manager_active_engine_changed (KioskInputSourcesManager *self)
|
||||
@@ -690,60 +692,66 @@ on_dbus_service_handle_select_input_source (KioskInputSourcesManager *self,
|
||||
static gboolean
|
||||
on_dbus_service_handle_select_next_input_source (KioskInputSourcesManager *self,
|
||||
GDBusMethodInvocation *invocation)
|
||||
{
|
||||
g_debug ("KioskService: Handling SelectNextInputSource() call");
|
||||
|
||||
kiosk_input_sources_manager_switch_to_next_input_source (self);
|
||||
kiosk_dbus_input_sources_manager_complete_select_next_input_source (self->dbus_service, invocation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_dbus_service_handle_select_previous_input_source (KioskInputSourcesManager *self,
|
||||
GDBusMethodInvocation *invocation)
|
||||
{
|
||||
g_debug ("KioskService: Handling SelectPreviousInputSource() call");
|
||||
|
||||
kiosk_input_sources_manager_switch_to_previous_input_source (self);
|
||||
kiosk_dbus_input_sources_manager_complete_select_previous_input_source (self->dbus_service, invocation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
KioskInputEngineManager *
|
||||
kiosk_input_sources_manager_get_input_engine_manager (KioskInputSourcesManager *self)
|
||||
{
|
||||
return self->input_engine_manager;
|
||||
}
|
||||
|
||||
+KioskXKeyboardManager *
|
||||
+kiosk_input_sources_manager_get_x_keyboard_manager (KioskInputSourcesManager *self)
|
||||
+{
|
||||
+ return self->x_keyboard_manager;
|
||||
+}
|
||||
+
|
||||
void
|
||||
kiosk_input_sources_manager_clear_input_sources (KioskInputSourcesManager *self)
|
||||
{
|
||||
g_debug ("KioskInputSourcesManager: Clearing selected keyboard mappings");
|
||||
|
||||
g_ptr_array_set_size (self->input_source_groups, 0);
|
||||
self->input_source_groups_index = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
kiosk_input_sources_manager_add_input_source_group (KioskInputSourcesManager *self,
|
||||
KioskInputSourceGroup *input_source_group)
|
||||
{
|
||||
g_ptr_array_add (self->input_source_groups, g_object_ref (input_source_group));
|
||||
}
|
||||
|
||||
static KioskInputSourceGroup *
|
||||
kiosk_input_sources_manager_add_new_input_source_group (KioskInputSourcesManager *self,
|
||||
const char *options)
|
||||
{
|
||||
g_autoptr (KioskInputSourceGroup) input_source_group = NULL;
|
||||
|
||||
g_debug ("KioskInputSourcesManager: Adding new, empty keyboard mapping with options '%s'",
|
||||
options);
|
||||
|
||||
input_source_group = kiosk_input_source_group_new (self);
|
||||
kiosk_input_source_group_set_options (input_source_group, options);
|
||||
|
||||
kiosk_input_sources_manager_add_input_source_group (self, input_source_group);
|
||||
|
||||
@@ -1340,60 +1348,180 @@ on_input_engine_manager_active_engine_changed (KioskInputSourcesManager *self)
|
||||
|
||||
active_input_engine = kiosk_input_engine_manager_get_active_engine (self->input_engine_manager);
|
||||
|
||||
@ -336,24 +545,27 @@ index 4b4ef62..c6c8c91 100644
|
||||
+static void
|
||||
+process_x_keyboard_manager_selected_layout_change (KioskInputSourcesManager *self)
|
||||
+{
|
||||
+ const char *selected_layout;
|
||||
+ const char *selected_layout;
|
||||
+
|
||||
+ selected_layout = kiosk_x_keyboard_manager_get_selected_layout (self->x_keyboard_manager);
|
||||
+ selected_layout = kiosk_x_keyboard_manager_get_selected_layout (self->x_keyboard_manager);
|
||||
+
|
||||
+ if (selected_layout == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (selected_layout == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ g_debug ("KioskInputSourcesManager: X server changed active layout to %s", selected_layout);
|
||||
+ g_debug ("KioskInputSourcesManager: X server changed active layout to %s", selected_layout);
|
||||
+
|
||||
+ activate_input_source_group_with_layout (self, selected_layout);
|
||||
+ activate_input_source_group_with_layout (self, selected_layout);
|
||||
+
|
||||
+ sync_dbus_service (self);
|
||||
+ sync_dbus_service (self);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+on_x_keyboard_manager_selected_layout_changed (KioskInputSourcesManager *self)
|
||||
+{
|
||||
+ /* We defer processing the layout change for a bit, because often in practice there is more than
|
||||
+ * one layout change at the same time, and only the last one is the desired one
|
||||
+ */
|
||||
+ kiosk_gobject_utils_queue_defer_callback (G_OBJECT (self),
|
||||
+ "[kiosk-input-sources-manager] process_x_keyboard_manager_selected_layout_change",
|
||||
+ self->cancellable,
|
||||
@ -400,7 +612,7 @@ index 4b4ef62..c6c8c91 100644
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+process_x_keyboard_manager_layouts_change (KioskInputSourcesManager *self)
|
||||
+on_x_keyboard_manager_layouts_changed (KioskInputSourcesManager *self)
|
||||
+{
|
||||
+ const char * const *new_layouts;
|
||||
+ const char *selected_layout;
|
||||
@ -433,23 +645,11 @@ index 4b4ef62..c6c8c91 100644
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+on_x_keyboard_manager_layouts_changed (KioskInputSourcesManager *self)
|
||||
+{
|
||||
+ kiosk_gobject_utils_queue_defer_callback (G_OBJECT (self),
|
||||
+ "[kiosk-input-sources-manager] process_x_keyboard_manager_layouts_change",
|
||||
+ self->cancellable,
|
||||
+ KIOSK_OBJECT_CALLBACK (process_x_keyboard_manager_layouts_change),
|
||||
+ NULL);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_input_source_manager_start_x_keyboard_manager (KioskInputSourcesManager *self)
|
||||
+{
|
||||
+ if (meta_is_wayland_compositor ()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ g_debug ("KioskInputSourcesManager: Starting X Keyboard Manager");
|
||||
+ self->x_keyboard_manager = kiosk_x_keyboard_manager_new (self->compositor);
|
||||
+
|
||||
+ g_signal_connect_object (G_OBJECT (self->x_keyboard_manager),
|
||||
+ "notify::selected-layout",
|
||||
+ G_CALLBACK (on_x_keyboard_manager_selected_layout_changed),
|
||||
@ -492,7 +692,7 @@ index 4b4ef62..c6c8c91 100644
|
||||
G_CALLBACK (on_dbus_service_handle_select_input_source),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
@@ -1430,63 +1564,71 @@ kiosk_input_sources_manager_handle_dbus_service (KioskInputSourcesManager *self)
|
||||
@@ -1407,63 +1535,78 @@ kiosk_input_sources_manager_handle_dbus_service (KioskInputSourcesManager *self)
|
||||
G_CALLBACK (on_dbus_service_handle_select_previous_input_source),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
@ -524,11 +724,19 @@ index 4b4ef62..c6c8c91 100644
|
||||
|
||||
kiosk_input_sources_manager_set_input_sources_from_session_configuration (self);
|
||||
+
|
||||
+ kiosk_gobject_utils_queue_defer_callback (G_OBJECT (self),
|
||||
+ "[kiosk-input-sources-manager] kiosk_input_source_manager_start_x_keyboard_manager",
|
||||
+ self->cancellable,
|
||||
+ KIOSK_OBJECT_CALLBACK (kiosk_input_source_manager_start_x_keyboard_manager ),
|
||||
+ NULL);
|
||||
+ /* We start the X keyboard manager after we've already loaded and locked in
|
||||
+ * GSettings etc, so the session settings take precedence over xorg.conf
|
||||
+ */
|
||||
+ if (!meta_is_wayland_compositor ()) {
|
||||
+ g_debug ("KioskInputSourcesManager: Will start X keyboard manager shortly");
|
||||
+ kiosk_gobject_utils_queue_defer_callback (G_OBJECT (self),
|
||||
+ "[kiosk-input-sources-manager] kiosk_input_source_manager_start_x_keyboard_manager",
|
||||
+ self->cancellable,
|
||||
+ KIOSK_OBJECT_CALLBACK (kiosk_input_source_manager_start_x_keyboard_manager),
|
||||
+ NULL);
|
||||
+ } else {
|
||||
+ g_debug ("KioskInputSourcesManager: Won't start X keyboard manager on wayland");
|
||||
+ }
|
||||
}
|
||||
|
||||
static void
|
||||
@ -558,18 +766,59 @@ index 4b4ef62..c6c8c91 100644
|
||||
kiosk_input_sources_manager_remove_key_bindings (self);
|
||||
g_clear_weak_pointer (&self->dbus_service);
|
||||
g_clear_weak_pointer (&self->dbus_object_manager);
|
||||
+
|
||||
g_clear_weak_pointer (&self->display);
|
||||
g_clear_weak_pointer (&self->compositor);
|
||||
|
||||
G_OBJECT_CLASS (kiosk_input_sources_manager_parent_class)->dispose (object);
|
||||
}
|
||||
diff --git a/compositor/kiosk-input-sources-manager.h b/compositor/kiosk-input-sources-manager.h
|
||||
index 0b1a738..8a44c3a 100644
|
||||
--- a/compositor/kiosk-input-sources-manager.h
|
||||
+++ b/compositor/kiosk-input-sources-manager.h
|
||||
@@ -1,35 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "kiosk-input-source-group.h"
|
||||
#include "kiosk-input-engine-manager.h"
|
||||
+#include "kiosk-x-keyboard-manager.h"
|
||||
|
||||
typedef struct _KioskCompositor KioskCompositor;
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define KIOSK_TYPE_INPUT_SOURCES_MANAGER (kiosk_input_sources_manager_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (KioskInputSourcesManager,
|
||||
kiosk_input_sources_manager,
|
||||
KIOSK, INPUT_SOURCES_MANAGER,
|
||||
GObject)
|
||||
|
||||
KioskInputSourcesManager *kiosk_input_sources_manager_new (KioskCompositor *compositor);
|
||||
KioskInputEngineManager *kiosk_input_sources_manager_get_input_engine_manager (KioskInputSourcesManager *manager);
|
||||
+KioskXKeyboardManager *kiosk_input_sources_manager_get_x_keyboard_manager (KioskInputSourcesManager *manager);
|
||||
|
||||
void kiosk_input_sources_manager_clear_input_sources (KioskInputSourcesManager *self);
|
||||
gboolean kiosk_input_sources_manager_set_input_sources_from_locales (KioskInputSourcesManager *self,
|
||||
const char * const *locales,
|
||||
const char *options);
|
||||
gboolean kiosk_input_sources_manager_set_input_sources_from_session_configuration (KioskInputSourcesManager *manager);
|
||||
|
||||
void kiosk_input_sources_manager_add_layout (KioskInputSourcesManager *self,
|
||||
const char *layout,
|
||||
const char *options);
|
||||
void kiosk_input_sources_manager_add_input_engine (KioskInputSourcesManager *self,
|
||||
const char *engine_name,
|
||||
const char *options);
|
||||
|
||||
G_END_DECLS
|
||||
diff --git a/compositor/kiosk-x-keyboard-manager.c b/compositor/kiosk-x-keyboard-manager.c
|
||||
new file mode 100644
|
||||
index 0000000..d5c64fb
|
||||
index 0000000..ad18d39
|
||||
--- /dev/null
|
||||
+++ b/compositor/kiosk-x-keyboard-manager.c
|
||||
@@ -0,0 +1,579 @@
|
||||
@@ -0,0 +1,565 @@
|
||||
+#include "config.h"
|
||||
+#include "kiosk-x-keyboard-manager.h"
|
||||
+
|
||||
@ -597,7 +846,6 @@ index 0000000..d5c64fb
|
||||
+ KioskCompositor *compositor;
|
||||
+ MetaBackend *backend;
|
||||
+ MetaDisplay *display;
|
||||
+ MetaX11Display *x11_display;
|
||||
+ Display *x_server_display;
|
||||
+
|
||||
+ /* strong references */
|
||||
@ -612,10 +860,10 @@ index 0000000..d5c64fb
|
||||
+ int xkb_event_base;
|
||||
+
|
||||
+ size_t layout_index;
|
||||
+ ssize_t pending_layout_index;
|
||||
+
|
||||
+ /* flags */
|
||||
+ guint32 watching_x_server_root_window : 1;
|
||||
+ guint32 disallow_layout_selection: 1;
|
||||
+ guint32 xkb_rules_names_data_changed: 1;
|
||||
+};
|
||||
+
|
||||
+enum
|
||||
@ -775,18 +1023,6 @@ index 0000000..d5c64fb
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_x_keyboard_manager_disallow_layout_selection (KioskXKeyboardManager *self)
|
||||
+{
|
||||
+ self->disallow_layout_selection = TRUE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_x_keyboard_manager_allow_layout_selection (KioskXKeyboardManager *self)
|
||||
+{
|
||||
+ self->disallow_layout_selection = FALSE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_x_keyboard_manager_set_layout_index (KioskXKeyboardManager *self,
|
||||
+ size_t layout_index)
|
||||
+{
|
||||
@ -809,23 +1045,21 @@ index 0000000..d5c64fb
|
||||
+ g_object_notify (G_OBJECT (self), "selected-layout");
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+static gboolean
|
||||
+kiosk_x_keyboard_manager_read_current_layout_index (KioskXKeyboardManager *self)
|
||||
+{
|
||||
+ XkbStateRec xkb_state = { 0 };
|
||||
+ int status;
|
||||
+
|
||||
+ meta_x11_error_trap_push (self->x11_display);
|
||||
+ status = XkbGetState (self->x_server_display, XkbUseCoreKbd, &xkb_state);
|
||||
+ meta_x11_error_trap_pop (self->x11_display);
|
||||
+
|
||||
+ if (status != Success) {
|
||||
+ g_debug ("KioskXKeyboardManager: Could not read current layout index");
|
||||
+ return;
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ g_debug ("KioskXKeyboardManager: Current layout index: %u", xkb_state.locked_group);
|
||||
+
|
||||
+ kiosk_x_keyboard_manager_set_layout_index (self, xkb_state.locked_group);
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
@ -855,7 +1089,7 @@ index 0000000..d5c64fb
|
||||
+ OPTIONS
|
||||
+ } property_value_index;
|
||||
+
|
||||
+ kiosk_x_keyboard_manager_allow_layout_selection (self);
|
||||
+ self->xkb_rules_names_data_changed = TRUE;
|
||||
+
|
||||
+ g_debug ("KioskXKeyboardManager: Reading active keyboard layouts from X server");
|
||||
+
|
||||
@ -886,14 +1120,6 @@ index 0000000..d5c64fb
|
||||
+ (GDestroyNotify) XFree,
|
||||
+ NULL);
|
||||
+
|
||||
+ if (self->xkb_rules_names_data != NULL && g_bytes_equal (self->xkb_rules_names_data, new_xkb_rules_names_data)) {
|
||||
+ g_debug ("KioskXKeyboardManager: XKB rules names data is unchanged");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ g_clear_pointer (&self->xkb_rules_names_data, g_bytes_unref);
|
||||
+ self->xkb_rules_names_data = g_steal_pointer (&new_xkb_rules_names_data);
|
||||
+
|
||||
+ property_value_index = 0;
|
||||
+ for (i = 0; i < number_of_bytes_read; i++) {
|
||||
+ g_autofree char *value = g_strdup ((char *) property_values + i);
|
||||
@ -912,8 +1138,8 @@ index 0000000..d5c64fb
|
||||
+ g_debug ("KioskXKeyboardManager: Read variants '%s'", variants_string);
|
||||
+ break;
|
||||
+ case OPTIONS:
|
||||
+ g_debug ("KioskXKeyboardManager: Read options '%s'", options);
|
||||
+ options = g_steal_pointer (&value);
|
||||
+ g_debug ("KioskXKeyboardManager: Read options '%s'", options);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
@ -921,6 +1147,14 @@ index 0000000..d5c64fb
|
||||
+ property_value_index++;
|
||||
+ }
|
||||
+
|
||||
+ if (self->xkb_rules_names_data != NULL && g_bytes_equal (self->xkb_rules_names_data, new_xkb_rules_names_data)) {
|
||||
+ g_debug ("KioskXKeyboardManager: XKB rules names data is unchanged");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ g_clear_pointer (&self->xkb_rules_names_data, g_bytes_unref);
|
||||
+ self->xkb_rules_names_data = g_steal_pointer (&new_xkb_rules_names_data);
|
||||
+
|
||||
+ layouts = g_strsplit (layouts_string, ",", -1);
|
||||
+ variants = g_strsplit (variants_string, ",", -1);
|
||||
+
|
||||
@ -951,32 +1185,22 @@ index 0000000..d5c64fb
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+on_x_server_xkb_rules_names_data_changed (KioskXKeyboardManager *self)
|
||||
+{
|
||||
+ g_debug ("KioskXKeyboardManager: X server keyboard layouts changed");
|
||||
+
|
||||
+ kiosk_x_keyboard_manager_read_xkb_rules_names_data (self);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+monitor_x_server_display_for_property_changes (KioskXKeyboardManager *self,
|
||||
+ Display *x_server_display)
|
||||
+monitor_x_server_display_for_changes (KioskXKeyboardManager *self)
|
||||
+{
|
||||
+ int major = XkbMajorVersion;
|
||||
+ int minor = XkbMinorVersion;
|
||||
+ XWindowAttributes attributes;
|
||||
+
|
||||
+ if (self->watching_x_server_root_window) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ XGetWindowAttributes (x_server_display, self->x_server_root_window, &attributes);
|
||||
+ XGetWindowAttributes (self->x_server_display, self->x_server_root_window, &attributes);
|
||||
+
|
||||
+ if (!(attributes.your_event_mask & PropertyChangeMask)) {
|
||||
+ XSelectInput (x_server_display,
|
||||
+ XSelectInput (self->x_server_display,
|
||||
+ self->x_server_root_window,
|
||||
+ attributes.your_event_mask | PropertyChangeMask);
|
||||
+ }
|
||||
+
|
||||
+ self->watching_x_server_root_window = TRUE;
|
||||
+ XkbQueryExtension (self->x_server_display, NULL, &self->xkb_event_base, NULL, &major, &minor);
|
||||
+ self->xkb_rules_names_atom = XInternAtom (self->x_server_display, "_XKB_RULES_NAMES", False);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
@ -991,17 +1215,8 @@ index 0000000..d5c64fb
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ g_debug ("KioskXKeyboardManager: XKB rules names data changed in X server");
|
||||
+
|
||||
+ /* We block layout index changes until we have a chance to figure out what the new layouts are
|
||||
+ */
|
||||
+ kiosk_x_keyboard_manager_disallow_layout_selection (self);
|
||||
+
|
||||
+ kiosk_gobject_utils_queue_defer_callback (G_OBJECT (self),
|
||||
+ "[kiosk-input-sources-manager] on_x_server_xkb_rules_names_data_changed",
|
||||
+ self->cancellable,
|
||||
+ KIOSK_OBJECT_CALLBACK (on_x_server_xkb_rules_names_data_changed),
|
||||
+ NULL);
|
||||
+ g_debug ("KioskXKeyboardManager: XKB rules names property changed in X server");
|
||||
+ kiosk_x_keyboard_manager_read_xkb_rules_names_data (self);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
@ -1016,12 +1231,19 @@ index 0000000..d5c64fb
|
||||
+ if (!(x_server_event->state.changed & XkbGroupStateMask)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (self->disallow_layout_selection) {
|
||||
+ g_debug ("KioskXKeyboardManager: Ignoring layout change request to group %lu", layout_index);
|
||||
+
|
||||
+ /* Mutter immediately reverts all layout changes coming from
|
||||
+ * the outside, so we hide the event from it.
|
||||
+ */
|
||||
+ x_server_event->state.changed &= ~XkbGroupLockMask;
|
||||
+
|
||||
+ if (self->xkb_rules_names_data_changed) {
|
||||
+ g_debug ("KioskXKeyboardManager: Ignoring spurious group change following layout change");
|
||||
+ self->xkb_rules_names_data_changed = FALSE;
|
||||
+ return;
|
||||
+
|
||||
+ }
|
||||
+ g_debug ("KioskXKeyboardManager: Approving keyboard group change to group %lu", layout_index);
|
||||
+ meta_backend_lock_layout_group (self->backend, layout_index);
|
||||
+ kiosk_x_keyboard_manager_set_layout_index (self, layout_index);
|
||||
+ break;
|
||||
+ }
|
||||
@ -1031,7 +1253,12 @@ index 0000000..d5c64fb
|
||||
+on_x_server_event (KioskXKeyboardManager *self,
|
||||
+ XEvent *x_server_event)
|
||||
+{
|
||||
+ monitor_x_server_display_for_property_changes (self, x_server_event->xany.display);
|
||||
+
|
||||
+ if (self->x_server_display == NULL) {
|
||||
+ self->x_server_display = x_server_event->xany.display;
|
||||
+ self->x_server_root_window = DefaultRootWindow (self->x_server_display);
|
||||
+ monitor_x_server_display_for_changes (self);
|
||||
+ }
|
||||
+
|
||||
+ switch (x_server_event->type) {
|
||||
+ case PropertyNotify:
|
||||
@ -1062,6 +1289,8 @@ index 0000000..d5c64fb
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ g_debug ("KioskXKeyboardManager: Selected layout is '%s'", self->layouts[self->layout_index]);
|
||||
+
|
||||
+ return self->layouts[self->layout_index];
|
||||
+}
|
||||
+
|
||||
@ -1073,20 +1302,41 @@ index 0000000..d5c64fb
|
||||
+ return self->options;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_x_keyboard_manager_init (KioskXKeyboardManager *self)
|
||||
+gboolean
|
||||
+kiosk_x_keyboard_manager_keymap_is_active (KioskXKeyboardManager *self,
|
||||
+ const char * const *layouts,
|
||||
+ const char * const *variants,
|
||||
+ const char *options)
|
||||
+{
|
||||
+ g_auto (GStrv) qualified_layouts = NULL;
|
||||
+
|
||||
+ if (g_strcmp0 (options, self->options) != 0) {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ qualified_layouts = qualify_layouts_with_variants (self, layouts, variants);
|
||||
+
|
||||
+ if (qualified_layouts == NULL) {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (!g_strv_equal ((const char * const *) qualified_layouts, (const char * const *) self->layouts)) {
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+gboolean
|
||||
+kiosk_x_keyboard_manager_layout_group_is_locked (KioskXKeyboardManager *self,
|
||||
+ xkb_layout_index_t layout_index)
|
||||
+{
|
||||
+ return self->layout_index == layout_index;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+kiosk_x_keyboard_manager_initialize_xkb_extension (KioskXKeyboardManager *self)
|
||||
+kiosk_x_keyboard_manager_init (KioskXKeyboardManager *self)
|
||||
+{
|
||||
+ int major = XkbMajorVersion;
|
||||
+ int minor = XkbMinorVersion;
|
||||
+
|
||||
+ XkbQueryExtension (self->x_server_display, NULL, &self->xkb_event_base, NULL, &major, &minor);
|
||||
+
|
||||
+ self->xkb_rules_names_atom = XInternAtom (self->x_server_display, "_XKB_RULES_NAMES", False);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
@ -1102,15 +1352,8 @@ index 0000000..d5c64fb
|
||||
+
|
||||
+ g_set_weak_pointer (&self->backend, meta_get_backend ());
|
||||
+ g_set_weak_pointer (&self->display, meta_plugin_get_display (META_PLUGIN (self->compositor)));
|
||||
+ g_set_weak_pointer (&self->x11_display, meta_display_get_x11_display (self->display));
|
||||
+
|
||||
+ self->x_server_display = meta_x11_display_get_xdisplay (self->x11_display);
|
||||
+ g_object_add_weak_pointer (G_OBJECT (self->x11_display), (gpointer *) &self->x_server_display);
|
||||
+
|
||||
+ self->x_server_root_window = meta_x11_display_get_xroot (self->x11_display);
|
||||
+ g_object_add_weak_pointer (G_OBJECT (self->x11_display), (gpointer *) &self->x_server_root_window);
|
||||
+
|
||||
+ kiosk_x_keyboard_manager_initialize_xkb_extension (self);
|
||||
+ self->pending_layout_index = -1;
|
||||
+
|
||||
+ g_signal_connect_object (G_OBJECT (self->compositor),
|
||||
+ "x-server-event",
|
||||
@ -1135,14 +1378,6 @@ index 0000000..d5c64fb
|
||||
+ g_clear_pointer (&self->layouts, g_strfreev);
|
||||
+ g_clear_pointer (&self->options, g_free);
|
||||
+
|
||||
+ if (self->x11_display != NULL) {
|
||||
+ g_object_remove_weak_pointer (G_OBJECT (self->x11_display),
|
||||
+ (gpointer *) &self->x_server_display);
|
||||
+ g_object_remove_weak_pointer (G_OBJECT (self->x11_display),
|
||||
+ (gpointer *) &self->x_server_root_window);
|
||||
+ }
|
||||
+ g_clear_weak_pointer (&self->x11_display);
|
||||
+
|
||||
+ g_clear_weak_pointer (&self->display);
|
||||
+ g_clear_weak_pointer (&self->backend);
|
||||
+ g_clear_weak_pointer (&self->compositor);
|
||||
@ -1151,13 +1386,14 @@ index 0000000..d5c64fb
|
||||
+}
|
||||
diff --git a/compositor/kiosk-x-keyboard-manager.h b/compositor/kiosk-x-keyboard-manager.h
|
||||
new file mode 100644
|
||||
index 0000000..b402465
|
||||
index 0000000..bae498f
|
||||
--- /dev/null
|
||||
+++ b/compositor/kiosk-x-keyboard-manager.h
|
||||
@@ -0,0 +1,22 @@
|
||||
@@ -0,0 +1,29 @@
|
||||
+#pragma once
|
||||
+
|
||||
+#include <glib-object.h>
|
||||
+#include <xkbcommon/xkbcommon.h>
|
||||
+
|
||||
+typedef struct _KioskCompositor KioskCompositor;
|
||||
+
|
||||
@ -1175,6 +1411,12 @@ index 0000000..b402465
|
||||
+const char * const *kiosk_x_keyboard_manager_get_layouts (KioskXKeyboardManager *manager);
|
||||
+const char *kiosk_x_keyboard_manager_get_selected_layout (KioskXKeyboardManager *manager);
|
||||
+const char *kiosk_x_keyboard_manager_get_options (KioskXKeyboardManager *manager);
|
||||
+gboolean kiosk_x_keyboard_manager_keymap_is_active (KioskXKeyboardManager *manager,
|
||||
+ const char * const *layouts,
|
||||
+ const char * const *variants,
|
||||
+ const char *options);
|
||||
+gboolean kiosk_x_keyboard_manager_layout_group_is_locked (KioskXKeyboardManager *manager,
|
||||
+ xkb_layout_index_t layout_index);
|
||||
+
|
||||
+G_END_DECLS
|
||||
diff --git a/meson.build b/meson.build
|
||||
@ -1244,5 +1486,5 @@ index 2b5640a..44afcea 100644
|
||||
type: 'desktop'
|
||||
)
|
||||
--
|
||||
2.31.1
|
||||
2.30.2
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
Name: gnome-kiosk
|
||||
Version: 40~alpha
|
||||
Release: 4%{?dist}
|
||||
Release: 5%{?dist}
|
||||
Summary: Window management and application launching for GNOME
|
||||
|
||||
License: GPLv2+
|
||||
@ -41,10 +41,10 @@ Requires: gsettings-desktop-schemas%{?_isa} >= %{gsettings_desktop_schemas
|
||||
Patch10001: 0001-compositor-Be-less-aggressive-about-full-screening-w.patch
|
||||
|
||||
# https://gitlab.gnome.org/halfline/gnome-kiosk/-/merge_requests/2
|
||||
Patch20001: 0001-compositor-Add-signal-for-reporting-X-server-events.patch
|
||||
Patch20001: 0001-gobject-utils-Log-when-executing-deferred-tasks.patch
|
||||
Patch20002: 0002-input-sources-manager-Fix-overzealous-rename-mistake.patch
|
||||
Patch20003: 0003-input-sources-manager-Add-function-to-load-input-sou.patch
|
||||
Patch20004: 0004-wip-Better-support-libxklavier.patch
|
||||
Patch20003: 0003-compositor-Add-signal-for-reporting-X-server-events.patch
|
||||
Patch20004: 0004-input-sources-manager-Support-libxklavier-managed-ke.patch
|
||||
|
||||
%description
|
||||
GNOME Kiosk provides a desktop enviroment suitable for fixed purpose, or
|
||||
@ -88,6 +88,9 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.gnome.Kiosk.Searc
|
||||
%{_datadir}/wayland-sessions/org.gnome.Kiosk.SearchApp.Session.desktop
|
||||
|
||||
%changelog
|
||||
* Wed Apr 21 2021 Ray Strode <rstrode@redhat.com> - 40~alpha-5
|
||||
- Fix keyboard layouts getting out of sync in anaconda
|
||||
|
||||
* Tue Apr 20 2021 Ray Strode <rstrode@redhat.com> - 40~alpha-4
|
||||
- Fix infinite loop
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user