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