From b7e1d695935ffafdb838b61afa7041c54b3f92bd Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 25 Sep 2018 20:19:39 +0200
Subject: [PATCH] keyboard: Enable ibus for OSK purposes
As gnome-shell relies on IBus for focus tracking, enable this IM whenever
the conditions for OSK popping up might arise.
Closes: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/issues/95
---
plugins/keyboard/gsd-keyboard-manager.c | 75 +++++++++++++++++++++----
1 file changed, 65 insertions(+), 10 deletions(-)
diff --git a/plugins/keyboard/gsd-keyboard-manager.c b/plugins/keyboard/gsd-keyboard-manager.c
index ea67dda1..31bfade7 100644
--- a/plugins/keyboard/gsd-keyboard-manager.c
+++ b/plugins/keyboard/gsd-keyboard-manager.c
@@ -78,11 +78,15 @@
#define DEFAULT_LAYOUT "us"
+#define GNOME_A11Y_APPLICATIONS_INTERFACE_DIR "org.gnome.desktop.a11y.applications"
+#define KEY_OSK_ENABLED "screen-keyboard-enabled"
+
struct GsdKeyboardManagerPrivate
{
guint start_idle_id;
GSettings *settings;
GSettings *input_sources_settings;
+ GSettings *a11y_settings;
GDBusProxy *localed;
GCancellable *cancellable;
@@ -90,12 +94,15 @@ struct GsdKeyboardManagerPrivate
GsdNumLockState old_state;
GdkDeviceManager *device_manager;
guint device_added_id;
+ guint device_removed_id;
};
static void gsd_keyboard_manager_class_init (GsdKeyboardManagerClass *klass);
static void gsd_keyboard_manager_init (GsdKeyboardManager *keyboard_manager);
static void gsd_keyboard_manager_finalize (GObject *object);
+static void update_gtk_im_module (GsdKeyboardManager *manager);
+
G_DEFINE_TYPE (GsdKeyboardManager, gsd_keyboard_manager, G_TYPE_OBJECT)
static gpointer manager_object = NULL;
@@ -363,9 +370,23 @@ device_added_cb (GdkDeviceManager *device_manager,
if (source == GDK_SOURCE_KEYBOARD) {
g_debug ("New keyboard plugged in, applying all settings");
apply_numlock (manager);
+ } else if (source == GDK_SOURCE_TOUCHSCREEN) {
+ update_gtk_im_module (manager);
}
}
+static void
+device_removed_cb (GdkDeviceManager *device_manager,
+ GdkDevice *device,
+ GsdKeyboardManager *manager)
+{
+ GdkInputSource source;
+
+ source = gdk_device_get_source (device);
+ if (source == GDK_SOURCE_TOUCHSCREEN)
+ update_gtk_im_module (manager);
+}
+
static void
set_devicepresence_handler (GsdKeyboardManager *manager)
{
@@ -378,6 +399,8 @@ set_devicepresence_handler (GsdKeyboardManager *manager)
manager->priv->device_added_id = g_signal_connect (G_OBJECT (device_manager), "device-added",
G_CALLBACK (device_added_cb), manager);
+ manager->priv->device_removed_id = g_signal_connect (G_OBJECT (device_manager), "device-removed",
+ G_CALLBACK (device_removed_cb), manager);
manager->priv->device_manager = device_manager;
}
@@ -395,14 +418,37 @@ need_ibus (GVariant *sources)
return FALSE;
}
+static gboolean
+need_osk (GsdKeyboardManager *manager)
+{
+ GSettings *a11y_settings;
+ gboolean has_touchscreen = FALSE;
+ GList *devices, *l;
+ GdkSeat *seat;
+
+ if (g_settings_get_boolean (manager->priv->a11y_settings,
+ KEY_OSK_ENABLED))
+ return TRUE;
+
+ seat = gdk_display_get_default_seat (gdk_display_get_default ());
+ devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_TOUCH);
+
+ has_touchscreen = devices != NULL;
+
+ g_list_free (devices);
+
+ return has_touchscreen;
+}
+
static void
-set_gtk_im_module (GSettings *settings,
- GVariant *sources)
+set_gtk_im_module (GsdKeyboardManager *manager,
+ GSettings *settings,
+ GVariant *sources)
{
const gchar *new_module;
gchar *current_module;
- if (need_ibus (sources))
+ if (need_ibus (sources) || need_osk (manager))
new_module = GTK_IM_MODULE_IBUS;
else
new_module = GTK_IM_MODULE_SIMPLE;
@@ -414,20 +460,20 @@ set_gtk_im_module (GSettings *settings,
}
static void
-input_sources_changed (GSettings *settings,
- const char *key,
- GsdKeyboardManager *manager)
+update_gtk_im_module (GsdKeyboardManager *manager)
{
GSettings *interface_settings;
GVariant *sources;
+
/* Gtk+ uses the IM module advertised in XSETTINGS so, if we
* have IBus input sources, we want it to load that
* module. Otherwise we can use the default "simple" module
* which is builtin gtk+
*/
- sources = g_settings_get_value (settings, KEY_INPUT_SOURCES);
interface_settings = g_settings_new (GNOME_DESKTOP_INTERFACE_DIR);
- set_gtk_im_module (interface_settings, sources);
+ sources = g_settings_get_value (manager->priv->input_sources_settings,
+ KEY_INPUT_SOURCES);
+ set_gtk_im_module (manager, interface_settings, sources);
g_object_unref (interface_settings);
g_variant_unref (sources);
}
@@ -686,8 +732,15 @@ start_keyboard_idle_cb (GsdKeyboardManager *manager)
set_devicepresence_handler (manager);
manager->priv->input_sources_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR);
- g_signal_connect (manager->priv->input_sources_settings, "changed::"KEY_INPUT_SOURCES,
- G_CALLBACK (input_sources_changed), manager);
+ g_signal_connect_swapped (manager->priv->input_sources_settings,
+ "changed::" KEY_INPUT_SOURCES,
+ G_CALLBACK (update_gtk_im_module), manager);
+
+ manager->priv->a11y_settings = g_settings_new (GNOME_A11Y_APPLICATIONS_INTERFACE_DIR);
+ g_signal_connect_swapped (manager->priv->a11y_settings,
+ "changed::" KEY_OSK_ENABLED,
+ G_CALLBACK (update_gtk_im_module), manager);
+ update_gtk_im_module (manager);
manager->priv->cancellable = g_cancellable_new ();
@@ -750,10 +803,12 @@ gsd_keyboard_manager_stop (GsdKeyboardManager *manager)
g_clear_object (&p->settings);
g_clear_object (&p->input_sources_settings);
+ g_clear_object (&p->a11y_settings);
g_clear_object (&p->localed);
if (p->device_manager != NULL) {
g_signal_handler_disconnect (p->device_manager, p->device_added_id);
+ g_signal_handler_disconnect (p->device_manager, p->device_removed_id);
p->device_manager = NULL;
}
--
2.19.2