~ps-jenkins/unity-settings-daemon/ubuntu-vivid-proposed

« back to all changes in this revision

Viewing changes to debian/patches/61_revert_libgnomekbd_drop

  • Committer: Robert Ancell
  • Date: 2013-11-13 01:33:12 UTC
  • Revision ID: robert.ancell@canonical.com-20131113013312-lqg7dhy39tvmjrda
Import packaging

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Index: b/configure.ac
 
2
===================================================================
 
3
--- a/configure.ac
 
4
+++ b/configure.ac
 
5
@@ -47,7 +47,7 @@
 
6
 GTK_REQUIRED_VERSION=3.3.18
 
7
 GCONF_REQUIRED_VERSION=2.6.1
 
8
 GIO_REQUIRED_VERSION=2.26.0
 
9
-GNOME_DESKTOP_REQUIRED_VERSION=3.5.3
 
10
+GNOME_DESKTOP_REQUIRED_VERSION=3.3.92
 
11
 LIBNOTIFY_REQUIRED_VERSION=0.7.3
 
12
 UPOWER_GLIB_REQUIRED_VERSION=0.9.1
 
13
 PA_REQUIRED_VERSION=0.9.16
 
14
@@ -175,7 +175,8 @@
 
15
 dnl - Keyboard plugin stuff
 
16
 dnl ---------------------------------------------------------------------------
 
17
 
 
18
-PKG_CHECK_MODULES(KEYBOARD, xkbfile gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
 
19
+LIBGNOMEKBD_REQUIRED=3.5.1
 
20
+PKG_CHECK_MODULES(KEYBOARD, [libgnomekbdui >= $LIBGNOMEKBD_REQUIRED libgnomekbd >= $LIBGNOMEKBD_REQUIRED libxklavier >= 5.0 kbproto])
 
21
 
 
22
 dnl ---------------------------------------------------------------------------
 
23
 dnl - Housekeeping plugin stuff
 
24
Index: b/plugins/keyboard/delayed-dialog.c
 
25
===================================================================
 
26
--- /dev/null
 
27
+++ b/plugins/keyboard/delayed-dialog.c
 
28
@@ -0,0 +1,128 @@
 
29
+/*
 
30
+ * Copyright © 2006 Novell, Inc.
 
31
+ *
 
32
+ * This program is free software; you can redistribute it and/or
 
33
+ * modify it under the terms of the GNU General Public License as
 
34
+ * published by the Free Software Foundation; either version 2, or (at
 
35
+ * your option) any later version.
 
36
+ *
 
37
+ * This program is distributed in the hope that it will be useful, but
 
38
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
 
39
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
40
+ * General Public License for more details.
 
41
+ *
 
42
+ * You should have received a copy of the GNU General Public License
 
43
+ * along with this program; if not, write to the Free Software
 
44
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
45
+ * 02111-1307, USA.
 
46
+ */
 
47
+
 
48
+#include <stdlib.h>
 
49
+#include <string.h>
 
50
+
 
51
+#include <gtk/gtk.h>
 
52
+#include <gdk/gdkx.h>
 
53
+
 
54
+#include "delayed-dialog.h"
 
55
+
 
56
+static gboolean        delayed_show_timeout (gpointer   data);
 
57
+static GdkFilterReturn message_filter       (GdkXEvent *xevent,
 
58
+                                             GdkEvent  *event,
 
59
+                                             gpointer   data);
 
60
+
 
61
+static GSList *dialogs = NULL;
 
62
+
 
63
+/**
 
64
+ * gsd_delayed_show_dialog:
 
65
+ * @dialog: the dialog
 
66
+ *
 
67
+ * Shows the dialog as with gtk_widget_show(), unless a window manager
 
68
+ * hasn't been started yet, in which case it will wait up to 5 seconds
 
69
+ * for that to happen before showing the dialog.
 
70
+ **/
 
71
+void
 
72
+gsd_delayed_show_dialog (GtkWidget *dialog)
 
73
+{
 
74
+        GdkDisplay *display = gtk_widget_get_display (dialog);
 
75
+        Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
 
76
+        GdkScreen *screen = gtk_widget_get_screen (dialog);
 
77
+        char selection_name[10];
 
78
+        Atom selection_atom;
 
79
+
 
80
+        /* We can't use gdk_selection_owner_get() for this, because
 
81
+         * it's an unknown out-of-process window.
 
82
+         */
 
83
+        snprintf (selection_name, sizeof (selection_name), "WM_S%d",
 
84
+                  gdk_screen_get_number (screen));
 
85
+        selection_atom = XInternAtom (xdisplay, selection_name, True);
 
86
+        if (selection_atom &&
 
87
+            XGetSelectionOwner (xdisplay, selection_atom) != None) {
 
88
+                gtk_widget_show (dialog);
 
89
+                return;
 
90
+        }
 
91
+
 
92
+        dialogs = g_slist_prepend (dialogs, dialog);
 
93
+
 
94
+        gdk_window_add_filter (NULL, message_filter, NULL);
 
95
+
 
96
+        g_timeout_add (5000, delayed_show_timeout, NULL);
 
97
+}
 
98
+
 
99
+static gboolean
 
100
+delayed_show_timeout (gpointer data)
 
101
+{
 
102
+        GSList *l;
 
103
+
 
104
+        for (l = dialogs; l; l = l->next)
 
105
+                gtk_widget_show (l->data);
 
106
+        g_slist_free (dialogs);
 
107
+        dialogs = NULL;
 
108
+
 
109
+        /* FIXME: There's no gdk_display_remove_client_message_filter */
 
110
+
 
111
+        return FALSE;
 
112
+}
 
113
+
 
114
+static GdkFilterReturn
 
115
+message_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
 
116
+{
 
117
+        XClientMessageEvent *evt;
 
118
+        char *selection_name;
 
119
+        int screen;
 
120
+        GSList *l, *next;
 
121
+
 
122
+        if (((XEvent *)xevent)->type != ClientMessage)
 
123
+          return GDK_FILTER_CONTINUE;
 
124
+
 
125
+        evt = (XClientMessageEvent *)xevent;
 
126
+
 
127
+        if (evt->message_type != XInternAtom (evt->display, "MANAGER", FALSE))
 
128
+          return GDK_FILTER_CONTINUE;
 
129
+
 
130
+        selection_name = XGetAtomName (evt->display, evt->data.l[1]);
 
131
+
 
132
+        if (strncmp (selection_name, "WM_S", 4) != 0) {
 
133
+                XFree (selection_name);
 
134
+                return GDK_FILTER_CONTINUE;
 
135
+        }
 
136
+
 
137
+        screen = atoi (selection_name + 4);
 
138
+
 
139
+        for (l = dialogs; l; l = next) {
 
140
+                GtkWidget *dialog = l->data;
 
141
+                next = l->next;
 
142
+
 
143
+                if (gdk_screen_get_number (gtk_widget_get_screen (dialog)) == screen) {
 
144
+                        gtk_widget_show (dialog);
 
145
+                        dialogs = g_slist_remove (dialogs, dialog);
 
146
+                }
 
147
+        }
 
148
+
 
149
+        if (!dialogs) {
 
150
+                gdk_window_remove_filter (NULL, message_filter, NULL);
 
151
+        }
 
152
+
 
153
+        XFree (selection_name);
 
154
+
 
155
+        return GDK_FILTER_CONTINUE;
 
156
+}
 
157
Index: b/plugins/keyboard/delayed-dialog.h
 
158
===================================================================
 
159
--- /dev/null
 
160
+++ b/plugins/keyboard/delayed-dialog.h
 
161
@@ -0,0 +1,32 @@
 
162
+/*
 
163
+ * Copyright © 2006 Novell, Inc.
 
164
+ *
 
165
+ * This program is free software; you can redistribute it and/or
 
166
+ * modify it under the terms of the GNU General Public License as
 
167
+ * published by the Free Software Foundation; either version 2, or (at
 
168
+ * your option) any later version.
 
169
+ *
 
170
+ * This program is distributed in the hope that it will be useful, but
 
171
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
 
172
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
173
+ * General Public License for more details.
 
174
+ *
 
175
+ * You should have received a copy of the GNU General Public License
 
176
+ * along with this program; if not, write to the Free Software
 
177
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
178
+ * 02111-1307, USA.
 
179
+ */
 
180
+
 
181
+
 
182
+#ifndef __DELAYED_DIALOG_H
 
183
+#define __DELAYED_DIALOG_H
 
184
+
 
185
+#include <gtk/gtk.h>
 
186
+
 
187
+G_BEGIN_DECLS
 
188
+
 
189
+void            gsd_delayed_show_dialog (GtkWidget *dialog);
 
190
+
 
191
+G_END_DECLS
 
192
+
 
193
+#endif
 
194
Index: b/plugins/keyboard/gsd-keyboard-manager.c
 
195
===================================================================
 
196
--- a/plugins/keyboard/gsd-keyboard-manager.c
 
197
+++ b/plugins/keyboard/gsd-keyboard-manager.c
 
198
@@ -40,15 +40,19 @@
 
199
 
 
200
 #include <X11/XKBlib.h>
 
201
 #include <X11/keysym.h>
 
202
-#include <X11/extensions/XKBrules.h>
 
203
 
 
204
-#define GNOME_DESKTOP_USE_UNSTABLE_API
 
205
-#include <libgnome-desktop/gnome-xkb-info.h>
 
206
+#include <libxklavier/xklavier.h>
 
207
+#include <libgnomekbd/gkbd-status.h>
 
208
+#include <libgnomekbd/gkbd-keyboard-drawing.h>
 
209
+#include <libgnomekbd/gkbd-desktop-config.h>
 
210
+#include <libgnomekbd/gkbd-keyboard-config.h>
 
211
+#include <libgnomekbd/gkbd-util.h>
 
212
 
 
213
 #include "gnome-settings-profile.h"
 
214
 #include "gsd-keyboard-manager.h"
 
215
 #include "gsd-input-helper.h"
 
216
 #include "gsd-enums.h"
 
217
+#include "delayed-dialog.h"
 
218
 
 
219
 #define GSD_KEYBOARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_KEYBOARD_MANAGER, GsdKeyboardManagerPrivate))
 
220
 
 
221
@@ -66,26 +70,31 @@
 
222
 #define KEY_BELL_DURATION  "bell-duration"
 
223
 #define KEY_BELL_MODE      "bell-mode"
 
224
 
 
225
-#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.gnome.desktop.input-sources"
 
226
-
 
227
-#define KEY_CURRENT_INPUT_SOURCE "current"
 
228
-#define KEY_INPUT_SOURCES        "sources"
 
229
-
 
230
-#define INPUT_SOURCE_TYPE_XKB "xkb"
 
231
-
 
232
 #define DEFAULT_LANGUAGE "en_US"
 
233
 
 
234
 struct GsdKeyboardManagerPrivate
 
235
 {
 
236
        guint      start_idle_id;
 
237
         GSettings *settings;
 
238
-        GSettings *input_sources_settings;
 
239
-        GnomeXkbInfo *xkb_info;
 
240
         gint       xkb_event_base;
 
241
         GsdNumLockState old_state;
 
242
         GdkDeviceManager *device_manager;
 
243
         guint device_added_id;
 
244
         guint device_removed_id;
 
245
+
 
246
+        /* XKB */
 
247
+        XklEngine *xkl_engine;
 
248
+        XklConfigRegistry *xkl_registry;
 
249
+
 
250
+        GkbdDesktopConfig current_config;
 
251
+        GkbdKeyboardConfig current_kbd_config;
 
252
+
 
253
+        GkbdKeyboardConfig initial_sys_kbd_config;
 
254
+        GSettings *settings_desktop;
 
255
+        GSettings *settings_keyboard;
 
256
+
 
257
+        GtkStatusIcon *icon;
 
258
+        GtkMenu *popup_menu;
 
259
 };
 
260
 
 
261
 static void     gsd_keyboard_manager_class_init  (GsdKeyboardManagerClass *klass);
 
262
@@ -96,6 +105,367 @@
 
263
 
 
264
 static gpointer manager_object = NULL;
 
265
 
 
266
+static gboolean try_activating_xkb_config_if_new (GsdKeyboardManager *manager,
 
267
+                                                 GkbdKeyboardConfig *current_sys_kbd_config);
 
268
+static gboolean filter_xkb_config (GsdKeyboardManager *manager);
 
269
+static void show_hide_icon (GsdKeyboardManager *manager);
 
270
+
 
271
+static void
 
272
+activation_error (void)
 
273
+{
 
274
+       char const *vendor;
 
275
+       GtkWidget *dialog;
 
276
+
 
277
+       vendor =
 
278
+           ServerVendor (GDK_DISPLAY_XDISPLAY
 
279
+                         (gdk_display_get_default ()));
 
280
+
 
281
+       /* VNC viewers will not work, do not barrage them with warnings */
 
282
+       if (NULL != vendor && NULL != strstr (vendor, "VNC"))
 
283
+               return;
 
284
+
 
285
+       dialog = gtk_message_dialog_new_with_markup (NULL,
 
286
+                                                    0,
 
287
+                                                    GTK_MESSAGE_ERROR,
 
288
+                                                    GTK_BUTTONS_CLOSE,
 
289
+                                                    _
 
290
+                                                    ("Error activating XKB configuration.\n"
 
291
+                                                     "There can be various reasons for that.\n\n"
 
292
+                                                     "If you report this situation as a bug, include the results of\n"
 
293
+                                                     " • <b>%s</b>\n"
 
294
+                                                     " • <b>%s</b>\n"
 
295
+                                                     " • <b>%s</b>\n"
 
296
+                                                     " • <b>%s</b>"),
 
297
+                                                    "xprop -root | grep XKB",
 
298
+                                                    "gsettings get org.gnome.libgnomekbd.keyboard model",
 
299
+                                                    "gsettings get org.gnome.libgnomekbd.keyboard layouts",
 
300
+                                                    "gsettings get org.gnome.libgnomekbd.keyboard options");
 
301
+       g_signal_connect (dialog, "response",
 
302
+                         G_CALLBACK (gtk_widget_destroy), NULL);
 
303
+       gsd_delayed_show_dialog (dialog);
 
304
+}
 
305
+
 
306
+static gboolean
 
307
+ensure_manager_xkl_registry (GsdKeyboardManager *manager)
 
308
+{
 
309
+       if (!manager->priv->xkl_registry) {
 
310
+               manager->priv->xkl_registry =
 
311
+                   xkl_config_registry_get_instance (manager->priv->xkl_engine);
 
312
+               /* load all materials, unconditionally! */
 
313
+               if (!xkl_config_registry_load (manager->priv->xkl_registry, TRUE)) {
 
314
+                       g_object_unref (manager->priv->xkl_registry);
 
315
+                       manager->priv->xkl_registry = NULL;
 
316
+                       return FALSE;
 
317
+               }
 
318
+       }
 
319
+
 
320
+       return TRUE;
 
321
+}
 
322
+
 
323
+static void
 
324
+apply_desktop_settings (GsdKeyboardManager *manager)
 
325
+{
 
326
+       if (manager->priv->xkl_engine == NULL)
 
327
+               return;
 
328
+
 
329
+       gsd_keyboard_manager_apply_settings (manager);
 
330
+       gkbd_desktop_config_load (&manager->priv->current_config);
 
331
+       /* again, probably it would be nice to compare things
 
332
+          before activating them */
 
333
+       gkbd_desktop_config_activate (&manager->priv->current_config);
 
334
+}
 
335
+
 
336
+static void
 
337
+apply_xkb_settings (GsdKeyboardManager *manager)
 
338
+{
 
339
+       GkbdKeyboardConfig current_sys_kbd_config;
 
340
+
 
341
+       if (manager->priv->xkl_engine == NULL)
 
342
+               return;
 
343
+
 
344
+       gkbd_keyboard_config_init (&current_sys_kbd_config, manager->priv->xkl_engine);
 
345
+
 
346
+       gkbd_keyboard_config_load (&manager->priv->current_kbd_config,
 
347
+                                  &manager->priv->initial_sys_kbd_config);
 
348
+
 
349
+       gkbd_keyboard_config_load_from_x_current (&current_sys_kbd_config,
 
350
+                                                 NULL);
 
351
+
 
352
+       if (!try_activating_xkb_config_if_new (manager, &current_sys_kbd_config)) {
 
353
+               if (filter_xkb_config (manager)) {
 
354
+                       if (!try_activating_xkb_config_if_new
 
355
+                           (manager, &current_sys_kbd_config)) {
 
356
+                               g_warning
 
357
+                                   ("Could not activate the filtered XKB configuration");
 
358
+                               activation_error ();
 
359
+                       }
 
360
+               } else {
 
361
+                       g_warning
 
362
+                           ("Could not activate the XKB configuration");
 
363
+                       activation_error ();
 
364
+               }
 
365
+       } else
 
366
+               g_debug (
 
367
+                          "Actual KBD configuration was not changed: redundant notification\n");
 
368
+
 
369
+       gkbd_keyboard_config_term (&current_sys_kbd_config);
 
370
+       show_hide_icon (manager);
 
371
+}
 
372
+
 
373
+static void
 
374
+desktop_settings_changed (GSettings          *settings,
 
375
+                         gchar              *key,
 
376
+                         GsdKeyboardManager *manager)
 
377
+{
 
378
+       apply_desktop_settings (manager);
 
379
+}
 
380
+
 
381
+static void
 
382
+xkb_settings_changed (GSettings          *settings,
 
383
+                     gchar              *key,
 
384
+                     GsdKeyboardManager *manager)
 
385
+{
 
386
+       apply_xkb_settings (manager);
 
387
+}
 
388
+
 
389
+static void
 
390
+popup_menu_launch_capplet (void)
 
391
+{
 
392
+       GAppInfo *info;
 
393
+       GdkAppLaunchContext *ctx;
 
394
+       GError *error = NULL;
 
395
+
 
396
+       info = g_app_info_create_from_commandline ("gnome-control-center region", NULL, 0, NULL);
 
397
+       if (info == NULL)
 
398
+               return;
 
399
+
 
400
+       ctx = gdk_display_get_app_launch_context (gdk_display_get_default ());
 
401
+
 
402
+       if (g_app_info_launch (info, NULL,
 
403
+                              G_APP_LAUNCH_CONTEXT (ctx), &error) == FALSE) {
 
404
+               g_warning ("Could not execute keyboard properties capplet: [%s]\n",
 
405
+                          error->message);
 
406
+               g_error_free (error);
 
407
+       }
 
408
+
 
409
+       g_object_unref (info);
 
410
+       g_object_unref (ctx);
 
411
+}
 
412
+
 
413
+static void
 
414
+popup_menu_show_layout (GtkMenuItem *menuitem,
 
415
+                       GsdKeyboardManager *manager)
 
416
+{
 
417
+       XklState *xkl_state;
 
418
+       char *command;
 
419
+
 
420
+       xkl_state = xkl_engine_get_current_state (manager->priv->xkl_engine);
 
421
+       if (xkl_state->group < 0)
 
422
+               return;
 
423
+
 
424
+       command = g_strdup_printf ("gkbd-keyboard-display -g %d", xkl_state->group + 1);
 
425
+       g_spawn_command_line_async (command, NULL);
 
426
+       g_free (command);
 
427
+}
 
428
+
 
429
+static void
 
430
+popup_menu_set_group (GtkMenuItem * item, gpointer param)
 
431
+{
 
432
+       gint group_number = GPOINTER_TO_INT (param);
 
433
+       XklEngine *engine = gkbd_status_get_xkl_engine ();
 
434
+       XklState st;
 
435
+       Window cur;
 
436
+
 
437
+       st.group = group_number;
 
438
+       xkl_engine_allow_one_switch_to_secondary_group (engine);
 
439
+       cur = xkl_engine_get_current_window (engine);
 
440
+       if (cur != (Window) NULL) {
 
441
+               g_debug ("Enforcing the state %d for window %lx\n",
 
442
+                          st.group, cur);
 
443
+               xkl_engine_save_state (engine,
 
444
+                                      xkl_engine_get_current_window
 
445
+                                      (engine), &st);
 
446
+/*    XSetInputFocus( GDK_DISPLAY(), cur, RevertToNone, CurrentTime );*/
 
447
+       } else {
 
448
+               g_debug (
 
449
+                          "??? Enforcing the state %d for unknown window\n",
 
450
+                          st.group);
 
451
+               /* strange situation - bad things can happen */
 
452
+       }
 
453
+       xkl_engine_lock_group (engine, st.group);
 
454
+}
 
455
+
 
456
+static void
 
457
+ensure_popup_menu (GsdKeyboardManager *manager)
 
458
+{
 
459
+       GtkMenu *popup_menu = GTK_MENU (gtk_menu_new ());
 
460
+       GtkMenu *groups_menu = GTK_MENU (gtk_menu_new ());
 
461
+       int i = 0;
 
462
+       gchar **current_name = gkbd_status_get_group_names ();
 
463
+
 
464
+       GtkWidget *item = gtk_menu_item_new_with_mnemonic (_("_Layouts"));
 
465
+       gtk_widget_show (item);
 
466
+       gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
 
467
+       gtk_menu_item_set_submenu (GTK_MENU_ITEM (item),
 
468
+                                  GTK_WIDGET (groups_menu));
 
469
+
 
470
+       item = gtk_menu_item_new_with_mnemonic (_("Show _Keyboard Layout..."));
 
471
+       gtk_widget_show (item);
 
472
+       g_signal_connect (item, "activate", G_CALLBACK (popup_menu_show_layout), manager);
 
473
+       gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
 
474
+
 
475
+       /* translators note:
 
476
+        * This is the name of the gnome-control-center "region" panel */
 
477
+       item = gtk_menu_item_new_with_mnemonic (_("Region and Language Settings"));
 
478
+       gtk_widget_show (item);
 
479
+       g_signal_connect (item, "activate", popup_menu_launch_capplet, NULL);
 
480
+       gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
 
481
+
 
482
+       for (i = 0; *current_name; i++, current_name++) {
 
483
+               item = gtk_menu_item_new_with_label (*current_name);
 
484
+               gtk_widget_show (item);
 
485
+               gtk_menu_shell_append (GTK_MENU_SHELL (groups_menu), item);
 
486
+               g_signal_connect (item, "activate",
 
487
+                                 G_CALLBACK (popup_menu_set_group),
 
488
+                                 GINT_TO_POINTER (i));
 
489
+       }
 
490
+
 
491
+       if (manager->priv->popup_menu != NULL)
 
492
+               gtk_widget_destroy (GTK_WIDGET (manager->priv->popup_menu));
 
493
+       manager->priv->popup_menu = popup_menu;
 
494
+}
 
495
+
 
496
+static void
 
497
+status_icon_popup_menu_cb (GtkStatusIcon      *icon,
 
498
+                          guint               button,
 
499
+                          guint               time,
 
500
+                          GsdKeyboardManager *manager)
 
501
+{
 
502
+       ensure_popup_menu (manager);
 
503
+       gtk_menu_popup (manager->priv->popup_menu, NULL, NULL,
 
504
+                       gtk_status_icon_position_menu,
 
505
+                       (gpointer) icon, button, time);
 
506
+}
 
507
+
 
508
+static void
 
509
+show_hide_icon (GsdKeyboardManager *manager)
 
510
+{
 
511
+       if (g_strv_length (manager->priv->current_kbd_config.layouts_variants) > 1) {
 
512
+               if (manager->priv->icon == NULL) {
 
513
+                       g_debug ("Creating keyboard status icon\n");
 
514
+                       manager->priv->icon = gkbd_status_new ();
 
515
+                       g_signal_connect (manager->priv->icon, "popup-menu",
 
516
+                                         G_CALLBACK
 
517
+                                         (status_icon_popup_menu_cb),
 
518
+                                         manager);
 
519
+
 
520
+               }
 
521
+       } else {
 
522
+               if (manager->priv->icon != NULL) {
 
523
+                       g_debug ("Destroying icon\n");
 
524
+                       g_object_unref (manager->priv->icon);
 
525
+                       manager->priv->icon = NULL;
 
526
+               }
 
527
+       }
 
528
+}
 
529
+
 
530
+static gboolean
 
531
+try_activating_xkb_config_if_new (GsdKeyboardManager *manager,
 
532
+                                 GkbdKeyboardConfig *current_sys_kbd_config)
 
533
+{
 
534
+       /* Activate - only if different! */
 
535
+       if (!gkbd_keyboard_config_equals
 
536
+           (&manager->priv->current_kbd_config, current_sys_kbd_config)) {
 
537
+               if (gkbd_keyboard_config_activate (&manager->priv->current_kbd_config)) {
 
538
+                       return FALSE;
 
539
+               }
 
540
+       }
 
541
+       return TRUE;
 
542
+}
 
543
+
 
544
+static gboolean
 
545
+filter_xkb_config (GsdKeyboardManager *manager)
 
546
+{
 
547
+       XklConfigItem *item;
 
548
+       gchar *lname;
 
549
+       gchar *vname;
 
550
+       gchar **lv;
 
551
+       gboolean any_change = FALSE;
 
552
+
 
553
+       g_debug ("Filtering configuration against the registry\n");
 
554
+       if (!ensure_manager_xkl_registry (manager))
 
555
+               return FALSE;
 
556
+
 
557
+       lv = manager->priv->current_kbd_config.layouts_variants;
 
558
+       item = xkl_config_item_new ();
 
559
+       while (*lv) {
 
560
+               g_debug ("Checking [%s]\n", *lv);
 
561
+               if (gkbd_keyboard_config_split_items (*lv, &lname, &vname)) {
 
562
+                       gboolean should_be_dropped = FALSE;
 
563
+                       g_snprintf (item->name, sizeof (item->name), "%s",
 
564
+                                   lname);
 
565
+                       if (!xkl_config_registry_find_layout
 
566
+                           (manager->priv->xkl_registry, item)) {
 
567
+                               g_debug ("Bad layout [%s]\n",
 
568
+                                          lname);
 
569
+                               should_be_dropped = TRUE;
 
570
+                       } else if (vname) {
 
571
+                               g_snprintf (item->name,
 
572
+                                           sizeof (item->name), "%s",
 
573
+                                           vname);
 
574
+                               if (!xkl_config_registry_find_variant
 
575
+                                   (manager->priv->xkl_registry, lname, item)) {
 
576
+                                       g_debug (
 
577
+                                                  "Bad variant [%s(%s)]\n",
 
578
+                                                  lname, vname);
 
579
+                                       should_be_dropped = TRUE;
 
580
+                               }
 
581
+                       }
 
582
+                       if (should_be_dropped) {
 
583
+                               gkbd_strv_behead (lv);
 
584
+                               any_change = TRUE;
 
585
+                               continue;
 
586
+                       }
 
587
+               }
 
588
+               lv++;
 
589
+       }
 
590
+       g_object_unref (item);
 
591
+       return any_change;
 
592
+}
 
593
+
 
594
+static void
 
595
+gsd_keyboard_xkb_init (GsdKeyboardManager *manager)
 
596
+{
 
597
+       Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
 
598
+
 
599
+       manager->priv->xkl_engine = xkl_engine_get_instance (dpy);
 
600
+       if (!manager->priv->xkl_engine)
 
601
+               return;
 
602
+
 
603
+       gkbd_desktop_config_init (&manager->priv->current_config, manager->priv->xkl_engine);
 
604
+       gkbd_keyboard_config_init (&manager->priv->current_kbd_config,
 
605
+                                  manager->priv->xkl_engine);
 
606
+       xkl_engine_backup_names_prop (manager->priv->xkl_engine);
 
607
+       gkbd_keyboard_config_init (&manager->priv->initial_sys_kbd_config, manager->priv->xkl_engine);
 
608
+       gkbd_keyboard_config_load_from_x_initial (&manager->priv->initial_sys_kbd_config,
 
609
+                                                 NULL);
 
610
+
 
611
+       gnome_settings_profile_start ("xkl_engine_start_listen");
 
612
+       xkl_engine_start_listen (manager->priv->xkl_engine,
 
613
+                                XKLL_MANAGE_LAYOUTS |
 
614
+                                XKLL_MANAGE_WINDOW_STATES);
 
615
+       gnome_settings_profile_end ("xkl_engine_start_listen");
 
616
+
 
617
+       gnome_settings_profile_start ("apply_desktop_settings");
 
618
+       apply_desktop_settings (manager);
 
619
+       gnome_settings_profile_end ("apply_desktop_settings");
 
620
+       gnome_settings_profile_start ("apply_xkb_settings");
 
621
+       apply_xkb_settings (manager);
 
622
+       gnome_settings_profile_end ("apply_xkb_settings");
 
623
+
 
624
+       gnome_settings_profile_end (NULL);
 
625
+}
 
626
+
 
627
 static gboolean
 
628
 xkb_set_keyboard_autorepeat_rate (guint delay, guint interval)
 
629
 {
 
630
@@ -118,11 +488,12 @@
 
631
                                       &error_base,
 
632
                                       &major,
 
633
                                       &minor);
 
634
+
 
635
         return have_xkb;
 
636
 }
 
637
 
 
638
 static void
 
639
-xkb_init (GsdKeyboardManager *manager)
 
640
+numlock_xkb_init (GsdKeyboardManager *manager)
 
641
 {
 
642
         Display *dpy;
 
643
 
 
644
@@ -161,8 +532,15 @@
 
645
        XkbEvent *xkbev = (XkbEvent *) xev;
 
646
         GsdKeyboardManager *manager = (GsdKeyboardManager *) user_data;
 
647
 
 
648
-        if (xev->type != manager->priv->xkb_event_base ||
 
649
-            xkbev->any.xkb_type != XkbStateNotify)
 
650
+       /* libxklavier's events first */
 
651
+       if (manager->priv->xkl_engine != NULL)
 
652
+               xkl_engine_filter_events (manager->priv->xkl_engine, xev);
 
653
+
 
654
+       /* Then XKB specific events */
 
655
+        if (xev->type != manager->priv->xkb_event_base)
 
656
+               return GDK_FILTER_CONTINUE;
 
657
+
 
658
+       if (xkbev->any.xkb_type != XkbStateNotify)
 
659
                return GDK_FILTER_CONTINUE;
 
660
 
 
661
        if (xkbev->state.changed & XkbModifierLockMask) {
 
662
@@ -200,262 +578,6 @@
 
663
 }
 
664
 
 
665
 static void
 
666
-free_xkb_component_names (XkbComponentNamesRec *p)
 
667
-{
 
668
-        g_return_if_fail (p != NULL);
 
669
-
 
670
-        free (p->keymap);
 
671
-        free (p->keycodes);
 
672
-        free (p->types);
 
673
-        free (p->compat);
 
674
-        free (p->symbols);
 
675
-        free (p->geometry);
 
676
-
 
677
-        g_free (p);
 
678
-}
 
679
-
 
680
-static void
 
681
-upload_xkb_description (const gchar          *rules_file_path,
 
682
-                        XkbRF_VarDefsRec     *var_defs,
 
683
-                        XkbComponentNamesRec *comp_names)
 
684
-{
 
685
-        Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
 
686
-        XkbDescRec *xkb_desc;
 
687
-        gchar *rules_file;
 
688
-
 
689
-        /* Upload it to the X server using the same method as setxkbmap */
 
690
-        xkb_desc = XkbGetKeyboardByName (display,
 
691
-                                         XkbUseCoreKbd,
 
692
-                                         comp_names,
 
693
-                                         XkbGBN_AllComponentsMask,
 
694
-                                         XkbGBN_AllComponentsMask &
 
695
-                                         (~XkbGBN_GeometryMask), True);
 
696
-        if (!xkb_desc) {
 
697
-                g_warning ("Couldn't upload new XKB keyboard description");
 
698
-                return;
 
699
-        }
 
700
-
 
701
-        XkbFreeKeyboard (xkb_desc, 0, True);
 
702
-
 
703
-        rules_file = g_path_get_basename (rules_file_path);
 
704
-
 
705
-        if (!XkbRF_SetNamesProp (display, rules_file, var_defs))
 
706
-                g_warning ("Couldn't update the XKB root window property");
 
707
-
 
708
-        g_free (rules_file);
 
709
-}
 
710
-
 
711
-static gchar *
 
712
-language_code_from_locale (const gchar *locale)
 
713
-{
 
714
-        if (!locale || !locale[0] || !locale[1])
 
715
-                return NULL;
 
716
-
 
717
-        if (!locale[2] || locale[2] == '_' || locale[2] == '.')
 
718
-                return g_strndup (locale, 2);
 
719
-
 
720
-        if (!locale[3] || locale[3] == '_' || locale[3] == '.')
 
721
-                return g_strndup (locale, 3);
 
722
-
 
723
-        return NULL;
 
724
-}
 
725
-
 
726
-static gchar *
 
727
-build_xkb_group_string (const gchar *user,
 
728
-                        const gchar *locale,
 
729
-                        const gchar *latin)
 
730
-{
 
731
-        gchar *string;
 
732
-        gsize length = 0;
 
733
-        guint commas = 2;
 
734
-
 
735
-        if (latin)
 
736
-                length += strlen (latin);
 
737
-        else
 
738
-                commas -= 1;
 
739
-
 
740
-        if (locale)
 
741
-                length += strlen (locale);
 
742
-        else
 
743
-                commas -= 1;
 
744
-
 
745
-        length += strlen (user) + commas + 1;
 
746
-
 
747
-        string = malloc (length);
 
748
-
 
749
-        if (locale && latin)
 
750
-                sprintf (string, "%s,%s,%s", user, locale, latin);
 
751
-        else if (locale)
 
752
-                sprintf (string, "%s,%s", user, locale);
 
753
-        else if (latin)
 
754
-                sprintf (string, "%s,%s", user, latin);
 
755
-        else
 
756
-                sprintf (string, "%s", user);
 
757
-
 
758
-        return string;
 
759
-}
 
760
-
 
761
-static gboolean
 
762
-layout_equal (const gchar *layout_a,
 
763
-              const gchar *variant_a,
 
764
-              const gchar *layout_b,
 
765
-              const gchar *variant_b)
 
766
-{
 
767
-        return !g_strcmp0 (layout_a, layout_b) && !g_strcmp0 (variant_a, variant_b);
 
768
-}
 
769
-
 
770
-static void
 
771
-replace_layout_and_variant (GsdKeyboardManager *manager,
 
772
-                            XkbRF_VarDefsRec   *xkb_var_defs,
 
773
-                            const gchar        *layout,
 
774
-                            const gchar        *variant)
 
775
-{
 
776
-        /* Toolkits need to know about both a latin layout to handle
 
777
-         * accelerators which are usually defined like Ctrl+C and a
 
778
-         * layout with the symbols for the language used in UI strings
 
779
-         * to handle mnemonics like Alt+Ф, so we try to find and add
 
780
-         * them in XKB group slots after the layout which the user
 
781
-         * actually intends to type with. */
 
782
-        const gchar *latin_layout = "us";
 
783
-        const gchar *latin_variant = "";
 
784
-        const gchar *locale_layout = NULL;
 
785
-        const gchar *locale_variant = NULL;
 
786
-        const gchar *locale;
 
787
-        gchar *language;
 
788
-
 
789
-        locale = setlocale (LC_MESSAGES, NULL);
 
790
-        /* If LANG is empty, default to en_US */
 
791
-        if (!locale)
 
792
-                language = g_strdup (DEFAULT_LANGUAGE);
 
793
-        else
 
794
-                language = language_code_from_locale (locale);
 
795
-
 
796
-        if (!language)
 
797
-                language = language_code_from_locale (DEFAULT_LANGUAGE);
 
798
-
 
799
-        gnome_xkb_info_get_layout_info_for_language (manager->priv->xkb_info,
 
800
-                                                     language,
 
801
-                                                     NULL,
 
802
-                                                     NULL,
 
803
-                                                     NULL,
 
804
-                                                     &locale_layout,
 
805
-                                                     &locale_variant);
 
806
-        g_free (language);
 
807
-
 
808
-        /* We want to minimize the number of XKB groups if we have
 
809
-         * duplicated layout+variant pairs.
 
810
-         *
 
811
-         * Also, if a layout doesn't have a variant we still have to
 
812
-         * include it in the variants string because the number of
 
813
-         * variants must agree with the number of layouts. For
 
814
-         * instance:
 
815
-         *
 
816
-         * layouts:  "us,ru,us"
 
817
-         * variants: "dvorak,,"
 
818
-         */
 
819
-        if (layout_equal (latin_layout, latin_variant, locale_layout, locale_variant) ||
 
820
-            layout_equal (latin_layout, latin_variant, layout, variant)) {
 
821
-                latin_layout = NULL;
 
822
-                latin_variant = NULL;
 
823
-        }
 
824
-
 
825
-        if (layout_equal (locale_layout, locale_variant, layout, variant)) {
 
826
-                locale_layout = NULL;
 
827
-                locale_variant = NULL;
 
828
-        }
 
829
-
 
830
-        free (xkb_var_defs->layout);
 
831
-        xkb_var_defs->layout = build_xkb_group_string (layout, locale_layout, latin_layout);
 
832
-
 
833
-        free (xkb_var_defs->variant);
 
834
-        xkb_var_defs->variant = build_xkb_group_string (variant, locale_variant, latin_variant);
 
835
-}
 
836
-
 
837
-static void
 
838
-apply_xkb_layout (GsdKeyboardManager *manager,
 
839
-                  const gchar        *layout,
 
840
-                  const gchar        *variant)
 
841
-{
 
842
-        XkbRF_RulesRec *xkb_rules;
 
843
-        XkbRF_VarDefsRec *xkb_var_defs;
 
844
-        gchar *rules_file_path;
 
845
-
 
846
-        gnome_xkb_info_get_var_defs (&rules_file_path, &xkb_var_defs);
 
847
-
 
848
-        replace_layout_and_variant (manager, xkb_var_defs, layout, variant);
 
849
-
 
850
-        gdk_error_trap_push ();
 
851
-
 
852
-        xkb_rules = XkbRF_Load (rules_file_path, NULL, True, True);
 
853
-        if (xkb_rules) {
 
854
-                XkbComponentNamesRec *xkb_comp_names;
 
855
-                xkb_comp_names = g_new0 (XkbComponentNamesRec, 1);
 
856
-
 
857
-                XkbRF_GetComponents (xkb_rules, xkb_var_defs, xkb_comp_names);
 
858
-                upload_xkb_description (rules_file_path, xkb_var_defs, xkb_comp_names);
 
859
-
 
860
-                free_xkb_component_names (xkb_comp_names);
 
861
-                XkbRF_Free (xkb_rules, True);
 
862
-        } else {
 
863
-                g_warning ("Couldn't load XKB rules");
 
864
-        }
 
865
-
 
866
-        if (gdk_error_trap_pop ())
 
867
-                g_warning ("Error loading XKB rules");
 
868
-
 
869
-        gnome_xkb_info_free_var_defs (xkb_var_defs);
 
870
-        g_free (rules_file_path);
 
871
-}
 
872
-
 
873
-static void
 
874
-apply_input_sources_settings (GSettings          *settings,
 
875
-                              gchar              *key,
 
876
-                              GsdKeyboardManager *manager)
 
877
-{
 
878
-        GsdKeyboardManagerPrivate *priv = manager->priv;
 
879
-        GVariant *sources;
 
880
-        guint current;
 
881
-        const gchar *type = NULL;
 
882
-        const gchar *id = NULL;
 
883
-        const gchar *layout = NULL;
 
884
-        const gchar *variant = NULL;
 
885
-
 
886
-        sources = g_settings_get_value (priv->input_sources_settings, KEY_INPUT_SOURCES);
 
887
-        current = g_settings_get_uint (priv->input_sources_settings, KEY_CURRENT_INPUT_SOURCE);
 
888
-
 
889
-        if (g_variant_n_children (sources) < 1) {
 
890
-                g_warning ("No input source configured, resetting");
 
891
-                g_settings_reset (priv->input_sources_settings, KEY_INPUT_SOURCES);
 
892
-                goto exit;
 
893
-        }
 
894
-        if (current >= g_variant_n_children (sources)) {
 
895
-                g_settings_set_uint (priv->input_sources_settings,
 
896
-                                     KEY_CURRENT_INPUT_SOURCE,
 
897
-                                     g_variant_n_children (sources) - 1);
 
898
-                goto exit;
 
899
-        }
 
900
-
 
901
-        g_variant_get_child (sources, current, "(&s&s)", &type, &id);
 
902
-
 
903
-        if (!g_str_equal (type, INPUT_SOURCE_TYPE_XKB)) {
 
904
-                g_warning ("Unknown input source type '%s'", type);
 
905
-                goto exit;
 
906
-        }
 
907
-
 
908
-        gnome_xkb_info_get_layout_info (priv->xkb_info, id, NULL, NULL, &layout, &variant);
 
909
-
 
910
-        if (!layout || !layout[0]) {
 
911
-                g_warning ("Couldn't find XKB input source '%s'", id);
 
912
-                goto exit;
 
913
-        }
 
914
-
 
915
-        apply_xkb_layout (manager, layout, variant);
 
916
-
 
917
- exit:
 
918
-        g_variant_unref (sources);
 
919
-}
 
920
-
 
921
-static void
 
922
 apply_settings (GSettings          *settings,
 
923
                 const char         *key,
 
924
                 GsdKeyboardManager *manager)
 
925
@@ -523,6 +645,12 @@
 
926
         gdk_error_trap_pop_ignored ();
 
927
 }
 
928
 
 
929
+void
 
930
+gsd_keyboard_manager_apply_settings (GsdKeyboardManager *manager)
 
931
+{
 
932
+        apply_settings (manager->priv->settings, NULL, manager);
 
933
+}
 
934
+
 
935
 static void
 
936
 device_added_cb (GdkDeviceManager   *device_manager,
 
937
                  GdkDevice          *device,
 
938
@@ -532,8 +660,8 @@
 
939
 
 
940
         source = gdk_device_get_source (device);
 
941
         if (source == GDK_SOURCE_KEYBOARD) {
 
942
-                apply_settings (manager->priv->settings, NULL, manager);
 
943
-                apply_input_sources_settings (manager->priv->input_sources_settings, NULL, manager);
 
944
+                apply_desktop_settings (manager);
 
945
+                apply_xkb_settings (manager);
 
946
                 run_custom_command (device, COMMAND_DEVICE_ADDED);
 
947
         }
 
948
 }
 
949
@@ -573,23 +701,23 @@
 
950
         g_debug ("Starting keyboard manager");
 
951
 
 
952
         manager->priv->settings = g_settings_new (GSD_KEYBOARD_DIR);
 
953
+       manager->priv->settings_desktop = g_settings_new (GKBD_DESKTOP_SCHEMA);
 
954
+       manager->priv->settings_keyboard = g_settings_new (GKBD_KEYBOARD_SCHEMA);
 
955
 
 
956
-       xkb_init (manager);
 
957
+       gsd_keyboard_xkb_init (manager);
 
958
+       numlock_xkb_init (manager);
 
959
 
 
960
        set_devicepresence_handler (manager);
 
961
 
 
962
-        manager->priv->input_sources_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR);
 
963
-
 
964
-        manager->priv->xkb_info = gnome_xkb_info_new ();
 
965
-
 
966
         /* apply current settings before we install the callback */
 
967
-        apply_settings (manager->priv->settings, NULL, manager);
 
968
-        apply_input_sources_settings (manager->priv->input_sources_settings, NULL, manager);
 
969
+        gsd_keyboard_manager_apply_settings (manager);
 
970
 
 
971
         g_signal_connect (G_OBJECT (manager->priv->settings), "changed",
 
972
                           G_CALLBACK (apply_settings), manager);
 
973
-        g_signal_connect (G_OBJECT (manager->priv->input_sources_settings), "changed",
 
974
-                          G_CALLBACK (apply_input_sources_settings), manager);
 
975
+       g_signal_connect (manager->priv->settings_desktop, "changed",
 
976
+                         (GCallback) desktop_settings_changed, manager);
 
977
+       g_signal_connect (manager->priv->settings_keyboard, "changed",
 
978
+                         (GCallback) xkb_settings_changed, manager);
 
979
 
 
980
        install_xkb_filter (manager);
 
981
 
 
982
@@ -625,9 +753,18 @@
 
983
 
 
984
         g_debug ("Stopping keyboard manager");
 
985
 
 
986
-        g_clear_object (&p->settings);
 
987
-        g_clear_object (&p->input_sources_settings);
 
988
-        g_clear_object (&p->xkb_info);
 
989
+        if (p->settings != NULL) {
 
990
+                g_object_unref (p->settings);
 
991
+                p->settings = NULL;
 
992
+        }
 
993
+        if (p->settings_desktop != NULL) {
 
994
+               g_object_unref (p->settings_desktop);
 
995
+               p->settings_desktop = NULL;
 
996
+       }
 
997
+       if (p->settings_keyboard != NULL) {
 
998
+               g_object_unref (p->settings_keyboard);
 
999
+               p->settings_keyboard = NULL;
 
1000
+       }
 
1001
 
 
1002
         if (p->device_manager != NULL) {
 
1003
                 g_signal_handler_disconnect (p->device_manager, p->device_added_id);
 
1004
@@ -635,7 +772,24 @@
 
1005
                 p->device_manager = NULL;
 
1006
         }
 
1007
 
 
1008
+        if (p->popup_menu != NULL) {
 
1009
+                gtk_widget_destroy (GTK_WIDGET (p->popup_menu));
 
1010
+                p->popup_menu = NULL;
 
1011
+       }
 
1012
+
 
1013
        remove_xkb_filter (manager);
 
1014
+
 
1015
+       if (p->xkl_registry != NULL) {
 
1016
+               g_object_unref (p->xkl_registry);
 
1017
+               p->xkl_registry = NULL;
 
1018
+       }
 
1019
+
 
1020
+       if (p->xkl_engine != NULL) {
 
1021
+               xkl_engine_stop_listen (p->xkl_engine,
 
1022
+                                       XKLL_MANAGE_LAYOUTS | XKLL_MANAGE_WINDOW_STATES);
 
1023
+               g_object_unref (p->xkl_engine);
 
1024
+               p->xkl_engine = NULL;
 
1025
+       }
 
1026
 }
 
1027
 
 
1028
 static void
 
1029
Index: b/plugins/keyboard/gsd-keyboard-manager.h
 
1030
===================================================================
 
1031
--- a/plugins/keyboard/gsd-keyboard-manager.h
 
1032
+++ b/plugins/keyboard/gsd-keyboard-manager.h
 
1033
@@ -51,6 +51,7 @@
 
1034
 gboolean                gsd_keyboard_manager_start               (GsdKeyboardManager *manager,
 
1035
                                                                GError         **error);
 
1036
 void                    gsd_keyboard_manager_stop                (GsdKeyboardManager *manager);
 
1037
+void                    gsd_keyboard_manager_apply_settings      (GsdKeyboardManager *manager);
 
1038
 
 
1039
 G_END_DECLS
 
1040
 
 
1041
Index: b/plugins/keyboard/Makefile.am
 
1042
===================================================================
 
1043
--- a/plugins/keyboard/Makefile.am
 
1044
+++ b/plugins/keyboard/Makefile.am
 
1045
@@ -20,6 +20,8 @@
 
1046
        gsd-keyboard-plugin.c   \
 
1047
        gsd-keyboard-manager.h  \
 
1048
        gsd-keyboard-manager.c  \
 
1049
+       delayed-dialog.h        \
 
1050
+       delayed-dialog.c        \
 
1051
        $(NULL)
 
1052
 
 
1053
 libkeyboard_la_CPPFLAGS = \
 
1054
@@ -52,8 +54,8 @@
 
1055
        test-keyboard.c         \
 
1056
        gsd-keyboard-manager.h  \
 
1057
        gsd-keyboard-manager.c  \
 
1058
-       $(NULL)
 
1059
-
 
1060
+       delayed-dialog.h        \
 
1061
+       delayed-dialog.c
 
1062
 test_keyboard_CFLAGS = $(libkeyboard_la_CFLAGS)
 
1063
 test_keyboard_CPPFLAGS = $(libkeyboard_la_CPPFLAGS)
 
1064
 test_keyboard_LDADD = $(libkeyboard_la_LIBADD) $(top_builddir)/gnome-settings-daemon/libgsd.la