diff options
author | Tobias Geerinckx-Rice <tobias.geerinckx.rice@gmail.com> | 2016-01-14 14:50:51 +0100 |
---|---|---|
committer | Tobias Geerinckx-Rice <tobias.geerinckx.rice@gmail.com> | 2016-01-14 23:55:47 +0100 |
commit | ad80ae008a5ad4ff4b569eabba6608aca7acacb4 (patch) | |
tree | b169363bfc867b3056a89a387ba2e9024c8680a3 | |
parent | 07f07f2d300e2a80c68b030a58692c2543c23646 (diff) | |
download | nixlib-ad80ae008a5ad4ff4b569eabba6608aca7acacb4.tar nixlib-ad80ae008a5ad4ff4b569eabba6608aca7acacb4.tar.gz nixlib-ad80ae008a5ad4ff4b569eabba6608aca7acacb4.tar.bz2 nixlib-ad80ae008a5ad4ff4b569eabba6608aca7acacb4.tar.lz nixlib-ad80ae008a5ad4ff4b569eabba6608aca7acacb4.tar.xz nixlib-ad80ae008a5ad4ff4b569eabba6608aca7acacb4.tar.zst nixlib-ad80ae008a5ad4ff4b569eabba6608aca7acacb4.zip |
cinnamon: remove dead packages
Broken since April 2014. Never more than a handful of basic framework packages, had most of its work ahead of it. Almost immediately abandoned, and the maintainer vanished. Close #2132.
-rw-r--r-- | pkgs/desktops/cinnamon/automount-plugin.patch | 448 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/cinnamon-control-center.nix | 41 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/cinnamon-desktop.nix | 42 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/cinnamon-session.nix | 49 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/cinnamon-settings-daemon.nix | 53 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/cinnamon-translations.nix | 28 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/cjs.nix | 42 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/dpms.patch | 30 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/gtkdoc.patch | 41 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/keyboard.patch | 4729 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/muffin.nix | 47 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/region.patch | 5314 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/remove-sessionmigration.patch | 19 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/systemd-support.patch | 536 | ||||
-rw-r--r-- | pkgs/desktops/cinnamon/timeout.patch | 26 | ||||
-rw-r--r-- | pkgs/top-level/all-packages.nix | 19 |
16 files changed, 0 insertions, 11464 deletions
diff --git a/pkgs/desktops/cinnamon/automount-plugin.patch b/pkgs/desktops/cinnamon/automount-plugin.patch deleted file mode 100644 index 3d90da99f088..000000000000 --- a/pkgs/desktops/cinnamon/automount-plugin.patch +++ /dev/null @@ -1,448 +0,0 @@ - -diff -Naur cinnamon-settings-daemon-2.0.1.orig/data/org.cinnamon.settings-daemon.plugins.gschema.xml.in.in cinnamon-settings-daemon-2.0.1/data/org.cinnamon.settings-daemon.plugins.gschema.xml.in.in ---- cinnamon-settings-daemon-2.0.6.orig/data/org.cinnamon.settings-daemon.plugins.gschema.xml.in.in 2013-11-03 10:50:04.000000000 -0500 -+++ cinnamon-settings-daemon-2.0.6/data/org.cinnamon.settings-daemon.plugins.gschema.xml.in.in 2013-11-05 15:33:21.112912392 -0500 -@@ -2,6 +2,7 @@ - <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.cinnamon.settings-daemon.plugins" path="/org/cinnamon/settings-daemon/plugins/"> - <child name="a11y-keyboard" schema="org.cinnamon.settings-daemon.plugins.a11y-keyboard"/> - <child name="a11y-settings" schema="org.cinnamon.settings-daemon.plugins.a11y-settings"/> -+ <child name="automount" schema="org.cinnamon.settings-daemon.plugins.automount"/> - <child name="clipboard" schema="org.cinnamon.settings-daemon.plugins.clipboard"/> - <child name="color" schema="org.cinnamon.settings-daemon.plugins.color"/> - <child name="cursor" schema="org.cinnamon.settings-daemon.plugins.cursor"/> -@@ -42,6 +43,18 @@ - <_summary>Priority to use for this plugin</_summary> - <_description>Priority to use for this plugin in cinnamon-settings-daemon startup queue</_description> - </key> -+ </schema> -+ <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.cinnamon.settings-daemon.plugins.automount" path="/org/cinnamon/settings-daemon/plugins/automount/"> -+ <key name="active" type="b"> -+ <default>true</default> -+ <_summary>Activation of this plugin</_summary> -+ <_description>Whether this plugin would be activated by cinnamon-settings-daemon or not</_description> -+ </key> -+ <key name="priority" type="i"> -+ <default>97</default> -+ <_summary>Priority to use for this plugin</_summary> -+ <_description>Priority to use for this plugin in cinnamon-settings-daemon startup queue</_description> -+ </key> - </schema> - <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.cinnamon.settings-daemon.plugins.clipboard" path="/org/cinnamon/settings-daemon/plugins/clipboard/"> - <key name="active" type="b"> -diff -Naur cinnamon-settings-daemon-2.0.1.orig/plugins/automount/automount.cinnamon-settings-plugin.in cinnamon-settings-daemon-2.0.1/plugins/automount/automount.cinnamon-settings-plugin.in ---- cinnamon-settings-daemon-2.0.1.orig/plugins/automount/automount.cinnamon-settings-plugin.in 1970-01-01 01:00:00.000000000 +0100 -+++ cinnamon-settings-daemon-2.0.1/plugins/automount/automount.cinnamon-settings-plugin.in 2013-10-08 22:35:10.771472456 +0200 -@@ -0,0 +1,8 @@ -+[Cinnamon Settings Plugin] -+Module=automount -+IAge=0 -+_Name=Automount -+_Description=Automounter plugin -+Authors=Tomas Bzatek -+Copyright=Copyright © 2010 Red Hat, Inc. -+Website= -diff -Naur cinnamon-settings-daemon-2.0.1.orig/plugins/automount/cinnamon-fallback-mount-helper.c cinnamon-settings-daemon-2.0.1/plugins/automount/cinnamon-fallback-mount-helper.c ---- cinnamon-settings-daemon-2.0.1.orig/plugins/automount/cinnamon-fallback-mount-helper.c 2013-10-02 16:13:56.000000000 +0200 -+++ cinnamon-settings-daemon-2.0.1/plugins/automount/cinnamon-fallback-mount-helper.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,65 +0,0 @@ --/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- -- * -- * Copyright (C) 2010 Red Hat, Inc. -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA -- * -- * Author: Tomas Bzatek <tbzatek@redhat.com> -- */ -- --#include "config.h" -- --#include <glib.h> --#include <glib/gi18n.h> --#include <unistd.h> --#include <gtk/gtk.h> -- --#include "csd-automount-manager.h" -- --int --main (int argc, -- char **argv) --{ -- GMainLoop *loop; -- CsdAutomountManager *manager; -- GError *error = NULL; -- -- g_type_init (); -- gtk_init (&argc, &argv); -- -- bindtextdomain (GETTEXT_PACKAGE, CINNAMON_SETTINGS_LOCALEDIR); -- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); -- textdomain (GETTEXT_PACKAGE); -- -- loop = g_main_loop_new (NULL, FALSE); -- manager = csd_automount_manager_new (); -- -- csd_automount_manager_start (manager, &error); -- -- if (error != NULL) { -- g_printerr ("Unable to start the mount manager: %s", -- error->message); -- -- g_error_free (error); -- _exit (1); -- } -- -- g_main_loop_run (loop); -- -- csd_automount_manager_stop (manager); -- g_main_loop_unref (loop); -- -- return 0; --} -diff -Naur cinnamon-settings-daemon-2.0.1.orig/plugins/automount/cinnamon-fallback-mount-helper.desktop.in.in cinnamon-settings-daemon-2.0.1/plugins/automount/cinnamon-fallback-mount-helper.desktop.in.in ---- cinnamon-settings-daemon-2.0.1.orig/plugins/automount/cinnamon-fallback-mount-helper.desktop.in.in 2013-10-02 16:13:56.000000000 +0200 -+++ cinnamon-settings-daemon-2.0.1/plugins/automount/cinnamon-fallback-mount-helper.desktop.in.in 1970-01-01 01:00:00.000000000 +0100 -@@ -1,12 +0,0 @@ --[Desktop Entry] --_Name=Mount Helper --_Comment=Automount and autorun plugged devices --Exec=@LIBEXECDIR@/cinnamon-fallback-mount-helper --Icon=drive-optical --Terminal=false --Type=Application --Categories= --NoDisplay=true --OnlyShowIn=GNOME; --X-GNOME-Autostart-Notify=true -- -diff -Naur cinnamon-settings-daemon-2.0.1.orig/plugins/automount/csd-automount-plugin.c cinnamon-settings-daemon-2.0.1/plugins/automount/csd-automount-plugin.c ---- cinnamon-settings-daemon-2.0.1.orig/plugins/automount/csd-automount-plugin.c 1970-01-01 01:00:00.000000000 +0100 -+++ cinnamon-settings-daemon-2.0.1/plugins/automount/csd-automount-plugin.c 2013-10-08 22:35:10.771472456 +0200 -@@ -0,0 +1,106 @@ -+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- -+ * -+ * Copyright (C) 2010 Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Author: Tomas Bzatek <tbzatek@redhat.com> -+ */ -+ -+#include "config.h" -+ -+#include <glib/gi18n-lib.h> -+#include <gmodule.h> -+ -+#include "cinnamon-settings-plugin.h" -+#include "csd-automount-plugin.h" -+#include "csd-automount-manager.h" -+ -+struct CsdAutomountPluginPrivate { -+ CsdAutomountManager *manager; -+}; -+ -+#define CSD_AUTOMOUNT_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), CSD_TYPE_AUTOMOUNT_PLUGIN, CsdAutomountPluginPrivate)) -+ -+CINNAMON_SETTINGS_PLUGIN_REGISTER (CsdAutomountPlugin, csd_automount_plugin) -+ -+static void -+csd_automount_plugin_init (CsdAutomountPlugin *plugin) -+{ -+ plugin->priv = CSD_AUTOMOUNT_PLUGIN_GET_PRIVATE (plugin); -+ -+ g_debug ("Automount plugin initializing"); -+ -+ plugin->priv->manager = csd_automount_manager_new (); -+} -+ -+static void -+csd_automount_plugin_finalize (GObject *object) -+{ -+ CsdAutomountPlugin *plugin; -+ -+ g_return_if_fail (object != NULL); -+ g_return_if_fail (CSD_IS_AUTOMOUNT_PLUGIN (object)); -+ -+ g_debug ("Automount plugin finalizing"); -+ -+ plugin = CSD_AUTOMOUNT_PLUGIN (object); -+ -+ g_return_if_fail (plugin->priv != NULL); -+ -+ if (plugin->priv->manager != NULL) { -+ g_object_unref (plugin->priv->manager); -+ } -+ -+ G_OBJECT_CLASS (csd_automount_plugin_parent_class)->finalize (object); -+} -+ -+static void -+impl_activate (CinnamonSettingsPlugin *plugin) -+{ -+ gboolean res; -+ GError *error; -+ -+ g_debug ("Activating automount plugin"); -+ -+ error = NULL; -+ res = csd_automount_manager_start (CSD_AUTOMOUNT_PLUGIN (plugin)->priv->manager, &error); -+ if (! res) { -+ g_warning ("Unable to start automount manager: %s", error->message); -+ g_error_free (error); -+ } -+} -+ -+static void -+impl_deactivate (CinnamonSettingsPlugin *plugin) -+{ -+ g_debug ("Deactivating automount plugin"); -+ csd_automount_manager_stop (CSD_AUTOMOUNT_PLUGIN (plugin)->priv->manager); -+} -+ -+static void -+csd_automount_plugin_class_init (CsdAutomountPluginClass *klass) -+{ -+ GObjectClass *object_class = G_OBJECT_CLASS (klass); -+ CinnamonSettingsPluginClass *plugin_class = CINNAMON_SETTINGS_PLUGIN_CLASS (klass); -+ -+ object_class->finalize = csd_automount_plugin_finalize; -+ -+ plugin_class->activate = impl_activate; -+ plugin_class->deactivate = impl_deactivate; -+ -+ g_type_class_add_private (klass, sizeof (CsdAutomountPluginPrivate)); -+} -+ -diff -Naur cinnamon-settings-daemon-2.0.1.orig/plugins/automount/csd-automount-plugin.h cinnamon-settings-daemon-2.0.1/plugins/automount/csd-automount-plugin.h ---- cinnamon-settings-daemon-2.0.1.orig/plugins/automount/csd-automount-plugin.h 1970-01-01 01:00:00.000000000 +0100 -+++ cinnamon-settings-daemon-2.0.1/plugins/automount/csd-automount-plugin.h 2013-10-08 22:35:10.771472456 +0200 -@@ -0,0 +1,60 @@ -+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- -+ * -+ * Copyright (C) 2010 Red Hat, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Author: Tomas Bzatek <tbzatek@redhat.com> -+ */ -+ -+#ifndef __CSD_AUTOMOUNT_PLUGIN_H__ -+#define __CSD_AUTOMOUNT_PLUGIN_H__ -+ -+#include <glib.h> -+#include <glib-object.h> -+#include <gmodule.h> -+ -+#include "cinnamon-settings-plugin.h" -+ -+G_BEGIN_DECLS -+ -+#define CSD_TYPE_AUTOMOUNT_PLUGIN (csd_automount_plugin_get_type ()) -+#define CSD_AUTOMOUNT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_AUTOMOUNT_PLUGIN, CsdAutomountPlugin)) -+#define CSD_AUTOMOUNT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_AUTOMOUNT_PLUGIN, CsdAutomountPluginClass)) -+#define CSD_IS_AUTOMOUNT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_AUTOMOUNT_PLUGIN)) -+#define CSD_IS_AUTOMOUNT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_AUTOMOUNT_PLUGIN)) -+#define CSD_AUTOMOUNT_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_AUTOMOUNT_PLUGIN, CsdAutomountPluginClass)) -+ -+typedef struct CsdAutomountPluginPrivate CsdAutomountPluginPrivate; -+ -+typedef struct -+{ -+ CinnamonSettingsPlugin parent; -+ CsdAutomountPluginPrivate *priv; -+} CsdAutomountPlugin; -+ -+typedef struct -+{ -+ CinnamonSettingsPluginClass parent_class; -+} CsdAutomountPluginClass; -+ -+GType csd_automount_plugin_get_type (void) G_GNUC_CONST; -+ -+/* All the plugins must implement this function */ -+G_MODULE_EXPORT GType register_cinnamon_settings_plugin (GTypeModule *module); -+ -+G_END_DECLS -+ -+#endif /* __CSD_AUTOMOUNT_PLUGIN_H__ */ -diff -Naur cinnamon-settings-daemon-2.0.1.orig/plugins/automount/Makefile.am cinnamon-settings-daemon-2.0.1/plugins/automount/Makefile.am ---- cinnamon-settings-daemon-2.0.1.orig/plugins/automount/Makefile.am 2013-10-02 16:13:56.000000000 +0200 -+++ cinnamon-settings-daemon-2.0.1/plugins/automount/Makefile.am 2013-10-08 22:48:19.240865461 +0200 -@@ -1,38 +1,87 @@ --libexec_PROGRAMS = cinnamon-fallback-mount-helper -+NULL = - --cinnamon_fallback_mount_helper_SOURCES = \ -- cinnamon-fallback-mount-helper.c \ -- csd-automount-manager.c \ -- csd-automount-manager.h \ -- csd-autorun.c \ -- csd-autorun.h -+plugin_name = automount - --cinnamon_fallback_mount_helper_CPPFLAGS = \ -+libexec_PROGRAMS = csd-test-automount -+ -+csd_test_automount_SOURCES = \ -+ test-automount.c \ -+ csd-automount-manager.h \ -+ csd-automount-manager.c \ -+ csd-autorun.c \ -+ csd-autorun.h \ -+ $(NULL) -+ -+csd_test_automount_CPPFLAGS = \ - -I$(top_srcdir)/cinnamon-settings-daemon \ -+ -I$(top_srcdir)/plugins/common \ - -DCINNAMON_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ - $(AM_CPPFLAGS) - --cinnamon_fallback_mount_helper_CFLAGS = \ -+csd_test_automount_CFLAGS = \ -+ $(PLUGIN_CFLAGS) \ - $(SETTINGS_PLUGIN_CFLAGS) \ - $(SYSTEMD_CFLAGS) \ - $(AUTOMOUNT_CFLAGS) -+ $(AM_CFLAGS) -+ -+csd_test_automount_LDADD = \ -+ $(top_builddir)/cinnamon-settings-daemon/libcsd.la \ -+ $(SETTINGS_PLUGIN_LIBS) \ -+ $(SYSTEMD_LIBS) \ -+ $(AUTOMOUNT_LIBS) \ -+ $(NULL) -+ -+plugin_LTLIBRARIES = \ -+ libautomount.la \ -+ $(NULL) -+ -+libautomount_la_SOURCES = \ -+ csd-automount-plugin.h \ -+ csd-automount-plugin.c \ -+ csd-automount-manager.h \ -+ csd-automount-manager.c \ -+ csd-autorun.c \ -+ csd-autorun.h \ -+ $(NULL) -+ -+libautomount_la_CPPFLAGS = \ -+ -I$(top_srcdir)/cinnamon-settings-daemon \ -+ -DCINNAMON_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ -+ $(AM_CPPFLAGS) -+ -+libautomount_la_CFLAGS = \ -+ $(SETTINGS_PLUGIN_CFLAGS) \ -+ $(SYSTEMD_CFLAGS) \ -+ $(AUTOMOUNT_CFLAGS) \ -+ $(AM_CFLAGS) -+ -+libautomount_la_LDFLAGS = \ -+ $(CSD_PLUGIN_LDFLAGS) \ -+ $(NULL) - --cinnamon_fallback_mount_helper_LDADD = \ -+libautomount_la_LIBADD = \ - $(SETTINGS_PLUGIN_LIBS) \ - $(SYSTEMD_LIBS) \ - $(AUTOMOUNT_LIBS) \ -- $(top_builddir)/cinnamon-settings-daemon/libcsd.la -+ $(NULL) - --autostartdir = $(datadir)/applications --autostart_in_files = cinnamon-fallback-mount-helper.desktop.in --autostart_in_in_files = cinnamon-fallback-mount-helper.desktop.in.in --autostart_DATA = $(autostart_in_files:.desktop.in=.desktop) -+plugin_in_files = \ -+ automount.cinnamon-settings-plugin.in \ -+ $(NULL) - --$(autostart_in_files): $(autostart_in_in_files) -- @sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@ -+plugin_DATA = $(plugin_in_files:.cinnamon-settings-plugin.in=.cinnamon-settings-plugin) - --@INTLTOOL_DESKTOP_RULE@ -+EXTRA_DIST = \ -+ $(plugin_in_files) \ -+ $(NULL) - --EXTRA_DIST = $(autostart_in_in_files) -+CLEANFILES = \ -+ $(plugin_DATA) \ -+ $(NULL) - --CLEANFILES = $(autostart_DATA) $(autostart_in_files) -+DISTCLEANFILES = \ -+ $(plugin_DATA) \ -+ $(NULL) -+ -+@CSD_INTLTOOL_PLUGIN_RULE@ -diff -Naur cinnamon-settings-daemon-2.0.1.orig/plugins/automount/test-automount.c cinnamon-settings-daemon-2.0.1/plugins/automount/test-automount.c ---- cinnamon-settings-daemon-2.0.1.orig/plugins/automount/test-automount.c 1970-01-01 01:00:00.000000000 +0100 -+++ cinnamon-settings-daemon-2.0.1/plugins/automount/test-automount.c 2013-10-08 22:42:53.759486525 +0200 -@@ -0,0 +1,7 @@ -+#define NEW csd_automount_manager_new -+#define START csd_automount_manager_start -+#define STOP csd_automount_manager_stop -+#define MANAGER CsdAutomountManager -+#include "csd-automount-manager.h" -+ -+#include "test-plugin.h" -diff -Naur cinnamon-settings-daemon-2.0.1.orig/po/POTFILES.in cinnamon-settings-daemon-2.0.1/po/POTFILES.in ---- cinnamon-settings-daemon-2.0.1.orig/po/POTFILES.in 2013-10-02 16:13:56.000000000 +0200 -+++ cinnamon-settings-daemon-2.0.1/po/POTFILES.in 2013-10-08 22:35:10.771472456 +0200 -@@ -18,8 +18,9 @@ - plugins/a11y-keyboard/csd-a11y-preferences-dialog.c - [type: gettext/glade]plugins/a11y-keyboard/csd-a11y-preferences-dialog.ui - [type: gettext/ini]plugins/a11y-settings/a11y-settings.cinnamon-settings-plugin.in --plugins/automount/cinnamon-fallback-mount-helper.desktop.in.in -+[type: gettext/ini]plugins/automount/automount.cinnamon-settings-plugin.in - plugins/automount/csd-automount-manager.c -+plugins/automount/csd-automount-plugin.c - plugins/automount/csd-autorun.c - [type: gettext/ini]plugins/background/background.cinnamon-settings-plugin.in - [type: gettext/ini]plugins/clipboard/clipboard.cinnamon-settings-plugin.in -diff -Naur cinnamon-settings-daemon-2.0.1.orig/po/POTFILES.skip cinnamon-settings-daemon-2.0.1/po/POTFILES.skip ---- cinnamon-settings-daemon-2.0.1.orig/po/POTFILES.skip 2013-10-02 16:13:56.000000000 +0200 -+++ cinnamon-settings-daemon-2.0.1/po/POTFILES.skip 2013-10-08 22:37:20.224645009 +0200 -@@ -20,6 +20,5 @@ - data/org.cinnamon.settings-daemon.plugins.updates.gschema.xml.in - data/org.cinnamon.settings-daemon.plugins.xrandr.gschema.xml.in - data/org.cinnamon.settings-daemon.plugins.xsettings.gschema.xml.in --plugins/automount/gnome-fallback-mount-helper.desktop.in - plugins/power/org.cinnamon.settings-daemon.plugins.power.policy.in - plugins/wacom/org.cinnamon.settings-daemon.plugins.wacom.policy.in diff --git a/pkgs/desktops/cinnamon/cinnamon-control-center.nix b/pkgs/desktops/cinnamon/cinnamon-control-center.nix deleted file mode 100644 index 97489a7ec087..000000000000 --- a/pkgs/desktops/cinnamon/cinnamon-control-center.nix +++ /dev/null @@ -1,41 +0,0 @@ - -{ stdenv, fetchurl, pkgconfig, autoreconfHook, glib, gettext, gnome_common, cinnamon-desktop, intltool, libxslt, gtk3, libnotify, -gnome-menus, libxml2, systemd, upower, cinnamon-settings-daemon, colord, polkit, ibus, libcanberra_gtk3, libpulseaudio, isocodes, kerberos, -libxkbfile}: - -let - version = "2.0.9"; -in -stdenv.mkDerivation { - name = "cinnamon-control-center-${version}"; - - src = fetchurl { - url = "http://github.com/linuxmint/cinnamon-control-center/archive/${version}.tar.gz"; - sha256 = "0kivqdgsf8w257j2ja6fap0dpvljcnb9gphr3knp7y6ma2d1gfv3"; - }; - - configureFlags = "--enable-systemd --disable-update-mimedb" ; - - patches = [ ./region.patch]; - - buildInputs = [ - pkgconfig autoreconfHook - glib gettext gnome_common - intltool libxslt gtk3 cinnamon-desktop - libnotify gnome-menus libxml2 systemd - upower cinnamon-settings-daemon colord - polkit ibus libcanberra_gtk3 libpulseaudio - isocodes kerberos libxkbfile ]; - - preBuild = "patchShebangs ./scripts"; - - meta = { - homepage = "http://cinnamon.linuxmint.com"; - description = "The cinnamon session files" ; - - platforms = stdenv.lib.platforms.linux; - maintainers = [ stdenv.lib.maintainers.roelof ]; - - broken = true; - }; -} diff --git a/pkgs/desktops/cinnamon/cinnamon-desktop.nix b/pkgs/desktops/cinnamon/cinnamon-desktop.nix deleted file mode 100644 index 8ead149fc2b1..000000000000 --- a/pkgs/desktops/cinnamon/cinnamon-desktop.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ stdenv, fetchurl, pkgconfig, autoreconfHook, intltool -, glib, gobjectIntrospection, gdk_pixbuf, gtk3, gnome_common -, xorg, xkeyboard_config -}: - -let - version = "2.0.4"; -in -stdenv.mkDerivation { - name = "cinnamon-desktop-${version}"; - - src = fetchurl { - url = "http://github.com/linuxmint/cinnamon-desktop/archive/${version}.tar.gz"; - sha256 = "1cywin712558pv58c0cr73m25hfcv5x8pv5frvqjr9gwr2gpi6h3"; - }; - - NIX_CFLAGS_COMPILE = "-I${glib}/include/gio-unix-2.0"; - - buildInputs = with xorg; [ - pkgconfig autoreconfHook intltool - glib gobjectIntrospection gdk_pixbuf gtk3 gnome_common - xkeyboard_config libxkbfile libX11 libXrandr libXext - ]; - - meta = { - homepage = "http://cinnamon.linuxmint.com"; - description = "Library and data for various Cinnamon modules"; - - longDescription = '' - The libcinnamon-desktop library provides API shared by several applications - on the desktop, but that cannot live in the platform for various - reasons. There is no API or ABI guarantee, although we are doing our - best to provide stability. Documentation for the API is available with - gtk-doc. - ''; - - platforms = stdenv.lib.platforms.linux; - maintainers = [ stdenv.lib.maintainers.roelof ]; - - broken = true; - }; -} diff --git a/pkgs/desktops/cinnamon/cinnamon-session.nix b/pkgs/desktops/cinnamon/cinnamon-session.nix deleted file mode 100644 index d84438b7bd14..000000000000 --- a/pkgs/desktops/cinnamon/cinnamon-session.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ stdenv, fetchurl, pkgconfig, autoreconfHook, glib, gettext, gnome_common, gtk3, dbus_glib -, upower, json_glib,intltool, systemd, hicolor_icon_theme, xorg, makeWrapper, cinnamon-desktop }: - -let - version = "2.0.6"; -in -stdenv.mkDerivation { - name = "cinnamon-session-${version}"; - - src = fetchurl { - url = "http://github.com/linuxmint/cinnamon-session/archive/${version}.tar.gz"; - sha256 = "0rs5w7npj3wf3gkk3sfb83awks2h7vjd6cz8mvfgbh6m3grn66l3"; - }; - - - configureFlags = "--enable-systemd --disable-gconf" ; - - patches = [ ./remove-sessionmigration.patch ./timeout.patch]; - - buildInputs = [ - pkgconfig autoreconfHook - glib gettext gnome_common - gtk3 dbus_glib upower json_glib - intltool systemd xorg.xtrans - makeWrapper - cinnamon-desktop /*gschemas*/ - ]; - - preBuild = "patchShebangs ./scripts"; - - - postFixup = '' - rm $out/share/icons/hicolor/icon-theme.cache - - for f in "$out/bin/"*; do - wrapProgram "$f" --prefix XDG_DATA_DIRS : "$GSETTINGS_SCHEMAS_PATH" - done - ''; - - meta = { - homepage = "http://cinnamon.linuxmint.com"; - description = "The cinnamon session files" ; - - platforms = stdenv.lib.platforms.linux; - maintainers = [ stdenv.lib.maintainers.roelof ]; - - broken = true; - }; -} diff --git a/pkgs/desktops/cinnamon/cinnamon-settings-daemon.nix b/pkgs/desktops/cinnamon/cinnamon-settings-daemon.nix deleted file mode 100644 index 550a7acaf62e..000000000000 --- a/pkgs/desktops/cinnamon/cinnamon-settings-daemon.nix +++ /dev/null @@ -1,53 +0,0 @@ - -{ stdenv, fetchurl, pkgconfig, autoreconfHook, glib, gettext, gnome_common, cinnamon-desktop, intltool, gtk3, -libnotify, lcms2, libxklavier, libgnomekbd, libcanberra, libpulseaudio, upower, libcanberra_gtk3, colord, -systemd, libxslt, docbook_xsl, makeWrapper, gsettings_desktop_schemas}: - -let - version = "2.0.10"; -in -stdenv.mkDerivation { - name = "cinnamon-settings-daemon-${version}"; - - src = fetchurl { - url = "http://github.com/linuxmint/cinnamon-settings-daemon/archive/${version}.tar.gz"; - sha256 = "10r75xsngb7ipv9fy07dyfb256bqybzcxbwny60sgjhrksk3v9mg"; - }; - - NIX_CFLAGS_COMPILE = "-I${glib}/include/gio-unix-2.0"; - - configureFlags = "--enable-systemd" ; - - patches = [ ./systemd-support.patch ./automount-plugin.patch ./dpms.patch]; - - buildInputs = [ - pkgconfig autoreconfHook - glib gettext gnome_common - intltool gtk3 libnotify lcms2 - libgnomekbd libxklavier colord - libcanberra libpulseaudio upower - libcanberra_gtk3 cinnamon-desktop - systemd libxslt docbook_xsl makeWrapper - gsettings_desktop_schemas - ]; - - preBuild = "patchShebangs ./scripts"; - - #ToDo: missing org.cinnamon.gschema.xml, probably not packaged yet - postFixup = '' - for f in "$out/libexec/"*; do - wrapProgram "$f" --prefix XDG_DATA_DIRS : "$GSETTINGS_SCHEMAS_PATH" - done - ''; - - - meta = { - homepage = "http://cinnamon.linuxmint.com"; - description = "The cinnamon session files" ; - - platforms = stdenv.lib.platforms.linux; - maintainers = [ stdenv.lib.maintainers.roelof ]; - - broken = true; - }; -} diff --git a/pkgs/desktops/cinnamon/cinnamon-translations.nix b/pkgs/desktops/cinnamon/cinnamon-translations.nix deleted file mode 100644 index 91a7acdef82b..000000000000 --- a/pkgs/desktops/cinnamon/cinnamon-translations.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ stdenv, fetchurl }: -let - version = "2.0.3"; -in -stdenv.mkDerivation { - name = "cinnamon-translations-${version}"; - - src = fetchurl { - url = "http://github.com/linuxmint/cinnamon-translations/archive/${version}.tar.gz"; - sha256 = "07w3v118xrfp8r4dkbdiyd1vr9ah7f3bm2zw9wag9s8l8x0zfxgc"; - }; - - installPhase = - '' - mkdir -pv $out/share/cinnamon/locale - cp -av "mo-export/"* $out/share/cinnamon/locale/ - ''; - - meta = { - homepage = "http://cinnamon.linuxmint.com"; - description = "Translations files for the Cinnamon desktop" ; - - platforms = stdenv.lib.platforms.linux; - maintainers = [ stdenv.lib.maintainers.roelof ]; - - broken = true; - }; -} diff --git a/pkgs/desktops/cinnamon/cjs.nix b/pkgs/desktops/cinnamon/cjs.nix deleted file mode 100644 index 5d5847615653..000000000000 --- a/pkgs/desktops/cinnamon/cjs.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ stdenv, fetchurl, pkgconfig, autoreconfHook, python -, dbus_glib, cairo, spidermonkey_185, gobjectIntrospection -}: - -let - version="2.0.0"; -in -stdenv.mkDerivation rec { - name = "cjs-${version}"; - - src = fetchurl { - url = "http://github.com/linuxmint/cjs/archive/${version}.tar.gz"; - sha256 = "16iazd5h2z27v9jxs4a8imwls5c1c690wk7i05r5ds3c3r4nrsig"; - }; - - buildInputs = [ - pkgconfig autoreconfHook python - dbus_glib cairo spidermonkey_185 - gobjectIntrospection - ]; - - preBuild = "patchShebangs ./scripts"; - - meta = { - homepage = "http://cinnamon.linuxmint.com"; - description = "JavaScript bindings for Cinnamon" ; - - longDescription = '' - This module contains JavaScript bindings based on gobject-introspection. - - Because JavaScript is pretty free-form, consistent coding style and unit tests - are critical to give it some structure and keep it readable. - We propose that all GNOME usage of JavaScript conform to the style guide - in doc/Style_Guide.txt to help keep things sane. - ''; - - platforms = stdenv.lib.platforms.linux; - maintainers = [ stdenv.lib.maintainers.roelof ]; - - broken = true; - }; -} diff --git a/pkgs/desktops/cinnamon/dpms.patch b/pkgs/desktops/cinnamon/dpms.patch deleted file mode 100644 index a73f33dc6182..000000000000 --- a/pkgs/desktops/cinnamon/dpms.patch +++ /dev/null @@ -1,30 +0,0 @@ - --- a/plugins/power/csd-power-manager.c -+++ b/plugins/power/csd-power-manager.c -@@ -33,6 +33,8 @@ - #include <libnotify/notify.h> - #include <canberra-gtk.h> - -+#include <X11/extensions/dpms.h> -+ - #define GNOME_DESKTOP_USE_UNSTABLE_API - #include <libcinnamon-desktop/gnome-rr.h> - -@@ -3967,6 +3790,17 @@ csd_power_manager_start (CsdPowerManager - /* set the initial dim time that can adapt for the user */ - refresh_idle_dim_settings (manager); - -+ /* Make sure that Xorg's DPMS extension never gets in our way. The defaults seem to have changed in Xorg 1.14 -+ * being "0" by default to being "600" by default -+ * https://bugzilla.gnome.org/show_bug.cgi?id=709114 -+ */ -+ gdk_error_trap_push (); -+ int dummy; -+ if (DPMSQueryExtension(GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &dummy, &dummy)) { -+ DPMSSetTimeouts (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), 0, 0, 0); -+ } -+ gdk_error_trap_pop_ignored (); -+ - manager->priv->xscreensaver_watchdog_timer_id = g_timeout_add_seconds (XSCREENSAVER_WATCHDOG_TIMEOUT, - disable_builtin_screensaver, - NULL); diff --git a/pkgs/desktops/cinnamon/gtkdoc.patch b/pkgs/desktops/cinnamon/gtkdoc.patch deleted file mode 100644 index 6398306a76ae..000000000000 --- a/pkgs/desktops/cinnamon/gtkdoc.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- a/src/meta/prefs.h -+++ b/src/meta/prefs.h -@@ -310,13 +310,13 @@ typedef struct - */ - GSList *bindings; - -- /** for keybindings that can have shift or not like Alt+Tab */ -+ /* for keybindings that can have shift or not like Alt+Tab */ - gboolean add_shift:1; - -- /** for keybindings that apply only to a window */ -+ /* for keybindings that apply only to a window */ - gboolean per_window:1; - -- /** for keybindings not added with meta_display_add_keybinding() */ -+ /* for keybindings not added with meta_display_add_keybinding() */ - gboolean builtin:1; - } MetaKeyPref; - -@@ -339,5 +339,3 @@ CDesktopVisualBellType meta_prefs_get_vi - MetaPlacementMode meta_prefs_get_placement_mode (void); - - #endif -- -- ---- a/src/core/workspace.c -+++ b/src/core/workspace.c -@@ -194,7 +194,7 @@ meta_workspace_new (MetaScreen *screen) - return workspace; - } - --/** Foreach function for workspace_free_struts() */ -+/* Foreach function for workspace_free_struts() */ - static void - free_this (gpointer candidate, gpointer dummy) - { -@@ -1390,4 +1390,3 @@ meta_workspace_get_screen (MetaWorkspace - { - return workspace->screen; - } -- diff --git a/pkgs/desktops/cinnamon/keyboard.patch b/pkgs/desktops/cinnamon/keyboard.patch deleted file mode 100644 index f67d961ff58f..000000000000 --- a/pkgs/desktops/cinnamon/keyboard.patch +++ /dev/null @@ -1,4729 +0,0 @@ - -diff -uNrp a/cinnamon-settings-daemon/main.c b/cinnamon-settings-daemon/main.c ---- a/cinnamon-settings-daemon/main.c 2013-08-24 18:04:31.000000000 +0100 -+++ b/cinnamon-settings-daemon/main.c 2013-08-25 16:36:02.000000000 +0100 -@@ -319,6 +319,29 @@ set_legacy_ibus_env_vars (GDBusProxy *pr - } - #endif - -+static void -+got_session_proxy (GObject *source_object, -+ GAsyncResult *res, -+ gpointer user_data) -+{ -+ GDBusProxy *proxy; -+ GError *error = NULL; -+ -+ proxy = g_dbus_proxy_new_finish (res, &error); -+ if (proxy == NULL) { -+ g_debug ("Could not connect to the Session manager: %s", error->message); -+ g_error_free (error); -+ } else { -+ set_locale (proxy); -+#ifdef HAVE_IBUS -+ /* This will register with cinnamon-session after calling Setenv. */ -+ set_legacy_ibus_env_vars (proxy); -+#else -+ register_with_gnome_session (proxy); -+#endif -+ } -+} -+ - static gboolean - on_term_signal_pipe_closed (GIOChannel *source, - GIOCondition condition, -@@ -368,6 +391,16 @@ set_session_over_handler (GDBusConnectio - { - g_assert (bus != NULL); - -+ g_dbus_proxy_new (bus, -+ G_DBUS_PROXY_FLAGS_NONE, -+ NULL, -+ GNOME_SESSION_DBUS_NAME, -+ GNOME_SESSION_DBUS_OBJECT, -+ GNOME_SESSION_DBUS_INTERFACE, -+ NULL, -+ (GAsyncReadyCallback) got_session_proxy, -+ NULL); -+ - watch_for_term_signal (manager); - } - -@@ -390,56 +423,6 @@ name_lost_handler (GDBusConnection *conn - gtk_main_quit (); - } - --static gboolean --do_register_client (gpointer user_data) --{ -- GDBusProxy *proxy = (GDBusProxy *) user_data; -- g_assert (proxy != NULL); -- -- const char *startup_id = g_getenv ("DESKTOP_AUTOSTART_ID"); -- g_dbus_proxy_call (proxy, -- "RegisterClient", -- g_variant_new ("(ss)", "cinnamon-settings-daemon", startup_id ? startup_id : ""), -- G_DBUS_CALL_FLAGS_NONE, -- -1, -- NULL, -- (GAsyncReadyCallback) on_client_registered, -- manager); -- -- return FALSE; --} -- --static void --queue_register_client (void) --{ -- GDBusConnection *bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); -- if (!bus) -- return; -- -- GError *error = NULL; -- GDBusProxy *proxy = g_dbus_proxy_new_sync (bus, -- G_DBUS_PROXY_FLAGS_NONE, -- NULL, -- GNOME_SESSION_DBUS_NAME, -- GNOME_SESSION_DBUS_OBJECT, -- GNOME_SESSION_DBUS_INTERFACE, -- NULL, -- &error); -- g_object_unref (bus); -- -- if (proxy == NULL) { -- g_debug ("Could not connect to the Session manager: %s", error->message); -- g_error_free (error); -- return; -- } -- -- /* Register the daemon with cinnamon-session */ -- g_signal_connect (G_OBJECT (proxy), "g-signal", -- G_CALLBACK (on_session_over), NULL); -- -- g_idle_add_full (G_PRIORITY_DEFAULT, do_register_client, proxy, NULL); --} -- - static void - bus_register (void) - { -@@ -541,8 +524,6 @@ main (int argc, char *argv[]) - - notify_init ("cinnamon-settings-daemon"); - -- queue_register_client (); -- - bus_register (); - - cinnamon_settings_profile_start ("cinnamon_settings_manager_new"); -diff -uNrp a/configure.ac b/configure.ac ---- a/configure.ac 2013-08-24 18:04:31.000000000 +0100 -+++ b/configure.ac 2013-08-25 16:36:02.000000000 +0100 -@@ -53,6 +53,7 @@ UPOWER_GLIB_REQUIRED_VERSION=0.9.1 - PA_REQUIRED_VERSION=0.9.16 - UPOWER_REQUIRED_VERSION=0.9.11 - GTK_XINPUT_2_3_VERSION=3.7.8 -+IBUS_REQUIRED_VERSION=1.4.2 - - #EXTRA_COMPILE_WARNINGS(yes) - -@@ -199,8 +200,21 @@ dnl ------------------------------------ - dnl - Keyboard plugin stuff - dnl --------------------------------------------------------------------------- - --LIBGNOMEKBD_REQUIRED=2.91.1 --PKG_CHECK_MODULES(KEYBOARD, [libgnomekbdui >= $LIBGNOMEKBD_REQUIRED libgnomekbd >= $LIBGNOMEKBD_REQUIRED libxklavier >= 5.0 kbproto]) -+AC_ARG_ENABLE(ibus, -+ AS_HELP_STRING([--disable-ibus], -+ [Disable IBus support]), -+ enable_ibus=$enableval, -+ enable_ibus=yes) -+ -+if test "x$enable_ibus" = "xyes" ; then -+ IBUS_MODULE="ibus-1.0 >= $IBUS_REQUIRED_VERSION" -+ AC_DEFINE(HAVE_IBUS, 1, [Defined if IBus support is enabled]) -+else -+ IBUS_MODULE= -+fi -+AM_CONDITIONAL(HAVE_IBUS, test "x$enable_ibus" == "xyes") -+ -+PKG_CHECK_MODULES(KEYBOARD, xkbfile $IBUS_MODULE cinnamon-desktop >= $CINNAMON_DESKTOP_REQUIRED_VERSION) - - dnl --------------------------------------------------------------------------- - dnl - Housekeeping plugin stuff -diff -uNrp a/data/org.cinnamon.settings-daemon.plugins.media-keys.gschema.xml.in.in b/data/org.cinnamon.settings-daemon.plugins.media-keys.gschema.xml.in.in ---- a/data/org.cinnamon.settings-daemon.plugins.media-keys.gschema.xml.in.in 2013-08-24 18:04:31.000000000 +0100 -+++ b/data/org.cinnamon.settings-daemon.plugins.media-keys.gschema.xml.in.in 2013-08-25 16:36:02.000000000 +0100 -@@ -175,6 +175,15 @@ - <_summary>Magnifier zoom out</_summary> - <_description>Binding for the magnifier to zoom out</_description> - </key> -+ <key name="switch-input-source" type="s"> -+ <default>''</default> -+ <_summary>Switch input source</_summary> -+ <_description>Binding to select the next input source</_description> -+ </key> -+ <key name="switch-input-source-backward" type="s"> -+ <default>''</default> -+ <_summary>Switch input source backward</_summary> -+ <_description>Binding to select the previous input source</_description> -+ </key> - </schema> -- --</schemalist> -+</schemalist> -\ No newline at end of file -diff -uNrp a/plugins/keyboard/csd-keyboard-manager.c b/plugins/keyboard/csd-keyboard-manager.c ---- a/plugins/keyboard/csd-keyboard-manager.c 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/keyboard/csd-keyboard-manager.c 2013-08-25 16:36:02.000000000 +0100 -@@ -40,19 +40,22 @@ - - #include <X11/XKBlib.h> - #include <X11/keysym.h> -+#include <X11/extensions/XKBrules.h> -+ -+#define GNOME_DESKTOP_USE_UNSTABLE_API -+#include <libcinnamon-desktop/gnome-xkb-info.h> -+ -+#ifdef HAVE_IBUS -+#include <ibus.h> -+#endif - - #include "cinnamon-settings-profile.h" - #include "csd-keyboard-manager.h" -+#include "csd-input-helper.h" - #include "csd-enums.h" - --#include "csd-keyboard-xkb.h" -- - #define CSD_KEYBOARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_KEYBOARD_MANAGER, CsdKeyboardManagerPrivate)) - --#ifndef HOST_NAME_MAX --# define HOST_NAME_MAX 255 --#endif -- - #define CSD_KEYBOARD_DIR "org.cinnamon.settings-daemon.peripherals.keyboard" - - #define KEY_REPEAT "repeat" -@@ -60,6 +63,7 @@ - #define KEY_INTERVAL "repeat-interval" - #define KEY_DELAY "delay" - #define KEY_CLICK_VOLUME "click-volume" -+#define KEY_REMEMBER_NUMLOCK_STATE "remember-numlock-state" - #define KEY_NUMLOCK_STATE "numlock-state" - - #define KEY_BELL_VOLUME "bell-volume" -@@ -67,27 +71,560 @@ - #define KEY_BELL_DURATION "bell-duration" - #define KEY_BELL_MODE "bell-mode" - --#define LIBGNOMEKBD_KEYBOARD_DIR "org.gnome.libgnomekbd.keyboard" --#define LIBGNOMEKBD_KEY_LAYOUTS "layouts" -+#define KEY_SWITCHER "input-sources-switcher" -+ -+#define GNOME_DESKTOP_INTERFACE_DIR "org.cinnamon.desktop.interface" -+ -+#define KEY_GTK_IM_MODULE "gtk-im-module" -+#define GTK_IM_MODULE_SIMPLE "gtk-im-context-simple" -+#define GTK_IM_MODULE_IBUS "ibus" -+ -+#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.cinnamon.desktop.input-sources" -+ -+#define KEY_CURRENT_INPUT_SOURCE "current" -+#define KEY_INPUT_SOURCES "sources" -+#define KEY_KEYBOARD_OPTIONS "xkb-options" -+ -+#define INPUT_SOURCE_TYPE_XKB "xkb" -+#define INPUT_SOURCE_TYPE_IBUS "ibus" -+ -+#define DEFAULT_LANGUAGE "en_US" - - struct CsdKeyboardManagerPrivate - { - guint start_idle_id; - GSettings *settings; -- GSettings *libgnomekbd_settings; -- gboolean have_xkb; -+ GSettings *input_sources_settings; -+ GSettings *interface_settings; -+ GnomeXkbInfo *xkb_info; -+#ifdef HAVE_IBUS -+ IBusBus *ibus; -+ GHashTable *ibus_engines; -+ GHashTable *ibus_xkb_engines; -+ GCancellable *ibus_cancellable; -+ gboolean session_is_fallback; -+#endif - gint xkb_event_base; - CsdNumLockState old_state; -+ GdkDeviceManager *device_manager; -+ guint device_added_id; -+ guint device_removed_id; -+ -+ gboolean input_sources_switcher_spawned; -+ GPid input_sources_switcher_pid; - }; - - static void csd_keyboard_manager_class_init (CsdKeyboardManagerClass *klass); - static void csd_keyboard_manager_init (CsdKeyboardManager *keyboard_manager); - static void csd_keyboard_manager_finalize (GObject *object); -+static gboolean apply_input_sources_settings (GSettings *settings, -+ gpointer keys, -+ gint n_keys, -+ CsdKeyboardManager *manager); -+static void set_gtk_im_module (CsdKeyboardManager *manager, -+ const gchar *new_module); - - G_DEFINE_TYPE (CsdKeyboardManager, csd_keyboard_manager, G_TYPE_OBJECT) - - static gpointer manager_object = NULL; - -+static void -+init_builder_with_sources (GVariantBuilder *builder, -+ GSettings *settings) -+{ -+ const gchar *type; -+ const gchar *id; -+ GVariantIter iter; -+ GVariant *sources; -+ -+ sources = g_settings_get_value (settings, KEY_INPUT_SOURCES); -+ -+ g_variant_builder_init (builder, G_VARIANT_TYPE ("a(ss)")); -+ -+ g_variant_iter_init (&iter, sources); -+ while (g_variant_iter_next (&iter, "(&s&s)", &type, &id)) -+ g_variant_builder_add (builder, "(ss)", type, id); -+ -+ g_variant_unref (sources); -+} -+ -+static gboolean -+schema_is_installed (const gchar *name) -+{ -+ const gchar * const *schemas; -+ const gchar * const *s; -+ -+ schemas = g_settings_list_schemas (); -+ for (s = schemas; *s; ++s) -+ if (g_str_equal (*s, name)) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+#ifdef HAVE_IBUS -+static void -+clear_ibus (CsdKeyboardManager *manager) -+{ -+ CsdKeyboardManagerPrivate *priv = manager->priv; -+ -+ g_cancellable_cancel (priv->ibus_cancellable); -+ g_clear_object (&priv->ibus_cancellable); -+ g_clear_pointer (&priv->ibus_engines, g_hash_table_destroy); -+ g_clear_pointer (&priv->ibus_xkb_engines, g_hash_table_destroy); -+ g_clear_object (&priv->ibus); -+} -+ -+static gchar * -+make_xkb_source_id (const gchar *engine_id) -+{ -+ gchar *id; -+ gchar *p; -+ gint n_colons = 0; -+ -+ /* engine_id is like "xkb:layout:variant:lang" where -+ * 'variant' and 'lang' might be empty */ -+ -+ engine_id += 4; -+ -+ for (p = (gchar *)engine_id; *p; ++p) -+ if (*p == ':') -+ if (++n_colons == 2) -+ break; -+ if (!*p) -+ return NULL; -+ -+ id = g_strndup (engine_id, p - engine_id + 1); -+ -+ id[p - engine_id] = '\0'; -+ -+ /* id is "layout:variant" where 'variant' might be empty */ -+ -+ for (p = id; *p; ++p) -+ if (*p == ':') { -+ if (*(p + 1) == '\0') -+ *p = '\0'; -+ else -+ *p = '+'; -+ break; -+ } -+ -+ /* id is "layout+variant" or "layout" */ -+ -+ return id; -+} -+ -+static void -+fetch_ibus_engines_result (GObject *object, -+ GAsyncResult *result, -+ CsdKeyboardManager *manager) -+{ -+ CsdKeyboardManagerPrivate *priv = manager->priv; -+ GList *list, *l; -+ GError *error = NULL; -+ -+ /* engines shouldn't be there yet */ -+ g_return_if_fail (priv->ibus_engines == NULL); -+ -+ g_clear_object (&priv->ibus_cancellable); -+ -+ list = ibus_bus_list_engines_async_finish (priv->ibus, -+ result, -+ &error); -+ if (!list && error) { -+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ g_warning ("Couldn't finish IBus request: %s", error->message); -+ g_error_free (error); -+ -+ clear_ibus (manager); -+ return; -+ } -+ -+ /* Maps IBus engine ids to engine description objects */ -+ priv->ibus_engines = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); -+ /* Maps XKB source id strings to engine description objects */ -+ priv->ibus_xkb_engines = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); -+ -+ for (l = list; l; l = l->next) { -+ IBusEngineDesc *engine = l->data; -+ const gchar *engine_id = ibus_engine_desc_get_name (engine); -+ -+ g_hash_table_replace (priv->ibus_engines, (gpointer)engine_id, engine); -+ -+ if (strncmp ("xkb:", engine_id, 4) == 0) { -+ gchar *xkb_source_id = make_xkb_source_id (engine_id); -+ if (xkb_source_id) -+ g_hash_table_replace (priv->ibus_xkb_engines, -+ xkb_source_id, -+ engine); -+ } -+ } -+ g_list_free (list); -+ -+ apply_input_sources_settings (priv->input_sources_settings, NULL, 0, manager); -+} -+ -+static void -+fetch_ibus_engines (CsdKeyboardManager *manager) -+{ -+ CsdKeyboardManagerPrivate *priv = manager->priv; -+ -+ /* engines shouldn't be there yet */ -+ g_return_if_fail (priv->ibus_engines == NULL); -+ g_return_if_fail (priv->ibus_cancellable == NULL); -+ -+ priv->ibus_cancellable = g_cancellable_new (); -+ -+ ibus_bus_list_engines_async (priv->ibus, -+ -1, -+ priv->ibus_cancellable, -+ (GAsyncReadyCallback)fetch_ibus_engines_result, -+ manager); -+} -+ -+static void -+maybe_start_ibus (CsdKeyboardManager *manager, -+ GVariant *sources) -+{ -+ gboolean need_ibus = FALSE; -+ GVariantIter iter; -+ const gchar *type; -+ -+ if (manager->priv->session_is_fallback) -+ return; -+ -+ g_variant_iter_init (&iter, sources); -+ while (g_variant_iter_next (&iter, "(&s&s)", &type, NULL)) -+ if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) { -+ need_ibus = TRUE; -+ break; -+ } -+ -+ if (!need_ibus) -+ return; -+ -+ if (!manager->priv->ibus) { -+ ibus_init (); -+ manager->priv->ibus = ibus_bus_new (); -+ g_signal_connect_swapped (manager->priv->ibus, "connected", -+ G_CALLBACK (fetch_ibus_engines), manager); -+ g_signal_connect_swapped (manager->priv->ibus, "disconnected", -+ G_CALLBACK (clear_ibus), manager); -+ } -+ /* IBus doesn't export API in the session bus. The only thing -+ * we have there is a well known name which we can use as a -+ * sure-fire way to activate it. */ -+ g_bus_unwatch_name (g_bus_watch_name (G_BUS_TYPE_SESSION, -+ IBUS_SERVICE_IBUS, -+ G_BUS_NAME_WATCHER_FLAGS_AUTO_START, -+ NULL, -+ NULL, -+ NULL, -+ NULL)); -+} -+ -+static void -+got_session_name (GObject *object, -+ GAsyncResult *res, -+ CsdKeyboardManager *manager) -+{ -+ GVariant *result, *variant; -+ GDBusConnection *connection = G_DBUS_CONNECTION (object); -+ CsdKeyboardManagerPrivate *priv = manager->priv; -+ const gchar *session_name = NULL; -+ GError *error = NULL; -+ -+ /* IBus shouldn't have been touched yet */ -+ g_return_if_fail (priv->ibus == NULL); -+ -+ g_clear_object (&priv->ibus_cancellable); -+ -+ result = g_dbus_connection_call_finish (connection, res, &error); -+ if (!result) { -+ g_warning ("Couldn't get session name: %s", error->message); -+ g_error_free (error); -+ goto out; -+ } -+ -+ g_variant_get (result, "(v)", &variant); -+ g_variant_unref (result); -+ -+ g_variant_get (variant, "&s", &session_name); -+ -+ if (g_strcmp0 (session_name, "gnome") == 0) -+ manager->priv->session_is_fallback = FALSE; -+ -+ g_variant_unref (variant); -+ out: -+ apply_input_sources_settings (manager->priv->input_sources_settings, NULL, 0, manager); -+ g_object_unref (connection); -+} -+ -+static void -+got_bus (GObject *object, -+ GAsyncResult *res, -+ CsdKeyboardManager *manager) -+{ -+ GDBusConnection *connection; -+ CsdKeyboardManagerPrivate *priv = manager->priv; -+ GError *error = NULL; -+ -+ /* IBus shouldn't have been touched yet */ -+ g_return_if_fail (priv->ibus == NULL); -+ -+ g_clear_object (&priv->ibus_cancellable); -+ -+ connection = g_bus_get_finish (res, &error); -+ if (!connection) { -+ g_warning ("Couldn't get session bus: %s", error->message); -+ g_error_free (error); -+ apply_input_sources_settings (priv->input_sources_settings, NULL, 0, manager); -+ return; -+ } -+ -+ priv->ibus_cancellable = g_cancellable_new (); -+ -+ g_dbus_connection_call (connection, -+ "org.gnome.SessionManager", -+ "/org/gnome/SessionManager", -+ "org.freedesktop.DBus.Properties", -+ "Get", -+ g_variant_new ("(ss)", -+ "org.gnome.SessionManager", -+ "SessionName"), -+ NULL, -+ G_DBUS_CALL_FLAGS_NONE, -+ -1, -+ priv->ibus_cancellable, -+ (GAsyncReadyCallback)got_session_name, -+ manager); -+} -+ -+static void -+set_ibus_engine_finish (GObject *object, -+ GAsyncResult *res, -+ CsdKeyboardManager *manager) -+{ -+ gboolean result; -+ IBusBus *ibus = IBUS_BUS (object); -+ CsdKeyboardManagerPrivate *priv = manager->priv; -+ GError *error = NULL; -+ -+ g_clear_object (&priv->ibus_cancellable); -+ -+ result = ibus_bus_set_global_engine_async_finish (ibus, res, &error); -+ if (!result) { -+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ g_warning ("Couldn't set IBus engine: %s", error->message); -+ g_error_free (error); -+ } -+} -+ -+static void -+set_ibus_engine (CsdKeyboardManager *manager, -+ const gchar *engine_id) -+{ -+ CsdKeyboardManagerPrivate *priv = manager->priv; -+ -+ g_return_if_fail (priv->ibus != NULL); -+ g_return_if_fail (priv->ibus_engines != NULL); -+ -+ g_cancellable_cancel (priv->ibus_cancellable); -+ g_clear_object (&priv->ibus_cancellable); -+ priv->ibus_cancellable = g_cancellable_new (); -+ -+ ibus_bus_set_global_engine_async (priv->ibus, -+ engine_id, -+ -1, -+ priv->ibus_cancellable, -+ (GAsyncReadyCallback)set_ibus_engine_finish, -+ manager); -+} -+ -+static void -+set_ibus_xkb_engine (CsdKeyboardManager *manager, -+ const gchar *xkb_id) -+{ -+ IBusEngineDesc *engine; -+ CsdKeyboardManagerPrivate *priv = manager->priv; -+ -+ if (!priv->ibus_xkb_engines) -+ return; -+ -+ engine = g_hash_table_lookup (priv->ibus_xkb_engines, xkb_id); -+ if (!engine) -+ return; -+ -+ set_ibus_engine (manager, ibus_engine_desc_get_name (engine)); -+} -+ -+/* XXX: See upstream bug: -+ * https://codereview.appspot.com/6586075/ */ -+static gchar * -+layout_from_ibus_layout (const gchar *ibus_layout) -+{ -+ const gchar *p; -+ -+ /* we get something like "layout(variant)[option1,option2]" */ -+ -+ p = ibus_layout; -+ while (*p) { -+ if (*p == '(' || *p == '[') -+ break; -+ p += 1; -+ } -+ -+ return g_strndup (ibus_layout, p - ibus_layout); -+} -+ -+static gchar * -+variant_from_ibus_layout (const gchar *ibus_layout) -+{ -+ const gchar *a, *b; -+ -+ /* we get something like "layout(variant)[option1,option2]" */ -+ -+ a = ibus_layout; -+ while (*a) { -+ if (*a == '(') -+ break; -+ a += 1; -+ } -+ if (!*a) -+ return NULL; -+ -+ a += 1; -+ b = a; -+ while (*b) { -+ if (*b == ')') -+ break; -+ b += 1; -+ } -+ if (!*b) -+ return NULL; -+ -+ return g_strndup (a, b - a); -+} -+ -+static gchar ** -+options_from_ibus_layout (const gchar *ibus_layout) -+{ -+ const gchar *a, *b; -+ GPtrArray *opt_array; -+ -+ /* we get something like "layout(variant)[option1,option2]" */ -+ -+ a = ibus_layout; -+ while (*a) { -+ if (*a == '[') -+ break; -+ a += 1; -+ } -+ if (!*a) -+ return NULL; -+ -+ opt_array = g_ptr_array_new (); -+ -+ do { -+ a += 1; -+ b = a; -+ while (*b) { -+ if (*b == ',' || *b == ']') -+ break; -+ b += 1; -+ } -+ if (!*b) -+ goto out; -+ -+ g_ptr_array_add (opt_array, g_strndup (a, b - a)); -+ -+ a = b; -+ } while (*a && *a == ','); -+ -+out: -+ g_ptr_array_add (opt_array, NULL); -+ return (gchar **) g_ptr_array_free (opt_array, FALSE); -+} -+ -+static const gchar * -+engine_from_locale (void) -+{ -+ const gchar *locale; -+ const gchar *locale_engine[][2] = { -+ { "as_IN", "m17n:as:phonetic" }, -+ { "bn_IN", "m17n:bn:inscript" }, -+ { "gu_IN", "m17n:gu:inscript" }, -+ { "hi_IN", "m17n:hi:inscript" }, -+ { "ja_JP", "anthy" }, -+ { "kn_IN", "m17n:kn:kgp" }, -+ { "ko_KR", "hangul" }, -+ { "mai_IN", "m17n:mai:inscript" }, -+ { "ml_IN", "m17n:ml:inscript" }, -+ { "mr_IN", "m17n:mr:inscript" }, -+ { "or_IN", "m17n:or:inscript" }, -+ { "pa_IN", "m17n:pa:inscript" }, -+ { "sd_IN", "m17n:sd:inscript" }, -+ { "ta_IN", "m17n:ta:tamil99" }, -+ { "te_IN", "m17n:te:inscript" }, -+ { "zh_CN", "pinyin" }, -+ { "zh_HK", "cangjie3" }, -+ { "zh_TW", "chewing" }, -+ }; -+ gint i; -+ -+ locale = setlocale (LC_CTYPE, NULL); -+ if (!locale) -+ return NULL; -+ -+ for (i = 0; i < G_N_ELEMENTS (locale_engine); ++i) -+ if (g_str_has_prefix (locale, locale_engine[i][0])) -+ return locale_engine[i][1]; -+ -+ return NULL; -+} -+ -+static void -+add_ibus_sources_from_locale (GSettings *settings) -+{ -+ const gchar *locale_engine; -+ GVariantBuilder builder; -+ -+ locale_engine = engine_from_locale (); -+ if (!locale_engine) -+ return; -+ -+ init_builder_with_sources (&builder, settings); -+ g_variant_builder_add (&builder, "(ss)", INPUT_SOURCE_TYPE_IBUS, locale_engine); -+ g_settings_set_value (settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); -+} -+ -+static void -+convert_ibus (GSettings *settings) -+{ -+ GVariantBuilder builder; -+ GSettings *ibus_settings; -+ gchar **engines, **e; -+ -+ if (!schema_is_installed ("org.freedesktop.ibus.general")) -+ return; -+ -+ init_builder_with_sources (&builder, settings); -+ -+ ibus_settings = g_settings_new ("org.freedesktop.ibus.general"); -+ engines = g_settings_get_strv (ibus_settings, "preload-engines"); -+ for (e = engines; *e; ++e) { -+ if (g_str_has_prefix (*e, "xkb:")) -+ continue; -+ g_variant_builder_add (&builder, "(ss)", INPUT_SOURCE_TYPE_IBUS, *e); -+ } -+ -+ g_settings_set_value (settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); -+ -+ g_strfreev (engines); -+ g_object_unref (ibus_settings); -+} -+#endif /* HAVE_IBUS */ -+ - static gboolean - xkb_set_keyboard_autorepeat_rate (guint delay, guint interval) - { -@@ -97,32 +634,33 @@ xkb_set_keyboard_autorepeat_rate (guint - interval); - } - --static void --numlock_xkb_init (CsdKeyboardManager *manager) -+static gboolean -+check_xkb_extension (CsdKeyboardManager *manager) - { - Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); -- gboolean have_xkb; - int opcode, error_base, major, minor; -+ gboolean have_xkb; - - have_xkb = XkbQueryExtension (dpy, - &opcode, - &manager->priv->xkb_event_base, - &error_base, - &major, -- &minor) -- && XkbUseExtension (dpy, &major, &minor); -+ &minor); -+ return have_xkb; -+} - -- if (have_xkb) { -- XkbSelectEventDetails (dpy, -- XkbUseCoreKbd, -- XkbStateNotifyMask, -- XkbModifierLockMask, -- XkbModifierLockMask); -- } else { -- g_warning ("XKB extension not available"); -- } -+static void -+xkb_init (CsdKeyboardManager *manager) -+{ -+ Display *dpy; - -- manager->priv->have_xkb = have_xkb; -+ dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); -+ XkbSelectEventDetails (dpy, -+ XkbUseCoreKbd, -+ XkbStateNotify, -+ XkbModifierLockMask, -+ XkbModifierLockMask); - } - - static unsigned -@@ -143,19 +681,32 @@ numlock_set_xkb_state (CsdNumLockState n - XkbLockModifiers (dpy, XkbUseCoreKbd, num_mask, new_state == CSD_NUM_LOCK_STATE_ON ? num_mask : 0); - } - -+static const char * -+num_lock_state_to_string (CsdNumLockState numlock_state) -+{ -+ switch (numlock_state) { -+ case CSD_NUM_LOCK_STATE_UNKNOWN: -+ return "CSD_NUM_LOCK_STATE_UNKNOWN"; -+ case CSD_NUM_LOCK_STATE_ON: -+ return "CSD_NUM_LOCK_STATE_ON"; -+ case CSD_NUM_LOCK_STATE_OFF: -+ return "CSD_NUM_LOCK_STATE_OFF"; -+ default: -+ return "UNKNOWN"; -+ } -+} -+ - static GdkFilterReturn --numlock_xkb_callback (GdkXEvent *xev_, -- GdkEvent *gdkev_, -- gpointer user_data) -+xkb_events_filter (GdkXEvent *xev_, -+ GdkEvent *gdkev_, -+ gpointer user_data) - { - XEvent *xev = (XEvent *) xev_; - XkbEvent *xkbev = (XkbEvent *) xev; - CsdKeyboardManager *manager = (CsdKeyboardManager *) user_data; - -- if (xev->type != manager->priv->xkb_event_base) -- return GDK_FILTER_CONTINUE; -- -- if (xkbev->any.xkb_type != XkbStateNotify) -+ if (xev->type != manager->priv->xkb_event_base || -+ xkbev->any.xkb_type != XkbStateNotify) - return GDK_FILTER_CONTINUE; - - if (xkbev->state.changed & XkbModifierLockMask) { -@@ -166,6 +717,9 @@ numlock_xkb_callback (GdkXEvent *xev_, - numlock_state = (num_mask & locked_mods) ? CSD_NUM_LOCK_STATE_ON : CSD_NUM_LOCK_STATE_OFF; - - if (numlock_state != manager->priv->old_state) { -+ g_debug ("New num-lock state '%s' != Old num-lock state '%s'", -+ num_lock_state_to_string (numlock_state), -+ num_lock_state_to_string (manager->priv->old_state)); - g_settings_set_enum (manager->priv->settings, - KEY_NUMLOCK_STATE, - numlock_state); -@@ -177,57 +731,509 @@ numlock_xkb_callback (GdkXEvent *xev_, - } - - static void --numlock_install_xkb_callback (CsdKeyboardManager *manager) -+install_xkb_filter (CsdKeyboardManager *manager) - { -- if (!manager->priv->have_xkb) -- return; -- - gdk_window_add_filter (NULL, -- numlock_xkb_callback, -+ xkb_events_filter, - manager); - } - --static guint --_csd_settings_get_uint (GSettings *settings, -- const char *key) -+static void -+remove_xkb_filter (CsdKeyboardManager *manager) - { -- guint value; -+ gdk_window_remove_filter (NULL, -+ xkb_events_filter, -+ manager); -+} - -- g_settings_get (settings, key, "u", &value); -- return value; -+static void -+free_xkb_component_names (XkbComponentNamesRec *p) -+{ -+ g_return_if_fail (p != NULL); -+ -+ free (p->keymap); -+ free (p->keycodes); -+ free (p->types); -+ free (p->compat); -+ free (p->symbols); -+ free (p->geometry); -+ -+ g_free (p); -+} -+ -+static void -+upload_xkb_description (const gchar *rules_file_path, -+ XkbRF_VarDefsRec *var_defs, -+ XkbComponentNamesRec *comp_names) -+{ -+ Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); -+ XkbDescRec *xkb_desc; -+ gchar *rules_file; -+ -+ /* Upload it to the X server using the same method as setxkbmap */ -+ xkb_desc = XkbGetKeyboardByName (display, -+ XkbUseCoreKbd, -+ comp_names, -+ XkbGBN_AllComponentsMask, -+ XkbGBN_AllComponentsMask & -+ (~XkbGBN_GeometryMask), True); -+ if (!xkb_desc) { -+ g_warning ("Couldn't upload new XKB keyboard description"); -+ return; -+ } -+ -+ XkbFreeKeyboard (xkb_desc, 0, True); -+ -+ rules_file = g_path_get_basename (rules_file_path); -+ -+ if (!XkbRF_SetNamesProp (display, rules_file, var_defs)) -+ g_warning ("Couldn't update the XKB root window property"); -+ -+ g_free (rules_file); -+} -+ -+static gchar * -+language_code_from_locale (const gchar *locale) -+{ -+ if (!locale || !locale[0] || !locale[1]) -+ return NULL; -+ -+ if (!locale[2] || locale[2] == '_' || locale[2] == '.') -+ return g_strndup (locale, 2); -+ -+ if (!locale[3] || locale[3] == '_' || locale[3] == '.') -+ return g_strndup (locale, 3); -+ -+ return NULL; -+} -+ -+static gchar * -+build_xkb_group_string (const gchar *user, -+ const gchar *locale, -+ const gchar *latin) -+{ -+ gchar *string; -+ gsize length = 0; -+ guint commas = 2; -+ -+ if (latin) -+ length += strlen (latin); -+ else -+ commas -= 1; -+ -+ if (locale) -+ length += strlen (locale); -+ else -+ commas -= 1; -+ -+ length += strlen (user) + commas + 1; -+ -+ string = malloc (length); -+ -+ if (locale && latin) -+ sprintf (string, "%s,%s,%s", user, locale, latin); -+ else if (locale) -+ sprintf (string, "%s,%s", user, locale); -+ else if (latin) -+ sprintf (string, "%s,%s", user, latin); -+ else -+ sprintf (string, "%s", user); -+ -+ return string; -+} -+ -+static gboolean -+layout_equal (const gchar *layout_a, -+ const gchar *variant_a, -+ const gchar *layout_b, -+ const gchar *variant_b) -+{ -+ return !g_strcmp0 (layout_a, layout_b) && !g_strcmp0 (variant_a, variant_b); - } - - static void --apply_settings (GSettings *settings, -- const char *key, -- CsdKeyboardManager *manager) -+replace_layout_and_variant (CsdKeyboardManager *manager, -+ XkbRF_VarDefsRec *xkb_var_defs, -+ const gchar *layout, -+ const gchar *variant) - { -+ /* Toolkits need to know about both a latin layout to handle -+ * accelerators which are usually defined like Ctrl+C and a -+ * layout with the symbols for the language used in UI strings -+ * to handle mnemonics like Alt+Ф, so we try to find and add -+ * them in XKB group slots after the layout which the user -+ * actually intends to type with. */ -+ const gchar *latin_layout = "us"; -+ const gchar *latin_variant = ""; -+ const gchar *locale_layout = NULL; -+ const gchar *locale_variant = NULL; -+ const gchar *locale; -+ gchar *language; -+ -+ if (!layout) -+ return; -+ -+ if (!variant) -+ variant = ""; -+ -+ locale = setlocale (LC_MESSAGES, NULL); -+ /* If LANG is empty, default to en_US */ -+ if (!locale) -+ language = g_strdup (DEFAULT_LANGUAGE); -+ else -+ language = language_code_from_locale (locale); -+ -+ if (!language) -+ language = language_code_from_locale (DEFAULT_LANGUAGE); -+ -+ gnome_xkb_info_get_layout_info_for_language (manager->priv->xkb_info, -+ language, -+ NULL, -+ NULL, -+ NULL, -+ &locale_layout, -+ &locale_variant); -+ g_free (language); -+ -+ /* We want to minimize the number of XKB groups if we have -+ * duplicated layout+variant pairs. -+ * -+ * Also, if a layout doesn't have a variant we still have to -+ * include it in the variants string because the number of -+ * variants must agree with the number of layouts. For -+ * instance: -+ * -+ * layouts: "us,ru,us" -+ * variants: "dvorak,," -+ */ -+ if (layout_equal (latin_layout, latin_variant, locale_layout, locale_variant) || -+ layout_equal (latin_layout, latin_variant, layout, variant)) { -+ latin_layout = NULL; -+ latin_variant = NULL; -+ } -+ -+ if (layout_equal (locale_layout, locale_variant, layout, variant)) { -+ locale_layout = NULL; -+ locale_variant = NULL; -+ } -+ -+ free (xkb_var_defs->layout); -+ xkb_var_defs->layout = build_xkb_group_string (layout, locale_layout, latin_layout); -+ -+ free (xkb_var_defs->variant); -+ xkb_var_defs->variant = build_xkb_group_string (variant, locale_variant, latin_variant); -+} -+ -+static gchar * -+build_xkb_options_string (gchar **options) -+{ -+ gchar *string; -+ -+ if (*options) { -+ gint i; -+ gsize len; -+ gchar *ptr; -+ -+ /* First part, getting length */ -+ len = 1 + strlen (options[0]); -+ for (i = 1; options[i] != NULL; i++) -+ len += strlen (options[i]); -+ len += (i - 1); /* commas */ -+ -+ /* Second part, building string */ -+ string = malloc (len); -+ ptr = g_stpcpy (string, *options); -+ for (i = 1; options[i] != NULL; i++) { -+ ptr = g_stpcpy (ptr, ","); -+ ptr = g_stpcpy (ptr, options[i]); -+ } -+ } else { -+ string = malloc (1); -+ *string = '\0'; -+ } -+ -+ return string; -+} -+ -+static gchar ** -+append_options (gchar **a, -+ gchar **b) -+{ -+ gchar **c, **p; -+ -+ if (!a && !b) -+ return NULL; -+ else if (!a) -+ return g_strdupv (b); -+ else if (!b) -+ return g_strdupv (a); -+ -+ c = g_new0 (gchar *, g_strv_length (a) + g_strv_length (b) + 1); -+ p = c; -+ -+ while (*a) { -+ *p = g_strdup (*a); -+ p += 1; -+ a += 1; -+ } -+ while (*b) { -+ *p = g_strdup (*b); -+ p += 1; -+ b += 1; -+ } -+ -+ return c; -+} -+ -+static void -+add_xkb_options (CsdKeyboardManager *manager, -+ XkbRF_VarDefsRec *xkb_var_defs, -+ gchar **extra_options) -+{ -+ gchar **options; -+ gchar **settings_options; -+ -+ settings_options = g_settings_get_strv (manager->priv->input_sources_settings, -+ KEY_KEYBOARD_OPTIONS); -+ options = append_options (settings_options, extra_options); -+ g_strfreev (settings_options); -+ -+ free (xkb_var_defs->options); -+ xkb_var_defs->options = build_xkb_options_string (options); -+ -+ g_strfreev (options); -+} -+ -+static void -+apply_xkb_settings (CsdKeyboardManager *manager, -+ const gchar *layout, -+ const gchar *variant, -+ gchar **options) -+{ -+ XkbRF_RulesRec *xkb_rules; -+ XkbRF_VarDefsRec *xkb_var_defs; -+ gchar *rules_file_path; -+ -+ gnome_xkb_info_get_var_defs (&rules_file_path, &xkb_var_defs); -+ -+ add_xkb_options (manager, xkb_var_defs, options); -+ replace_layout_and_variant (manager, xkb_var_defs, layout, variant); -+ -+ gdk_error_trap_push (); -+ -+ xkb_rules = XkbRF_Load (rules_file_path, NULL, True, True); -+ if (xkb_rules) { -+ XkbComponentNamesRec *xkb_comp_names; -+ xkb_comp_names = g_new0 (XkbComponentNamesRec, 1); -+ -+ XkbRF_GetComponents (xkb_rules, xkb_var_defs, xkb_comp_names); -+ upload_xkb_description (rules_file_path, xkb_var_defs, xkb_comp_names); -+ -+ free_xkb_component_names (xkb_comp_names); -+ XkbRF_Free (xkb_rules, True); -+ } else { -+ g_warning ("Couldn't load XKB rules"); -+ } -+ -+ if (gdk_error_trap_pop ()) -+ g_warning ("Error loading XKB rules"); -+ -+ gnome_xkb_info_free_var_defs (xkb_var_defs); -+ g_free (rules_file_path); -+} -+ -+static void -+set_gtk_im_module (CsdKeyboardManager *manager, -+ const gchar *new_module) -+{ -+ CsdKeyboardManagerPrivate *priv = manager->priv; -+ gchar *current_module; -+ -+ current_module = g_settings_get_string (priv->interface_settings, -+ KEY_GTK_IM_MODULE); -+ if (!g_str_equal (current_module, new_module)) -+ g_settings_set_string (priv->interface_settings, -+ KEY_GTK_IM_MODULE, -+ new_module); -+ g_free (current_module); -+} -+ -+static gboolean -+apply_input_sources_settings (GSettings *settings, -+ gpointer keys, -+ gint n_keys, -+ CsdKeyboardManager *manager) -+{ -+ CsdKeyboardManagerPrivate *priv = manager->priv; -+ GVariant *sources; -+ guint current; -+ guint n_sources; -+ const gchar *type = NULL; -+ const gchar *id = NULL; -+ gchar *layout = NULL; -+ gchar *variant = NULL; -+ gchar **options = NULL; -+ -+ sources = g_settings_get_value (priv->input_sources_settings, KEY_INPUT_SOURCES); -+ current = g_settings_get_uint (priv->input_sources_settings, KEY_CURRENT_INPUT_SOURCE); -+ n_sources = g_variant_n_children (sources); -+ -+ if (n_sources < 1) -+ goto exit; -+ -+ if (current >= n_sources) { -+ g_settings_set_uint (priv->input_sources_settings, -+ KEY_CURRENT_INPUT_SOURCE, -+ n_sources - 1); -+ goto exit; -+ } -+ -+#ifdef HAVE_IBUS -+ maybe_start_ibus (manager, sources); -+#endif -+ -+ g_variant_get_child (sources, current, "(&s&s)", &type, &id); -+ -+ if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB)) { -+ const gchar *l, *v; -+ gnome_xkb_info_get_layout_info (priv->xkb_info, id, NULL, NULL, &l, &v); -+ -+ layout = g_strdup (l); -+ variant = g_strdup (v); -+ -+ if (!layout || !layout[0]) { -+ g_warning ("Couldn't find XKB input source '%s'", id); -+ goto exit; -+ } -+ set_gtk_im_module (manager, GTK_IM_MODULE_SIMPLE); -+#ifdef HAVE_IBUS -+ set_ibus_xkb_engine (manager, id); -+#endif -+ } else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) { -+#ifdef HAVE_IBUS -+ IBusEngineDesc *engine_desc = NULL; -+ -+ if (priv->session_is_fallback) -+ goto exit; -+ -+ if (priv->ibus_engines) -+ engine_desc = g_hash_table_lookup (priv->ibus_engines, id); -+ else -+ goto exit; /* we'll be called again when ibus is up and running */ -+ -+ if (engine_desc) { -+ const gchar *ibus_layout; -+ ibus_layout = ibus_engine_desc_get_layout (engine_desc); -+ -+ if (ibus_layout) { -+ layout = layout_from_ibus_layout (ibus_layout); -+ variant = variant_from_ibus_layout (ibus_layout); -+ options = options_from_ibus_layout (ibus_layout); -+ } -+ } else { -+ g_warning ("Couldn't find IBus input source '%s'", id); -+ goto exit; -+ } -+ -+ set_gtk_im_module (manager, GTK_IM_MODULE_IBUS); -+ set_ibus_engine (manager, id); -+#else -+ g_warning ("IBus input source type specified but IBus support was not compiled"); -+#endif -+ } else { -+ g_warning ("Unknown input source type '%s'", type); -+ } -+ -+ exit: -+ apply_xkb_settings (manager, layout, variant, options); -+ g_variant_unref (sources); -+ g_free (layout); -+ g_free (variant); -+ g_strfreev (options); -+ /* Prevent individual "changed" signal invocations since we -+ don't need them. */ -+ return TRUE; -+} -+ -+static void -+apply_bell (CsdKeyboardManager *manager) -+{ -+ GSettings *settings; - XKeyboardControl kbdcontrol; -- gboolean repeat; - gboolean click; -- guint interval; -- guint delay; -- int click_volume; - int bell_volume; - int bell_pitch; - int bell_duration; - CsdBellMode bell_mode; -- gboolean rnumlock; -- -- if (g_strcmp0 (key, KEY_NUMLOCK_STATE) == 0) -- return; -+ int click_volume; - -- repeat = g_settings_get_boolean (settings, KEY_REPEAT); -+ g_debug ("Applying the bell settings"); -+ settings = manager->priv->settings; - click = g_settings_get_boolean (settings, KEY_CLICK); -- interval = _csd_settings_get_uint (settings, KEY_INTERVAL); -- delay = _csd_settings_get_uint (settings, KEY_DELAY); - click_volume = g_settings_get_int (settings, KEY_CLICK_VOLUME); -+ - bell_pitch = g_settings_get_int (settings, KEY_BELL_PITCH); - bell_duration = g_settings_get_int (settings, KEY_BELL_DURATION); - - bell_mode = g_settings_get_enum (settings, KEY_BELL_MODE); - bell_volume = (bell_mode == CSD_BELL_MODE_ON) ? 50 : 0; - -+ /* as percentage from 0..100 inclusive */ -+ if (click_volume < 0) { -+ click_volume = 0; -+ } else if (click_volume > 100) { -+ click_volume = 100; -+ } -+ kbdcontrol.key_click_percent = click ? click_volume : 0; -+ kbdcontrol.bell_percent = bell_volume; -+ kbdcontrol.bell_pitch = bell_pitch; -+ kbdcontrol.bell_duration = bell_duration; -+ -+ gdk_error_trap_push (); -+ XChangeKeyboardControl (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), -+ KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration, -+ &kbdcontrol); -+ -+ XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE); -+ gdk_error_trap_pop_ignored (); -+} -+ -+static void -+apply_numlock (CsdKeyboardManager *manager) -+{ -+ GSettings *settings; -+ gboolean rnumlock; -+ -+ g_debug ("Applying the num-lock settings"); -+ settings = manager->priv->settings; -+ rnumlock = g_settings_get_boolean (settings, KEY_REMEMBER_NUMLOCK_STATE); -+ manager->priv->old_state = g_settings_get_enum (manager->priv->settings, KEY_NUMLOCK_STATE); -+ -+ gdk_error_trap_push (); -+ if (rnumlock) { -+ g_debug ("Remember num-lock is set, so applying setting '%s'", -+ num_lock_state_to_string (manager->priv->old_state)); -+ numlock_set_xkb_state (manager->priv->old_state); -+ } -+ -+ XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE); -+ gdk_error_trap_pop_ignored (); -+} -+ -+static void -+apply_repeat (CsdKeyboardManager *manager) -+{ -+ GSettings *settings; -+ gboolean repeat; -+ guint interval; -+ guint delay; -+ -+ g_debug ("Applying the repeat settings"); -+ settings = manager->priv->settings; -+ repeat = g_settings_get_boolean (settings, KEY_REPEAT); -+ interval = g_settings_get_uint (settings, KEY_INTERVAL); -+ delay = g_settings_get_uint (settings, KEY_DELAY); -+ - gdk_error_trap_push (); - if (repeat) { - gboolean rate_set = FALSE; -@@ -243,124 +1249,319 @@ apply_settings (GSettings *sett - XAutoRepeatOff (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); - } - -- /* as percentage from 0..100 inclusive */ -- if (click_volume < 0) { -- click_volume = 0; -- } else if (click_volume > 100) { -- click_volume = 100; -+ XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE); -+ gdk_error_trap_pop_ignored (); -+} -+ -+static void -+apply_all_settings (CsdKeyboardManager *manager) -+{ -+ apply_repeat (manager); -+ apply_bell (manager); -+ apply_numlock (manager); -+} -+ -+static void -+set_input_sources_switcher (CsdKeyboardManager *manager, -+ gboolean state) -+{ -+ if (state) { -+ GError *error = NULL; -+ char *args[2]; -+ -+ if (manager->priv->input_sources_switcher_spawned) -+ set_input_sources_switcher (manager, FALSE); -+ -+ args[0] = LIBEXECDIR "/csd-input-sources-switcher"; -+ args[1] = NULL; -+ -+ g_spawn_async (NULL, args, NULL, -+ 0, NULL, NULL, -+ &manager->priv->input_sources_switcher_pid, &error); -+ -+ manager->priv->input_sources_switcher_spawned = (error == NULL); -+ -+ if (error) { -+ g_warning ("Couldn't spawn %s: %s", args[0], error->message); -+ g_error_free (error); -+ } -+ } else if (manager->priv->input_sources_switcher_spawned) { -+ kill (manager->priv->input_sources_switcher_pid, SIGHUP); -+ g_spawn_close_pid (manager->priv->input_sources_switcher_pid); -+ manager->priv->input_sources_switcher_spawned = FALSE; - } -- kbdcontrol.key_click_percent = click ? click_volume : 0; -- kbdcontrol.bell_percent = bell_volume; -- kbdcontrol.bell_pitch = bell_pitch; -- kbdcontrol.bell_duration = bell_duration; -- XChangeKeyboardControl (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), -- KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration, -- &kbdcontrol); -+} - -- if (g_strcmp0 (key, "remember-numlock-state") == 0 || key == NULL) { -- rnumlock = g_settings_get_boolean (settings, "remember-numlock-state"); -+static gboolean -+enable_switcher (CsdKeyboardManager *manager) -+{ -+ CsdInputSourcesSwitcher switcher; - -- manager->priv->old_state = g_settings_get_enum (manager->priv->settings, KEY_NUMLOCK_STATE); -+ switcher = g_settings_get_enum (manager->priv->settings, KEY_SWITCHER); - -- if (manager->priv->have_xkb && rnumlock) -- numlock_set_xkb_state (manager->priv->old_state); -+ return switcher != CSD_INPUT_SOURCES_SWITCHER_OFF; -+} -+ -+static void -+settings_changed (GSettings *settings, -+ const char *key, -+ CsdKeyboardManager *manager) -+{ -+ if (g_strcmp0 (key, KEY_CLICK) == 0|| -+ g_strcmp0 (key, KEY_CLICK_VOLUME) == 0 || -+ g_strcmp0 (key, KEY_BELL_PITCH) == 0 || -+ g_strcmp0 (key, KEY_BELL_DURATION) == 0 || -+ g_strcmp0 (key, KEY_BELL_MODE) == 0) { -+ g_debug ("Bell setting '%s' changed, applying bell settings", key); -+ apply_bell (manager); -+ } else if (g_strcmp0 (key, KEY_REMEMBER_NUMLOCK_STATE) == 0) { -+ g_debug ("Remember Num-Lock state '%s' changed, applying num-lock settings", key); -+ apply_numlock (manager); -+ } else if (g_strcmp0 (key, KEY_NUMLOCK_STATE) == 0) { -+ g_debug ("Num-Lock state '%s' changed, will apply at next startup", key); -+ } else if (g_strcmp0 (key, KEY_REPEAT) == 0 || -+ g_strcmp0 (key, KEY_INTERVAL) == 0 || -+ g_strcmp0 (key, KEY_DELAY) == 0) { -+ g_debug ("Key repeat setting '%s' changed, applying key repeat settings", key); -+ apply_repeat (manager); -+ } else if (g_strcmp0 (key, KEY_SWITCHER) == 0) { -+ set_input_sources_switcher (manager, enable_switcher (manager)); -+ } else { -+ g_warning ("Unhandled settings change, key '%s'", key); - } - -- XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE); -- gdk_error_trap_pop_ignored (); - } - --void --csd_keyboard_manager_apply_settings (CsdKeyboardManager *manager) -+static void -+device_added_cb (GdkDeviceManager *device_manager, -+ GdkDevice *device, -+ CsdKeyboardManager *manager) - { -- apply_settings (manager->priv->settings, NULL, manager); -+ GdkInputSource source; -+ -+ source = gdk_device_get_source (device); -+ if (source == GDK_SOURCE_KEYBOARD) { -+ g_debug ("New keyboard plugged in, applying all settings"); -+ apply_all_settings (manager); -+ apply_input_sources_settings (manager->priv->input_sources_settings, NULL, 0, manager); -+ run_custom_command (device, COMMAND_DEVICE_ADDED); -+ } - } - - static void --apply_libgnomekbd_settings (GSettings *settings, -- const char *key, -- CsdKeyboardManager *manager) -+device_removed_cb (GdkDeviceManager *device_manager, -+ GdkDevice *device, -+ CsdKeyboardManager *manager) - { -- gchar **layouts; -+ GdkInputSource source; - -- layouts = g_settings_get_strv (settings, LIBGNOMEKBD_KEY_LAYOUTS); -+ source = gdk_device_get_source (device); -+ if (source == GDK_SOURCE_KEYBOARD) { -+ run_custom_command (device, COMMAND_DEVICE_REMOVED); -+ } -+} - -- /* Get accounts daemon */ -- GDBusProxy *proxy = NULL; -- GDBusProxy *user = NULL; -- GVariant *variant = NULL; -- GError *error = NULL; -- gchar *object_path = NULL; -+static void -+set_devicepresence_handler (CsdKeyboardManager *manager) -+{ -+ GdkDeviceManager *device_manager; - -- proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, -- G_DBUS_PROXY_FLAGS_NONE, -- NULL, -- "org.freedesktop.Accounts", -- "/org/freedesktop/Accounts", -- "org.freedesktop.Accounts", -- NULL, -- &error); -+ device_manager = gdk_display_get_device_manager (gdk_display_get_default ()); - -- if (proxy == NULL) { -- g_warning ("Failed to contact accounts service: %s", error->message); -- g_error_free (error); -- goto bail; -+ 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; -+} -+ -+static void -+create_sources_from_current_xkb_config (GSettings *settings) -+{ -+ GVariantBuilder builder; -+ XkbRF_VarDefsRec *xkb_var_defs; -+ gchar *tmp; -+ gchar **layouts = NULL; -+ gchar **variants = NULL; -+ guint i, n; -+ -+ gnome_xkb_info_get_var_defs (&tmp, &xkb_var_defs); -+ g_free (tmp); -+ -+ if (xkb_var_defs->layout) -+ layouts = g_strsplit (xkb_var_defs->layout, ",", 0); -+ if (xkb_var_defs->variant) -+ variants = g_strsplit (xkb_var_defs->variant, ",", 0); -+ -+ gnome_xkb_info_free_var_defs (xkb_var_defs); -+ -+ if (!layouts) -+ goto out; -+ -+ if (variants && variants[0]) -+ n = MIN (g_strv_length (layouts), g_strv_length (variants)); -+ else -+ n = g_strv_length (layouts); -+ -+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); -+ for (i = 0; i < n && layouts[i][0]; ++i) { -+ if (variants && variants[i] && variants[i][0]) -+ tmp = g_strdup_printf ("%s+%s", layouts[i], variants[i]); -+ else -+ tmp = g_strdup (layouts[i]); -+ -+ g_variant_builder_add (&builder, "(ss)", INPUT_SOURCE_TYPE_XKB, tmp); -+ g_free (tmp); - } -+ g_settings_set_value (settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); -+out: -+ g_strfreev (layouts); -+ g_strfreev (variants); -+} - -- variant = g_dbus_proxy_call_sync (proxy, -- "FindUserByName", -- g_variant_new ("(s)", g_get_user_name ()), -- G_DBUS_CALL_FLAGS_NONE, -- -1, -- NULL, -- &error); -+static void -+convert_libgnomekbd_options (GSettings *settings) -+{ -+ GPtrArray *opt_array; -+ GSettings *libgnomekbd_settings; -+ gchar **options, **o; - -- if (variant == NULL) { -- g_warning ("Could not contact accounts service to look up '%s': %s", -- g_get_user_name (), error->message); -- g_error_free (error); -- goto bail; -+ if (!schema_is_installed ("org.gnome.libgnomekbd.keyboard")) -+ return; -+ -+ opt_array = g_ptr_array_new_with_free_func (g_free); -+ -+ libgnomekbd_settings = g_settings_new ("org.gnome.libgnomekbd.keyboard"); -+ options = g_settings_get_strv (libgnomekbd_settings, "options"); -+ -+ for (o = options; *o; ++o) { -+ gchar **strv; -+ -+ strv = g_strsplit (*o, "\t", 2); -+ if (strv[0] && strv[1]) { -+ /* We don't want the group switcher because -+ * it's incompatible with the way we use XKB -+ * groups. */ -+ if (!g_str_has_prefix (strv[1], "grp:")) -+ g_ptr_array_add (opt_array, g_strdup (strv[1])); -+ } -+ g_strfreev (strv); - } -+ g_ptr_array_add (opt_array, NULL); - -- g_variant_get (variant, "(o)", &object_path); -- user = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, -- G_DBUS_PROXY_FLAGS_NONE, -- NULL, -- "org.freedesktop.Accounts", -- object_path, -- "org.freedesktop.Accounts.User", -- NULL, -- &error); -- g_free (object_path); -+ g_settings_set_strv (settings, KEY_KEYBOARD_OPTIONS, (const gchar * const*) opt_array->pdata); - -- if (user == NULL) { -- g_warning ("Could not create proxy for user '%s': %s", -- g_variant_get_string (variant, NULL), error->message); -- g_error_free (error); -- goto bail; -+ g_strfreev (options); -+ g_object_unref (libgnomekbd_settings); -+ g_ptr_array_free (opt_array, TRUE); -+} -+ -+static void -+convert_libgnomekbd_layouts (GSettings *settings) -+{ -+ GVariantBuilder builder; -+ GSettings *libgnomekbd_settings; -+ gchar **layouts, **l; -+ -+ if (!schema_is_installed ("org.gnome.libgnomekbd.keyboard")) -+ return; -+ -+ init_builder_with_sources (&builder, settings); -+ -+ libgnomekbd_settings = g_settings_new ("org.gnome.libgnomekbd.keyboard"); -+ layouts = g_settings_get_strv (libgnomekbd_settings, "layouts"); -+ -+ for (l = layouts; *l; ++l) { -+ gchar *id; -+ gchar **strv; -+ -+ strv = g_strsplit (*l, "\t", 2); -+ if (strv[0] && !strv[1]) -+ id = g_strdup (strv[0]); -+ else if (strv[0] && strv[1]) -+ id = g_strdup_printf ("%s+%s", strv[0], strv[1]); -+ else -+ id = NULL; -+ -+ if (id) -+ g_variant_builder_add (&builder, "(ss)", INPUT_SOURCE_TYPE_XKB, id); -+ -+ g_free (id); -+ g_strfreev (strv); - } -- g_variant_unref (variant); - -- variant = g_dbus_proxy_call_sync (user, -- "SetXKeyboardLayouts", -- g_variant_new ("(^as)", layouts), -- G_DBUS_CALL_FLAGS_NONE, -- -1, -- NULL, -- &error); -+ g_settings_set_value (settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); -+ -+ g_strfreev (layouts); -+ g_object_unref (libgnomekbd_settings); -+} - -- if (variant == NULL) { -- g_warning ("Failed to set the keyboard layouts: %s", error->message); -+static void -+maybe_convert_old_settings (GSettings *settings) -+{ -+ GVariant *sources; -+ gchar **options; -+ gchar *stamp_dir_path = NULL; -+ gchar *stamp_file_path = NULL; -+ GError *error = NULL; -+ -+ stamp_dir_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME, NULL); -+ if (g_mkdir_with_parents (stamp_dir_path, 0755)) { -+ g_warning ("Failed to create directory %s: %s", stamp_dir_path, g_strerror (errno)); -+ goto out; -+ } -+ -+ stamp_file_path = g_build_filename (stamp_dir_path, "input-sources-converted", NULL); -+ if (g_file_test (stamp_file_path, G_FILE_TEST_EXISTS)) -+ goto out; -+ -+ sources = g_settings_get_value (settings, KEY_INPUT_SOURCES); -+ if (g_variant_n_children (sources) < 1) { -+ convert_libgnomekbd_layouts (settings); -+#ifdef HAVE_IBUS -+ convert_ibus (settings); -+#endif -+ } -+ g_variant_unref (sources); -+ -+ options = g_settings_get_strv (settings, KEY_KEYBOARD_OPTIONS); -+ if (g_strv_length (options) < 1) -+ convert_libgnomekbd_options (settings); -+ g_strfreev (options); -+ -+ if (!g_file_set_contents (stamp_file_path, "", 0, &error)) { -+ g_warning ("%s", error->message); - g_error_free (error); -- goto bail; - } -+out: -+ g_free (stamp_file_path); -+ g_free (stamp_dir_path); -+} - --bail: -- if (proxy != NULL) -- g_object_unref (proxy); -- if (variant != NULL) -- g_variant_unref (variant); -- g_strfreev (layouts); -+static void -+maybe_create_input_sources (CsdKeyboardManager *manager) -+{ -+ GSettings *settings; -+ GVariant *sources; -+ -+ settings = manager->priv->input_sources_settings; -+ -+ if (g_getenv ("RUNNING_UNDER_GDM")) { -+ create_sources_from_current_xkb_config (settings); -+ return; -+ } -+ -+ maybe_convert_old_settings (settings); -+ -+ /* if we still don't have anything do some educated guesses */ -+ sources = g_settings_get_value (settings, KEY_INPUT_SOURCES); -+ if (g_variant_n_children (sources) < 1) { -+ create_sources_from_current_xkb_config (settings); -+#ifdef HAVE_IBUS -+ add_ibus_sources_from_locale (settings); -+#endif -+ } -+ g_variant_unref (sources); - } - - static gboolean -@@ -370,26 +1571,41 @@ start_keyboard_idle_cb (CsdKeyboardManag - - g_debug ("Starting keyboard manager"); - -- manager->priv->have_xkb = 0; - manager->priv->settings = g_settings_new (CSD_KEYBOARD_DIR); -- manager->priv->libgnomekbd_settings = g_settings_new (LIBGNOMEKBD_KEYBOARD_DIR); - -- /* Essential - xkb initialization should happen before */ -- csd_keyboard_xkb_init (manager); -+ xkb_init (manager); - -- numlock_xkb_init (manager); -+ set_devicepresence_handler (manager); - -+ manager->priv->input_sources_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR); -+ manager->priv->interface_settings = g_settings_new (GNOME_DESKTOP_INTERFACE_DIR); -+ manager->priv->xkb_info = gnome_xkb_info_new (); -+ -+ maybe_create_input_sources (manager); -+ -+#ifdef HAVE_IBUS -+ /* We don't want to touch IBus until we are sure this isn't a -+ fallback session. */ -+ manager->priv->session_is_fallback = TRUE; -+ manager->priv->ibus_cancellable = g_cancellable_new (); -+ g_bus_get (G_BUS_TYPE_SESSION, -+ manager->priv->ibus_cancellable, -+ (GAsyncReadyCallback)got_bus, -+ manager); -+#else -+ apply_input_sources_settings (manager->priv->input_sources_settings, NULL, 0, manager); -+#endif - /* apply current settings before we install the callback */ -- csd_keyboard_manager_apply_settings (manager); -+ g_debug ("Started the keyboard plugin, applying all settings"); -+ apply_all_settings (manager); - - g_signal_connect (G_OBJECT (manager->priv->settings), "changed", -- G_CALLBACK (apply_settings), manager); -- -- apply_libgnomekbd_settings (manager->priv->libgnomekbd_settings, NULL, manager); -- g_signal_connect (G_OBJECT (manager->priv->libgnomekbd_settings), "changed", -- G_CALLBACK (apply_libgnomekbd_settings), manager); -+ G_CALLBACK (settings_changed), manager); -+ g_signal_connect (G_OBJECT (manager->priv->input_sources_settings), "change-event", -+ G_CALLBACK (apply_input_sources_settings), manager); - -- numlock_install_xkb_callback (manager); -+ install_xkb_filter (manager); -+ set_input_sources_switcher (manager, enable_switcher (manager)); - - cinnamon_settings_profile_end (NULL); - -@@ -404,6 +1620,11 @@ csd_keyboard_manager_start (CsdKeyboardM - { - cinnamon_settings_profile_start (NULL); - -+ if (check_xkb_extension (manager) == FALSE) { -+ g_debug ("XKB is not supported, not applying any settings"); -+ return TRUE; -+ } -+ - manager->priv->start_idle_id = g_idle_add ((GSourceFunc) start_keyboard_idle_cb, manager); - - cinnamon_settings_profile_end (NULL); -@@ -418,37 +1639,24 @@ csd_keyboard_manager_stop (CsdKeyboardMa - - g_debug ("Stopping keyboard manager"); - -- if (p->settings != NULL) { -- g_object_unref (p->settings); -- p->settings = NULL; -- } -+ g_clear_object (&p->settings); -+ g_clear_object (&p->input_sources_settings); -+ g_clear_object (&p->interface_settings); -+ g_clear_object (&p->xkb_info); - -- if (p->libgnomekbd_settings != NULL) { -- g_object_unref (p->libgnomekbd_settings); -- p->libgnomekbd_settings = NULL; -- } -+#ifdef HAVE_IBUS -+ clear_ibus (manager); -+#endif - -- if (p->have_xkb) { -- gdk_window_remove_filter (NULL, -- numlock_xkb_callback, -- manager); -+ 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; - } - -- csd_keyboard_xkb_shutdown (); --} -- --static GObject * --csd_keyboard_manager_constructor (GType type, -- guint n_construct_properties, -- GObjectConstructParam *construct_properties) --{ -- CsdKeyboardManager *keyboard_manager; -- -- keyboard_manager = CSD_KEYBOARD_MANAGER (G_OBJECT_CLASS (csd_keyboard_manager_parent_class)->constructor (type, -- n_construct_properties, -- construct_properties)); -+ remove_xkb_filter (manager); - -- return G_OBJECT (keyboard_manager); -+ set_input_sources_switcher (manager, FALSE); - } - - static void -@@ -456,7 +1664,6 @@ csd_keyboard_manager_class_init (CsdKeyb - { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - -- object_class->constructor = csd_keyboard_manager_constructor; - object_class->finalize = csd_keyboard_manager_finalize; - - g_type_class_add_private (klass, sizeof (CsdKeyboardManagerPrivate)); -diff -uNrp a/plugins/keyboard/csd-keyboard-manager.h b/plugins/keyboard/csd-keyboard-manager.h ---- a/plugins/keyboard/csd-keyboard-manager.h 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/keyboard/csd-keyboard-manager.h 2013-08-25 16:36:02.000000000 +0100 -@@ -51,7 +51,6 @@ CsdKeyboardManager * csd_keyboard_ - gboolean csd_keyboard_manager_start (CsdKeyboardManager *manager, - GError **error); - void csd_keyboard_manager_stop (CsdKeyboardManager *manager); --void csd_keyboard_manager_apply_settings (CsdKeyboardManager *manager); - - G_END_DECLS - -diff -uNrp a/plugins/keyboard/csd-keyboard-plugin.h b/plugins/keyboard/csd-keyboard-plugin.h ---- a/plugins/keyboard/csd-keyboard-plugin.h 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/keyboard/csd-keyboard-plugin.h 2013-08-25 16:36:02.000000000 +0100 -@@ -52,7 +52,7 @@ typedef struct - GType csd_keyboard_plugin_get_type (void) G_GNUC_CONST; - - /* All the plugins must implement this function */ --G_MODULE_EXPORT GType register_cinnamon_settings_plugin (GTypeModule *module); -+G_MODULE_EXPORT GType register_gnome_settings_plugin (GTypeModule *module); - - G_END_DECLS - -diff -uNrp a/plugins/keyboard/csd-keyboard-xkb.c b/plugins/keyboard/csd-keyboard-xkb.c ---- a/plugins/keyboard/csd-keyboard-xkb.c 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/keyboard/csd-keyboard-xkb.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,579 +0,0 @@ --/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- -- * -- * Copyright (C) 2001 Udaltsoft -- * -- * Written by Sergey V. Oudaltsov <svu@users.sourceforge.net> -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -- * 02110-1335, USA. -- */ -- --#include "config.h" -- --#include <string.h> --#include <time.h> -- --#include <glib/gi18n.h> --#include <gdk/gdk.h> --#include <gdk/gdkx.h> --#include <gtk/gtk.h> -- --#include <libgnomekbd/gkbd-status.h> -- --#include <libgnomekbd/gkbd-keyboard-drawing.h> --#include <libgnomekbd/gkbd-desktop-config.h> --#include <libgnomekbd/gkbd-indicator-config.h> --#include <libgnomekbd/gkbd-keyboard-config.h> --#include <libgnomekbd/gkbd-util.h> -- --#include "csd-keyboard-xkb.h" --#include "delayed-dialog.h" --#include "cinnamon-settings-profile.h" -- --#define SETTINGS_KEYBOARD_DIR "org.cinnamon.settings-daemon.plugins.keyboard" -- --static CsdKeyboardManager *manager = NULL; -- --static XklEngine *xkl_engine; --static XklConfigRegistry *xkl_registry = NULL; -- --static GkbdDesktopConfig current_config; --static GkbdKeyboardConfig current_kbd_config; -- --/* never terminated */ --static GkbdKeyboardConfig initial_sys_kbd_config; -- --static gboolean inited_ok = FALSE; -- --static GSettings *settings_desktop = NULL; --static GSettings *settings_keyboard = NULL; -- --static PostActivationCallback pa_callback = NULL; --static void *pa_callback_user_data = NULL; -- --static GtkStatusIcon *icon = NULL; -- --static GHashTable *preview_dialogs = NULL; -- --static void --activation_error (void) --{ -- char const *vendor; -- GtkWidget *dialog; -- -- vendor = -- ServerVendor (GDK_DISPLAY_XDISPLAY -- (gdk_display_get_default ())); -- -- /* VNC viewers will not work, do not barrage them with warnings */ -- if (NULL != vendor && NULL != strstr (vendor, "VNC")) -- return; -- -- dialog = gtk_message_dialog_new_with_markup (NULL, -- 0, -- GTK_MESSAGE_ERROR, -- GTK_BUTTONS_CLOSE, -- _ -- ("Error activating XKB configuration.\n" -- "There can be various reasons for that.\n\n" -- "If you report this situation as a bug, include the results of\n" -- " • <b>%s</b>\n" -- " • <b>%s</b>\n" -- " • <b>%s</b>\n" -- " • <b>%s</b>"), -- "xprop -root | grep XKB", -- "gsettings get org.gnome.libgnomekbd.keyboard model", -- "gsettings get org.gnome.libgnomekbd.keyboard layouts", -- "gsettings get org.gnome.libgnomekbd.keyboard options"); -- g_signal_connect (dialog, "response", -- G_CALLBACK (gtk_widget_destroy), NULL); -- csd_delayed_show_dialog (dialog); --} -- --static gboolean --ensure_xkl_registry (void) --{ -- if (!xkl_registry) { -- xkl_registry = -- xkl_config_registry_get_instance (xkl_engine); -- /* load all materials, unconditionally! */ -- if (!xkl_config_registry_load (xkl_registry, TRUE)) { -- g_object_unref (xkl_registry); -- xkl_registry = NULL; -- return FALSE; -- } -- } -- -- return TRUE; --} -- --static void --apply_desktop_settings (void) --{ -- if (!inited_ok) -- return; -- -- csd_keyboard_manager_apply_settings (manager); -- gkbd_desktop_config_load (¤t_config); -- /* again, probably it would be nice to compare things -- before activating them */ -- gkbd_desktop_config_activate (¤t_config); --} -- --static void --popup_menu_launch_capplet () --{ -- GAppInfo *info; -- GdkAppLaunchContext *ctx; -- GError *error = NULL; -- -- info = -- g_app_info_create_from_commandline -- ("cinnamon-settings region", NULL, 0, &error); -- -- if (info != NULL) { -- ctx = -- gdk_display_get_app_launch_context -- (gdk_display_get_default ()); -- -- if (g_app_info_launch (info, NULL, -- G_APP_LAUNCH_CONTEXT (ctx), &error) == FALSE) { -- g_warning -- ("Could not execute keyboard properties capplet: [%s]\n", -- error->message); -- g_error_free (error); -- } -- -- g_object_unref (info); -- g_object_unref (ctx); -- } -- --} -- --static void --show_layout_destroy (GtkWidget * dialog, gint group) --{ -- g_hash_table_remove (preview_dialogs, GINT_TO_POINTER (group)); --} -- --static void --popup_menu_show_layout () --{ -- GtkWidget *dialog; -- XklEngine *engine = -- xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY -- (gdk_display_get_default ())); -- XklState *xkl_state = xkl_engine_get_current_state (engine); -- -- gchar **group_names = gkbd_status_get_group_names (); -- -- gpointer p = g_hash_table_lookup (preview_dialogs, -- GINT_TO_POINTER -- (xkl_state->group)); -- -- if (xkl_state->group < 0 -- || xkl_state->group >= g_strv_length (group_names)) { -- return; -- } -- -- if (p != NULL) { -- /* existing window */ -- gtk_window_present (GTK_WINDOW (p)); -- return; -- } -- -- if (!ensure_xkl_registry ()) -- return; -- -- dialog = gkbd_keyboard_drawing_dialog_new (); -- gkbd_keyboard_drawing_dialog_set_group (dialog, xkl_registry, xkl_state->group); -- -- g_signal_connect (dialog, "destroy", -- G_CALLBACK (show_layout_destroy), -- GINT_TO_POINTER (xkl_state->group)); -- g_hash_table_insert (preview_dialogs, -- GINT_TO_POINTER (xkl_state->group), dialog); -- gtk_widget_show_all (dialog); --} -- --static void --popup_menu_set_group (gint group_number, gboolean only_menu) --{ -- -- XklEngine *engine = gkbd_status_get_xkl_engine (); -- -- XklState *st = xkl_engine_get_current_state(engine); -- Window cur; -- st->group = group_number; -- xkl_engine_allow_one_switch_to_secondary_group (engine); -- cur = xkl_engine_get_current_window (engine); -- if (cur != (Window) NULL) { -- xkl_debug (150, "Enforcing the state %d for window %lx\n", -- st->group, cur); -- -- xkl_engine_save_state (engine, -- xkl_engine_get_current_window -- (engine), st); --/* XSetInputFocus( GDK_DISPLAY(), cur, RevertToNone, CurrentTime );*/ -- } else { -- xkl_debug (150, -- "??? Enforcing the state %d for unknown window\n", -- st->group); -- /* strange situation - bad things can happen */ -- } -- if (!only_menu) -- xkl_engine_lock_group (engine, st->group); --} -- --static void --popup_menu_set_group_cb (GtkMenuItem * item, gpointer param) --{ -- gint group_number = GPOINTER_TO_INT (param); -- -- popup_menu_set_group(group_number, FALSE); --} -- -- --static GtkMenu * --create_status_menu (void) --{ -- GtkMenu *popup_menu = GTK_MENU (gtk_menu_new ()); -- int i = 0; -- -- GtkMenu *groups_menu = GTK_MENU (gtk_menu_new ()); -- gchar **current_name = gkbd_status_get_group_names (); -- -- GtkWidget *item = gtk_menu_item_new_with_mnemonic (_("_Layouts")); -- gtk_widget_show (item); -- gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); -- gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), -- GTK_WIDGET (groups_menu)); -- -- item = gtk_menu_item_new_with_mnemonic (_("Show _Keyboard Layout...")); -- gtk_widget_show (item); -- g_signal_connect (item, "activate", popup_menu_show_layout, NULL); -- gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); -- -- /* translators note: -- * This is the name of the cinnamon-settings "region" panel */ -- item = gtk_menu_item_new_with_mnemonic (_("Region and Language Settings")); -- gtk_widget_show (item); -- g_signal_connect (item, "activate", popup_menu_launch_capplet, NULL); -- gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); -- -- for (i = 0; current_name && *current_name; i++, current_name++) { -- -- gchar *image_file = gkbd_status_get_image_filename (i); -- -- if (image_file == NULL) { -- item = -- gtk_menu_item_new_with_label (*current_name); -- } else { -- GdkPixbuf *pixbuf = -- gdk_pixbuf_new_from_file_at_size (image_file, -- 24, 24, -- NULL); -- GtkWidget *img = -- gtk_image_new_from_pixbuf (pixbuf); -- item = -- gtk_image_menu_item_new_with_label -- (*current_name); -- gtk_widget_show (img); -- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM -- (item), img); -- gtk_image_menu_item_set_always_show_image -- (GTK_IMAGE_MENU_ITEM (item), TRUE); -- g_free (image_file); -- } -- gtk_widget_show (item); -- gtk_menu_shell_append (GTK_MENU_SHELL (groups_menu), item); -- g_signal_connect (item, "activate", -- G_CALLBACK (popup_menu_set_group_cb), -- GINT_TO_POINTER (i)); -- } -- -- return popup_menu; --} -- --static void --status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) --{ -- GtkMenu *popup_menu = create_status_menu (); -- -- gtk_menu_popup (popup_menu, NULL, NULL, -- gtk_status_icon_position_menu, -- (gpointer) icon, button, time); --} -- --static void --show_hide_icon () --{ -- if (g_strv_length (current_kbd_config.layouts_variants) > 1) { -- if (icon == NULL) { -- xkl_debug (150, "Creating keyboard status icon\n"); -- icon = gkbd_status_new (); -- g_signal_connect (icon, "popup-menu", -- G_CALLBACK -- (status_icon_popup_menu_cb), -- NULL); -- -- } -- } else { -- if (icon != NULL) { -- xkl_debug (150, "Destroying icon\n"); -- g_object_unref (icon); -- icon = NULL; -- } -- } --} -- --static gboolean --try_activating_xkb_config_if_new (GkbdKeyboardConfig * -- current_sys_kbd_config) --{ -- /* Activate - only if different! */ -- if (!gkbd_keyboard_config_equals -- (¤t_kbd_config, current_sys_kbd_config)) { -- if (gkbd_keyboard_config_activate (¤t_kbd_config)) { -- if (pa_callback != NULL) { -- (*pa_callback) (pa_callback_user_data); -- return TRUE; -- } -- } else { -- return FALSE; -- } -- } -- return TRUE; --} -- --static gboolean --filter_xkb_config (void) --{ -- XklConfigItem *item; -- gchar *lname; -- gchar *vname; -- gchar **lv; -- gboolean any_change = FALSE; -- -- xkl_debug (100, "Filtering configuration against the registry\n"); -- if (!ensure_xkl_registry ()) -- return FALSE; -- -- lv = current_kbd_config.layouts_variants; -- item = xkl_config_item_new (); -- while (*lv) { -- xkl_debug (100, "Checking [%s]\n", *lv); -- if (gkbd_keyboard_config_split_items (*lv, &lname, &vname)) { -- gboolean should_be_dropped = FALSE; -- g_snprintf (item->name, sizeof (item->name), "%s", -- lname); -- if (!xkl_config_registry_find_layout -- (xkl_registry, item)) { -- xkl_debug (100, "Bad layout [%s]\n", -- lname); -- should_be_dropped = TRUE; -- } else if (vname) { -- g_snprintf (item->name, -- sizeof (item->name), "%s", -- vname); -- if (!xkl_config_registry_find_variant -- (xkl_registry, lname, item)) { -- xkl_debug (100, -- "Bad variant [%s(%s)]\n", -- lname, vname); -- should_be_dropped = TRUE; -- } -- } -- if (should_be_dropped) { -- gkbd_strv_behead (lv); -- any_change = TRUE; -- continue; -- } -- } -- lv++; -- } -- g_object_unref (item); -- return any_change; --} -- --static void --apply_xkb_settings (void) --{ -- GkbdKeyboardConfig current_sys_kbd_config; -- -- if (!inited_ok) -- return; -- -- gkbd_keyboard_config_init (¤t_sys_kbd_config, xkl_engine); -- -- gkbd_keyboard_config_load (¤t_kbd_config, -- &initial_sys_kbd_config); -- -- gkbd_keyboard_config_load_from_x_current (¤t_sys_kbd_config, -- NULL); -- -- if (!try_activating_xkb_config_if_new (¤t_sys_kbd_config)) { -- if (filter_xkb_config ()) { -- if (!try_activating_xkb_config_if_new -- (¤t_sys_kbd_config)) { -- g_warning -- ("Could not activate the filtered XKB configuration"); -- activation_error (); -- } -- } else { -- g_warning -- ("Could not activate the XKB configuration"); -- activation_error (); -- } -- } else -- xkl_debug (100, -- "Actual KBD configuration was not changed: redundant notification\n"); -- -- gkbd_keyboard_config_term (¤t_sys_kbd_config); -- show_hide_icon (); --} -- --static void --csd_keyboard_xkb_analyze_sysconfig (void) --{ -- if (!inited_ok) -- return; -- -- gkbd_keyboard_config_init (&initial_sys_kbd_config, xkl_engine); -- gkbd_keyboard_config_load_from_x_initial (&initial_sys_kbd_config, -- NULL); --} -- --void --csd_keyboard_xkb_set_post_activation_callback (PostActivationCallback fun, -- void *user_data) --{ -- pa_callback = fun; -- pa_callback_user_data = user_data; --} -- --static GdkFilterReturn --csd_keyboard_xkb_evt_filter (GdkXEvent * xev, GdkEvent * event) --{ -- XEvent *xevent = (XEvent *) xev; -- xkl_engine_filter_events (xkl_engine, xevent); -- return GDK_FILTER_CONTINUE; --} -- --/* When new Keyboard is plugged in - reload the settings */ --static void --csd_keyboard_new_device (XklEngine * engine) --{ -- apply_desktop_settings (); -- apply_xkb_settings (); --} -- --void --csd_keyboard_xkb_init (CsdKeyboardManager * kbd_manager) --{ -- Display *display = -- GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); -- cinnamon_settings_profile_start (NULL); -- -- gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), -- DATADIR G_DIR_SEPARATOR_S -- "icons"); -- -- manager = kbd_manager; -- cinnamon_settings_profile_start ("xkl_engine_get_instance"); -- xkl_engine = xkl_engine_get_instance (display); -- cinnamon_settings_profile_end ("xkl_engine_get_instance"); -- if (xkl_engine) { -- inited_ok = TRUE; -- -- gkbd_desktop_config_init (¤t_config, xkl_engine); -- gkbd_keyboard_config_init (¤t_kbd_config, -- xkl_engine); -- xkl_engine_backup_names_prop (xkl_engine); -- csd_keyboard_xkb_analyze_sysconfig (); -- -- settings_desktop = g_settings_new (GKBD_DESKTOP_SCHEMA); -- settings_keyboard = g_settings_new (GKBD_KEYBOARD_SCHEMA); -- g_signal_connect (settings_desktop, "changed", -- (GCallback) apply_desktop_settings, -- NULL); -- g_signal_connect (settings_keyboard, "changed", -- (GCallback) apply_xkb_settings, NULL); -- -- gdk_window_add_filter (NULL, (GdkFilterFunc) -- csd_keyboard_xkb_evt_filter, NULL); -- -- if (xkl_engine_get_features (xkl_engine) & -- XKLF_DEVICE_DISCOVERY) -- g_signal_connect (xkl_engine, "X-new-device", -- G_CALLBACK -- (csd_keyboard_new_device), NULL); -- -- cinnamon_settings_profile_start ("xkl_engine_start_listen"); -- xkl_engine_start_listen (xkl_engine, -- XKLL_MANAGE_LAYOUTS | -- XKLL_MANAGE_WINDOW_STATES); -- cinnamon_settings_profile_end ("xkl_engine_start_listen"); -- -- cinnamon_settings_profile_start ("apply_desktop_settings"); -- apply_desktop_settings (); -- cinnamon_settings_profile_end ("apply_desktop_settings"); -- cinnamon_settings_profile_start ("apply_xkb_settings"); -- apply_xkb_settings (); -- cinnamon_settings_profile_end ("apply_xkb_settings"); -- } -- preview_dialogs = g_hash_table_new (g_direct_hash, g_direct_equal); -- -- cinnamon_settings_profile_end (NULL); --} -- --void --csd_keyboard_xkb_shutdown (void) --{ -- if (!inited_ok) -- return; -- -- pa_callback = NULL; -- pa_callback_user_data = NULL; -- manager = NULL; -- -- if (preview_dialogs != NULL) -- g_hash_table_destroy (preview_dialogs); -- -- if (!inited_ok) -- return; -- -- xkl_engine_stop_listen (xkl_engine, -- XKLL_MANAGE_LAYOUTS | -- XKLL_MANAGE_WINDOW_STATES); -- -- gdk_window_remove_filter (NULL, (GdkFilterFunc) -- csd_keyboard_xkb_evt_filter, NULL); -- -- g_object_unref (settings_desktop); -- settings_desktop = NULL; -- g_object_unref (settings_keyboard); -- settings_keyboard = NULL; -- -- if (xkl_registry) { -- g_object_unref (xkl_registry); -- } -- -- g_object_unref (xkl_engine); -- -- xkl_engine = NULL; -- -- inited_ok = FALSE; --} -diff -uNrp a/plugins/keyboard/csd-keyboard-xkb.h b/plugins/keyboard/csd-keyboard-xkb.h ---- a/plugins/keyboard/csd-keyboard-xkb.h 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/keyboard/csd-keyboard-xkb.h 1970-01-01 01:00:00.000000000 +0100 -@@ -1,39 +0,0 @@ --/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- -- * cinnamon-settings-keyboard-xkb.h -- * -- * Copyright (C) 2001 Udaltsoft -- * -- * Written by Sergey V. Oudaltsov <svu@users.sourceforge.net> -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -- * 02110-1335, USA. -- */ -- --#ifndef __CSD_KEYBOARD_XKB_H --#define __CSD_KEYBOARD_XKB_H -- --#include <libxklavier/xklavier.h> --#include "csd-keyboard-manager.h" -- --void csd_keyboard_xkb_init (CsdKeyboardManager *manager); --void csd_keyboard_xkb_shutdown (void); -- --typedef void (*PostActivationCallback) (void *userData); -- --void --csd_keyboard_xkb_set_post_activation_callback (PostActivationCallback fun, -- void *userData); -- --#endif -diff -uNrp a/plugins/keyboard/delayed-dialog.c b/plugins/keyboard/delayed-dialog.c ---- a/plugins/keyboard/delayed-dialog.c 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/keyboard/delayed-dialog.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,128 +0,0 @@ --/* -- * Copyright © 2006 Novell, Inc. -- * -- * This program is free software; you can redistribute it and/or -- * modify it under the terms of the GNU General Public License as -- * published by the Free Software Foundation; either version 2, or (at -- * your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, but -- * WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -- * 02110-1335, USA. -- */ -- --#include <stdlib.h> --#include <string.h> -- --#include <gtk/gtk.h> --#include <gdk/gdkx.h> -- --#include "delayed-dialog.h" -- --static gboolean delayed_show_timeout (gpointer data); --static GdkFilterReturn message_filter (GdkXEvent *xevent, -- GdkEvent *event, -- gpointer data); -- --static GSList *dialogs = NULL; -- --/** -- * csd_delayed_show_dialog: -- * @dialog: the dialog -- * -- * Shows the dialog as with gtk_widget_show(), unless a window manager -- * hasn't been started yet, in which case it will wait up to 5 seconds -- * for that to happen before showing the dialog. -- **/ --void --csd_delayed_show_dialog (GtkWidget *dialog) --{ -- GdkDisplay *display = gtk_widget_get_display (dialog); -- Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); -- GdkScreen *screen = gtk_widget_get_screen (dialog); -- char selection_name[10]; -- Atom selection_atom; -- -- /* We can't use gdk_selection_owner_get() for this, because -- * it's an unknown out-of-process window. -- */ -- snprintf (selection_name, sizeof (selection_name), "WM_S%d", -- gdk_screen_get_number (screen)); -- selection_atom = XInternAtom (xdisplay, selection_name, True); -- if (selection_atom && -- XGetSelectionOwner (xdisplay, selection_atom) != None) { -- gtk_widget_show (dialog); -- return; -- } -- -- dialogs = g_slist_prepend (dialogs, dialog); -- -- gdk_window_add_filter (NULL, message_filter, NULL); -- -- g_timeout_add (5000, delayed_show_timeout, NULL); --} -- --static gboolean --delayed_show_timeout (gpointer data) --{ -- GSList *l; -- -- for (l = dialogs; l; l = l->next) -- gtk_widget_show (l->data); -- g_slist_free (dialogs); -- dialogs = NULL; -- -- /* FIXME: There's no gdk_display_remove_client_message_filter */ -- -- return FALSE; --} -- --static GdkFilterReturn --message_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) --{ -- XClientMessageEvent *evt; -- char *selection_name; -- int screen; -- GSList *l, *next; -- -- if (((XEvent *)xevent)->type != ClientMessage) -- return GDK_FILTER_CONTINUE; -- -- evt = (XClientMessageEvent *)xevent; -- -- if (evt->message_type != XInternAtom (evt->display, "MANAGER", FALSE)) -- return GDK_FILTER_CONTINUE; -- -- selection_name = XGetAtomName (evt->display, evt->data.l[1]); -- -- if (strncmp (selection_name, "WM_S", 4) != 0) { -- XFree (selection_name); -- return GDK_FILTER_CONTINUE; -- } -- -- screen = atoi (selection_name + 4); -- -- for (l = dialogs; l; l = next) { -- GtkWidget *dialog = l->data; -- next = l->next; -- -- if (gdk_screen_get_number (gtk_widget_get_screen (dialog)) == screen) { -- gtk_widget_show (dialog); -- dialogs = g_slist_remove (dialogs, dialog); -- } -- } -- -- if (!dialogs) { -- gdk_window_remove_filter (NULL, message_filter, NULL); -- } -- -- XFree (selection_name); -- -- return GDK_FILTER_CONTINUE; --} -diff -uNrp a/plugins/keyboard/delayed-dialog.h b/plugins/keyboard/delayed-dialog.h ---- a/plugins/keyboard/delayed-dialog.h 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/keyboard/delayed-dialog.h 1970-01-01 01:00:00.000000000 +0100 -@@ -1,32 +0,0 @@ --/* -- * Copyright © 2006 Novell, Inc. -- * -- * This program is free software; you can redistribute it and/or -- * modify it under the terms of the GNU General Public License as -- * published by the Free Software Foundation; either version 2, or (at -- * your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, but -- * WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -- * 02110-1335, USA. -- */ -- -- --#ifndef __DELAYED_DIALOG_H --#define __DELAYED_DIALOG_H -- --#include <gtk/gtk.h> -- --G_BEGIN_DECLS -- --void csd_delayed_show_dialog (GtkWidget *dialog); -- --G_END_DECLS -- --#endif -diff -uNrp a/plugins/keyboard/gkbd-configuration.c b/plugins/keyboard/gkbd-configuration.c ---- a/plugins/keyboard/gkbd-configuration.c 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/keyboard/gkbd-configuration.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,350 +0,0 @@ --/* -- * Copyright (C) 2010 Canonical Ltd. -- * -- * Authors: Jan Arne Petersen <jpetersen@openismus.com> -- * -- * Based on gkbd-status.c by Sergey V. Udaltsov <svu@gnome.org> -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General Public -- * License along with this library; if not, write to the -- * Free Software Foundation, Inc., 51 Franklin Street - Suite 500, -- * Boston, MA 02110-1335, USA. -- */ -- --#include <memory.h> -- --#include <gdk/gdkkeysyms.h> --#include <gdk/gdkx.h> --#include <glib/gi18n.h> -- --#include <libgnomekbd/gkbd-desktop-config.h> --#include <libgnomekbd/gkbd-indicator-config.h> -- --#include "gkbd-configuration.h" -- --struct _GkbdConfigurationPrivate { -- XklEngine *engine; -- XklConfigRegistry *registry; -- -- GkbdDesktopConfig cfg; -- GkbdIndicatorConfig ind_cfg; -- GkbdKeyboardConfig kbd_cfg; -- -- gchar **full_group_names; -- gchar **short_group_names; -- -- gulong state_changed_handler; -- gulong config_changed_handler; --}; -- --enum { -- SIGNAL_CHANGED, -- SIGNAL_GROUP_CHANGED, -- LAST_SIGNAL --}; -- --static guint signals[LAST_SIGNAL] = { 0, }; -- --#define GKBD_CONFIGURATION_GET_PRIVATE(o) \ -- (G_TYPE_INSTANCE_GET_PRIVATE ((o), GKBD_TYPE_CONFIGURATION, GkbdConfigurationPrivate)) -- --G_DEFINE_TYPE (GkbdConfiguration, gkbd_configuration, G_TYPE_OBJECT) -- --/* Should be called once for all widgets */ --static void --gkbd_configuration_cfg_changed (GSettings *settings, -- const char *key, -- GkbdConfiguration * configuration) --{ -- GkbdConfigurationPrivate *priv = configuration->priv; -- -- xkl_debug (100, -- "General configuration changed in GSettings - reiniting...\n"); -- gkbd_desktop_config_load (&priv->cfg); -- gkbd_desktop_config_activate (&priv->cfg); -- -- g_signal_emit (configuration, -- signals[SIGNAL_CHANGED], 0); --} -- --/* Should be called once for all widgets */ --static void --gkbd_configuration_ind_cfg_changed (GSettings *settings, -- const char *key, -- GkbdConfiguration * configuration) --{ -- GkbdConfigurationPrivate *priv = configuration->priv; -- xkl_debug (100, -- "Applet configuration changed in GSettings - reiniting...\n"); -- gkbd_indicator_config_load (&priv->ind_cfg); -- -- gkbd_indicator_config_free_image_filenames (&priv->ind_cfg); -- gkbd_indicator_config_load_image_filenames (&priv->ind_cfg, -- &priv->kbd_cfg); -- -- gkbd_indicator_config_activate (&priv->ind_cfg); -- -- g_signal_emit (configuration, -- signals[SIGNAL_CHANGED], 0); --} -- --static void --gkbd_configuration_load_group_names (GkbdConfiguration * configuration, -- XklConfigRec * xklrec) --{ -- GkbdConfigurationPrivate *priv = configuration->priv; -- -- if (!gkbd_desktop_config_load_group_descriptions (&priv->cfg, -- priv->registry, -- (const char **) xklrec->layouts, -- (const char **) xklrec->variants, -- &priv->short_group_names, -- &priv->full_group_names)) { -- /* We just populate no short names (remain NULL) - -- * full names are going to be used anyway */ -- gint i, total_groups = -- xkl_engine_get_num_groups (priv->engine); -- xkl_debug (150, "group descriptions loaded: %d!\n", -- total_groups); -- priv->full_group_names = -- g_new0 (char *, total_groups + 1); -- -- if (xkl_engine_get_features (priv->engine) & -- XKLF_MULTIPLE_LAYOUTS_SUPPORTED) { -- for (i = 0; priv->kbd_cfg.layouts_variants[i]; i++) { -- priv->full_group_names[i] = -- g_strdup ((char *) priv->kbd_cfg.layouts_variants[i]); -- } -- } else { -- for (i = total_groups; --i >= 0;) { -- priv->full_group_names[i] = -- g_strdup_printf ("Group %d", i); -- } -- } -- } --} -- --/* Should be called once for all widgets */ --static void --gkbd_configuration_kbd_cfg_callback (XklEngine *engine, -- GkbdConfiguration *configuration) --{ -- GkbdConfigurationPrivate *priv = configuration->priv; -- XklConfigRec *xklrec = xkl_config_rec_new (); -- xkl_debug (100, -- "XKB configuration changed on X Server - reiniting...\n"); -- -- gkbd_keyboard_config_load_from_x_current (&priv->kbd_cfg, -- xklrec); -- -- gkbd_indicator_config_free_image_filenames (&priv->ind_cfg); -- gkbd_indicator_config_load_image_filenames (&priv->ind_cfg, -- &priv->kbd_cfg); -- -- g_strfreev (priv->full_group_names); -- priv->full_group_names = NULL; -- -- g_strfreev (priv->short_group_names); -- priv->short_group_names = NULL; -- -- gkbd_configuration_load_group_names (configuration, -- xklrec); -- -- g_signal_emit (configuration, -- signals[SIGNAL_CHANGED], -- 0); -- -- g_object_unref (G_OBJECT (xklrec)); --} -- --/* Should be called once for all applets */ --static void --gkbd_configuration_state_callback (XklEngine * engine, -- XklEngineStateChange changeType, -- gint group, gboolean restore, -- GkbdConfiguration * configuration) --{ -- xkl_debug (150, "group is now %d, restore: %d\n", group, restore); -- -- if (changeType == GROUP_CHANGED) { -- g_signal_emit (configuration, -- signals[SIGNAL_GROUP_CHANGED], 0, -- group); -- } --} -- --static void --gkbd_configuration_init (GkbdConfiguration *configuration) --{ -- GkbdConfigurationPrivate *priv; -- XklConfigRec *xklrec = xkl_config_rec_new (); -- -- priv = GKBD_CONFIGURATION_GET_PRIVATE (configuration); -- configuration->priv = priv; -- -- priv->engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); -- if (priv->engine == NULL) { -- xkl_debug (0, "Libxklavier initialization error"); -- return; -- } -- -- priv->state_changed_handler = -- g_signal_connect (priv->engine, "X-state-changed", -- G_CALLBACK (gkbd_configuration_state_callback), -- configuration); -- priv->config_changed_handler = -- g_signal_connect (priv->engine, "X-config-changed", -- G_CALLBACK (gkbd_configuration_kbd_cfg_callback), -- configuration); -- -- gkbd_desktop_config_init (&priv->cfg, priv->engine); -- gkbd_keyboard_config_init (&priv->kbd_cfg, priv->engine); -- gkbd_indicator_config_init (&priv->ind_cfg, priv->engine); -- -- gkbd_desktop_config_load (&priv->cfg); -- gkbd_desktop_config_activate (&priv->cfg); -- -- priv->registry = xkl_config_registry_get_instance (priv->engine); -- xkl_config_registry_load (priv->registry, -- priv->cfg.load_extra_items); -- -- gkbd_keyboard_config_load_from_x_current (&priv->kbd_cfg, -- xklrec); -- -- gkbd_indicator_config_load (&priv->ind_cfg); -- -- gkbd_indicator_config_load_image_filenames (&priv->ind_cfg, -- &priv->kbd_cfg); -- -- gkbd_indicator_config_activate (&priv->ind_cfg); -- -- gkbd_configuration_load_group_names (configuration, -- xklrec); -- g_object_unref (G_OBJECT (xklrec)); -- -- gkbd_desktop_config_start_listen (&priv->cfg, -- G_CALLBACK (gkbd_configuration_cfg_changed), -- configuration); -- gkbd_indicator_config_start_listen (&priv->ind_cfg, -- G_CALLBACK (gkbd_configuration_ind_cfg_changed), -- configuration); -- xkl_engine_start_listen (priv->engine, -- XKLL_TRACK_KEYBOARD_STATE); -- -- xkl_debug (100, "Initiating the widget startup process for %p\n", -- configuration); --} -- --static void --gkbd_configuration_finalize (GObject * obj) --{ -- GkbdConfiguration *configuration = GKBD_CONFIGURATION (obj); -- GkbdConfigurationPrivate *priv = configuration->priv; -- -- xkl_debug (100, -- "Starting the gnome-kbd-configuration widget shutdown process for %p\n", -- configuration); -- -- xkl_engine_stop_listen (priv->engine, -- XKLL_TRACK_KEYBOARD_STATE); -- -- gkbd_desktop_config_stop_listen (&priv->cfg); -- gkbd_indicator_config_stop_listen (&priv->ind_cfg); -- -- gkbd_indicator_config_term (&priv->ind_cfg); -- gkbd_keyboard_config_term (&priv->kbd_cfg); -- gkbd_desktop_config_term (&priv->cfg); -- -- if (g_signal_handler_is_connected (priv->engine, -- priv->state_changed_handler)) { -- g_signal_handler_disconnect (priv->engine, -- priv->state_changed_handler); -- priv->state_changed_handler = 0; -- } -- if (g_signal_handler_is_connected (priv->engine, -- priv->config_changed_handler)) { -- g_signal_handler_disconnect (priv->engine, -- priv->config_changed_handler); -- priv->config_changed_handler = 0; -- } -- -- g_object_unref (priv->registry); -- priv->registry = NULL; -- g_object_unref (priv->engine); -- priv->engine = NULL; -- -- G_OBJECT_CLASS (gkbd_configuration_parent_class)->finalize (obj); --} -- --static void --gkbd_configuration_class_init (GkbdConfigurationClass * klass) --{ -- GObjectClass *object_class = G_OBJECT_CLASS (klass); -- -- /* Initing vtable */ -- object_class->finalize = gkbd_configuration_finalize; -- -- /* Signals */ -- signals[SIGNAL_CHANGED] = g_signal_new ("changed", -- GKBD_TYPE_CONFIGURATION, -- G_SIGNAL_RUN_LAST, -- 0, -- NULL, NULL, -- g_cclosure_marshal_VOID__VOID, -- G_TYPE_NONE, -- 0); -- signals[SIGNAL_GROUP_CHANGED] = g_signal_new ("group-changed", -- GKBD_TYPE_CONFIGURATION, -- G_SIGNAL_RUN_LAST, -- 0, -- NULL, NULL, -- g_cclosure_marshal_VOID__INT, -- G_TYPE_NONE, -- 1, -- G_TYPE_INT); -- -- g_type_class_add_private (klass, sizeof (GkbdConfigurationPrivate)); --} -- --GkbdConfiguration * --gkbd_configuration_get (void) --{ -- static gpointer instance = NULL; -- -- if (!instance) { -- instance = g_object_new (GKBD_TYPE_CONFIGURATION, NULL); -- g_object_add_weak_pointer (instance, &instance); -- } else { -- g_object_ref (instance); -- } -- -- return instance; --} -- --XklEngine * --gkbd_configuration_get_xkl_engine (GkbdConfiguration *configuration) --{ -- return configuration->priv->engine; --} -- --const char * const * --gkbd_configuration_get_group_names (GkbdConfiguration *configuration) --{ -- return configuration->priv->full_group_names; --} -- --const char * const * --gkbd_configuration_get_short_group_names (GkbdConfiguration *configuration) --{ -- return configuration->priv->short_group_names; --} -diff -uNrp a/plugins/keyboard/gkbd-configuration.h b/plugins/keyboard/gkbd-configuration.h ---- a/plugins/keyboard/gkbd-configuration.h 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/keyboard/gkbd-configuration.h 1970-01-01 01:00:00.000000000 +0100 -@@ -1,65 +0,0 @@ --/* -- * Copyright (C) 2010 Canonical Ltd. -- * -- * Authors: Jan Arne Petersen <jpetersen@openismus.com> -- * -- * Based on gkbd-status.h by Sergey V. Udaltsov <svu@gnome.org> -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General Public -- * License along with this library; if not, write to the -- * Free Software Foundation, Inc., 51 Franklin Street - Suite 500, -- * Boston, MA 02110-1335, USA. -- */ -- --#ifndef __GKBD_CONFIGURATION_H__ --#define __GKBD_CONFIGURATION_H__ -- --#include <glib-object.h> -- --#include <libxklavier/xklavier.h> -- --G_BEGIN_DECLS -- --typedef struct _GkbdConfiguration GkbdConfiguration; --typedef struct _GkbdConfigurationPrivate GkbdConfigurationPrivate; --typedef struct _GkbdConfigurationClass GkbdConfigurationClass; -- --#define GKBD_TYPE_CONFIGURATION (gkbd_configuration_get_type ()) --#define GKBD_CONFIGURATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKBD_TYPE_CONFIGURATION, GkbdConfiguration)) --#define GKBD_INDCATOR_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GKBD_TYPE_CONFIGURATION, GkbdConfigurationClass)) --#define GKBD_IS_CONFIGURATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKBD_TYPE_CONFIGURATION)) --#define GKBD_IS_CONFIGURATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), GKBD_TYPE_CONFIGURATION)) --#define GKBD_CONFIGURATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKBD_TYPE_CONFIGURATION, GkbdConfigurationClass)) -- --struct _GkbdConfiguration { -- GObject parent; -- -- GkbdConfigurationPrivate *priv; --}; -- --struct _GkbdConfigurationClass { -- GObjectClass parent_class; --}; -- --extern GType gkbd_configuration_get_type (void); -- --extern GkbdConfiguration *gkbd_configuration_get (void); -- --extern XklEngine *gkbd_configuration_get_xkl_engine (GkbdConfiguration *configuration); -- --extern const char * const *gkbd_configuration_get_group_names (GkbdConfiguration *configuration); --extern const char * const *gkbd_configuration_get_short_group_names (GkbdConfiguration *configuration); -- --G_END_DECLS -- --#endif -diff -uNrp a/plugins/keyboard/.indent.pro b/plugins/keyboard/.indent.pro ---- a/plugins/keyboard/.indent.pro 1970-01-01 01:00:00.000000000 +0100 -+++ b/plugins/keyboard/.indent.pro 2013-08-25 16:36:02.000000000 +0100 -@@ -0,0 +1,2 @@ -+-kr -i8 -pcs -lps -psl -+ -diff -uNrp a/plugins/keyboard/Makefile.am b/plugins/keyboard/Makefile.am ---- a/plugins/keyboard/Makefile.am 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/keyboard/Makefile.am 2013-08-25 16:36:02.000000000 +0100 -@@ -20,25 +20,20 @@ libkeyboard_la_SOURCES = \ - csd-keyboard-plugin.c \ - csd-keyboard-manager.h \ - csd-keyboard-manager.c \ -- csd-keyboard-xkb.h \ -- csd-keyboard-xkb.c \ -- delayed-dialog.h \ -- delayed-dialog.c \ -- gkbd-configuration.c \ -- gkbd-configuration.h \ - $(NULL) - - libkeyboard_la_CPPFLAGS = \ - -I$(top_srcdir)/cinnamon-settings-daemon \ - -I$(top_srcdir)/data \ -+ -I$(top_srcdir)/plugins/common \ - -DDATADIR=\""$(pkgdatadir)"\" \ -+ -DLIBEXECDIR=\""$(libexecdir)"\" \ - -DCINNAMON_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ - $(AM_CPPFLAGS) - - libkeyboard_la_CFLAGS = \ - $(PLUGIN_CFLAGS) \ - $(SETTINGS_PLUGIN_CFLAGS) \ -- $(APPINDICATOR_CFLAGS) \ - $(KEYBOARD_CFLAGS) \ - $(AM_CFLAGS) - -@@ -46,19 +41,63 @@ libkeyboard_la_LDFLAGS = \ - $(CSD_PLUGIN_LDFLAGS) \ - $(NULL) - --libkeyboard_la_LIBADD = \ -- $(SETTINGS_PLUGIN_LIBS) \ -- $(XF86MISC_LIBS) \ -- $(KEYBOARD_LIBS) \ -- $(APPINDICATOR_LIBS) \ -+libkeyboard_la_LIBADD = \ -+ $(top_builddir)/plugins/common/libcommon.la \ -+ $(SETTINGS_PLUGIN_LIBS) \ -+ $(XF86MISC_LIBS) \ -+ $(KEYBOARD_LIBS) \ - $(NULL) - -+libexec_PROGRAMS = csd-test-keyboard -+csd_test_keyboard_SOURCES = \ -+ test-keyboard.c \ -+ csd-keyboard-manager.h \ -+ csd-keyboard-manager.c \ -+ $(NULL) -+ -+csd_test_keyboard_CFLAGS = $(libkeyboard_la_CFLAGS) -+csd_test_keyboard_CPPFLAGS = $(libkeyboard_la_CPPFLAGS) -+csd_test_keyboard_LDADD = $(libkeyboard_la_LIBADD) $(top_builddir)/cinnamon-settings-daemon/libcsd.la -+ - plugin_in_files = \ - keyboard.cinnamon-settings-plugin.in \ - $(NULL) - - plugin_DATA = $(plugin_in_files:.cinnamon-settings-plugin.in=.cinnamon-settings-plugin) - -+if HAVE_IBUS -+noinst_PROGRAMS = test-keyboard-ibus-utils -+test_keyboard_ibus_utils_SOURCES = test-keyboard-ibus-utils.c -+test_keyboard_ibus_utils_CFLAGS = $(libkeyboard_la_CFLAGS) -+test_keyboard_ibus_utils_CPPFLAGS = $(libkeyboard_la_CPPFLAGS) -+test_keyboard_ibus_utils_LDADD = $(libkeyboard_la_LIBADD) $(top_builddir)/cinnamon-settings-daemon/libcsd.la -+ -+check-local: test-keyboard-ibus-utils -+ $(builddir)/test-keyboard-ibus-utils > /dev/null -+endif -+ -+libexec_PROGRAMS += csd-input-sources-switcher -+ -+csd_input_sources_switcher_SOURCES = \ -+ csd-input-sources-switcher.c \ -+ $(NULL) -+ -+csd_input_sources_switcher_CPPFLAGS = \ -+ -I$(top_srcdir)/data \ -+ -I$(top_srcdir)/plugins/common \ -+ $(AM_CPPFLAGS) \ -+ $(NULL) -+ -+csd_input_sources_switcher_CFLAGS = \ -+ $(SETTINGS_PLUGIN_CFLAGS) \ -+ $(AM_CFLAGS) \ -+ $(NULL) -+ -+csd_input_sources_switcher_LDADD = \ -+ $(top_builddir)/plugins/common/libcommon.la \ -+ $(SETTINGS_PLUGIN_LIBS) \ -+ $(NULL) -+ - EXTRA_DIST = \ - $(icons_DATA) \ - $(plugin_in_files) \ -diff -uNrp a/plugins/keyboard/test-keyboard.c b/plugins/keyboard/test-keyboard.c ---- a/plugins/keyboard/test-keyboard.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/plugins/keyboard/test-keyboard.c 2013-08-25 16:36:02.000000000 +0100 -@@ -0,0 +1,7 @@ -+#define NEW csd_keyboard_manager_new -+#define START csd_keyboard_manager_start -+#define STOP csd_keyboard_manager_stop -+#define MANAGER CsdKeyboardManager -+#include "csd-keyboard-manager.h" -+ -+#include "test-plugin.h" -diff -uNrp a/plugins/keyboard/test-keyboard-ibus-utils.c b/plugins/keyboard/test-keyboard-ibus-utils.c ---- a/plugins/keyboard/test-keyboard-ibus-utils.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/plugins/keyboard/test-keyboard-ibus-utils.c 2013-08-25 16:36:02.000000000 +0100 -@@ -0,0 +1,116 @@ -+#include "csd-keyboard-manager.c" -+ -+static void -+test_make_xkb_source_id (void) -+{ -+ gint i; -+ const gchar *test_strings[][2] = { -+ /* input output */ -+ { "xkb:aa:bb:cc", "aa+bb" }, -+ { "xkb:aa:bb:", "aa+bb" }, -+ { "xkb:aa::cc", "aa" }, -+ { "xkb:aa::", "aa" }, -+ { "xkb::bb:cc", "+bb" }, -+ { "xkb::bb:", "+bb" }, -+ { "xkb:::cc", "" }, -+ { "xkb:::", "" }, -+ }; -+ -+ for (i = 0; i < G_N_ELEMENTS (test_strings); ++i) -+ g_assert_cmpstr (make_xkb_source_id (test_strings[i][0]), ==, test_strings[i][1]); -+} -+ -+static void -+test_layout_from_ibus_layout (void) -+{ -+ gint i; -+ const gchar *test_strings[][2] = { -+ /* input output */ -+ { "", "" }, -+ { "a", "a" }, -+ { "a(", "a" }, -+ { "a[", "a" }, -+ }; -+ -+ for (i = 0; i < G_N_ELEMENTS (test_strings); ++i) -+ g_assert_cmpstr (layout_from_ibus_layout (test_strings[i][0]), ==, test_strings[i][1]); -+} -+ -+static void -+test_variant_from_ibus_layout (void) -+{ -+ gint i; -+ const gchar *test_strings[][2] = { -+ /* input output */ -+ { "", NULL }, -+ { "a", NULL }, -+ { "(", NULL }, -+ { "()", "" }, -+ { "(b)", "b" }, -+ { "a(", NULL }, -+ { "a()", "" }, -+ { "a(b)", "b" }, -+ }; -+ -+ for (i = 0; i < G_N_ELEMENTS (test_strings); ++i) -+ g_assert_cmpstr (variant_from_ibus_layout (test_strings[i][0]), ==, test_strings[i][1]); -+} -+ -+static void -+test_options_from_ibus_layout (void) -+{ -+ gint i, j; -+ gchar *output_0[] = { -+ NULL -+ }; -+ gchar *output_1[] = { -+ "", -+ NULL -+ }; -+ gchar *output_2[] = { -+ "b", -+ NULL -+ }; -+ gchar *output_3[] = { -+ "b", "", -+ NULL -+ }; -+ gchar *output_4[] = { -+ "b", "c", -+ NULL -+ }; -+ const gpointer tests[][2] = { -+ /* input output */ -+ { "", NULL }, -+ { "a", NULL }, -+ { "a[", output_0 }, -+ { "a[]", output_1 }, -+ { "a[b]", output_2 }, -+ { "a[b,]", output_3 }, -+ { "a[b,c]", output_4 }, -+ }; -+ -+ for (i = 0; i < G_N_ELEMENTS (tests); ++i) { -+ if (tests[i][1] == NULL) { -+ g_assert (options_from_ibus_layout (tests[i][0]) == NULL); -+ } else { -+ gchar **strv_a = options_from_ibus_layout (tests[i][0]); -+ gchar **strv_b = tests[i][1]; -+ -+ g_assert (g_strv_length (strv_a) == g_strv_length (strv_b)); -+ for (j = 0; j < g_strv_length (strv_a); ++j) -+ g_assert_cmpstr (strv_a[j], ==, strv_b[j]); -+ } -+ } -+} -+ -+int -+main (void) -+{ -+ test_make_xkb_source_id (); -+ test_layout_from_ibus_layout (); -+ test_variant_from_ibus_layout (); -+ test_options_from_ibus_layout (); -+ -+ return 0; -+} -diff -uNrp a/plugins/keyboard/xxx/csd-keyboard-xkb.c b/plugins/keyboard/xxx/csd-keyboard-xkb.c ---- a/plugins/keyboard/xxx/csd-keyboard-xkb.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/plugins/keyboard/xxx/csd-keyboard-xkb.c 2013-08-25 16:36:02.000000000 +0100 -@@ -0,0 +1,579 @@ -+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- -+ * -+ * Copyright (C) 2001 Udaltsoft -+ * -+ * Written by Sergey V. Oudaltsov <svu@users.sourceforge.net> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -+ * 02110-1335, USA. -+ */ -+ -+#include "config.h" -+ -+#include <string.h> -+#include <time.h> -+ -+#include <glib/gi18n.h> -+#include <gdk/gdk.h> -+#include <gdk/gdkx.h> -+#include <gtk/gtk.h> -+ -+#include <libgnomekbd/gkbd-status.h> -+ -+#include <libgnomekbd/gkbd-keyboard-drawing.h> -+#include <libgnomekbd/gkbd-desktop-config.h> -+#include <libgnomekbd/gkbd-indicator-config.h> -+#include <libgnomekbd/gkbd-keyboard-config.h> -+#include <libgnomekbd/gkbd-util.h> -+ -+#include "csd-keyboard-xkb.h" -+#include "delayed-dialog.h" -+#include "cinnamon-settings-profile.h" -+ -+#define SETTINGS_KEYBOARD_DIR "org.cinnamon.settings-daemon.plugins.keyboard" -+ -+static CsdKeyboardManager *manager = NULL; -+ -+static XklEngine *xkl_engine; -+static XklConfigRegistry *xkl_registry = NULL; -+ -+static GkbdDesktopConfig current_config; -+static GkbdKeyboardConfig current_kbd_config; -+ -+/* never terminated */ -+static GkbdKeyboardConfig initial_sys_kbd_config; -+ -+static gboolean inited_ok = FALSE; -+ -+static GSettings *settings_desktop = NULL; -+static GSettings *settings_keyboard = NULL; -+ -+static PostActivationCallback pa_callback = NULL; -+static void *pa_callback_user_data = NULL; -+ -+static GtkStatusIcon *icon = NULL; -+ -+static GHashTable *preview_dialogs = NULL; -+ -+static void -+activation_error (void) -+{ -+ char const *vendor; -+ GtkWidget *dialog; -+ -+ vendor = -+ ServerVendor (GDK_DISPLAY_XDISPLAY -+ (gdk_display_get_default ())); -+ -+ /* VNC viewers will not work, do not barrage them with warnings */ -+ if (NULL != vendor && NULL != strstr (vendor, "VNC")) -+ return; -+ -+ dialog = gtk_message_dialog_new_with_markup (NULL, -+ 0, -+ GTK_MESSAGE_ERROR, -+ GTK_BUTTONS_CLOSE, -+ _ -+ ("Error activating XKB configuration.\n" -+ "There can be various reasons for that.\n\n" -+ "If you report this situation as a bug, include the results of\n" -+ " • <b>%s</b>\n" -+ " • <b>%s</b>\n" -+ " • <b>%s</b>\n" -+ " • <b>%s</b>"), -+ "xprop -root | grep XKB", -+ "gsettings get org.gnome.libgnomekbd.keyboard model", -+ "gsettings get org.gnome.libgnomekbd.keyboard layouts", -+ "gsettings get org.gnome.libgnomekbd.keyboard options"); -+ g_signal_connect (dialog, "response", -+ G_CALLBACK (gtk_widget_destroy), NULL); -+ csd_delayed_show_dialog (dialog); -+} -+ -+static gboolean -+ensure_xkl_registry (void) -+{ -+ if (!xkl_registry) { -+ xkl_registry = -+ xkl_config_registry_get_instance (xkl_engine); -+ /* load all materials, unconditionally! */ -+ if (!xkl_config_registry_load (xkl_registry, TRUE)) { -+ g_object_unref (xkl_registry); -+ xkl_registry = NULL; -+ return FALSE; -+ } -+ } -+ -+ return TRUE; -+} -+ -+static void -+apply_desktop_settings (void) -+{ -+ if (!inited_ok) -+ return; -+ -+ csd_keyboard_manager_apply_settings (manager); -+ gkbd_desktop_config_load (¤t_config); -+ /* again, probably it would be nice to compare things -+ before activating them */ -+ gkbd_desktop_config_activate (¤t_config); -+} -+ -+static void -+popup_menu_launch_capplet () -+{ -+ GAppInfo *info; -+ GdkAppLaunchContext *ctx; -+ GError *error = NULL; -+ -+ info = -+ g_app_info_create_from_commandline -+ ("cinnamon-settings region", NULL, 0, &error); -+ -+ if (info != NULL) { -+ ctx = -+ gdk_display_get_app_launch_context -+ (gdk_display_get_default ()); -+ -+ if (g_app_info_launch (info, NULL, -+ G_APP_LAUNCH_CONTEXT (ctx), &error) == FALSE) { -+ g_warning -+ ("Could not execute keyboard properties capplet: [%s]\n", -+ error->message); -+ g_error_free (error); -+ } -+ -+ g_object_unref (info); -+ g_object_unref (ctx); -+ } -+ -+} -+ -+static void -+show_layout_destroy (GtkWidget * dialog, gint group) -+{ -+ g_hash_table_remove (preview_dialogs, GINT_TO_POINTER (group)); -+} -+ -+static void -+popup_menu_show_layout () -+{ -+ GtkWidget *dialog; -+ XklEngine *engine = -+ xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY -+ (gdk_display_get_default ())); -+ XklState *xkl_state = xkl_engine_get_current_state (engine); -+ -+ gchar **group_names = gkbd_status_get_group_names (); -+ -+ gpointer p = g_hash_table_lookup (preview_dialogs, -+ GINT_TO_POINTER -+ (xkl_state->group)); -+ -+ if (xkl_state->group < 0 -+ || xkl_state->group >= g_strv_length (group_names)) { -+ return; -+ } -+ -+ if (p != NULL) { -+ /* existing window */ -+ gtk_window_present (GTK_WINDOW (p)); -+ return; -+ } -+ -+ if (!ensure_xkl_registry ()) -+ return; -+ -+ dialog = gkbd_keyboard_drawing_dialog_new (); -+ gkbd_keyboard_drawing_dialog_set_group (dialog, xkl_registry, xkl_state->group); -+ -+ g_signal_connect (dialog, "destroy", -+ G_CALLBACK (show_layout_destroy), -+ GINT_TO_POINTER (xkl_state->group)); -+ g_hash_table_insert (preview_dialogs, -+ GINT_TO_POINTER (xkl_state->group), dialog); -+ gtk_widget_show_all (dialog); -+} -+ -+static void -+popup_menu_set_group (gint group_number, gboolean only_menu) -+{ -+ -+ XklEngine *engine = gkbd_status_get_xkl_engine (); -+ -+ XklState *st = xkl_engine_get_current_state(engine); -+ Window cur; -+ st->group = group_number; -+ xkl_engine_allow_one_switch_to_secondary_group (engine); -+ cur = xkl_engine_get_current_window (engine); -+ if (cur != (Window) NULL) { -+ xkl_debug (150, "Enforcing the state %d for window %lx\n", -+ st->group, cur); -+ -+ xkl_engine_save_state (engine, -+ xkl_engine_get_current_window -+ (engine), st); -+/* XSetInputFocus( GDK_DISPLAY(), cur, RevertToNone, CurrentTime );*/ -+ } else { -+ xkl_debug (150, -+ "??? Enforcing the state %d for unknown window\n", -+ st->group); -+ /* strange situation - bad things can happen */ -+ } -+ if (!only_menu) -+ xkl_engine_lock_group (engine, st->group); -+} -+ -+static void -+popup_menu_set_group_cb (GtkMenuItem * item, gpointer param) -+{ -+ gint group_number = GPOINTER_TO_INT (param); -+ -+ popup_menu_set_group(group_number, FALSE); -+} -+ -+ -+static GtkMenu * -+create_status_menu (void) -+{ -+ GtkMenu *popup_menu = GTK_MENU (gtk_menu_new ()); -+ int i = 0; -+ -+ GtkMenu *groups_menu = GTK_MENU (gtk_menu_new ()); -+ gchar **current_name = gkbd_status_get_group_names (); -+ -+ GtkWidget *item = gtk_menu_item_new_with_mnemonic (_("_Layouts")); -+ gtk_widget_show (item); -+ gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); -+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), -+ GTK_WIDGET (groups_menu)); -+ -+ item = gtk_menu_item_new_with_mnemonic (_("Show _Keyboard Layout...")); -+ gtk_widget_show (item); -+ g_signal_connect (item, "activate", popup_menu_show_layout, NULL); -+ gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); -+ -+ /* translators note: -+ * This is the name of the cinnamon-settings "region" panel */ -+ item = gtk_menu_item_new_with_mnemonic (_("Region and Language Settings")); -+ gtk_widget_show (item); -+ g_signal_connect (item, "activate", popup_menu_launch_capplet, NULL); -+ gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); -+ -+ for (i = 0; current_name && *current_name; i++, current_name++) { -+ -+ gchar *image_file = gkbd_status_get_image_filename (i); -+ -+ if (image_file == NULL) { -+ item = -+ gtk_menu_item_new_with_label (*current_name); -+ } else { -+ GdkPixbuf *pixbuf = -+ gdk_pixbuf_new_from_file_at_size (image_file, -+ 24, 24, -+ NULL); -+ GtkWidget *img = -+ gtk_image_new_from_pixbuf (pixbuf); -+ item = -+ gtk_image_menu_item_new_with_label -+ (*current_name); -+ gtk_widget_show (img); -+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM -+ (item), img); -+ gtk_image_menu_item_set_always_show_image -+ (GTK_IMAGE_MENU_ITEM (item), TRUE); -+ g_free (image_file); -+ } -+ gtk_widget_show (item); -+ gtk_menu_shell_append (GTK_MENU_SHELL (groups_menu), item); -+ g_signal_connect (item, "activate", -+ G_CALLBACK (popup_menu_set_group_cb), -+ GINT_TO_POINTER (i)); -+ } -+ -+ return popup_menu; -+} -+ -+static void -+status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) -+{ -+ GtkMenu *popup_menu = create_status_menu (); -+ -+ gtk_menu_popup (popup_menu, NULL, NULL, -+ gtk_status_icon_position_menu, -+ (gpointer) icon, button, time); -+} -+ -+static void -+show_hide_icon () -+{ -+ if (g_strv_length (current_kbd_config.layouts_variants) > 1) { -+ if (icon == NULL) { -+ xkl_debug (150, "Creating keyboard status icon\n"); -+ icon = gkbd_status_new (); -+ g_signal_connect (icon, "popup-menu", -+ G_CALLBACK -+ (status_icon_popup_menu_cb), -+ NULL); -+ -+ } -+ } else { -+ if (icon != NULL) { -+ xkl_debug (150, "Destroying icon\n"); -+ g_object_unref (icon); -+ icon = NULL; -+ } -+ } -+} -+ -+static gboolean -+try_activating_xkb_config_if_new (GkbdKeyboardConfig * -+ current_sys_kbd_config) -+{ -+ /* Activate - only if different! */ -+ if (!gkbd_keyboard_config_equals -+ (¤t_kbd_config, current_sys_kbd_config)) { -+ if (gkbd_keyboard_config_activate (¤t_kbd_config)) { -+ if (pa_callback != NULL) { -+ (*pa_callback) (pa_callback_user_data); -+ return TRUE; -+ } -+ } else { -+ return FALSE; -+ } -+ } -+ return TRUE; -+} -+ -+static gboolean -+filter_xkb_config (void) -+{ -+ XklConfigItem *item; -+ gchar *lname; -+ gchar *vname; -+ gchar **lv; -+ gboolean any_change = FALSE; -+ -+ xkl_debug (100, "Filtering configuration against the registry\n"); -+ if (!ensure_xkl_registry ()) -+ return FALSE; -+ -+ lv = current_kbd_config.layouts_variants; -+ item = xkl_config_item_new (); -+ while (*lv) { -+ xkl_debug (100, "Checking [%s]\n", *lv); -+ if (gkbd_keyboard_config_split_items (*lv, &lname, &vname)) { -+ gboolean should_be_dropped = FALSE; -+ g_snprintf (item->name, sizeof (item->name), "%s", -+ lname); -+ if (!xkl_config_registry_find_layout -+ (xkl_registry, item)) { -+ xkl_debug (100, "Bad layout [%s]\n", -+ lname); -+ should_be_dropped = TRUE; -+ } else if (vname) { -+ g_snprintf (item->name, -+ sizeof (item->name), "%s", -+ vname); -+ if (!xkl_config_registry_find_variant -+ (xkl_registry, lname, item)) { -+ xkl_debug (100, -+ "Bad variant [%s(%s)]\n", -+ lname, vname); -+ should_be_dropped = TRUE; -+ } -+ } -+ if (should_be_dropped) { -+ gkbd_strv_behead (lv); -+ any_change = TRUE; -+ continue; -+ } -+ } -+ lv++; -+ } -+ g_object_unref (item); -+ return any_change; -+} -+ -+static void -+apply_xkb_settings (void) -+{ -+ GkbdKeyboardConfig current_sys_kbd_config; -+ -+ if (!inited_ok) -+ return; -+ -+ gkbd_keyboard_config_init (¤t_sys_kbd_config, xkl_engine); -+ -+ gkbd_keyboard_config_load (¤t_kbd_config, -+ &initial_sys_kbd_config); -+ -+ gkbd_keyboard_config_load_from_x_current (¤t_sys_kbd_config, -+ NULL); -+ -+ if (!try_activating_xkb_config_if_new (¤t_sys_kbd_config)) { -+ if (filter_xkb_config ()) { -+ if (!try_activating_xkb_config_if_new -+ (¤t_sys_kbd_config)) { -+ g_warning -+ ("Could not activate the filtered XKB configuration"); -+ activation_error (); -+ } -+ } else { -+ g_warning -+ ("Could not activate the XKB configuration"); -+ activation_error (); -+ } -+ } else -+ xkl_debug (100, -+ "Actual KBD configuration was not changed: redundant notification\n"); -+ -+ gkbd_keyboard_config_term (¤t_sys_kbd_config); -+ show_hide_icon (); -+} -+ -+static void -+csd_keyboard_xkb_analyze_sysconfig (void) -+{ -+ if (!inited_ok) -+ return; -+ -+ gkbd_keyboard_config_init (&initial_sys_kbd_config, xkl_engine); -+ gkbd_keyboard_config_load_from_x_initial (&initial_sys_kbd_config, -+ NULL); -+} -+ -+void -+csd_keyboard_xkb_set_post_activation_callback (PostActivationCallback fun, -+ void *user_data) -+{ -+ pa_callback = fun; -+ pa_callback_user_data = user_data; -+} -+ -+static GdkFilterReturn -+csd_keyboard_xkb_evt_filter (GdkXEvent * xev, GdkEvent * event) -+{ -+ XEvent *xevent = (XEvent *) xev; -+ xkl_engine_filter_events (xkl_engine, xevent); -+ return GDK_FILTER_CONTINUE; -+} -+ -+/* When new Keyboard is plugged in - reload the settings */ -+static void -+csd_keyboard_new_device (XklEngine * engine) -+{ -+ apply_desktop_settings (); -+ apply_xkb_settings (); -+} -+ -+void -+csd_keyboard_xkb_init (CsdKeyboardManager * kbd_manager) -+{ -+ Display *display = -+ GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); -+ cinnamon_settings_profile_start (NULL); -+ -+ gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), -+ DATADIR G_DIR_SEPARATOR_S -+ "icons"); -+ -+ manager = kbd_manager; -+ cinnamon_settings_profile_start ("xkl_engine_get_instance"); -+ xkl_engine = xkl_engine_get_instance (display); -+ cinnamon_settings_profile_end ("xkl_engine_get_instance"); -+ if (xkl_engine) { -+ inited_ok = TRUE; -+ -+ gkbd_desktop_config_init (¤t_config, xkl_engine); -+ gkbd_keyboard_config_init (¤t_kbd_config, -+ xkl_engine); -+ xkl_engine_backup_names_prop (xkl_engine); -+ csd_keyboard_xkb_analyze_sysconfig (); -+ -+ settings_desktop = g_settings_new (GKBD_DESKTOP_SCHEMA); -+ settings_keyboard = g_settings_new (GKBD_KEYBOARD_SCHEMA); -+ g_signal_connect (settings_desktop, "changed", -+ (GCallback) apply_desktop_settings, -+ NULL); -+ g_signal_connect (settings_keyboard, "changed", -+ (GCallback) apply_xkb_settings, NULL); -+ -+ gdk_window_add_filter (NULL, (GdkFilterFunc) -+ csd_keyboard_xkb_evt_filter, NULL); -+ -+ if (xkl_engine_get_features (xkl_engine) & -+ XKLF_DEVICE_DISCOVERY) -+ g_signal_connect (xkl_engine, "X-new-device", -+ G_CALLBACK -+ (csd_keyboard_new_device), NULL); -+ -+ cinnamon_settings_profile_start ("xkl_engine_start_listen"); -+ xkl_engine_start_listen (xkl_engine, -+ XKLL_MANAGE_LAYOUTS | -+ XKLL_MANAGE_WINDOW_STATES); -+ cinnamon_settings_profile_end ("xkl_engine_start_listen"); -+ -+ cinnamon_settings_profile_start ("apply_desktop_settings"); -+ apply_desktop_settings (); -+ cinnamon_settings_profile_end ("apply_desktop_settings"); -+ cinnamon_settings_profile_start ("apply_xkb_settings"); -+ apply_xkb_settings (); -+ cinnamon_settings_profile_end ("apply_xkb_settings"); -+ } -+ preview_dialogs = g_hash_table_new (g_direct_hash, g_direct_equal); -+ -+ cinnamon_settings_profile_end (NULL); -+} -+ -+void -+csd_keyboard_xkb_shutdown (void) -+{ -+ if (!inited_ok) -+ return; -+ -+ pa_callback = NULL; -+ pa_callback_user_data = NULL; -+ manager = NULL; -+ -+ if (preview_dialogs != NULL) -+ g_hash_table_destroy (preview_dialogs); -+ -+ if (!inited_ok) -+ return; -+ -+ xkl_engine_stop_listen (xkl_engine, -+ XKLL_MANAGE_LAYOUTS | -+ XKLL_MANAGE_WINDOW_STATES); -+ -+ gdk_window_remove_filter (NULL, (GdkFilterFunc) -+ csd_keyboard_xkb_evt_filter, NULL); -+ -+ g_object_unref (settings_desktop); -+ settings_desktop = NULL; -+ g_object_unref (settings_keyboard); -+ settings_keyboard = NULL; -+ -+ if (xkl_registry) { -+ g_object_unref (xkl_registry); -+ } -+ -+ g_object_unref (xkl_engine); -+ -+ xkl_engine = NULL; -+ -+ inited_ok = FALSE; -+} -diff -uNrp a/plugins/keyboard/xxx/csd-keyboard-xkb.h b/plugins/keyboard/xxx/csd-keyboard-xkb.h ---- a/plugins/keyboard/xxx/csd-keyboard-xkb.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/plugins/keyboard/xxx/csd-keyboard-xkb.h 2013-08-25 16:36:02.000000000 +0100 -@@ -0,0 +1,39 @@ -+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- -+ * cinnamon-settings-keyboard-xkb.h -+ * -+ * Copyright (C) 2001 Udaltsoft -+ * -+ * Written by Sergey V. Oudaltsov <svu@users.sourceforge.net> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -+ * 02110-1335, USA. -+ */ -+ -+#ifndef __CSD_KEYBOARD_XKB_H -+#define __CSD_KEYBOARD_XKB_H -+ -+#include <libxklavier/xklavier.h> -+#include "csd-keyboard-manager.h" -+ -+void csd_keyboard_xkb_init (CsdKeyboardManager *manager); -+void csd_keyboard_xkb_shutdown (void); -+ -+typedef void (*PostActivationCallback) (void *userData); -+ -+void -+csd_keyboard_xkb_set_post_activation_callback (PostActivationCallback fun, -+ void *userData); -+ -+#endif -diff -uNrp a/plugins/keyboard/xxx/delayed-dialog.c b/plugins/keyboard/xxx/delayed-dialog.c ---- a/plugins/keyboard/xxx/delayed-dialog.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/plugins/keyboard/xxx/delayed-dialog.c 2013-08-25 16:36:02.000000000 +0100 -@@ -0,0 +1,128 @@ -+/* -+ * Copyright © 2006 Novell, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2, or (at -+ * your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -+ * 02110-1335, USA. -+ */ -+ -+#include <stdlib.h> -+#include <string.h> -+ -+#include <gtk/gtk.h> -+#include <gdk/gdkx.h> -+ -+#include "delayed-dialog.h" -+ -+static gboolean delayed_show_timeout (gpointer data); -+static GdkFilterReturn message_filter (GdkXEvent *xevent, -+ GdkEvent *event, -+ gpointer data); -+ -+static GSList *dialogs = NULL; -+ -+/** -+ * csd_delayed_show_dialog: -+ * @dialog: the dialog -+ * -+ * Shows the dialog as with gtk_widget_show(), unless a window manager -+ * hasn't been started yet, in which case it will wait up to 5 seconds -+ * for that to happen before showing the dialog. -+ **/ -+void -+csd_delayed_show_dialog (GtkWidget *dialog) -+{ -+ GdkDisplay *display = gtk_widget_get_display (dialog); -+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); -+ GdkScreen *screen = gtk_widget_get_screen (dialog); -+ char selection_name[10]; -+ Atom selection_atom; -+ -+ /* We can't use gdk_selection_owner_get() for this, because -+ * it's an unknown out-of-process window. -+ */ -+ snprintf (selection_name, sizeof (selection_name), "WM_S%d", -+ gdk_screen_get_number (screen)); -+ selection_atom = XInternAtom (xdisplay, selection_name, True); -+ if (selection_atom && -+ XGetSelectionOwner (xdisplay, selection_atom) != None) { -+ gtk_widget_show (dialog); -+ return; -+ } -+ -+ dialogs = g_slist_prepend (dialogs, dialog); -+ -+ gdk_window_add_filter (NULL, message_filter, NULL); -+ -+ g_timeout_add (5000, delayed_show_timeout, NULL); -+} -+ -+static gboolean -+delayed_show_timeout (gpointer data) -+{ -+ GSList *l; -+ -+ for (l = dialogs; l; l = l->next) -+ gtk_widget_show (l->data); -+ g_slist_free (dialogs); -+ dialogs = NULL; -+ -+ /* FIXME: There's no gdk_display_remove_client_message_filter */ -+ -+ return FALSE; -+} -+ -+static GdkFilterReturn -+message_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) -+{ -+ XClientMessageEvent *evt; -+ char *selection_name; -+ int screen; -+ GSList *l, *next; -+ -+ if (((XEvent *)xevent)->type != ClientMessage) -+ return GDK_FILTER_CONTINUE; -+ -+ evt = (XClientMessageEvent *)xevent; -+ -+ if (evt->message_type != XInternAtom (evt->display, "MANAGER", FALSE)) -+ return GDK_FILTER_CONTINUE; -+ -+ selection_name = XGetAtomName (evt->display, evt->data.l[1]); -+ -+ if (strncmp (selection_name, "WM_S", 4) != 0) { -+ XFree (selection_name); -+ return GDK_FILTER_CONTINUE; -+ } -+ -+ screen = atoi (selection_name + 4); -+ -+ for (l = dialogs; l; l = next) { -+ GtkWidget *dialog = l->data; -+ next = l->next; -+ -+ if (gdk_screen_get_number (gtk_widget_get_screen (dialog)) == screen) { -+ gtk_widget_show (dialog); -+ dialogs = g_slist_remove (dialogs, dialog); -+ } -+ } -+ -+ if (!dialogs) { -+ gdk_window_remove_filter (NULL, message_filter, NULL); -+ } -+ -+ XFree (selection_name); -+ -+ return GDK_FILTER_CONTINUE; -+} -diff -uNrp a/plugins/keyboard/xxx/delayed-dialog.h b/plugins/keyboard/xxx/delayed-dialog.h ---- a/plugins/keyboard/xxx/delayed-dialog.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/plugins/keyboard/xxx/delayed-dialog.h 2013-08-25 16:36:02.000000000 +0100 -@@ -0,0 +1,32 @@ -+/* -+ * Copyright © 2006 Novell, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2, or (at -+ * your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -+ * 02110-1335, USA. -+ */ -+ -+ -+#ifndef __DELAYED_DIALOG_H -+#define __DELAYED_DIALOG_H -+ -+#include <gtk/gtk.h> -+ -+G_BEGIN_DECLS -+ -+void csd_delayed_show_dialog (GtkWidget *dialog); -+ -+G_END_DECLS -+ -+#endif -diff -uNrp a/plugins/keyboard/xxx/gkbd-configuration.c b/plugins/keyboard/xxx/gkbd-configuration.c ---- a/plugins/keyboard/xxx/gkbd-configuration.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/plugins/keyboard/xxx/gkbd-configuration.c 2013-08-25 16:36:02.000000000 +0100 -@@ -0,0 +1,350 @@ -+/* -+ * Copyright (C) 2010 Canonical Ltd. -+ * -+ * Authors: Jan Arne Petersen <jpetersen@openismus.com> -+ * -+ * Based on gkbd-status.c by Sergey V. Udaltsov <svu@gnome.org> -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the -+ * Free Software Foundation, Inc., 51 Franklin Street - Suite 500, -+ * Boston, MA 02110-1335, USA. -+ */ -+ -+#include <memory.h> -+ -+#include <gdk/gdkkeysyms.h> -+#include <gdk/gdkx.h> -+#include <glib/gi18n.h> -+ -+#include <libgnomekbd/gkbd-desktop-config.h> -+#include <libgnomekbd/gkbd-indicator-config.h> -+ -+#include "gkbd-configuration.h" -+ -+struct _GkbdConfigurationPrivate { -+ XklEngine *engine; -+ XklConfigRegistry *registry; -+ -+ GkbdDesktopConfig cfg; -+ GkbdIndicatorConfig ind_cfg; -+ GkbdKeyboardConfig kbd_cfg; -+ -+ gchar **full_group_names; -+ gchar **short_group_names; -+ -+ gulong state_changed_handler; -+ gulong config_changed_handler; -+}; -+ -+enum { -+ SIGNAL_CHANGED, -+ SIGNAL_GROUP_CHANGED, -+ LAST_SIGNAL -+}; -+ -+static guint signals[LAST_SIGNAL] = { 0, }; -+ -+#define GKBD_CONFIGURATION_GET_PRIVATE(o) \ -+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GKBD_TYPE_CONFIGURATION, GkbdConfigurationPrivate)) -+ -+G_DEFINE_TYPE (GkbdConfiguration, gkbd_configuration, G_TYPE_OBJECT) -+ -+/* Should be called once for all widgets */ -+static void -+gkbd_configuration_cfg_changed (GSettings *settings, -+ const char *key, -+ GkbdConfiguration * configuration) -+{ -+ GkbdConfigurationPrivate *priv = configuration->priv; -+ -+ xkl_debug (100, -+ "General configuration changed in GSettings - reiniting...\n"); -+ gkbd_desktop_config_load (&priv->cfg); -+ gkbd_desktop_config_activate (&priv->cfg); -+ -+ g_signal_emit (configuration, -+ signals[SIGNAL_CHANGED], 0); -+} -+ -+/* Should be called once for all widgets */ -+static void -+gkbd_configuration_ind_cfg_changed (GSettings *settings, -+ const char *key, -+ GkbdConfiguration * configuration) -+{ -+ GkbdConfigurationPrivate *priv = configuration->priv; -+ xkl_debug (100, -+ "Applet configuration changed in GSettings - reiniting...\n"); -+ gkbd_indicator_config_load (&priv->ind_cfg); -+ -+ gkbd_indicator_config_free_image_filenames (&priv->ind_cfg); -+ gkbd_indicator_config_load_image_filenames (&priv->ind_cfg, -+ &priv->kbd_cfg); -+ -+ gkbd_indicator_config_activate (&priv->ind_cfg); -+ -+ g_signal_emit (configuration, -+ signals[SIGNAL_CHANGED], 0); -+} -+ -+static void -+gkbd_configuration_load_group_names (GkbdConfiguration * configuration, -+ XklConfigRec * xklrec) -+{ -+ GkbdConfigurationPrivate *priv = configuration->priv; -+ -+ if (!gkbd_desktop_config_load_group_descriptions (&priv->cfg, -+ priv->registry, -+ (const char **) xklrec->layouts, -+ (const char **) xklrec->variants, -+ &priv->short_group_names, -+ &priv->full_group_names)) { -+ /* We just populate no short names (remain NULL) - -+ * full names are going to be used anyway */ -+ gint i, total_groups = -+ xkl_engine_get_num_groups (priv->engine); -+ xkl_debug (150, "group descriptions loaded: %d!\n", -+ total_groups); -+ priv->full_group_names = -+ g_new0 (char *, total_groups + 1); -+ -+ if (xkl_engine_get_features (priv->engine) & -+ XKLF_MULTIPLE_LAYOUTS_SUPPORTED) { -+ for (i = 0; priv->kbd_cfg.layouts_variants[i]; i++) { -+ priv->full_group_names[i] = -+ g_strdup ((char *) priv->kbd_cfg.layouts_variants[i]); -+ } -+ } else { -+ for (i = total_groups; --i >= 0;) { -+ priv->full_group_names[i] = -+ g_strdup_printf ("Group %d", i); -+ } -+ } -+ } -+} -+ -+/* Should be called once for all widgets */ -+static void -+gkbd_configuration_kbd_cfg_callback (XklEngine *engine, -+ GkbdConfiguration *configuration) -+{ -+ GkbdConfigurationPrivate *priv = configuration->priv; -+ XklConfigRec *xklrec = xkl_config_rec_new (); -+ xkl_debug (100, -+ "XKB configuration changed on X Server - reiniting...\n"); -+ -+ gkbd_keyboard_config_load_from_x_current (&priv->kbd_cfg, -+ xklrec); -+ -+ gkbd_indicator_config_free_image_filenames (&priv->ind_cfg); -+ gkbd_indicator_config_load_image_filenames (&priv->ind_cfg, -+ &priv->kbd_cfg); -+ -+ g_strfreev (priv->full_group_names); -+ priv->full_group_names = NULL; -+ -+ g_strfreev (priv->short_group_names); -+ priv->short_group_names = NULL; -+ -+ gkbd_configuration_load_group_names (configuration, -+ xklrec); -+ -+ g_signal_emit (configuration, -+ signals[SIGNAL_CHANGED], -+ 0); -+ -+ g_object_unref (G_OBJECT (xklrec)); -+} -+ -+/* Should be called once for all applets */ -+static void -+gkbd_configuration_state_callback (XklEngine * engine, -+ XklEngineStateChange changeType, -+ gint group, gboolean restore, -+ GkbdConfiguration * configuration) -+{ -+ xkl_debug (150, "group is now %d, restore: %d\n", group, restore); -+ -+ if (changeType == GROUP_CHANGED) { -+ g_signal_emit (configuration, -+ signals[SIGNAL_GROUP_CHANGED], 0, -+ group); -+ } -+} -+ -+static void -+gkbd_configuration_init (GkbdConfiguration *configuration) -+{ -+ GkbdConfigurationPrivate *priv; -+ XklConfigRec *xklrec = xkl_config_rec_new (); -+ -+ priv = GKBD_CONFIGURATION_GET_PRIVATE (configuration); -+ configuration->priv = priv; -+ -+ priv->engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); -+ if (priv->engine == NULL) { -+ xkl_debug (0, "Libxklavier initialization error"); -+ return; -+ } -+ -+ priv->state_changed_handler = -+ g_signal_connect (priv->engine, "X-state-changed", -+ G_CALLBACK (gkbd_configuration_state_callback), -+ configuration); -+ priv->config_changed_handler = -+ g_signal_connect (priv->engine, "X-config-changed", -+ G_CALLBACK (gkbd_configuration_kbd_cfg_callback), -+ configuration); -+ -+ gkbd_desktop_config_init (&priv->cfg, priv->engine); -+ gkbd_keyboard_config_init (&priv->kbd_cfg, priv->engine); -+ gkbd_indicator_config_init (&priv->ind_cfg, priv->engine); -+ -+ gkbd_desktop_config_load (&priv->cfg); -+ gkbd_desktop_config_activate (&priv->cfg); -+ -+ priv->registry = xkl_config_registry_get_instance (priv->engine); -+ xkl_config_registry_load (priv->registry, -+ priv->cfg.load_extra_items); -+ -+ gkbd_keyboard_config_load_from_x_current (&priv->kbd_cfg, -+ xklrec); -+ -+ gkbd_indicator_config_load (&priv->ind_cfg); -+ -+ gkbd_indicator_config_load_image_filenames (&priv->ind_cfg, -+ &priv->kbd_cfg); -+ -+ gkbd_indicator_config_activate (&priv->ind_cfg); -+ -+ gkbd_configuration_load_group_names (configuration, -+ xklrec); -+ g_object_unref (G_OBJECT (xklrec)); -+ -+ gkbd_desktop_config_start_listen (&priv->cfg, -+ G_CALLBACK (gkbd_configuration_cfg_changed), -+ configuration); -+ gkbd_indicator_config_start_listen (&priv->ind_cfg, -+ G_CALLBACK (gkbd_configuration_ind_cfg_changed), -+ configuration); -+ xkl_engine_start_listen (priv->engine, -+ XKLL_TRACK_KEYBOARD_STATE); -+ -+ xkl_debug (100, "Initiating the widget startup process for %p\n", -+ configuration); -+} -+ -+static void -+gkbd_configuration_finalize (GObject * obj) -+{ -+ GkbdConfiguration *configuration = GKBD_CONFIGURATION (obj); -+ GkbdConfigurationPrivate *priv = configuration->priv; -+ -+ xkl_debug (100, -+ "Starting the gnome-kbd-configuration widget shutdown process for %p\n", -+ configuration); -+ -+ xkl_engine_stop_listen (priv->engine, -+ XKLL_TRACK_KEYBOARD_STATE); -+ -+ gkbd_desktop_config_stop_listen (&priv->cfg); -+ gkbd_indicator_config_stop_listen (&priv->ind_cfg); -+ -+ gkbd_indicator_config_term (&priv->ind_cfg); -+ gkbd_keyboard_config_term (&priv->kbd_cfg); -+ gkbd_desktop_config_term (&priv->cfg); -+ -+ if (g_signal_handler_is_connected (priv->engine, -+ priv->state_changed_handler)) { -+ g_signal_handler_disconnect (priv->engine, -+ priv->state_changed_handler); -+ priv->state_changed_handler = 0; -+ } -+ if (g_signal_handler_is_connected (priv->engine, -+ priv->config_changed_handler)) { -+ g_signal_handler_disconnect (priv->engine, -+ priv->config_changed_handler); -+ priv->config_changed_handler = 0; -+ } -+ -+ g_object_unref (priv->registry); -+ priv->registry = NULL; -+ g_object_unref (priv->engine); -+ priv->engine = NULL; -+ -+ G_OBJECT_CLASS (gkbd_configuration_parent_class)->finalize (obj); -+} -+ -+static void -+gkbd_configuration_class_init (GkbdConfigurationClass * klass) -+{ -+ GObjectClass *object_class = G_OBJECT_CLASS (klass); -+ -+ /* Initing vtable */ -+ object_class->finalize = gkbd_configuration_finalize; -+ -+ /* Signals */ -+ signals[SIGNAL_CHANGED] = g_signal_new ("changed", -+ GKBD_TYPE_CONFIGURATION, -+ G_SIGNAL_RUN_LAST, -+ 0, -+ NULL, NULL, -+ g_cclosure_marshal_VOID__VOID, -+ G_TYPE_NONE, -+ 0); -+ signals[SIGNAL_GROUP_CHANGED] = g_signal_new ("group-changed", -+ GKBD_TYPE_CONFIGURATION, -+ G_SIGNAL_RUN_LAST, -+ 0, -+ NULL, NULL, -+ g_cclosure_marshal_VOID__INT, -+ G_TYPE_NONE, -+ 1, -+ G_TYPE_INT); -+ -+ g_type_class_add_private (klass, sizeof (GkbdConfigurationPrivate)); -+} -+ -+GkbdConfiguration * -+gkbd_configuration_get (void) -+{ -+ static gpointer instance = NULL; -+ -+ if (!instance) { -+ instance = g_object_new (GKBD_TYPE_CONFIGURATION, NULL); -+ g_object_add_weak_pointer (instance, &instance); -+ } else { -+ g_object_ref (instance); -+ } -+ -+ return instance; -+} -+ -+XklEngine * -+gkbd_configuration_get_xkl_engine (GkbdConfiguration *configuration) -+{ -+ return configuration->priv->engine; -+} -+ -+const char * const * -+gkbd_configuration_get_group_names (GkbdConfiguration *configuration) -+{ -+ return configuration->priv->full_group_names; -+} -+ -+const char * const * -+gkbd_configuration_get_short_group_names (GkbdConfiguration *configuration) -+{ -+ return configuration->priv->short_group_names; -+} -diff -uNrp a/plugins/keyboard/xxx/gkbd-configuration.h b/plugins/keyboard/xxx/gkbd-configuration.h ---- a/plugins/keyboard/xxx/gkbd-configuration.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/plugins/keyboard/xxx/gkbd-configuration.h 2013-08-25 16:36:02.000000000 +0100 -@@ -0,0 +1,65 @@ -+/* -+ * Copyright (C) 2010 Canonical Ltd. -+ * -+ * Authors: Jan Arne Petersen <jpetersen@openismus.com> -+ * -+ * Based on gkbd-status.h by Sergey V. Udaltsov <svu@gnome.org> -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the -+ * Free Software Foundation, Inc., 51 Franklin Street - Suite 500, -+ * Boston, MA 02110-1335, USA. -+ */ -+ -+#ifndef __GKBD_CONFIGURATION_H__ -+#define __GKBD_CONFIGURATION_H__ -+ -+#include <glib-object.h> -+ -+#include <libxklavier/xklavier.h> -+ -+G_BEGIN_DECLS -+ -+typedef struct _GkbdConfiguration GkbdConfiguration; -+typedef struct _GkbdConfigurationPrivate GkbdConfigurationPrivate; -+typedef struct _GkbdConfigurationClass GkbdConfigurationClass; -+ -+#define GKBD_TYPE_CONFIGURATION (gkbd_configuration_get_type ()) -+#define GKBD_CONFIGURATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKBD_TYPE_CONFIGURATION, GkbdConfiguration)) -+#define GKBD_INDCATOR_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GKBD_TYPE_CONFIGURATION, GkbdConfigurationClass)) -+#define GKBD_IS_CONFIGURATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKBD_TYPE_CONFIGURATION)) -+#define GKBD_IS_CONFIGURATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), GKBD_TYPE_CONFIGURATION)) -+#define GKBD_CONFIGURATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKBD_TYPE_CONFIGURATION, GkbdConfigurationClass)) -+ -+struct _GkbdConfiguration { -+ GObject parent; -+ -+ GkbdConfigurationPrivate *priv; -+}; -+ -+struct _GkbdConfigurationClass { -+ GObjectClass parent_class; -+}; -+ -+extern GType gkbd_configuration_get_type (void); -+ -+extern GkbdConfiguration *gkbd_configuration_get (void); -+ -+extern XklEngine *gkbd_configuration_get_xkl_engine (GkbdConfiguration *configuration); -+ -+extern const char * const *gkbd_configuration_get_group_names (GkbdConfiguration *configuration); -+extern const char * const *gkbd_configuration_get_short_group_names (GkbdConfiguration *configuration); -+ -+G_END_DECLS -+ -+#endif -diff -uNrp a/plugins/media-keys/csd-media-keys-manager.c b/plugins/media-keys/csd-media-keys-manager.c ---- a/plugins/media-keys/csd-media-keys-manager.c 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/media-keys/csd-media-keys-manager.c 2013-08-25 16:36:02.000000000 +0100 -@@ -120,6 +120,10 @@ static const gchar kb_introspection_xml[ - #define VOLUME_STEP 6 /* percents for one volume button press */ - #define MAX_VOLUME 65536.0 - -+#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.cinnamon.desktop.input-sources" -+#define KEY_CURRENT_INPUT_SOURCE "current" -+#define KEY_INPUT_SOURCES "sources" -+ - #define CSD_MEDIA_KEYS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_MEDIA_KEYS_MANAGER, CsdMediaKeysManagerPrivate)) - - typedef struct { -@@ -1750,6 +1754,40 @@ do_keyboard_brightness_action (CsdMediaK - manager); - } - -+static void -+do_switch_input_source_action (CsdMediaKeysManager *manager, -+ MediaKeyType type) -+{ -+ GSettings *settings; -+ GVariant *sources; -+ gint i, n; -+ -+ settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR); -+ sources = g_settings_get_value (settings, KEY_INPUT_SOURCES); -+ -+ n = g_variant_n_children (sources); -+ if (n < 2) -+ goto out; -+ -+ i = g_settings_get_uint (settings, KEY_CURRENT_INPUT_SOURCE); -+ -+ if (type == SWITCH_INPUT_SOURCE_KEY) -+ i += 1; -+ else -+ i -= 1; -+ -+ if (i < 0) -+ i = n - 1; -+ else if (i >= n) -+ i = 0; -+ -+ g_settings_set_uint (settings, KEY_CURRENT_INPUT_SOURCE, i); -+ -+ out: -+ g_variant_unref (sources); -+ g_object_unref (settings); -+} -+ - static gboolean - do_action (CsdMediaKeysManager *manager, - guint deviceid, -@@ -1908,6 +1946,10 @@ do_action (CsdMediaKeysManager *manager, - case BATTERY_KEY: - do_execute_desktop (manager, "gnome-power-statistics.desktop", timestamp); - break; -+ case SWITCH_INPUT_SOURCE_KEY: -+ case SWITCH_INPUT_SOURCE_BACKWARD_KEY: -+ do_switch_input_source_action (manager, type); -+ break; - /* Note, no default so compiler catches missing keys */ - case CUSTOM_KEY: - g_assert_not_reached (); -diff -uNrp a/plugins/media-keys/shortcuts-list.h b/plugins/media-keys/shortcuts-list.h ---- a/plugins/media-keys/shortcuts-list.h 2013-08-24 18:04:31.000000000 +0100 -+++ b/plugins/media-keys/shortcuts-list.h 2013-08-25 16:36:02.000000000 +0100 -@@ -81,6 +81,8 @@ typedef enum { - KEYBOARD_BRIGHTNESS_DOWN_KEY, - KEYBOARD_BRIGHTNESS_TOGGLE_KEY, - BATTERY_KEY, -+ SWITCH_INPUT_SOURCE_KEY, -+ SWITCH_INPUT_SOURCE_BACKWARD_KEY, - CUSTOM_KEY - } MediaKeyType; - -@@ -148,6 +150,9 @@ static struct { - { KEYBOARD_BRIGHTNESS_UP_KEY, NULL, "XF86KbdBrightnessUp" }, - { KEYBOARD_BRIGHTNESS_DOWN_KEY, NULL, "XF86KbdBrightnessDown" }, - { KEYBOARD_BRIGHTNESS_TOGGLE_KEY, NULL, "XF86KbdLightOnOff" }, -+ { SWITCH_INPUT_SOURCE_KEY, "switch-input-source", NULL }, -+ { SWITCH_INPUT_SOURCE_BACKWARD_KEY, "switch-input-source-backward", NULL }, -+ - { BATTERY_KEY, NULL, "XF86Battery" }, - }; - diff --git a/pkgs/desktops/cinnamon/muffin.nix b/pkgs/desktops/cinnamon/muffin.nix deleted file mode 100644 index a1fd6b97ac16..000000000000 --- a/pkgs/desktops/cinnamon/muffin.nix +++ /dev/null @@ -1,47 +0,0 @@ - -{ stdenv, fetchurl, pkgconfig, autoreconfHook, glib, gettext, gnome_common, gtk3,intltool, -cinnamon-desktop, clutter, cogl, zenity, python, gnome_doc_utils, makeWrapper}: - -let - version = "2.0.5"; -in -stdenv.mkDerivation { - name = "muffin-${version}"; - - src = fetchurl { - url = "http://github.com/linuxmint/muffin/archive/${version}.tar.gz"; - sha256 = "1vn7shxwyxsa6dd3zldrnc0095i1y0rq0944n8kak3m85r2pv9c1"; - }; - - - configureFlags = "--enable-compile-warnings=minium" ; - - patches = [./gtkdoc.patch]; - - buildInputs = [ - pkgconfig autoreconfHook - glib gettext gnome_common - gtk3 intltool cinnamon-desktop - clutter cogl zenity python - gnome_doc_utils makeWrapper]; - - preBuild = "patchShebangs ./scripts"; - - - postFixup = '' - - for f in "$out/bin/"*; do - wrapProgram "$f" --prefix XDG_DATA_DIRS : "$GSETTINGS_SCHEMAS_PATH" - done - ''; - - meta = { - homepage = "http://cinnamon.linuxmint.com"; - description = "The cinnamon session files" ; - - platforms = stdenv.lib.platforms.linux; - maintainers = [ stdenv.lib.maintainers.roelof ]; - - broken = true; - }; -} diff --git a/pkgs/desktops/cinnamon/region.patch b/pkgs/desktops/cinnamon/region.patch deleted file mode 100644 index 7b8133e820ed..000000000000 --- a/pkgs/desktops/cinnamon/region.patch +++ /dev/null @@ -1,5314 +0,0 @@ - -diff -uNrp a/configure.ac b/configure.ac ---- a/configure.ac 2013-08-25 14:40:14.000000000 +0100 -+++ b/configure.ac 2013-08-25 16:50:30.000000000 +0100 -@@ -82,6 +82,22 @@ else - SYSTEMD= - fi - -+# IBus support -+IBUS_REQUIRED_VERSION=1.4.2 -+ -+#AC_ARG_ENABLE(ibus, -+# AS_HELP_STRING([--disable-ibus], -+# [Disable IBus support]), -+# enable_ibus=$enableval, -+# enable_ibus=yes) -+enable_ibus=yes -+#if test "x$enable_ibus" = "xyes" ; then -+IBUS_MODULE="ibus-1.0 >= $IBUS_REQUIRED_VERSION" -+AC_DEFINE(HAVE_IBUS, 1, [Defined if IBus support is enabled]) -+#else -+# IBUS_MODULE= -+#fi -+ - dnl ============================================== - dnl Check that we meet the dependencies - dnl ============================================== -@@ -119,9 +135,10 @@ PKG_CHECK_MODULES(NETWORK_PANEL, $COMMON - PKG_CHECK_MODULES(POWER_PANEL, $COMMON_MODULES upower-glib >= 0.9.1 - cinnamon-settings-daemon >= $CSD_REQUIRED_VERSION) - PKG_CHECK_MODULES(COLOR_PANEL, $COMMON_MODULES colord >= 0.1.8) --PKG_CHECK_MODULES(REGION_PANEL, $COMMON_MODULES libgnomekbd >= 2.91.91 -+PKG_CHECK_MODULES(REGION_PANEL, $COMMON_MODULES - polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION -- libxklavier >= 5.1 libgnomekbdui >= 2.91.91) -+ cinnamon-desktop >= $CINNAMON_DESKTOP_REQUIRED_VERSION -+ $IBUS_MODULE) - PKG_CHECK_MODULES(SCREEN_PANEL, $COMMON_MODULES) - PKG_CHECK_MODULES(SOUND_PANEL, $COMMON_MODULES libxml-2.0 - libcanberra-gtk3 >= $CANBERRA_REQUIRED_VERSION -diff -uNrp a/panels/region/cc-region-panel.c b/panels/region/cc-region-panel.c ---- a/panels/region/cc-region-panel.c 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cc-region-panel.c 2013-09-21 13:24:15.329949897 +0100 -@@ -18,17 +18,18 @@ - * Author: Sergey Udaltsov <svu@gnome.org> - * - */ --#include "config.h" -+ - #include "cc-region-panel.h" -+#include <config.h> - #include <gtk/gtk.h> - #include <glib/gi18n-lib.h> - --#include "cinnamon-region-panel-xkb.h" -+#include "cinnamon-region-panel-input.h" - #include "cinnamon-region-panel-lang.h" - #include "cinnamon-region-panel-formats.h" - #include "cinnamon-region-panel-system.h" - --G_DEFINE_DYNAMIC_TYPE (CcRegionPanel, cc_region_panel, CC_TYPE_PANEL) -+CC_PANEL_REGISTER (CcRegionPanel, cc_region_panel) - - #define REGION_PANEL_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_REGION_PANEL, CcRegionPanelPrivate)) - -@@ -48,14 +49,6 @@ enum { - SYSTEM_PAGE - }; - -- --static gboolean --languages_link_cb (GtkButton *button, gpointer user_data) --{ -- g_spawn_command_line_async ("gnome-language-selector", NULL); -- return TRUE; --} -- - static void - cc_region_panel_set_page (CcRegionPanel *panel, - const char *page) -@@ -116,13 +109,22 @@ cc_region_panel_finalize (GObject * obje - G_OBJECT_CLASS (cc_region_panel_parent_class)->finalize (object); - } - -+static const char * -+cc_region_panel_get_help_uri (CcPanel *panel) -+{ -+ return "help:gnome-help/prefs-language"; -+} -+ - static void - cc_region_panel_class_init (CcRegionPanelClass * klass) - { - GObjectClass *object_class = G_OBJECT_CLASS (klass); -+ CcPanelClass * panel_class = CC_PANEL_CLASS (klass); - - g_type_class_add_private (klass, sizeof (CcRegionPanelPrivate)); - -+ panel_class->get_help_uri = cc_region_panel_get_help_uri; -+ - object_class->set_property = cc_region_panel_set_property; - object_class->finalize = cc_region_panel_finalize; - -@@ -130,22 +132,14 @@ cc_region_panel_class_init (CcRegionPane - } - - static void --cc_region_panel_class_finalize (CcRegionPanelClass * klass) --{ --} -- --static void - cc_region_panel_init (CcRegionPanel * self) - { - CcRegionPanelPrivate *priv; - GtkWidget *prefs_widget; -- const char *desktop; - GError *error = NULL; - - priv = self->priv = REGION_PANEL_PRIVATE (self); - -- desktop = g_getenv ("XDG_CURRENT_DESKTOP"); -- - priv->builder = gtk_builder_new (); - gtk_builder_set_translation_domain (priv->builder, GETTEXT_PACKAGE); - gtk_builder_add_from_file (priv->builder, -@@ -157,29 +151,16 @@ cc_region_panel_init (CcRegionPanel * se - return; - } - -- prefs_widget = (GtkWidget *) gtk_builder_get_object (priv->builder, -- "region_notebook"); -- -+ prefs_widget = (GtkWidget *) gtk_builder_get_object (priv->builder, -+ "region_notebook"); - gtk_widget_set_size_request (GTK_WIDGET (prefs_widget), -1, 400); - - gtk_widget_reparent (prefs_widget, GTK_WIDGET (self)); - -- setup_xkb_tabs (priv->builder); -- -- setup_language (priv->builder); -- setup_formats (priv->builder); -- setup_system (priv->builder); -- -- /* set screen link */ -- -- GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (self->priv->builder, -- "get_languages_button")); -- -- gtk_button_set_label (GTK_BUTTON (widget), _("Get more languages...")); -- -- g_signal_connect (widget, "clicked", -- G_CALLBACK (languages_link_cb), -- self); -+ setup_input_tabs (priv->builder, self); -+ setup_language (priv->builder); -+ setup_formats (priv->builder); -+ setup_system (priv->builder); - } - - void -@@ -187,6 +168,7 @@ cc_region_panel_register (GIOModule * mo - { - bindtextdomain (GETTEXT_PACKAGE, "/usr/share/cinnamon/locale"); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); -+ - cc_region_panel_register_type (G_TYPE_MODULE (module)); - g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT, - CC_TYPE_REGION_PANEL, -diff -uNrp a/panels/region/cinnamon-region-panel-formats.h b/panels/region/cinnamon-region-panel-formats.h ---- a/panels/region/cinnamon-region-panel-formats.h 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-formats.h 2013-09-21 13:24:15.332949789 +0100 -@@ -19,8 +19,8 @@ - * 02110-1335, USA. - */ - --#ifndef __GNOME_REGION_PANEL_FORMATS_H --#define __GNOME_REGION_PANEL_FORMATS_H -+#ifndef __CINNAMON_REGION_PANEL_FORMATS_H -+#define __CINNAMON_REGION_PANEL_FORMATS_H - - #include <gtk/gtk.h> - -diff -uNrp a/panels/region/cinnamon-region-panel-input.c b/panels/region/cinnamon-region-panel-input.c ---- a/panels/region/cinnamon-region-panel-input.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-input.c 2013-09-21 13:24:15.338949572 +0100 -@@ -0,0 +1,1563 @@ -+/* -+ * Copyright (C) 2011 Red Hat, Inc. -+ * -+ * Written by: Matthias Clasen <mclasen@redhat.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -+ * 02110-1335, USA. -+ */ -+ -+#include <config.h> -+ -+#include <string.h> -+ -+#include <glib.h> -+#include <glib/gi18n.h> -+#include <gio/gdesktopappinfo.h> -+ -+#define GNOME_DESKTOP_USE_UNSTABLE_API -+#include <libcinnamon-desktop/gnome-xkb-info.h> -+ -+#ifdef HAVE_IBUS -+#include <ibus.h> -+#endif -+ -+#include "gdm-languages.h" -+#include "cinnamon-region-panel-input.h" -+ -+#define WID(s) GTK_WIDGET(gtk_builder_get_object (builder, s)) -+ -+#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.cinnamon.desktop.input-sources" -+ -+#define KEY_CURRENT_INPUT_SOURCE "current" -+#define KEY_INPUT_SOURCES "sources" -+ -+#define INPUT_SOURCE_TYPE_XKB "xkb" -+#define INPUT_SOURCE_TYPE_IBUS "ibus" -+ -+enum { -+ NAME_COLUMN, -+ TYPE_COLUMN, -+ ID_COLUMN, -+ SETUP_COLUMN, -+ N_COLUMNS -+}; -+ -+static GSettings *input_sources_settings = NULL; -+static GnomeXkbInfo *xkb_info = NULL; -+static GtkWidget *input_chooser = NULL; /* weak pointer */ -+ -+#ifdef HAVE_IBUS -+static IBusBus *ibus = NULL; -+static GHashTable *ibus_engines = NULL; -+static GCancellable *ibus_cancellable = NULL; -+static guint shell_name_watch_id = 0; -+ -+static const gchar *supported_ibus_engines[] = { -+ /* Simplified Chinese */ -+ "pinyin", -+ "bopomofo", -+ "wubi", -+ "erbi", -+ /* Default in Fedora, where ibus-libpinyin replaces ibus-pinyin */ -+ "libpinyin", -+ "libbopomofo", -+ -+ /* Traditional Chinese */ -+ /* https://bugzilla.gnome.org/show_bug.cgi?id=680840 */ -+ "chewing", -+ "cangjie5", -+ "cangjie3", -+ "quick5", -+ "quick3", -+ "stroke5", -+ -+ /* Japanese */ -+ "anthy", -+ "mozc-jp", -+ "skk", -+ -+ /* Korean */ -+ "hangul", -+ -+ /* Thai */ -+ "m17n:th:kesmanee", -+ "m17n:th:pattachote", -+ "m17n:th:tis820", -+ -+ /* Vietnamese */ -+ "m17n:vi:tcvn", -+ "m17n:vi:telex", -+ "m17n:vi:viqr", -+ "m17n:vi:vni", -+ "Unikey", -+ -+ /* Sinhala */ -+ "m17n:si:wijesekera", -+ "m17n:si:phonetic-dynamic", -+ "m17n:si:trans", -+ "sayura", -+ -+ /* Indic */ -+ /* https://fedoraproject.org/wiki/I18N/Indic#Keyboard_Layouts */ -+ -+ /* Assamese */ -+ "m17n:as:phonetic", -+ "m17n:as:inscript", -+ "m17n:as:itrans", -+ -+ /* Bengali */ -+ "m17n:bn:inscript", -+ "m17n:bn:itrans", -+ "m17n:bn:probhat", -+ -+ /* Gujarati */ -+ "m17n:gu:inscript", -+ "m17n:gu:itrans", -+ "m17n:gu:phonetic", -+ -+ /* Hindi */ -+ "m17n:hi:inscript", -+ "m17n:hi:itrans", -+ "m17n:hi:phonetic", -+ "m17n:hi:remington", -+ "m17n:hi:typewriter", -+ "m17n:hi:vedmata", -+ -+ /* Kannada */ -+ "m17n:kn:kgp", -+ "m17n:kn:inscript", -+ "m17n:kn:itrans", -+ -+ /* Kashmiri */ -+ "m17n:ks:inscript", -+ -+ /* Maithili */ -+ "m17n:mai:inscript", -+ -+ /* Malayalam */ -+ "m17n:ml:inscript", -+ "m17n:ml:itrans", -+ "m17n:ml:mozhi", -+ "m17n:ml:swanalekha", -+ -+ /* Marathi */ -+ "m17n:mr:inscript", -+ "m17n:mr:itrans", -+ "m17n:mr:phonetic", -+ -+ /* Nepali */ -+ "m17n:ne:rom", -+ "m17n:ne:trad", -+ -+ /* Oriya */ -+ "m17n:or:inscript", -+ "m17n:or:itrans", -+ "m17n:or:phonetic", -+ -+ /* Punjabi */ -+ "m17n:pa:inscript", -+ "m17n:pa:itrans", -+ "m17n:pa:phonetic", -+ "m17n:pa:jhelum", -+ -+ /* Sanskrit */ -+ "m17n:sa:harvard-kyoto", -+ -+ /* Sindhi */ -+ "m17n:sd:inscript", -+ -+ /* Tamil */ -+ "m17n:ta:tamil99", -+ "m17n:ta:inscript", -+ "m17n:ta:itrans", -+ "m17n:ta:phonetic", -+ "m17n:ta:lk-renganathan", -+ "m17n:ta:vutam", -+ "m17n:ta:typewriter", -+ -+ /* Telugu */ -+ "m17n:te:inscript", -+ "m17n:te:apple", -+ "m17n:te:pothana", -+ "m17n:te:rts", -+ -+ /* Urdu */ -+ "m17n:ur:phonetic", -+ -+ /* Inscript2 - https://bugzilla.gnome.org/show_bug.cgi?id=684854 */ -+ "m17n:as:inscript2", -+ "m17n:bn:inscript2", -+ "m17n:brx:inscript2-deva", -+ "m17n:doi:inscript2-deva", -+ "m17n:gu:inscript2", -+ "m17n:hi:inscript2", -+ "m17n:kn:inscript2", -+ "m17n:kok:inscript2-deva", -+ "m17n:mai:inscript2", -+ "m17n:ml:inscript2", -+ "m17n:mni:inscript2-beng", -+ "m17n:mni:inscript2-mtei", -+ "m17n:mr:inscript2", -+ "m17n:ne:inscript2-deva", -+ "m17n:or:inscript2", -+ "m17n:pa:inscript2-guru", -+ "m17n:sa:inscript2", -+ "m17n:sat:inscript2-deva", -+ "m17n:sat:inscript2-olck", -+ "m17n:sd:inscript2-deva", -+ "m17n:ta:inscript2", -+ "m17n:te:inscript2", -+ -+ /* No corresponding XKB map available for the languages */ -+ -+ /* Chinese Yi */ -+ "m17n:ii:phonetic", -+ -+ /* Tai-Viet */ -+ "m17n:tai:sonla", -+ -+ /* Kazakh in Arabic script */ -+ "m17n:kk:arabic", -+ -+ /* Yiddish */ -+ "m17n:yi:yivo", -+ -+ /* Canadian Aboriginal languages */ -+ "m17n:ath:phonetic", -+ "m17n:bla:phonetic", -+ "m17n:cr:western", -+ "m17n:iu:phonetic", -+ "m17n:nsk:phonetic", -+ "m17n:oj:phonetic", -+ -+ /* Non-trivial engines, like transliteration-based instead of -+ keymap-based. Confirmation needed that the engines below are -+ actually used by local language users. */ -+ -+ /* Tibetan */ -+ "m17n:bo:ewts", -+ "m17n:bo:tcrc", -+ "m17n:bo:wylie", -+ -+ /* Esperanto */ -+ "m17n:eo:h-f", -+ "m17n:eo:h", -+ "m17n:eo:plena", -+ "m17n:eo:q", -+ "m17n:eo:vi", -+ "m17n:eo:x", -+ -+ /* Amharic */ -+ "m17n:am:sera", -+ -+ /* Russian */ -+ "m17n:ru:translit", -+ -+ /* Classical Greek */ -+ "m17n:grc:mizuochi", -+ -+ /* Lao */ -+ "m17n:lo:lrt", -+ -+ /* Postfix modifier input methods */ -+ "m17n:da:post", -+ "m17n:sv:post", -+ NULL -+}; -+#endif /* HAVE_IBUS */ -+ -+static void populate_model (GtkListStore *store, -+ GtkListStore *active_sources_store); -+static GtkWidget *input_chooser_new (GtkWindow *main_window, -+ GtkListStore *active_sources); -+static gboolean input_chooser_get_selected (GtkWidget *chooser, -+ GtkTreeModel **model, -+ GtkTreeIter *iter); -+static GtkTreeModel *tree_view_get_actual_model (GtkTreeView *tv); -+ -+static gboolean -+strv_contains (const gchar * const *strv, -+ const gchar *str) -+{ -+ const gchar * const *p = strv; -+ for (p = strv; *p; p++) -+ if (g_strcmp0 (*p, str) == 0) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+#ifdef HAVE_IBUS -+static void -+clear_ibus (void) -+{ -+ if (shell_name_watch_id > 0) -+ { -+ g_bus_unwatch_name (shell_name_watch_id); -+ shell_name_watch_id = 0; -+ } -+ g_cancellable_cancel (ibus_cancellable); -+ g_clear_object (&ibus_cancellable); -+ g_clear_pointer (&ibus_engines, g_hash_table_destroy); -+ g_clear_object (&ibus); -+} -+ -+static gchar * -+engine_get_display_name (IBusEngineDesc *engine_desc) -+{ -+ const gchar *name; -+ const gchar *language_code; -+ const gchar *language; -+ gchar *display_name; -+ -+ name = ibus_engine_desc_get_longname (engine_desc); -+ language_code = ibus_engine_desc_get_language (engine_desc); -+ language = ibus_get_language_name (language_code); -+ -+ display_name = g_strdup_printf ("%s (%s)", language, name); -+ -+ return display_name; -+} -+ -+static GDesktopAppInfo * -+setup_app_info_for_id (const gchar *id) -+{ -+ GDesktopAppInfo *app_info; -+ gchar *desktop_file_name; -+ gchar **strv; -+ -+ strv = g_strsplit (id, ":", 2); -+ desktop_file_name = g_strdup_printf ("ibus-setup-%s.desktop", strv[0]); -+ g_strfreev (strv); -+ -+ app_info = g_desktop_app_info_new (desktop_file_name); -+ g_free (desktop_file_name); -+ -+ return app_info; -+} -+ -+static void -+input_chooser_repopulate (GtkListStore *active_sources_store) -+{ -+ GtkBuilder *builder; -+ GtkListStore *model; -+ -+ if (!input_chooser) -+ return; -+ -+ builder = g_object_get_data (G_OBJECT (input_chooser), "builder"); -+ model = GTK_LIST_STORE (gtk_builder_get_object (builder, "input_source_model")); -+ -+ gtk_list_store_clear (model); -+ populate_model (model, active_sources_store); -+} -+ -+static void -+update_ibus_active_sources (GtkBuilder *builder) -+{ -+ GtkTreeView *tv; -+ GtkTreeModel *model; -+ GtkTreeIter iter; -+ gchar *type, *id; -+ gboolean ret; -+ -+ tv = GTK_TREE_VIEW (WID ("active_input_sources")); -+ model = tree_view_get_actual_model (tv); -+ -+ ret = gtk_tree_model_get_iter_first (model, &iter); -+ while (ret) -+ { -+ gtk_tree_model_get (model, &iter, -+ TYPE_COLUMN, &type, -+ ID_COLUMN, &id, -+ -1); -+ -+ if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) -+ { -+ IBusEngineDesc *engine_desc = NULL; -+ GDesktopAppInfo *app_info = NULL; -+ gchar *display_name = NULL; -+ -+ engine_desc = g_hash_table_lookup (ibus_engines, id); -+ if (engine_desc) -+ { -+ display_name = engine_get_display_name (engine_desc); -+ app_info = setup_app_info_for_id (id); -+ -+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, -+ NAME_COLUMN, display_name, -+ SETUP_COLUMN, app_info, -+ -1); -+ g_free (display_name); -+ if (app_info) -+ g_object_unref (app_info); -+ } -+ } -+ -+ g_free (type); -+ g_free (id); -+ -+ ret = gtk_tree_model_iter_next (model, &iter); -+ } -+ -+ input_chooser_repopulate (GTK_LIST_STORE (model)); -+} -+ -+static void -+fetch_ibus_engines_result (GObject *object, -+ GAsyncResult *result, -+ GtkBuilder *builder) -+{ -+ gboolean show_all_sources; -+ GList *list, *l; -+ GError *error; -+ -+ error = NULL; -+ list = ibus_bus_list_engines_async_finish (ibus, result, &error); -+ -+ g_clear_object (&ibus_cancellable); -+ -+ if (!list && error) -+ { -+ g_warning ("Couldn't finish IBus request: %s", error->message); -+ g_error_free (error); -+ return; -+ } -+ -+ show_all_sources = g_settings_get_boolean (input_sources_settings, "show-all-sources"); -+ -+ /* Maps engine ids to engine description objects */ -+ ibus_engines = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); -+ -+ for (l = list; l; l = l->next) -+ { -+ IBusEngineDesc *engine = l->data; -+ const gchar *engine_id = ibus_engine_desc_get_name (engine); -+ -+ if (show_all_sources || strv_contains (supported_ibus_engines, engine_id)) -+ g_hash_table_replace (ibus_engines, (gpointer)engine_id, engine); -+ else -+ g_object_unref (engine); -+ } -+ g_list_free (list); -+ -+ update_ibus_active_sources (builder); -+} -+ -+static void -+fetch_ibus_engines (GtkBuilder *builder) -+{ -+ ibus_cancellable = g_cancellable_new (); -+ -+ ibus_bus_list_engines_async (ibus, -+ -1, -+ ibus_cancellable, -+ (GAsyncReadyCallback)fetch_ibus_engines_result, -+ builder); -+ -+ /* We've got everything we needed, don't want to be called again. */ -+ g_signal_handlers_disconnect_by_func (ibus, fetch_ibus_engines, builder); -+} -+ -+static void -+maybe_start_ibus (void) -+{ -+ /* IBus doesn't export API in the session bus. The only thing -+ * we have there is a well known name which we can use as a -+ * sure-fire way to activate it. */ -+ g_bus_unwatch_name (g_bus_watch_name (G_BUS_TYPE_SESSION, -+ IBUS_SERVICE_IBUS, -+ G_BUS_NAME_WATCHER_FLAGS_AUTO_START, -+ NULL, -+ NULL, -+ NULL, -+ NULL)); -+} -+ -+static void -+on_shell_appeared (GDBusConnection *connection, -+ const gchar *name, -+ const gchar *name_owner, -+ gpointer data) -+{ -+ GtkBuilder *builder = data; -+ -+ if (!ibus) -+ { -+ ibus = ibus_bus_new (); -+ if (ibus_bus_is_connected (ibus)) -+ fetch_ibus_engines (builder); -+ else -+ g_signal_connect_swapped (ibus, "connected", -+ G_CALLBACK (fetch_ibus_engines), builder); -+ } -+ maybe_start_ibus (); -+} -+#endif /* HAVE_IBUS */ -+ -+static gboolean -+add_source_to_table (GtkTreeModel *model, -+ GtkTreePath *path, -+ GtkTreeIter *iter, -+ gpointer data) -+{ -+ GHashTable *hash = data; -+ gchar *type; -+ gchar *id; -+ -+ gtk_tree_model_get (model, iter, -+ TYPE_COLUMN, &type, -+ ID_COLUMN, &id, -+ -1); -+ -+ g_hash_table_add (hash, g_strconcat (type, id, NULL)); -+ -+ g_free (type); -+ g_free (id); -+ -+ return FALSE; -+} -+ -+static void -+populate_model (GtkListStore *store, -+ GtkListStore *active_sources_store) -+{ -+ GHashTable *active_sources_table; -+ GtkTreeIter iter; -+ const gchar *name; -+ GList *sources, *tmp; -+ gchar *source_id = NULL; -+ -+ active_sources_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); -+ -+ gtk_tree_model_foreach (GTK_TREE_MODEL (active_sources_store), -+ add_source_to_table, -+ active_sources_table); -+ -+ sources = gnome_xkb_info_get_all_layouts (xkb_info); -+ -+ for (tmp = sources; tmp; tmp = tmp->next) -+ { -+ g_free (source_id); -+ source_id = g_strconcat (INPUT_SOURCE_TYPE_XKB, tmp->data, NULL); -+ -+ if (g_hash_table_contains (active_sources_table, source_id)) -+ continue; -+ -+ gnome_xkb_info_get_layout_info (xkb_info, (const gchar *)tmp->data, -+ &name, NULL, NULL, NULL); -+ -+ gtk_list_store_append (store, &iter); -+ gtk_list_store_set (store, &iter, -+ NAME_COLUMN, name, -+ TYPE_COLUMN, INPUT_SOURCE_TYPE_XKB, -+ ID_COLUMN, tmp->data, -+ -1); -+ } -+ g_free (source_id); -+ -+ g_list_free (sources); -+ -+#ifdef HAVE_IBUS -+ if (ibus_engines) -+ { -+ gchar *display_name; -+ -+ sources = g_hash_table_get_keys (ibus_engines); -+ -+ source_id = NULL; -+ for (tmp = sources; tmp; tmp = tmp->next) -+ { -+ g_free (source_id); -+ source_id = g_strconcat (INPUT_SOURCE_TYPE_IBUS, tmp->data, NULL); -+ -+ if (g_hash_table_contains (active_sources_table, source_id)) -+ continue; -+ -+ display_name = engine_get_display_name (g_hash_table_lookup (ibus_engines, tmp->data)); -+ -+ gtk_list_store_append (store, &iter); -+ gtk_list_store_set (store, &iter, -+ NAME_COLUMN, display_name, -+ TYPE_COLUMN, INPUT_SOURCE_TYPE_IBUS, -+ ID_COLUMN, tmp->data, -+ -1); -+ g_free (display_name); -+ } -+ g_free (source_id); -+ -+ g_list_free (sources); -+ } -+#endif -+ -+ g_hash_table_destroy (active_sources_table); -+} -+ -+static void -+populate_with_active_sources (GtkListStore *store) -+{ -+ GVariant *sources; -+ GVariantIter iter; -+ const gchar *name; -+ const gchar *type; -+ const gchar *id; -+ gchar *display_name; -+ GDesktopAppInfo *app_info; -+ GtkTreeIter tree_iter; -+ -+ sources = g_settings_get_value (input_sources_settings, KEY_INPUT_SOURCES); -+ -+ g_variant_iter_init (&iter, sources); -+ while (g_variant_iter_next (&iter, "(&s&s)", &type, &id)) -+ { -+ display_name = NULL; -+ app_info = NULL; -+ -+ if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB)) -+ { -+ gnome_xkb_info_get_layout_info (xkb_info, id, &name, NULL, NULL, NULL); -+ if (!name) -+ { -+ g_warning ("Couldn't find XKB input source '%s'", id); -+ continue; -+ } -+ display_name = g_strdup (name); -+ } -+ else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) -+ { -+#ifdef HAVE_IBUS -+ IBusEngineDesc *engine_desc = NULL; -+ -+ if (ibus_engines) -+ engine_desc = g_hash_table_lookup (ibus_engines, id); -+ -+ if (engine_desc) -+ { -+ display_name = engine_get_display_name (engine_desc); -+ app_info = setup_app_info_for_id (id); -+ } -+#else -+ g_warning ("IBus input source type specified but IBus support was not compiled"); -+ continue; -+#endif -+ } -+ else -+ { -+ g_warning ("Unknown input source type '%s'", type); -+ continue; -+ } -+ -+ gtk_list_store_append (store, &tree_iter); -+ gtk_list_store_set (store, &tree_iter, -+ NAME_COLUMN, display_name, -+ TYPE_COLUMN, type, -+ ID_COLUMN, id, -+ SETUP_COLUMN, app_info, -+ -1); -+ g_free (display_name); -+ if (app_info) -+ g_object_unref (app_info); -+ } -+ -+ g_variant_unref (sources); -+} -+ -+static void -+update_configuration (GtkTreeModel *model) -+{ -+ GtkTreeIter iter; -+ gchar *type; -+ gchar *id; -+ GVariantBuilder builder; -+ GVariant *old_sources; -+ const gchar *old_current_type; -+ const gchar *old_current_id; -+ guint old_current_index; -+ guint old_n_sources; -+ guint index; -+ -+ old_sources = g_settings_get_value (input_sources_settings, KEY_INPUT_SOURCES); -+ old_current_index = g_settings_get_uint (input_sources_settings, KEY_CURRENT_INPUT_SOURCE); -+ old_n_sources = g_variant_n_children (old_sources); -+ -+ if (old_n_sources > 0 && old_current_index < old_n_sources) -+ { -+ g_variant_get_child (old_sources, -+ old_current_index, -+ "(&s&s)", -+ &old_current_type, -+ &old_current_id); -+ } -+ else -+ { -+ old_current_type = ""; -+ old_current_id = ""; -+ } -+ -+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); -+ index = 0; -+ gtk_tree_model_get_iter_first (model, &iter); -+ do -+ { -+ gtk_tree_model_get (model, &iter, -+ TYPE_COLUMN, &type, -+ ID_COLUMN, &id, -+ -1); -+ if (index != old_current_index && -+ g_str_equal (type, old_current_type) && -+ g_str_equal (id, old_current_id)) -+ { -+ g_settings_set_uint (input_sources_settings, KEY_CURRENT_INPUT_SOURCE, index); -+ } -+ g_variant_builder_add (&builder, "(ss)", type, id); -+ g_free (type); -+ g_free (id); -+ index += 1; -+ } -+ while (gtk_tree_model_iter_next (model, &iter)); -+ -+ g_settings_set_value (input_sources_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); -+ g_settings_apply (input_sources_settings); -+ -+ g_variant_unref (old_sources); -+} -+ -+static gboolean -+get_selected_iter (GtkBuilder *builder, -+ GtkTreeModel **model, -+ GtkTreeIter *iter) -+{ -+ GtkTreeSelection *selection; -+ -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("active_input_sources"))); -+ -+ return gtk_tree_selection_get_selected (selection, model, iter); -+} -+ -+static gint -+idx_from_model_iter (GtkTreeModel *model, -+ GtkTreeIter *iter) -+{ -+ GtkTreePath *path; -+ gint idx; -+ -+ path = gtk_tree_model_get_path (model, iter); -+ if (path == NULL) -+ return -1; -+ -+ idx = gtk_tree_path_get_indices (path)[0]; -+ gtk_tree_path_free (path); -+ -+ return idx; -+} -+ -+static void -+update_button_sensitivity (GtkBuilder *builder) -+{ -+ GtkWidget *remove_button; -+ GtkWidget *up_button; -+ GtkWidget *down_button; -+ GtkWidget *show_button; -+ GtkWidget *settings_button; -+ GtkTreeView *tv; -+ GtkTreeModel *model; -+ GtkTreeIter iter; -+ gint n_active; -+ gint index; -+ gboolean settings_sensitive; -+ GDesktopAppInfo *app_info; -+ -+ remove_button = WID("input_source_remove"); -+ show_button = WID("input_source_show"); -+ up_button = WID("input_source_move_up"); -+ down_button = WID("input_source_move_down"); -+ settings_button = WID("input_source_settings"); -+ -+ tv = GTK_TREE_VIEW (WID ("active_input_sources")); -+ n_active = gtk_tree_model_iter_n_children (gtk_tree_view_get_model (tv), NULL); -+ -+ if (get_selected_iter (builder, &model, &iter)) -+ { -+ index = idx_from_model_iter (model, &iter); -+ gtk_tree_model_get (model, &iter, SETUP_COLUMN, &app_info, -1); -+ } -+ else -+ { -+ index = -1; -+ app_info = NULL; -+ } -+ -+ settings_sensitive = (index >= 0 && app_info != NULL); -+ -+ if (app_info) -+ g_object_unref (app_info); -+ -+ gtk_widget_set_sensitive (remove_button, index >= 0 && n_active > 1); -+ gtk_widget_set_sensitive (show_button, index >= 0); -+ gtk_widget_set_sensitive (up_button, index > 0); -+ gtk_widget_set_sensitive (down_button, index >= 0 && index < n_active - 1); -+ gtk_widget_set_sensitive (settings_button, settings_sensitive); -+} -+ -+static void -+set_selected_path (GtkBuilder *builder, -+ GtkTreePath *path) -+{ -+ GtkTreeSelection *selection; -+ -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("active_input_sources"))); -+ -+ gtk_tree_selection_select_path (selection, path); -+} -+ -+static GtkTreeModel * -+tree_view_get_actual_model (GtkTreeView *tv) -+{ -+ GtkTreeModel *filtered_store; -+ -+ filtered_store = gtk_tree_view_get_model (tv); -+ -+ return gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filtered_store)); -+} -+ -+static void -+chooser_response (GtkWidget *chooser, gint response_id, gpointer data) -+{ -+ GtkBuilder *builder = data; -+ -+ if (response_id == GTK_RESPONSE_OK) -+ { -+ GtkTreeModel *model; -+ GtkTreeIter iter; -+ -+ if (input_chooser_get_selected (chooser, &model, &iter)) -+ { -+ GtkTreeView *tv; -+ GtkListStore *child_model; -+ GtkTreeIter child_iter, filter_iter; -+ gchar *name; -+ gchar *type; -+ gchar *id; -+ GDesktopAppInfo *app_info = NULL; -+ -+ gtk_tree_model_get (model, &iter, -+ NAME_COLUMN, &name, -+ TYPE_COLUMN, &type, -+ ID_COLUMN, &id, -+ -1); -+ -+#ifdef HAVE_IBUS -+ if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) -+ app_info = setup_app_info_for_id (id); -+#endif -+ -+ tv = GTK_TREE_VIEW (WID ("active_input_sources")); -+ child_model = GTK_LIST_STORE (tree_view_get_actual_model (tv)); -+ -+ gtk_list_store_append (child_model, &child_iter); -+ -+ gtk_list_store_set (child_model, &child_iter, -+ NAME_COLUMN, name, -+ TYPE_COLUMN, type, -+ ID_COLUMN, id, -+ SETUP_COLUMN, app_info, -+ -1); -+ g_free (name); -+ g_free (type); -+ g_free (id); -+ if (app_info) -+ g_object_unref (app_info); -+ -+ gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (tv)), -+ &filter_iter, -+ &child_iter); -+ gtk_tree_selection_select_iter (gtk_tree_view_get_selection (tv), &filter_iter); -+ -+ update_button_sensitivity (builder); -+ update_configuration (GTK_TREE_MODEL (child_model)); -+ } -+ else -+ { -+ g_debug ("nothing selected, nothing added"); -+ } -+ } -+ -+ gtk_widget_destroy (GTK_WIDGET (chooser)); -+} -+ -+static void -+add_input (GtkButton *button, gpointer data) -+{ -+ GtkBuilder *builder = data; -+ GtkWidget *chooser; -+ GtkWidget *toplevel; -+ GtkWidget *treeview; -+ GtkListStore *active_sources; -+ -+ g_debug ("add an input source"); -+ -+ toplevel = gtk_widget_get_toplevel (WID ("region_notebook")); -+ treeview = WID ("active_input_sources"); -+ active_sources = GTK_LIST_STORE (tree_view_get_actual_model (GTK_TREE_VIEW (treeview))); -+ -+ chooser = input_chooser_new (GTK_WINDOW (toplevel), active_sources); -+ g_signal_connect (chooser, "response", -+ G_CALLBACK (chooser_response), builder); -+} -+ -+static void -+remove_selected_input (GtkButton *button, gpointer data) -+{ -+ GtkBuilder *builder = data; -+ GtkTreeModel *model; -+ GtkTreeModel *child_model; -+ GtkTreeIter iter; -+ GtkTreeIter child_iter; -+ GtkTreePath *path; -+ -+ g_debug ("remove selected input source"); -+ -+ if (get_selected_iter (builder, &model, &iter) == FALSE) -+ return; -+ -+ path = gtk_tree_model_get_path (model, &iter); -+ -+ child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)); -+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), -+ &child_iter, -+ &iter); -+ gtk_list_store_remove (GTK_LIST_STORE (child_model), &child_iter); -+ -+ if (!gtk_tree_model_get_iter (model, &iter, path)) -+ gtk_tree_path_prev (path); -+ -+ set_selected_path (builder, path); -+ -+ gtk_tree_path_free (path); -+ -+ update_button_sensitivity (builder); -+ update_configuration (child_model); -+} -+ -+static void -+move_selected_input_up (GtkButton *button, gpointer data) -+{ -+ GtkBuilder *builder = data; -+ GtkTreeModel *model; -+ GtkTreeModel *child_model; -+ GtkTreeIter iter, prev; -+ GtkTreeIter child_iter, child_prev; -+ GtkTreePath *path; -+ -+ g_debug ("move selected input source up"); -+ -+ if (!get_selected_iter (builder, &model, &iter)) -+ return; -+ -+ prev = iter; -+ if (!gtk_tree_model_iter_previous (model, &prev)) -+ return; -+ -+ path = gtk_tree_model_get_path (model, &prev); -+ -+ child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)); -+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), -+ &child_iter, -+ &iter); -+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), -+ &child_prev, -+ &prev); -+ gtk_list_store_swap (GTK_LIST_STORE (child_model), &child_iter, &child_prev); -+ -+ set_selected_path (builder, path); -+ gtk_tree_path_free (path); -+ -+ update_button_sensitivity (builder); -+ update_configuration (child_model); -+} -+ -+static void -+move_selected_input_down (GtkButton *button, gpointer data) -+{ -+ GtkBuilder *builder = data; -+ GtkTreeModel *model; -+ GtkTreeModel *child_model; -+ GtkTreeIter iter, next; -+ GtkTreeIter child_iter, child_next; -+ GtkTreePath *path; -+ -+ g_debug ("move selected input source down"); -+ -+ if (!get_selected_iter (builder, &model, &iter)) -+ return; -+ -+ next = iter; -+ if (!gtk_tree_model_iter_next (model, &next)) -+ return; -+ -+ path = gtk_tree_model_get_path (model, &next); -+ -+ child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)); -+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), -+ &child_iter, -+ &iter); -+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), -+ &child_next, -+ &next); -+ gtk_list_store_swap (GTK_LIST_STORE (child_model), &child_iter, &child_next); -+ -+ set_selected_path (builder, path); -+ gtk_tree_path_free (path); -+ -+ update_button_sensitivity (builder); -+ update_configuration (child_model); -+} -+ -+static void -+show_selected_layout (GtkButton *button, gpointer data) -+{ -+ GtkBuilder *builder = data; -+ GtkTreeModel *model; -+ GtkTreeIter iter; -+ gchar *type; -+ gchar *id; -+ gchar *kbd_viewer_args; -+ const gchar *xkb_layout; -+ const gchar *xkb_variant; -+ -+ g_debug ("show selected layout"); -+ -+ if (!get_selected_iter (builder, &model, &iter)) -+ return; -+ -+ gtk_tree_model_get (model, &iter, -+ TYPE_COLUMN, &type, -+ ID_COLUMN, &id, -+ -1); -+ -+ if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB)) -+ { -+ gnome_xkb_info_get_layout_info (xkb_info, id, NULL, NULL, &xkb_layout, &xkb_variant); -+ -+ if (!xkb_layout || !xkb_layout[0]) -+ { -+ g_warning ("Couldn't find XKB input source '%s'", id); -+ goto exit; -+ } -+ } -+ else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) -+ { -+#ifdef HAVE_IBUS -+ IBusEngineDesc *engine_desc = NULL; -+ -+ if (ibus_engines) -+ engine_desc = g_hash_table_lookup (ibus_engines, id); -+ -+ if (engine_desc) -+ { -+ xkb_layout = ibus_engine_desc_get_layout (engine_desc); -+ xkb_variant = ""; -+ } -+ else -+ { -+ g_warning ("Couldn't find IBus input source '%s'", id); -+ goto exit; -+ } -+#else -+ g_warning ("IBus input source type specified but IBus support was not compiled"); -+ goto exit; -+#endif -+ } -+ else -+ { -+ g_warning ("Unknown input source type '%s'", type); -+ goto exit; -+ } -+ -+ if (xkb_variant[0]) -+ kbd_viewer_args = g_strdup_printf ("gkbd-keyboard-display -l \"%s\t%s\"", -+ xkb_layout, xkb_variant); -+ else -+ kbd_viewer_args = g_strdup_printf ("gkbd-keyboard-display -l %s", -+ xkb_layout); -+ -+ g_spawn_command_line_async (kbd_viewer_args, NULL); -+ -+ g_free (kbd_viewer_args); -+ exit: -+ g_free (type); -+ g_free (id); -+} -+ -+static void -+show_selected_settings (GtkButton *button, gpointer data) -+{ -+ GtkBuilder *builder = data; -+ GtkTreeModel *model; -+ GtkTreeIter iter; -+ GdkAppLaunchContext *ctx; -+ GDesktopAppInfo *app_info; -+ gchar *id; -+ GError *error = NULL; -+ -+ g_debug ("show selected layout"); -+ -+ if (!get_selected_iter (builder, &model, &iter)) -+ return; -+ -+ gtk_tree_model_get (model, &iter, SETUP_COLUMN, &app_info, -1); -+ -+ if (!app_info) -+ return; -+ -+ ctx = gdk_display_get_app_launch_context (gdk_display_get_default ()); -+ gdk_app_launch_context_set_timestamp (ctx, gtk_get_current_event_time ()); -+ -+ gtk_tree_model_get (model, &iter, ID_COLUMN, &id, -1); -+ g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (ctx), -+ "IBUS_ENGINE_NAME", -+ id); -+ g_free (id); -+ -+ if (!g_app_info_launch (G_APP_INFO (app_info), NULL, G_APP_LAUNCH_CONTEXT (ctx), &error)) -+ { -+ g_warning ("Failed to launch input source setup: %s", error->message); -+ g_error_free (error); -+ } -+ -+ g_object_unref (ctx); -+ g_object_unref (app_info); -+} -+ -+static gboolean -+go_to_shortcuts (GtkLinkButton *button, -+ CcRegionPanel *panel) -+{ -+ gchar *argv[3]; -+ argv[0] = "cinnamon-settings"; -+ argv[1] = "keyboard"; -+ argv[3] = NULL; -+ g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); -+ return TRUE; -+} -+ -+static void -+input_sources_changed (GSettings *settings, -+ gchar *key, -+ GtkBuilder *builder) -+{ -+ GtkWidget *treeview; -+ GtkTreeModel *store; -+ GtkTreePath *path; -+ GtkTreeIter iter; -+ GtkTreeModel *model; -+ -+ treeview = WID("active_input_sources"); -+ store = tree_view_get_actual_model (GTK_TREE_VIEW (treeview)); -+ -+ if (get_selected_iter (builder, &model, &iter)) -+ path = gtk_tree_model_get_path (model, &iter); -+ else -+ path = NULL; -+ -+ gtk_list_store_clear (GTK_LIST_STORE (store)); -+ populate_with_active_sources (GTK_LIST_STORE (store)); -+ -+ if (path) -+ { -+ set_selected_path (builder, path); -+ gtk_tree_path_free (path); -+ } -+} -+ -+static void -+update_shortcut_label (GtkWidget *widget, -+ const char *value) -+{ -+ char *text; -+ guint accel_key, *keycode; -+ GdkModifierType mods; -+ -+ if (value == NULL || *value == '\0') -+ { -+ gtk_label_set_text (GTK_LABEL (widget), "\342\200\224"); -+ return; -+ } -+ gtk_accelerator_parse_with_keycode (value, &accel_key, &keycode, &mods); -+ if (accel_key == 0 && keycode == NULL && mods == 0) -+ { -+ gtk_label_set_text (GTK_LABEL (widget), "\342\200\224"); -+ g_warning ("Failed to parse keyboard shortcut: '%s'", value); -+ return; -+ } -+ -+ text = gtk_accelerator_get_label_with_keycode (gtk_widget_get_display (widget), accel_key, *keycode, mods); -+ g_free (keycode); -+ gtk_label_set_text (GTK_LABEL (widget), text); -+ g_free (text); -+} -+ -+static void -+update_shortcuts (GtkBuilder *builder) -+{ -+ char *previous, *next; -+ GSettings *settings; -+ -+ settings = g_settings_new ("org.cinnamon.settings-daemon.plugins.media-keys"); -+ -+ previous = g_settings_get_string (settings, "switch-input-source-backward"); -+ next = g_settings_get_string (settings, "switch-input-source"); -+ -+ update_shortcut_label (WID ("prev-source-shortcut-label"), previous); -+ update_shortcut_label (WID ("next-source-shortcut-label"), next); -+ -+ g_free (previous); -+ g_free (next); -+} -+ -+static gboolean -+active_sources_visible_func (GtkTreeModel *model, -+ GtkTreeIter *iter, -+ gpointer data) -+{ -+ gchar *display_name; -+ -+ gtk_tree_model_get (model, iter, NAME_COLUMN, &display_name, -1); -+ -+ if (!display_name) -+ return FALSE; -+ -+ g_free (display_name); -+ -+ return TRUE; -+} -+ -+void -+setup_input_tabs (GtkBuilder *builder, -+ CcRegionPanel *panel) -+{ -+ GtkWidget *treeview; -+ GtkTreeViewColumn *column; -+ GtkCellRenderer *cell; -+ GtkListStore *store; -+ GtkTreeModel *filtered_store; -+ GtkTreeSelection *selection; -+ -+ /* set up the list of active inputs */ -+ treeview = WID("active_input_sources"); -+ column = gtk_tree_view_column_new (); -+ cell = gtk_cell_renderer_text_new (); -+ gtk_tree_view_column_pack_start (column, cell, TRUE); -+ gtk_tree_view_column_add_attribute (column, cell, "text", NAME_COLUMN); -+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); -+ -+ store = gtk_list_store_new (N_COLUMNS, -+ G_TYPE_STRING, -+ G_TYPE_STRING, -+ G_TYPE_STRING, -+ G_TYPE_DESKTOP_APP_INFO); -+ -+ gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store)); -+ -+ input_sources_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR); -+ g_settings_delay (input_sources_settings); -+ g_object_weak_ref (G_OBJECT (builder), (GWeakNotify) g_object_unref, input_sources_settings); -+ -+ if (!xkb_info) -+ xkb_info = gnome_xkb_info_new (); -+ -+#ifdef HAVE_IBUS -+ ibus_init (); -+ shell_name_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, -+ "org.Cinnamon", -+ G_BUS_NAME_WATCHER_FLAGS_NONE, -+ on_shell_appeared, -+ NULL, -+ builder, -+ NULL); -+ g_object_weak_ref (G_OBJECT (builder), (GWeakNotify) clear_ibus, NULL); -+#endif -+ -+ populate_with_active_sources (store); -+ -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); -+ g_signal_connect_swapped (selection, "changed", -+ G_CALLBACK (update_button_sensitivity), builder); -+ -+ /* Some input source types might have their info loaded -+ * asynchronously. In that case we don't want to show them -+ * immediately so we use a filter model on top of the real model -+ * which mirrors the GSettings key. */ -+ filtered_store = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); -+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered_store), -+ active_sources_visible_func, -+ NULL, -+ NULL); -+ gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), filtered_store); -+ -+ /* set up the buttons */ -+ g_signal_connect (WID("input_source_add"), "clicked", -+ G_CALLBACK (add_input), builder); -+ g_signal_connect (WID("input_source_remove"), "clicked", -+ G_CALLBACK (remove_selected_input), builder); -+ g_signal_connect (WID("input_source_move_up"), "clicked", -+ G_CALLBACK (move_selected_input_up), builder); -+ g_signal_connect (WID("input_source_move_down"), "clicked", -+ G_CALLBACK (move_selected_input_down), builder); -+ g_signal_connect (WID("input_source_show"), "clicked", -+ G_CALLBACK (show_selected_layout), builder); -+ g_signal_connect (WID("input_source_settings"), "clicked", -+ G_CALLBACK (show_selected_settings), builder); -+ -+ /* use an em dash is no shortcut */ -+ update_shortcuts (builder); -+ -+ g_signal_connect (WID("jump-to-shortcuts"), "activate-link", -+ G_CALLBACK (go_to_shortcuts), panel); -+ -+ g_signal_connect (G_OBJECT (input_sources_settings), -+ "changed::" KEY_INPUT_SOURCES, -+ G_CALLBACK (input_sources_changed), -+ builder); -+} -+ -+static void -+filter_clear (GtkEntry *entry, -+ GtkEntryIconPosition icon_pos, -+ GdkEvent *event, -+ gpointer user_data) -+{ -+ gtk_entry_set_text (entry, ""); -+} -+ -+static gchar **search_pattern_list; -+ -+static void -+filter_changed (GtkBuilder *builder) -+{ -+ GtkTreeModelFilter *filtered_model; -+ GtkTreeView *tree_view; -+ GtkTreeSelection *selection; -+ GtkTreeIter selected_iter; -+ GtkWidget *filter_entry; -+ const gchar *pattern; -+ gchar *upattern; -+ -+ filter_entry = WID ("input_source_filter"); -+ pattern = gtk_entry_get_text (GTK_ENTRY (filter_entry)); -+ upattern = g_utf8_strup (pattern, -1); -+ if (!g_strcmp0 (pattern, "")) -+ g_object_set (G_OBJECT (filter_entry), -+ "secondary-icon-name", "edit-find-symbolic", -+ "secondary-icon-activatable", FALSE, -+ "secondary-icon-sensitive", FALSE, -+ NULL); -+ else -+ g_object_set (G_OBJECT (filter_entry), -+ "secondary-icon-name", "edit-clear-symbolic", -+ "secondary-icon-activatable", TRUE, -+ "secondary-icon-sensitive", TRUE, -+ NULL); -+ -+ if (search_pattern_list != NULL) -+ g_strfreev (search_pattern_list); -+ -+ search_pattern_list = g_strsplit (upattern, " ", -1); -+ g_free (upattern); -+ -+ filtered_model = GTK_TREE_MODEL_FILTER (gtk_builder_get_object (builder, "filtered_input_source_model")); -+ gtk_tree_model_filter_refilter (filtered_model); -+ -+ tree_view = GTK_TREE_VIEW (WID ("filtered_input_source_list")); -+ selection = gtk_tree_view_get_selection (tree_view); -+ if (gtk_tree_selection_get_selected (selection, NULL, &selected_iter)) -+ { -+ GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (filtered_model), -+ &selected_iter); -+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5); -+ gtk_tree_path_free (path); -+ } -+ else -+ { -+ GtkTreeIter iter; -+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (filtered_model), &iter)) -+ gtk_tree_selection_select_iter (selection, &iter); -+ } -+} -+ -+static void -+selection_changed (GtkTreeSelection *selection, -+ GtkBuilder *builder) -+{ -+ gtk_widget_set_sensitive (WID ("ok-button"), -+ gtk_tree_selection_get_selected (selection, NULL, NULL)); -+} -+ -+static void -+row_activated (GtkTreeView *tree_view, -+ GtkTreePath *path, -+ GtkTreeViewColumn *column, -+ GtkBuilder *builder) -+{ -+ GtkWidget *add_button; -+ GtkWidget *dialog; -+ -+ add_button = WID ("ok-button"); -+ dialog = WID ("input_source_chooser"); -+ if (gtk_widget_is_sensitive (add_button)) -+ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); -+} -+ -+static void -+entry_activated (GtkBuilder *builder, -+ gpointer data) -+{ -+ row_activated (NULL, NULL, NULL, builder); -+} -+ -+static gboolean -+filter_func (GtkTreeModel *model, -+ GtkTreeIter *iter, -+ gpointer data) -+{ -+ gchar *name = NULL; -+ gchar **pattern; -+ gboolean rv = TRUE; -+ -+ if (search_pattern_list == NULL || search_pattern_list[0] == NULL) -+ return TRUE; -+ -+ gtk_tree_model_get (model, iter, -+ NAME_COLUMN, &name, -+ -1); -+ -+ pattern = search_pattern_list; -+ do { -+ gboolean is_pattern_found = FALSE; -+ gchar *udesc = g_utf8_strup (name, -1); -+ if (udesc != NULL && g_strstr_len (udesc, -1, *pattern)) -+ { -+ is_pattern_found = TRUE; -+ } -+ g_free (udesc); -+ -+ if (!is_pattern_found) -+ { -+ rv = FALSE; -+ break; -+ } -+ -+ } while (*++pattern != NULL); -+ -+ g_free (name); -+ -+ return rv; -+} -+ -+static GtkWidget * -+input_chooser_new (GtkWindow *main_window, -+ GtkListStore *active_sources) -+{ -+ GtkBuilder *builder; -+ GtkWidget *chooser; -+ GtkWidget *filtered_list; -+ GtkWidget *filter_entry; -+ GtkTreeViewColumn *visible_column; -+ GtkTreeSelection *selection; -+ GtkListStore *model; -+ GtkTreeModelFilter *filtered_model; -+ GtkTreeIter iter; -+ -+ builder = gtk_builder_new (); -+ gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE); -+ gtk_builder_add_from_file (builder, -+ CINNAMONCC_UI_DIR "/cinnamon-region-panel-input-chooser.ui", -+ NULL); -+ chooser = WID ("input_source_chooser"); -+ input_chooser = chooser; -+ g_object_add_weak_pointer (G_OBJECT (chooser), (gpointer *) &input_chooser); -+ g_object_set_data_full (G_OBJECT (chooser), "builder", builder, g_object_unref); -+ -+ filtered_list = WID ("filtered_input_source_list"); -+ filter_entry = WID ("input_source_filter"); -+ -+ g_object_set_data (G_OBJECT (chooser), -+ "filtered_input_source_list", filtered_list); -+ visible_column = -+ gtk_tree_view_column_new_with_attributes ("Input Sources", -+ gtk_cell_renderer_text_new (), -+ "text", NAME_COLUMN, -+ NULL); -+ -+ gtk_window_set_transient_for (GTK_WINDOW (chooser), main_window); -+ -+ gtk_tree_view_append_column (GTK_TREE_VIEW (filtered_list), -+ visible_column); -+ /* We handle searching ourselves, thank you. */ -+ gtk_tree_view_set_enable_search (GTK_TREE_VIEW (filtered_list), FALSE); -+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (filtered_list), -1); -+ -+ g_signal_connect_swapped (G_OBJECT (filter_entry), "activate", -+ G_CALLBACK (entry_activated), builder); -+ g_signal_connect_swapped (G_OBJECT (filter_entry), "notify::text", -+ G_CALLBACK (filter_changed), builder); -+ -+ g_signal_connect (G_OBJECT (filter_entry), "icon-release", -+ G_CALLBACK (filter_clear), NULL); -+ -+ filtered_model = GTK_TREE_MODEL_FILTER (gtk_builder_get_object (builder, "filtered_input_source_model")); -+ model = GTK_LIST_STORE (gtk_builder_get_object (builder, "input_source_model")); -+ -+ populate_model (model, active_sources); -+ -+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), -+ NAME_COLUMN, GTK_SORT_ASCENDING); -+ -+ gtk_tree_model_filter_set_visible_func (filtered_model, -+ filter_func, -+ NULL, NULL); -+ -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (filtered_list)); -+ -+ g_signal_connect (G_OBJECT (selection), "changed", -+ G_CALLBACK (selection_changed), builder); -+ -+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (filtered_model), &iter)) -+ gtk_tree_selection_select_iter (selection, &iter); -+ -+ g_signal_connect (G_OBJECT (filtered_list), "row-activated", -+ G_CALLBACK (row_activated), builder); -+ -+ gtk_widget_grab_focus (filter_entry); -+ -+ gtk_widget_show (chooser); -+ -+ return chooser; -+} -+ -+static gboolean -+input_chooser_get_selected (GtkWidget *dialog, -+ GtkTreeModel **model, -+ GtkTreeIter *iter) -+{ -+ GtkWidget *tv; -+ GtkTreeSelection *selection; -+ -+ tv = g_object_get_data (G_OBJECT (dialog), "filtered_input_source_list"); -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv)); -+ -+ return gtk_tree_selection_get_selected (selection, model, iter); -+} -diff -uNrp a/panels/region/cinnamon-region-panel-input-chooser.ui b/panels/region/cinnamon-region-panel-input-chooser.ui ---- a/panels/region/cinnamon-region-panel-input-chooser.ui 1970-01-01 01:00:00.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-input-chooser.ui 2013-09-21 13:24:15.339949536 +0100 -@@ -0,0 +1,157 @@ -+<?xml version="1.0" encoding="UTF-8"?> -+<interface> -+ <requires lib="gtk+" version="2.16"/> -+ <object class="GtkListStore" id="input_source_model"> -+ <columns> -+ <!-- display name --> -+ <column type="gchararray"/> -+ <!-- input source type --> -+ <column type="gchararray"/> -+ <!-- type specific identifier --> -+ <column type="gchararray"/> -+ </columns> -+ </object> -+ <object class="GtkTreeModelFilter" id="filtered_input_source_model"> -+ <property name="child_model">input_source_model</property> -+ </object> -+ <object class="GtkDialog" id="input_source_chooser"> -+ <property name="visible">False</property> -+ <property name="can_focus">False</property> -+ <property name="border_width">5</property> -+ <property name="title" translatable="yes">Choose an input source</property> -+ <property name="modal">True</property> -+ <property name="window_position">center-on-parent</property> -+ <property name="type_hint">dialog</property> -+ <child internal-child="vbox"> -+ <object class="GtkBox" id="dialog-vbox3"> -+ <property name="visible">True</property> -+ <property name="can_focus">False</property> -+ <property name="orientation">vertical</property> -+ <property name="spacing">2</property> -+ <child internal-child="action_area"> -+ <object class="GtkButtonBox" id="hbtnBox"> -+ <property name="visible">True</property> -+ <property name="can_focus">False</property> -+ <property name="layout_style">end</property> -+ <child> -+ <object class="GtkButton" id="cancel-button"> -+ <property name="label">gtk-cancel</property> -+ <property name="visible">True</property> -+ <property name="can_focus">True</property> -+ <property name="can_default">True</property> -+ <property name="receives_default">False</property> -+ <property name="use_action_appearance">False</property> -+ <property name="use_stock">True</property> -+ </object> -+ <packing> -+ <property name="expand">False</property> -+ <property name="fill">False</property> -+ <property name="pack_type">end</property> -+ <property name="position">1</property> -+ </packing> -+ </child> -+ <child> -+ <object class="GtkButton" id="ok-button"> -+ <property name="label">gtk-add</property> -+ <property name="visible">True</property> -+ <property name="can_focus">True</property> -+ <property name="can_default">True</property> -+ <property name="receives_default">False</property> -+ <property name="use_action_appearance">False</property> -+ <property name="use_stock">True</property> -+ </object> -+ <packing> -+ <property name="expand">False</property> -+ <property name="fill">False</property> -+ <property name="pack_type">end</property> -+ <property name="position">2</property> -+ </packing> -+ </child> -+ </object> -+ </child> -+ <child> -+ <object class="GtkVBox" id="vbox40"> -+ <property name="visible">True</property> -+ <property name="can_focus">False</property> -+ <property name="border_width">5</property> -+ <property name="spacing">6</property> -+ <child> -+ <object class="GtkVBox" id="vbox1"> -+ <property name="visible">True</property> -+ <property name="can_focus">False</property> -+ <property name="spacing">6</property> -+ <child> -+ <object class="GtkLabel" id="label1"> -+ <property name="visible">True</property> -+ <property name="can_focus">False</property> -+ <property name="xalign">0</property> -+ <property name="label" translatable="yes">Select an input source to add</property> -+ </object> -+ <packing> -+ <property name="expand">False</property> -+ <property name="fill">False</property> -+ <property name="position">0</property> -+ </packing> -+ </child> -+ <child> -+ <object class="GtkScrolledWindow" id="scrolledwindow1"> -+ <property name="visible">True</property> -+ <property name="can_focus">True</property> -+ <property name="hscrollbar_policy">never</property> -+ <property name="shadow_type">etched-in</property> -+ <property name="min_content_width">450</property> -+ <property name="min_content_height">250</property> -+ <child> -+ <object class="GtkTreeView" id="filtered_input_source_list"> -+ <property name="visible">True</property> -+ <property name="can_focus">True</property> -+ <property name="model">filtered_input_source_model</property> -+ <property name="headers_visible">False</property> -+ <property name="search_column">0</property> -+ </object> -+ </child> -+ </object> -+ <packing> -+ <property name="expand">True</property> -+ <property name="fill">True</property> -+ <property name="position">1</property> -+ </packing> -+ </child> -+ </object> -+ <packing> -+ <property name="expand">True</property> -+ <property name="fill">True</property> -+ <property name="position">0</property> -+ </packing> -+ </child> -+ <child> -+ <object class="GtkEntry" id="input_source_filter"> -+ <property name="visible">True</property> -+ <property name="can_focus">True</property> -+ <property name="invisible_char">•</property> -+ <property name="secondary-icon-name">edit-find-symbolic</property> -+ <property name="secondary-icon-activatable">False</property> -+ <property name="secondary-icon-sensitive">False</property> -+ </object> -+ <packing> -+ <property name="expand">False</property> -+ <property name="fill">False</property> -+ <property name="pack_type">end</property> -+ <property name="position">1</property> -+ </packing> -+ </child> -+ </object> -+ <packing> -+ <property name="expand">True</property> -+ <property name="fill">True</property> -+ <property name="position">1</property> -+ </packing> -+ </child> -+ </object> -+ </child> -+ <action-widgets> -+ <action-widget response="-5">ok-button</action-widget> -+ <action-widget response="-6">cancel-button</action-widget> -+ </action-widgets> -+ </object> -+</interface> -diff -uNrp a/panels/region/cinnamon-region-panel-input.h b/panels/region/cinnamon-region-panel-input.h ---- a/panels/region/cinnamon-region-panel-input.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-input.h 2013-09-21 13:24:15.339949536 +0100 -@@ -0,0 +1,36 @@ -+/* cinnamon-region-panel-input.h -+ * Copyright (C) 2011 Red Hat, Inc. -+ * -+ * Written by Matthias Clasen -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -+ * 02110-1335, USA. -+ */ -+ -+#ifndef __CINNAMON_KEYBOARD_PROPERTY_INPUT_H -+#define __CINNAMON_KEYBOARD_PROPERTY_INPUT_H -+ -+#include <gtk/gtk.h> -+ -+#include "cc-region-panel.h" -+ -+G_BEGIN_DECLS -+ -+void setup_input_tabs (GtkBuilder *builder, -+ CcRegionPanel *self); -+ -+G_END_DECLS -+ -+#endif /* __CINNAMON_KEYBOARD_PROPERTY_INPUT_H */ -diff -uNrp a/panels/region/cinnamon-region-panel-lang.c b/panels/region/cinnamon-region-panel-lang.c ---- a/panels/region/cinnamon-region-panel-lang.c 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-lang.c 2013-09-21 13:24:15.340949500 +0100 -@@ -24,7 +24,7 @@ - #endif - - #include <string.h> --#include <glib/gi18n-lib.h> -+#include <glib/gi18n.h> - - #include "cinnamon-region-panel-lang.h" - #include "cinnamon-region-panel-formats.h" -diff -uNrp a/panels/region/cinnamon-region-panel-lang.h b/panels/region/cinnamon-region-panel-lang.h ---- a/panels/region/cinnamon-region-panel-lang.h 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-lang.h 2013-09-21 13:24:15.340949500 +0100 -@@ -19,8 +19,8 @@ - * 02110-1335, USA. - */ - --#ifndef __GNOME_KEYBOARD_PROPERTY_LANG_H --#define __GNOME_KEYBOARD_PROPERTY_LANG_H -+#ifndef __CINNAMON_KEYBOARD_PROPERTY_LANG_H -+#define __CINNAMON_KEYBOARD_PROPERTY_LANG_H - - #include <gtk/gtk.h> - -@@ -29,4 +29,4 @@ G_BEGIN_DECLS - void setup_language (GtkBuilder *builder); - - G_END_DECLS --#endif /* __GNOME_KEYBOARD_PROPERTY_LANG_H */ -+#endif /* __CINNAMON_KEYBOARD_PROPERTY_LANG_H */ -diff -uNrp a/panels/region/cinnamon-region-panel-layout-chooser.ui b/panels/region/cinnamon-region-panel-layout-chooser.ui ---- a/panels/region/cinnamon-region-panel-layout-chooser.ui 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-layout-chooser.ui 1970-01-01 01:00:00.000000000 +0100 -@@ -1,180 +0,0 @@ --<?xml version="1.0" encoding="UTF-8"?> --<interface> -- <requires lib="gtk+" version="2.16"/> -- <object class="GtkListStore" id="layout_list_model"> -- <columns> -- <!-- column-name sort_order --> -- <column type="gchararray"/> -- <!-- column-name visible --> -- <column type="gchararray"/> -- <!-- column-name xkb_id --> -- <column type="gchararray"/> -- <!-- column-name country_desc --> -- <column type="gchararray"/> -- <!-- column-name language_desc --> -- <column type="gchararray"/> -- </columns> -- </object> -- <object class="GtkTreeModelFilter" id="filtered_layout_list_model"> -- <property name="child_model">layout_list_model</property> -- </object> -- <object class="GtkDialog" id="xkb_layout_chooser"> -- <property name="visible">False</property> -- <property name="can_focus">False</property> -- <property name="border_width">5</property> -- <property name="title" translatable="yes">Choose a Layout</property> -- <property name="modal">True</property> -- <property name="window_position">center-on-parent</property> -- <property name="type_hint">dialog</property> -- <child internal-child="vbox"> -- <object class="GtkBox" id="dialog-vbox3"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="orientation">vertical</property> -- <property name="spacing">2</property> -- <child internal-child="action_area"> -- <object class="GtkButtonBox" id="hbtnBox"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="layout_style">end</property> -- <child> -- <object class="GtkButton" id="btnPreview"> -- <property name="label" translatable="yes">Preview</property> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="receives_default">True</property> -- <property name="use_action_appearance">False</property> -- </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">False</property> -- <property name="position">0</property> -- <property name="secondary">True</property> -- </packing> -- </child> -- <child> -- <object class="GtkButton" id="btnCancel"> -- <property name="label">gtk-cancel</property> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="can_default">True</property> -- <property name="receives_default">False</property> -- <property name="use_action_appearance">False</property> -- <property name="use_stock">True</property> -- </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">False</property> -- <property name="pack_type">end</property> -- <property name="position">1</property> -- </packing> -- </child> -- <child> -- <object class="GtkButton" id="btnOk"> -- <property name="label">gtk-add</property> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="can_default">True</property> -- <property name="receives_default">False</property> -- <property name="use_action_appearance">False</property> -- <property name="use_stock">True</property> -- </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">False</property> -- <property name="pack_type">end</property> -- <property name="position">2</property> -- </packing> -- </child> -- </object> -- </child> -- <child> -- <object class="GtkVBox" id="vbox40"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="border_width">5</property> -- <property name="spacing">6</property> -- <child> -- <object class="GtkVBox" id="vbox1"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="spacing">6</property> -- <child> -- <object class="GtkLabel" id="label1"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="xalign">0</property> -- <property name="label" translatable="yes">Select an input source to add</property> -- </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">False</property> -- <property name="position">0</property> -- </packing> -- </child> -- <child> -- <object class="GtkScrolledWindow" id="scrolledwindow1"> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="hscrollbar_policy">never</property> -- <property name="shadow_type">etched-in</property> -- <property name="min_content_width">450</property> -- <property name="min_content_height">250</property> -- <child> -- <object class="GtkTreeView" id="xkb_filtered_layouts_list"> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="model">filtered_layout_list_model</property> -- <property name="headers_visible">False</property> -- <property name="search_column">0</property> -- <child internal-child="selection"> -- <object class="GtkTreeSelection" id="treeview-selection1"/> -- </child> -- </object> -- </child> -- </object> -- <packing> -- <property name="expand">True</property> -- <property name="fill">True</property> -- <property name="position">1</property> -- </packing> -- </child> -- </object> -- <packing> -- <property name="expand">True</property> -- <property name="fill">True</property> -- <property name="position">0</property> -- </packing> -- </child> -- <child> -- <object class="GtkEntry" id="xkb_layout_filter"> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="invisible_char">•</property> -- <property name="secondary-icon-name">edit-find-symbolic</property> -- <property name="secondary-icon-activatable">False</property> -- <property name="secondary-icon-sensitive">False</property> -- </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">False</property> -- <property name="pack_type">end</property> -- <property name="position">1</property> -- </packing> -- </child> -- </object> -- <packing> -- <property name="expand">True</property> -- <property name="fill">True</property> -- <property name="position">1</property> -- </packing> -- </child> -- </object> -- </child> -- <action-widgets> -- <action-widget response="1">btnPreview</action-widget> -- <action-widget response="-5">btnOk</action-widget> -- <action-widget response="-6">btnCancel</action-widget> -- </action-widgets> -- </object> --</interface> -diff -uNrp a/panels/region/cinnamon-region-panel-options-dialog.ui b/panels/region/cinnamon-region-panel-options-dialog.ui ---- a/panels/region/cinnamon-region-panel-options-dialog.ui 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-options-dialog.ui 1970-01-01 01:00:00.000000000 +0100 -@@ -1,79 +0,0 @@ --<?xml version="1.0" encoding="UTF-8"?> --<interface> -- <requires lib="gtk+" version="2.16"/> -- <object class="GtkDialog" id="xkb_options_dialog"> -- <property name="can_focus">False</property> -- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> -- <property name="border_width">5</property> -- <property name="title" translatable="yes">Keyboard Layout Options</property> -- <property name="window_position">center-on-parent</property> -- <property name="default_width">550</property> -- <property name="default_height">400</property> -- <property name="type_hint">dialog</property> -- <child internal-child="vbox"> -- <object class="GtkBox" id="dialog_vbox"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> -- <property name="orientation">vertical</property> -- <property name="spacing">2</property> -- <child> -- <object class="GtkScrolledWindow" id="options_scroll"> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="border_width">5</property> -- <property name="shadow_type">out</property> -- <child> -- <object class="GtkViewport" id="viewport1"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="shadow_type">none</property> -- <child> -- <object class="GtkVBox" id="options_vbox"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> -- </object> -- </child> -- </object> -- </child> -- </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">True</property> -- <property name="position">1</property> -- </packing> -- </child> -- <child internal-child="action_area"> -- <object class="GtkButtonBox" id="dialog-action_area4"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> -- <property name="layout_style">end</property> -- <child> -- <placeholder/> -- </child> -- <child> -- <object class="GtkButton" id="button2"> -- <property name="label">gtk-close</property> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="receives_default">True</property> -- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> -- <property name="use_action_appearance">False</property> -- <property name="use_stock">True</property> -- </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">False</property> -- <property name="position">1</property> -- </packing> -- </child> -- </object> -- </child> -- </object> -- </child> -- <action-widgets> -- <action-widget response="-7">button2</action-widget> -- </action-widgets> -- </object> --</interface> -diff -uNrp a/panels/region/cinnamon-region-panel-system.c b/panels/region/cinnamon-region-panel-system.c ---- a/panels/region/cinnamon-region-panel-system.c 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-system.c 2013-09-21 13:24:15.342949428 +0100 -@@ -27,15 +27,18 @@ - - #include <polkit/polkit.h> - --#include <glib/gi18n-lib.h> -+#include <glib/gi18n.h> -+ -+#define GNOME_DESKTOP_USE_UNSTABLE_API -+#include <libcinnamon-desktop/gnome-xkb-info.h> - --#include <libgnomekbd/gkbd-keyboard-config.h> - #include "cc-common-language.h" - #include "gdm-languages.h" - #include "cinnamon-region-panel-system.h" --#include "cinnamon-region-panel-xkb.h" - --static GSettings *locale_settings, *xkb_settings; -+#define WID(s) GTK_WIDGET(gtk_builder_get_object (dialog, s)) -+ -+static GSettings *locale_settings, *input_sources_settings; - static GDBusProxy *localed_proxy; - static GPermission *localed_permission; - -@@ -72,13 +75,14 @@ update_copy_button (GtkBuilder *dialog) - - button = WID ("copy_settings_button"); - -- /* If the version of localed doesn't include layouts... */ -- if (system_input_source) { -+ if (user_input_source && user_input_source[0]) { - layouts_differ = (g_strcmp0 (user_input_source, system_input_source) != 0); - if (layouts_differ == FALSE) - layouts_differ = (g_strcmp0 (user_input_variants, system_input_variants) != 0); -- } else -+ } else { -+ /* Nothing to copy */ - layouts_differ = FALSE; -+ } - - if (g_strcmp0 (user_lang, system_lang) == 0 && - g_strcmp0 (user_region, system_region) == 0 && -@@ -131,61 +135,67 @@ system_update_language (GtkBuilder *dial - } - - static void --xkb_settings_changed (GSettings *settings, -- const gchar *key, -- GtkBuilder *dialog) -+input_sources_changed (GSettings *settings, -+ const gchar *key, -+ GtkBuilder *dialog) - { -- guint i; -- GString *disp, *list, *variants; -- GtkWidget *label; -- gchar **layouts; -- -- layouts = g_settings_get_strv (settings, "layouts"); -- if (layouts == NULL) -- return; -- -- label = WID ("user_input_source"); -- disp = g_string_new (""); -- list = g_string_new (""); -- variants = g_string_new (""); -- -- for (i = 0; layouts[i]; i++) { -- gchar *utf_visible; -- char **split; -- gchar *layout, *variant; -- -- utf_visible = xkb_layout_description_utf8 (layouts[i]); -- if (disp->str[0] != '\0') -- g_string_append (disp, ", "); -- g_string_append (disp, utf_visible ? utf_visible : layouts[i]); -- g_free (utf_visible); -- -- split = g_strsplit_set (layouts[i], " \t", 2); -- -- if (split == NULL || split[0] == NULL) -- continue; -- -- layout = split[0]; -- variant = split[1]; -- -- if (list->str[0] != '\0') -- g_string_append (list, ","); -- g_string_append (list, layout); -- -- if (variants->str[0] != '\0') -- g_string_append (variants, ","); -- g_string_append (variants, variant ? variant : ""); -- -- g_strfreev (split); -- } -- g_strfreev (layouts); -+ GString *disp, *list, *variants; -+ GtkWidget *label; -+ GnomeXkbInfo *xkb_info; -+ GVariantIter iter; -+ GVariant *sources; -+ const gchar *type; -+ const gchar *id; -+ -+ sources = g_settings_get_value (input_sources_settings, "sources"); -+ xkb_info = gnome_xkb_info_new (); -+ -+ label = WID ("user_input_source"); -+ disp = g_string_new (""); -+ list = g_string_new (""); -+ variants = g_string_new (""); -+ -+ g_variant_iter_init (&iter, sources); -+ while (g_variant_iter_next (&iter, "(&s&s)", &type, &id)) { -+ /* We can't copy non-XKB layouts to the system yet */ -+ if (g_str_equal (type, "xkb")) { -+ char **split; -+ gchar *layout, *variant; -+ const char *name; -+ -+ gnome_xkb_info_get_layout_info (xkb_info, id, &name, NULL, NULL, NULL); -+ if (disp->str[0] != '\0') -+ g_string_append (disp, ", "); -+ g_string_append (disp, name); -+ -+ split = g_strsplit (id, "+", 2); -+ -+ if (split == NULL || split[0] == NULL) -+ continue; -+ -+ layout = split[0]; -+ variant = split[1]; -+ -+ if (list->str[0] != '\0') { -+ g_string_append (list, ","); -+ g_string_append (variants, ","); -+ } -+ g_string_append (list, layout); -+ g_string_append (variants, variant ? variant : ""); -+ -+ g_strfreev (split); -+ } -+ } -+ g_variant_unref (sources); -+ g_object_unref (xkb_info); - - g_object_set_data_full (G_OBJECT (label), "input_source", g_string_free (list, FALSE), g_free); - g_object_set_data_full (G_OBJECT (label), "input_variants", g_string_free (variants, FALSE), g_free); -+ - gtk_label_set_text (GTK_LABEL (label), disp->str); - g_string_free (disp, TRUE); - -- update_copy_button (dialog); -+ update_copy_button (dialog); - } - - static void -@@ -222,12 +232,13 @@ on_localed_properties_changed (GDBusProx - const gchar **invalidated_properties, - GtkBuilder *dialog) - { -- GVariant *v; -+ GVariant *v, *w; - GtkWidget *label; -- const char *layout; -+ GnomeXkbInfo *xkb_info; - char **layouts; -+ char **variants; - GString *disp; -- guint i; -+ guint i, n; - - if (invalidated_properties != NULL) { - guint i; -@@ -236,6 +247,8 @@ on_localed_properties_changed (GDBusProx - update_property (proxy, "Locale"); - else if (g_str_equal (invalidated_properties[i], "X11Layout")) - update_property (proxy, "X11Layout"); -+ else if (g_str_equal (invalidated_properties[i], "X11Variant")) -+ update_property (proxy, "X11Variant"); - } - } - -@@ -290,29 +303,56 @@ on_localed_properties_changed (GDBusProx - label = WID ("system_input_source"); - v = g_dbus_proxy_get_cached_property (proxy, "X11Layout"); - if (v) { -- layout = g_variant_get_string (v, NULL); -- g_object_set_data_full (G_OBJECT (label), "input_source", g_strdup (layout), g_free); -- } else { -+ layouts = g_strsplit (g_variant_get_string (v, NULL), ",", -1); -+ g_object_set_data_full (G_OBJECT (label), "input_source", -+ g_variant_dup_string (v, NULL), g_free); -+ g_variant_unref (v); -+ } else { - g_object_set_data_full (G_OBJECT (label), "input_source", NULL, g_free); - update_copy_button (dialog); - return; - } - -- disp = g_string_new (""); -- layouts = g_strsplit (layout, ",", -1); -- for (i = 0; layouts[i]; i++) { -- gchar *utf_visible; -- -- utf_visible = xkb_layout_description_utf8 (layouts[i]); -- if (disp->str[0] != '\0') -- disp = g_string_append (disp, ", "); -- disp = g_string_append (disp, utf_visible ? utf_visible : layouts[i]); -- g_free (utf_visible); -- } -+ w = g_dbus_proxy_get_cached_property (proxy, "X11Variant"); -+ if (w) { -+ variants = g_strsplit (g_variant_get_string (w, NULL), ",", -1); -+ g_object_set_data_full (G_OBJECT (label), "input_variants", -+ g_variant_dup_string (w, NULL), g_free); -+ g_variant_unref (w); -+ } else { -+ variants = NULL; -+ g_object_set_data_full (G_OBJECT (label), "input_variants", NULL, g_free); -+ } -+ -+ if (variants && variants[0]) -+ n = MIN (g_strv_length (layouts), g_strv_length (variants)); -+ else -+ n = g_strv_length (layouts); -+ -+ xkb_info = gnome_xkb_info_new (); -+ disp = g_string_new (""); -+ for (i = 0; i < n && layouts[i][0]; i++) { -+ const char *name; -+ char *id; -+ -+ if (variants && variants[i] && variants[i][0]) -+ id = g_strdup_printf ("%s+%s", layouts[i], variants[i]); -+ else -+ id = g_strdup (layouts[i]); -+ -+ gnome_xkb_info_get_layout_info (xkb_info, id, &name, NULL, NULL, NULL); -+ if (disp->str[0] != '\0') -+ disp = g_string_append (disp, ", "); -+ disp = g_string_append (disp, name ? name : id); -+ -+ g_free (id); -+ } - gtk_label_set_text (GTK_LABEL (label), disp->str); - g_string_free (disp, TRUE); - -- g_variant_unref (v); -+ g_strfreev (variants); -+ g_strfreev (layouts); -+ g_object_unref (xkb_info); - - update_copy_button (dialog); - } -@@ -386,6 +426,11 @@ copy_settings (GtkButton *button, GtkBui - layout = g_object_get_data (G_OBJECT (label), "input_source"); - variants = g_object_get_data (G_OBJECT (label), "input_variants"); - -+ if (layout == NULL || layout[0] == '\0') { -+ g_debug ("Not calling SetX11Keyboard, as there are no XKB input sources in the user's settings"); -+ return; -+ } -+ - g_dbus_proxy_call (localed_proxy, - "SetX11Keyboard", - g_variant_new ("(ssssbb)", layout, "", variants ? variants : "", "", TRUE, TRUE), -@@ -468,10 +513,10 @@ setup_system (GtkBuilder *dialog) - G_CALLBACK (locale_settings_changed), dialog); - g_object_weak_ref (G_OBJECT (dialog), (GWeakNotify) g_object_unref, locale_settings); - -- xkb_settings = g_settings_new (GKBD_KEYBOARD_SCHEMA); -- g_signal_connect (xkb_settings, "changed::layouts", -- G_CALLBACK (xkb_settings_changed), dialog); -- g_object_weak_ref (G_OBJECT (dialog), (GWeakNotify) g_object_unref, xkb_settings); -+ input_sources_settings = g_settings_new ("org.cinnamon.desktop.input-sources"); -+ g_signal_connect (input_sources_settings, "changed::sources", -+ G_CALLBACK (input_sources_changed), dialog); -+ g_object_weak_ref (G_OBJECT (dialog), (GWeakNotify) g_object_unref, input_sources_settings); - - /* Display user settings */ - language = cc_common_language_get_current_language (); -@@ -480,7 +525,7 @@ setup_system (GtkBuilder *dialog) - - locale_settings_changed (locale_settings, "region", dialog); - -- xkb_settings_changed (xkb_settings, "layouts", dialog); -+ input_sources_changed (input_sources_settings, "sources", dialog); - - bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); - g_dbus_proxy_new (bus, -diff -uNrp a/panels/region/cinnamon-region-panel-system.h b/panels/region/cinnamon-region-panel-system.h ---- a/panels/region/cinnamon-region-panel-system.h 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-system.h 2013-09-21 13:24:15.342949428 +0100 -@@ -19,8 +19,8 @@ - * 02110-1335, USA. - */ - --#ifndef __GNOME_REGION_PANEL_SYSTEM_H --#define __GNOME_REGION_PANEL_SYSTEM_H -+#ifndef __CINNAMON_REGION_PANEL_SYSTEM_H -+#define __CINNAMON_REGION_PANEL_SYSTEM_H - - #include <gtk/gtk.h> - -diff -uNrp a/panels/region/cinnamon-region-panel.ui b/panels/region/cinnamon-region-panel.ui ---- a/panels/region/cinnamon-region-panel.ui 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel.ui 2013-09-21 13:24:15.347949247 +0100 -@@ -162,27 +162,17 @@ - <style> - <class name="inline-toolbar"/> - </style> -+ <style> -+ <class name="inline-toolbar"/> -+ </style> - <child> - <object class="GtkToolButton" id="language_add"> -+ <property name="use_action_appearance">False</property> - <property name="visible">True</property> -- <property name="can_focus">False</property> - <property name="label" translatable="yes">Add Language</property> -- <property name="use_underline">True</property> -- <property name="icon_name">list-add-symbolic</property> -- </object> -- <packing> -- <property name="expand">False</property> -- <property name="homogeneous">True</property> -- </packing> -- </child> -- <child> -- <object class="GtkToolButton" id="language_remove"> -- <property name="visible">True</property> -- <property name="sensitive">False</property> - <property name="can_focus">False</property> -- <property name="label" translatable="yes">Remove Language</property> - <property name="use_underline">True</property> -- <property name="icon_name">list-remove-symbolic</property> -+ <property name="icon_name">list-add-symbolic</property> - </object> - <packing> - <property name="expand">False</property> -@@ -198,12 +188,13 @@ - </child> - <child> - <object class="GtkVBox" id="vbox3"> -- <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkLabel" id="label23"> - <property name="visible">True</property> - <property name="can_focus">False</property> -+ <property name="use_underline">True</property> -+ <property name="label" translatable="yes">Add Language</property> - </object> - <packing> - <property name="expand">True</property> -@@ -212,23 +203,24 @@ - </packing> - </child> - <child> -- <object class="GtkButton" id="get_languages_button"> -- <property name="label" translatable="yes">button</property> -+ <object class="GtkLinkButton" id="linkbutton1"> -+ <property name="label" translatable="yes">Install languages...</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> -+ <property name="has_tooltip">True</property> - </object> - <packing> -- <property name="expand">True</property> -+ <property name="expand">False</property> - <property name="fill">True</property> -- <property name="position">13</property> -+ <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> -- <property name="position">2</property> -+ <property name="position">1</property> - </packing> - </child> - </object> -@@ -305,19 +297,19 @@ - </child> - <child> - <object class="GtkToolbar" id="region-toolbar"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> - <property name="toolbar_style">icons</property> - <property name="show_arrow">False</property> - <property name="icon_size">1</property> -+ <property name="visible">True</property> - <style> - <class name="inline-toolbar"/> - </style> - <child> - <object class="GtkToolButton" id="region_add"> -+ <property name="use_action_appearance">False</property> -+ <property name="label" translatable="yes">Add Region</property> - <property name="visible">True</property> - <property name="can_focus">False</property> -- <property name="label" translatable="yes">Add Region</property> - <property name="use_underline">True</property> - <property name="icon_name">list-add-symbolic</property> - </object> -@@ -328,10 +320,11 @@ - </child> - <child> - <object class="GtkToolButton" id="region_remove"> -+ <property name="use_action_appearance">False</property> - <property name="visible">True</property> -+ <property name="label" translatable="yes">Remove Region</property> - <property name="sensitive">False</property> - <property name="can_focus">False</property> -- <property name="label" translatable="yes">Remove Region</property> - <property name="use_underline">True</property> - <property name="icon_name">list-remove-symbolic</property> - </object> -@@ -373,18 +366,6 @@ - <property name="n_rows">9</property> - <property name="n_columns">2</property> - <child> -- <placeholder/> -- </child> -- <child> -- <placeholder/> -- </child> -- <child> -- <placeholder/> -- </child> -- <child> -- <placeholder/> -- </child> -- <child> - <object class="GtkLabel" id="label7"> - <property name="visible">True</property> - <property name="can_focus">False</property> -@@ -626,6 +607,12 @@ - <property name="height">1</property> - </packing> - </child> -+ <child> -+ <placeholder/> -+ </child> -+ <child> -+ <placeholder/> -+ </child> - </object> - <packing> - <property name="position">1</property> -@@ -643,36 +630,43 @@ - </packing> - </child> - <child> -- <object class="GtkVBox" id="vbox1"> -+ <object class="GtkVBox" id="vbox5"> - <property name="visible">True</property> - <property name="can_focus">False</property> -- <property name="border_width">10</property> -+ <property name="border_width">12</property> - <property name="spacing">12</property> - <child> -- <placeholder/> -+ <object class="GtkLabel" id="label24"> -+ <property name="visible">True</property> -+ <property name="can_focus">False</property> -+ <property name="xalign">0</property> -+ <property name="label" translatable="yes">Select keyboards or other input sources</property> -+ </object> -+ <packing> -+ <property name="expand">False</property> -+ <property name="fill">False</property> -+ <property name="position">0</property> -+ </packing> - </child> - <child> -- <object class="GtkHBox" id="hbox2"> -+ <object class="GtkHBox" id="hbox3"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">12</property> - <child> -- <object class="GtkVBox" id="vbox7"> -+ <object class="GtkVBox" id="vbox6"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> -- <object class="GtkScrolledWindow" id="xkb_layouts_swindow"> -+ <object class="GtkScrolledWindow" id="input_sources_swindow"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="shadow_type">in</property> - <child> -- <object class="GtkTreeView" id="xkb_layouts_selected"> -+ <object class="GtkTreeView" id="active_input_sources"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">False</property> -- <child internal-child="selection"> -- <object class="GtkTreeSelection" id="treeview-selection1"/> -- </child> - </object> - </child> - </object> -@@ -683,7 +677,7 @@ - </packing> - </child> - <child> -- <object class="GtkToolbar" id="layouts-toolbar"> -+ <object class="GtkToolbar" id="input-toolbar"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="toolbar_style">icons</property> -@@ -693,70 +687,166 @@ - <class name="inline-toolbar"/> - </style> - <child> -- <object class="GtkToolButton" id="xkb_layouts_add"> -+ <object class="GtkToolItem" id="i_s_ar_item"> - <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="label" translatable="yes">Add Layout</property> -- <property name="use_underline">True</property> -- <property name="icon_name">list-add-symbolic</property> -+ <child> -+ <object class="GtkBox" id="i_s_ar_box"> -+ <property name="visible">True</property> -+ <child> -+ <object class="GtkButton" id="input_source_add"> -+ <property name="visible">True</property> -+ <child internal-child="accessible"> -+ <object class="AtkObject" id="i_s_a_a11y"> -+ <property name="accessible-name" translatable="yes">Add Input Source</property> -+ </object> -+ </child> -+ <child> -+ <object class="GtkImage" id="i_s_a_image"> -+ -+ <property name="visible">True</property> -+ <property name="icon-name">list-add-symbolic</property> -+ <property name="icon-size">1</property> -+ </object> -+ </child> -+ </object> -+ </child> -+ <child> -+ <object class="GtkButton" id="input_source_remove"> -+ <property name="visible">True</property> -+ <child internal-child="accessible"> -+ <object class="AtkObject" id="i_s_r_a11y"> -+ <property name="accessible-name" translatable="yes">Remove Input Source</property> -+ </object> -+ </child> -+ <child> -+ <object class="GtkImage" id="i_s_r_image"> -+ <property name="visible">True</property> -+ <property name="icon-name">list-remove-symbolic</property> -+ <property name="icon-size">1</property> -+ </object> -+ </child> -+ </object> -+ </child> -+ </object> -+ </child> - </object> -- <packing> -- <property name="expand">False</property> -- <property name="homogeneous">True</property> -- </packing> - </child> -+ - <child> -- <object class="GtkToolButton" id="xkb_layouts_remove"> -+ <object class="GtkSeparatorToolItem" id="sep1"> - <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="label" translatable="yes">Remove Layout</property> -- <property name="use_underline">True</property> -- <property name="icon_name">list-remove-symbolic</property> -+ <property name="draw">False</property> - </object> - <packing> -- <property name="expand">False</property> -- <property name="homogeneous">True</property> -+ <property name="expand">True</property> - </packing> - </child> -+ - <child> -- <object class="GtkToolButton" id="xkb_layouts_move_up"> -+ <object class="GtkToolItem" id="i_s_ud_item"> - <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="label" translatable="yes">Move Up</property> -- <property name="use_underline">True</property> -- <property name="icon_name">go-up-symbolic</property> -+ <child> -+ <object class="GtkBox" id="i_s_ud_box"> -+ <property name="visible">True</property> -+ <child> -+ <object class="GtkButton" id="input_source_move_up"> -+ <property name="visible">True</property> -+ <child internal-child="accessible"> -+ <object class="AtkObject" id="i_s_u_a11y"> -+ <property name="accessible-name" translatable="yes">Move Input Source Up</property> -+ </object> -+ </child> -+ <child> -+ <object class="GtkImage" id="i_s_u_image"> -+ -+ <property name="visible">True</property> -+ <property name="icon-name">go-up-symbolic</property> -+ <property name="icon-size">1</property> -+ </object> -+ </child> -+ </object> -+ </child> -+ <child> -+ <object class="GtkButton" id="input_source_move_down"> -+ <property name="visible">True</property> -+ <child internal-child="accessible"> -+ <object class="AtkObject" id="i_s_d_a11y"> -+ <property name="accessible-name" translatable="yes">Move Input Source Down</property> -+ </object> -+ </child> -+ <child> -+ <object class="GtkImage" id="i_s_d_image"> -+ <property name="visible">True</property> -+ <property name="icon-name">go-down-symbolic</property> -+ <property name="icon-size">1</property> -+ </object> -+ </child> -+ </object> -+ </child> -+ </object> -+ </child> - </object> -- <packing> -- <property name="expand">False</property> -- <property name="homogeneous">True</property> -- </packing> - </child> -+ - <child> -- <object class="GtkToolButton" id="xkb_layouts_move_down"> -+ <object class="GtkSeparatorToolItem" id="sep2"> - <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="label" translatable="yes">Move Down</property> -- <property name="use_underline">True</property> -- <property name="icon_name">go-down-symbolic</property> -+ <property name="draw">False</property> -+ <property name="hexpand">True</property> - </object> - <packing> -- <property name="expand">False</property> -- <property name="homogeneous">True</property> -+ <property name="expand">True</property> - </packing> - </child> -+ - <child> -- <object class="GtkToolButton" id="xkb_layouts_show"> -+ <object class="GtkToolItem" id="i_s_sp_item"> - <property name="visible">True</property> -- <property name="can_focus">False</property> -- <property name="label" translatable="yes">Preview Layout</property> -- <property name="use_underline">True</property> -- <property name="icon_name">input-keyboard-symbolic</property> -+ <child> -+ <object class="GtkBox" id="i_s_sp_box"> -+ <property name="visible">True</property> -+ <child> -+ <object class="GtkButton" id="input_source_settings"> -+ <property name="visible">True</property> -+ <child internal-child="accessible"> -+ <object class="AtkObject" id="i_s_s_a11y"> -+ <property name="accessible-name" translatable="yes">Input Source Settings</property> -+ </object> -+ </child> -+ <child> -+ <object class="GtkImage" id="i_s_s_image"> -+ -+ <property name="visible">True</property> -+ <property name="icon_name">preferences-system-symbolic</property> -+ <property name="icon_size">1</property> -+ <property name="pixel_size">16</property> -+ </object> -+ </child> -+ </object> -+ </child> -+ <child> -+ <object class="GtkButton" id="input_source_show"> -+ <property name="visible">True</property> -+ <child internal-child="accessible"> -+ <object class="AtkObject" id="i_s_p_a11y"> -+ <property name="accessible-name" translatable="yes">Show Keyboard Layout</property> -+ </object> -+ </child> -+ <child> -+ <object class="GtkImage" id="i_s_p_image"> -+ -+ <property name="visible">True</property> -+ <property name="icon_name">input-keyboard-symbolic</property> -+ <property name="icon-size">1</property> -+ </object> -+ </child> -+ </object> -+ </child> -+ </object> -+ </child> - </object> -- <packing> -- <property name="expand">False</property> -- <property name="homogeneous">True</property> -- </packing> - </child> -+ - </object> - <packing> - <property name="expand">False</property> -@@ -772,168 +862,111 @@ - </packing> - </child> - <child> -- <object class="GtkVBox" id="vbox33"> -+ <object class="GtkFrame" id="frame4"> - <property name="visible">True</property> - <property name="can_focus">False</property> -- <property name="spacing">12</property> -+ <property name="label_xalign">0</property> -+ <property name="shadow_type">none</property> - <child> -- <object class="GtkVBox" id="vbox34"> -+ <object class="GtkAlignment" id="alignment3"> - <property name="visible">True</property> - <property name="can_focus">False</property> -- <property name="spacing">6</property> -+ <property name="left_padding">12</property> - <child> -- <object class="GtkRadioButton" id="chk_same_group"> -- <property name="label" translatable="yes">Use the same layout for all windows</property> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="receives_default">False</property> -- <property name="xalign">0</property> -- <property name="active">True</property> -- <property name="draw_indicator">True</property> -- </object> -- <packing> -- <property name="expand">True</property> -- <property name="fill">True</property> -- <property name="position">0</property> -- </packing> -- </child> -- <child> -- <object class="GtkRadioButton" id="chk_separate_group_per_window"> -- <property name="label" translatable="yes">Allow different layouts for individual windows</property> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="receives_default">False</property> -- <property name="xalign">0</property> -- <property name="active">True</property> -- <property name="draw_indicator">True</property> -- <property name="group">chk_same_group</property> -- </object> -- <packing> -- <property name="expand">True</property> -- <property name="fill">True</property> -- <property name="position">1</property> -- </packing> -- </child> -- <child> -- <object class="GtkAlignment" id="alignment1"> -+ <object class="GtkGrid" id="shortcuts-grid"> - <property name="visible">True</property> - <property name="can_focus">False</property> -- <property name="left_padding">12</property> -+ <property name="margin_top">6</property> -+ <property name="row_spacing">6</property> -+ <property name="column_spacing">6</property> - <child> -- <object class="GtkVBox" id="vbox4"> -+ <object class="GtkLabel" id="prev-source-label"> - <property name="visible">True</property> - <property name="can_focus">False</property> -- <child> -- <object class="GtkRadioButton" id="chk_new_windows_default_layout"> -- <property name="label" translatable="yes">New windows use the default layout</property> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="receives_default">False</property> -- <property name="xalign">0</property> -- <property name="active">True</property> -- <property name="draw_indicator">True</property> -- </object> -- <packing> -- <property name="expand">True</property> -- <property name="fill">True</property> -- <property name="position">0</property> -- </packing> -- </child> -- <child> -- <object class="GtkRadioButton" id="chk_new_windows_inherit_layout"> -- <property name="label" translatable="yes">New windows use the previous window's layout</property> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="receives_default">False</property> -- <property name="xalign">0</property> -- <property name="active">True</property> -- <property name="draw_indicator">True</property> -- <property name="group">chk_new_windows_default_layout</property> -- </object> -- <packing> -- <property name="expand">True</property> -- <property name="fill">True</property> -- <property name="position">1</property> -- </packing> -- </child> -+ <property name="xalign">0</property> -+ <property name="label" translatable="yes">Switch to previous source</property> - </object> -+ <packing> -+ <property name="left_attach">0</property> -+ <property name="top_attach">0</property> -+ <property name="width">1</property> -+ <property name="height">1</property> -+ </packing> -+ </child> -+ <child> -+ <object class="GtkLabel" id="prev-source-shortcut-label"> -+ <property name="visible">True</property> -+ <property name="can_focus">False</property> -+ <property name="halign">end</property> -+ <property name="hexpand">True</property> -+ <property name="label" translatable="yes">Ctrl+Alt+Space</property> -+ <style><class name="dim-label"/></style> -+ </object> -+ <packing> -+ <property name="left_attach">1</property> -+ <property name="top_attach">0</property> -+ <property name="width">1</property> -+ <property name="height">1</property> -+ </packing> -+ </child> -+ <child> -+ <object class="GtkLabel" id="next-source-label"> -+ <property name="visible">True</property> -+ <property name="can_focus">False</property> -+ <property name="xalign">0</property> -+ <property name="label" translatable="yes">Switch to next source</property> -+ </object> -+ <packing> -+ <property name="left_attach">0</property> -+ <property name="top_attach">1</property> -+ <property name="width">1</property> -+ <property name="height">1</property> -+ </packing> -+ </child> -+ <child> -+ <object class="GtkLabel" id="next-source-shortcut-label"> -+ <property name="visible">True</property> -+ <property name="can_focus">False</property> -+ <property name="halign">end</property> -+ <property name="hexpand">True</property> -+ <property name="label" translatable="yes">Ctrl+Alt+Shift+Space</property> -+ <style><class name="dim-label"/></style> -+ </object> -+ <packing> -+ <property name="left_attach">1</property> -+ <property name="top_attach">1</property> -+ <property name="width">1</property> -+ <property name="height">1</property> -+ </packing> -+ </child> -+ <child> -+ <object class="GtkLinkButton" id="jump-to-shortcuts"> -+ <property name="visible">True</property> -+ <property name="can_focus">True</property> -+ <property name="label" translatable="yes">Shortcut Settings</property> -+ <property name="halign">end</property> -+ </object> -+ <packing> -+ <property name="left_attach">1</property> -+ <property name="top_attach">2</property> -+ <property name="width">1</property> -+ <property name="height">1</property> -+ </packing> - </child> - </object> -- <packing> -- <property name="expand">True</property> -- <property name="fill">True</property> -- <property name="position">2</property> -- </packing> - </child> - </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">False</property> -- <property name="position">0</property> -- </packing> -- </child> -- <child> -- <object class="GtkLabel" id="label2"> -- <property name="visible">True</property> -- <property name="can_focus">False</property> -- </object> -- <packing> -- <property name="expand">True</property> -- <property name="fill">False</property> -- <property name="position">1</property> -- </packing> - </child> -- <child> -- <object class="GtkHButtonBox" id="hbuttonbox2"> -+ <child type="label"> -+ <object class="GtkLabel" id="shortcuts-frame-label"> - <property name="visible">True</property> - <property name="can_focus">False</property> -- <property name="spacing">6</property> -- <property name="layout_style">end</property> -- <child> -- <object class="GtkButton" id="xkb_layout_options"> -- <property name="label" translatable="yes">_Options...</property> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="receives_default">True</property> -- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> -- <property name="has_tooltip">True</property> -- <property name="tooltip_markup" translatable="yes">View and edit keyboard layout options</property> -- <property name="tooltip_text" translatable="yes">View and edit keyboard layout options</property> -- <property name="use_underline">True</property> -- </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">False</property> -- <property name="position">0</property> -- </packing> -- </child> -- <child> -- <object class="GtkButton" id="xkb_reset_to_defaults"> -- <property name="label" translatable="yes">Reset to De_faults</property> -- <property name="visible">True</property> -- <property name="can_focus">True</property> -- <property name="receives_default">True</property> -- <property name="has_tooltip">True</property> -- <property name="tooltip_markup" translatable="yes">Replace the current keyboard layout settings with the --default settings</property> -- <property name="tooltip_text" translatable="yes">Replace the current keyboard layout settings with the --default settings</property> -- <property name="use_underline">True</property> -- </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">False</property> -- <property name="pack_type">end</property> -- <property name="position">1</property> -- <property name="secondary">True</property> -- </packing> -- </child> -+ <property name="label" translatable="yes">Shortcuts</property> -+ <property name="use_markup">True</property> -+ <attributes> -+ <attribute name="weight" value="bold"/> -+ </attributes> - </object> -- <packing> -- <property name="expand">False</property> -- <property name="fill">False</property> -- <property name="position">2</property> -- </packing> - </child> - </object> - <packing> -@@ -951,17 +984,17 @@ default settings</property> - </child> - </object> - <packing> -- <property name="position">2</property> -+ <property name="position">3</property> - </packing> - </child> - <child type="tab"> -- <object class="GtkLabel" id="label46"> -+ <object class="GtkLabel" id="label13"> - <property name="visible">True</property> - <property name="can_focus">False</property> -- <property name="label" translatable="yes">Keyboard Layouts</property> -+ <property name="label" translatable="yes">Input Sources</property> - </object> - <packing> -- <property name="position">2</property> -+ <property name="position">3</property> - <property name="tab_fill">False</property> - </packing> - </child> -@@ -974,9 +1007,6 @@ default settings</property> - <property name="column_spacing">12</property> - <property name="row_spacing">12</property> - <child> -- <placeholder/> -- </child> -- <child> - <object class="GtkLabel" id="system-title"> - <property name="visible">True</property> - <property name="can_focus">False</property> -@@ -1051,6 +1081,7 @@ default settings</property> - <property name="bottom_attach">2</property> - <property name="x_padding">3</property> - <property name="y_padding">3</property> -+ <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> -@@ -1060,6 +1091,7 @@ default settings</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="wrap">True</property> -+ <property name="width-chars">18</property> - </object> - <packing> - <property name="left_attach">1</property> -@@ -1068,6 +1100,7 @@ default settings</property> - <property name="bottom_attach">2</property> - <property name="x_padding">3</property> - <property name="y_padding">3</property> -+ <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> -@@ -1178,6 +1211,7 @@ default settings</property> - <property name="bottom_attach">2</property> - <property name="x_padding">3</property> - <property name="y_padding">3</property> -+ <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> -@@ -1187,6 +1221,7 @@ default settings</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="wrap">True</property> -+ <property name="width-chars">18</property> - </object> - <packing> - <property name="left_attach">1</property> -@@ -1195,6 +1230,7 @@ default settings</property> - <property name="bottom_attach">2</property> - <property name="x_padding">3</property> - <property name="y_padding">3</property> -+ <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> -@@ -1254,6 +1290,7 @@ default settings</property> - <child> - <object class="GtkButton" id="copy_settings_button"> - <property name="label" translatable="yes">Copy Settings...</property> -+ <property name="use_action_appearance">False</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> -@@ -1269,9 +1306,12 @@ default settings</property> - <property name="y_padding">3</property> - </packing> - </child> -+ <child> -+ <placeholder/> -+ </child> - </object> - <packing> -- <property name="position">3</property> -+ <property name="position">4</property> - </packing> - </child> - <child type="tab"> -@@ -1281,7 +1321,7 @@ default settings</property> - <property name="label" translatable="yes">System</property> - </object> - <packing> -- <property name="position">3</property> -+ <property name="position">4</property> - <property name="tab_fill">False</property> - </packing> - </child> -@@ -1302,4 +1342,11 @@ default settings</property> - </object> - </child> - </object> -+ <object class="GtkSizeGroup" id="system-input-source-sizegroup"> -+ <property name="mode">vertical</property> -+ <widgets> -+ <widget name="user_input_source"/> -+ <widget name="system_input_source"/> -+ </widgets> -+ </object> - </interface> -diff -uNrp a/panels/region/cinnamon-region-panel-xkb.c b/panels/region/cinnamon-region-panel-xkb.c ---- a/panels/region/cinnamon-region-panel-xkb.c 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-xkb.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,190 +0,0 @@ --/* cinnamon-region-panel-xkb.c -- * Copyright (C) 2003-2007 Sergey V. Udaltsov -- * -- * Written by: Sergey V. Udaltsov <svu@gnome.org> -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -- * 02110-1335, USA. -- */ -- --#ifdef HAVE_CONFIG_H --# include <config.h> --#endif -- --#include <string.h> --#include <gdk/gdkx.h> --#include <glib/gi18n-lib.h> -- --#include "cinnamon-region-panel-xkb.h" -- --#include <libgnomekbd/gkbd-desktop-config.h> -- --XklEngine *engine; --XklConfigRegistry *config_registry; -- --GkbdKeyboardConfig initial_config; --GkbdDesktopConfig desktop_config; -- --GSettings *xkb_keyboard_settings; --GSettings *xkb_desktop_settings; -- --char * --xci_desc_to_utf8 (const XklConfigItem * ci) --{ -- gchar *dd = g_strdup (ci->description); -- gchar *sd = g_strstrip (dd); -- gchar *rv = g_strdup (sd[0] == 0 ? ci->name : sd); -- g_free (dd); -- return rv; --} -- --static void --cleanup_xkb_tabs (GtkBuilder * dialog, -- GObject *where_the_object_wa) --{ -- gkbd_desktop_config_term (&desktop_config); -- gkbd_keyboard_config_term (&initial_config); -- g_object_unref (G_OBJECT (config_registry)); -- config_registry = NULL; -- /* Don't unref it here, or we'll crash if open the panel again */ -- engine = NULL; -- g_object_unref (G_OBJECT (xkb_keyboard_settings)); -- g_object_unref (G_OBJECT (xkb_desktop_settings)); -- xkb_keyboard_settings = NULL; -- xkb_desktop_settings = NULL; --} -- --static void --reset_to_defaults (GtkWidget * button, GtkBuilder * dialog) --{ -- GkbdKeyboardConfig empty_kbd_config; -- -- gkbd_keyboard_config_init (&empty_kbd_config, engine); -- gkbd_keyboard_config_save (&empty_kbd_config); -- gkbd_keyboard_config_term (&empty_kbd_config); -- -- g_settings_reset (xkb_desktop_settings, -- GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP); -- -- /* all the rest is g-s-d's business */ --} -- --static void --chk_new_windows_inherit_layout_toggled (GtkWidget * -- chk_new_windows_inherit_layout, -- GtkBuilder * dialog) --{ -- xkb_save_default_group (gtk_toggle_button_get_active -- (GTK_TOGGLE_BUTTON -- (chk_new_windows_inherit_layout)) ? -1 : -- 0); --} -- --void --setup_xkb_tabs (GtkBuilder * dialog) --{ -- GtkWidget *widget; -- GtkStyleContext *context; -- GtkWidget *chk_new_windows_inherit_layout; -- -- chk_new_windows_inherit_layout = WID ("chk_new_windows_inherit_layout"); -- -- xkb_desktop_settings = g_settings_new (GKBD_DESKTOP_SCHEMA); -- xkb_keyboard_settings = g_settings_new (GKBD_KEYBOARD_SCHEMA); -- -- engine = -- xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY -- (gdk_display_get_default ())); -- config_registry = xkl_config_registry_get_instance (engine); -- -- gkbd_desktop_config_init (&desktop_config, engine); -- gkbd_desktop_config_load (&desktop_config); -- -- xkl_config_registry_load (config_registry, -- desktop_config.load_extra_items); -- -- gkbd_keyboard_config_init (&initial_config, engine); -- gkbd_keyboard_config_load_from_x_initial (&initial_config, NULL); -- -- /* Set initial state */ -- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("chk_separate_group_per_window")), -- g_settings_get_boolean (xkb_desktop_settings, -- GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW)); -- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chk_new_windows_inherit_layout), -- xkb_get_default_group () < 0); -- -- g_settings_bind (xkb_desktop_settings, -- GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW, -- WID ("chk_separate_group_per_window"), "active", -- G_SETTINGS_BIND_DEFAULT); -- g_settings_bind (xkb_desktop_settings, -- GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW, -- WID ("chk_new_windows_inherit_layout"), "sensitive", -- G_SETTINGS_BIND_DEFAULT); -- g_settings_bind (xkb_desktop_settings, -- GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW, -- WID ("chk_new_windows_default_layout"), "sensitive", -- G_SETTINGS_BIND_DEFAULT); -- -- xkb_layouts_prepare_selected_tree (dialog); -- xkb_layouts_fill_selected_tree (dialog); -- -- xkb_layouts_register_buttons_handlers (dialog); -- g_signal_connect (G_OBJECT (WID ("xkb_reset_to_defaults")), -- "clicked", G_CALLBACK (reset_to_defaults), -- dialog); -- -- g_signal_connect (G_OBJECT (chk_new_windows_inherit_layout), -- "toggled", -- G_CALLBACK -- (chk_new_windows_inherit_layout_toggled), -- dialog); -- -- g_signal_connect_swapped (G_OBJECT (WID ("xkb_layout_options")), -- "clicked", -- G_CALLBACK (xkb_options_popup_dialog), -- dialog); -- -- xkb_layouts_register_conf_listener (dialog); -- xkb_options_register_conf_listener (dialog); -- -- g_object_weak_ref (G_OBJECT (WID ("region_notebook")), -- (GWeakNotify) cleanup_xkb_tabs, dialog); -- -- enable_disable_restoring (dialog); -- -- /* Setup junction between toolbar and treeview */ -- widget = WID ("xkb_layouts_swindow"); -- context = gtk_widget_get_style_context (widget); -- gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM); -- widget = WID ("layouts-toolbar"); -- context = gtk_widget_get_style_context (widget); -- gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP); --} -- --void --enable_disable_restoring (GtkBuilder * dialog) --{ -- GkbdKeyboardConfig gswic; -- gboolean enable; -- -- gkbd_keyboard_config_init (&gswic, engine); -- gkbd_keyboard_config_load (&gswic, NULL); -- -- enable = !gkbd_keyboard_config_equals (&gswic, &initial_config); -- -- gkbd_keyboard_config_term (&gswic); -- gtk_widget_set_sensitive (WID ("xkb_reset_to_defaults"), enable); --} -diff -uNrp a/panels/region/cinnamon-region-panel-xkb.h b/panels/region/cinnamon-region-panel-xkb.h ---- a/panels/region/cinnamon-region-panel-xkb.h 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-xkb.h 1970-01-01 01:00:00.000000000 +0100 -@@ -1,96 +0,0 @@ --/* cinnamon-region-panel-xkb.h -- * Copyright (C) 2003-2007 Sergey V Udaltsov -- * -- * Written by Sergey V. Udaltsov <svu@gnome.org> -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -- * 02110-1335, USA. -- */ -- --#ifndef __GNOME_KEYBOARD_PROPERTY_XKB_H --#define __GNOME_KEYBOARD_PROPERTY_XKB_H -- --#include <gtk/gtk.h> -- --#include "libgnomekbd/gkbd-keyboard-config.h" --#include "libgnomekbd/gkbd-util.h" -- --G_BEGIN_DECLS --#define CWID(s) GTK_WIDGET (gtk_builder_get_object (chooser_dialog, s)) --#define WID(s) GTK_WIDGET (gtk_builder_get_object (dialog, s)) --extern XklEngine *engine; --extern XklConfigRegistry *config_registry; --extern GSettings *xkb_keyboard_settings; --extern GSettings *xkb_desktop_settings; --extern GkbdKeyboardConfig initial_config; -- --extern void setup_xkb_tabs (GtkBuilder * dialog); -- --extern void xkb_layouts_fill_selected_tree (GtkBuilder * dialog); -- --extern void xkb_layouts_register_buttons_handlers (GtkBuilder * dialog); -- --extern void xkb_layouts_register_conf_listener (GtkBuilder * dialog); -- --extern void xkb_options_register_conf_listener (GtkBuilder * dialog); -- --extern void xkb_layouts_prepare_selected_tree (GtkBuilder * dialog); -- --extern void xkb_options_load_options (GtkBuilder * dialog); -- --extern void xkb_options_popup_dialog (GtkBuilder * dialog); -- --extern char *xci_desc_to_utf8 (const XklConfigItem * ci); -- --extern gchar *xkb_layout_description_utf8 (const gchar * visible); -- --extern void enable_disable_restoring (GtkBuilder * dialog); -- --extern void preview_toggled (GtkBuilder * dialog, GtkWidget * button); -- --extern GtkWidget *xkb_layout_choose (GtkBuilder * dialog); -- --extern void xkb_layout_chooser_response (GtkDialog *dialog, gint response_id); -- --extern gchar **xkb_layouts_get_selected_list (void); -- --extern gchar **xkb_options_get_selected_list (void); -- --#define xkb_layouts_set_selected_list(list) \ -- g_settings_set_strv (xkb_keyboard_settings, \ -- GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, \ -- (const gchar *const*)(list)) -- --#define xkb_options_set_selected_list(list) \ -- g_settings_set_strv (xkb_keyboard_settings, \ -- GKBD_KEYBOARD_CONFIG_KEY_OPTIONS, \ -- (const gchar *const*)(list)) -- --extern GtkWidget *xkb_layout_preview_create_widget (GtkBuilder * -- chooser_dialog); -- --extern void xkb_layout_preview_update (GtkBuilder * chooser_dialog); -- --extern void xkb_layout_preview_set_drawing_layout (GtkWidget * kbdraw, -- const gchar * id); -- --extern gchar *xkb_layout_chooser_get_selected_id (GtkDialog *dialog); -- --extern void xkb_save_default_group (gint group_no); -- --extern gint xkb_get_default_group (void); -- --G_END_DECLS --#endif /* __GNOME_KEYBOARD_PROPERTY_XKB_H */ -diff -uNrp a/panels/region/cinnamon-region-panel-xkbltadd.c b/panels/region/cinnamon-region-panel-xkbltadd.c ---- a/panels/region/cinnamon-region-panel-xkbltadd.c 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-xkbltadd.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,495 +0,0 @@ --/* cinnamon-region-panel-xkbltadd.c -- * Copyright (C) 2007 Sergey V. Udaltsov -- * -- * Written by: Sergey V. Udaltsov <svu@gnome.org> -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -- * 02110-1335, USA. -- */ -- --#ifdef HAVE_CONFIG_H --# include <config.h> --#endif -- --#include <string.h> -- --#include <libgnomekbd/gkbd-keyboard-drawing.h> --#include <libgnomekbd/gkbd-util.h> -- --#include "cinnamon-region-panel-xkb.h" -- --enum { -- COMBO_BOX_MODEL_COL_SORT, -- COMBO_BOX_MODEL_COL_VISIBLE, -- COMBO_BOX_MODEL_COL_XKB_ID, -- COMBO_BOX_MODEL_COL_COUNTRY_DESC, -- COMBO_BOX_MODEL_COL_LANGUAGE_DESC --}; -- --static gchar **search_pattern_list = NULL; -- --static GtkWidget *preview_dialog = NULL; -- --static GRegex *left_bracket_regex = NULL; -- --#define RESPONSE_PREVIEW 1 -- --static void --xkb_preview_destroy_callback (GtkWidget * widget) --{ -- preview_dialog = NULL; --} -- --static gboolean --xkb_layout_chooser_selection_dupe (GtkDialog * dialog) --{ -- gchar *selected_id = -- (gchar *) xkb_layout_chooser_get_selected_id (dialog); -- gchar **layouts_list, **pl; -- gboolean rv = FALSE; -- if (selected_id == NULL) -- return rv; -- layouts_list = pl = xkb_layouts_get_selected_list (); -- while (pl && *pl) { -- if (!g_ascii_strcasecmp (*pl++, selected_id)) { -- rv = TRUE; -- break; -- } -- } -- g_strfreev (layouts_list); -- return rv; --} -- --void --xkb_layout_chooser_response (GtkDialog * dialog, gint response) --{ -- switch (response) -- case GTK_RESPONSE_OK:{ -- /* Handled by the main code */ -- break; -- case RESPONSE_PREVIEW:{ -- gchar *selected_id = (gchar *) -- xkb_layout_chooser_get_selected_id -- (dialog); -- -- if (selected_id != NULL) { -- if (preview_dialog == NULL) { -- preview_dialog = -- gkbd_keyboard_drawing_dialog_new -- (); -- g_signal_connect (G_OBJECT -- (preview_dialog), -- "destroy", -- G_CALLBACK -- (xkb_preview_destroy_callback), -- NULL); -- /* Put into the separate group to avoid conflict -- with modal parent */ -- gtk_window_group_add_window -- (gtk_window_group_new -- (), -- GTK_WINDOW -- (preview_dialog)); -- }; -- gkbd_keyboard_drawing_dialog_set_layout -- (preview_dialog, -- config_registry, selected_id); -- -- gtk_widget_show_all -- (preview_dialog); -- } -- } -- -- return; -- } -- if (preview_dialog != NULL) { -- gtk_widget_destroy (preview_dialog); -- } -- if (search_pattern_list != NULL) { -- g_strfreev (search_pattern_list); -- search_pattern_list = NULL; -- } -- gtk_widget_destroy (GTK_WIDGET (dialog)); --} -- --static gchar * --xkl_create_description_from_list (const XklConfigItem * item, -- const XklConfigItem * subitem, -- const gchar * prop_name, -- const gchar * -- (*desc_getter) (const gchar * code)) --{ -- gchar *rv = NULL, *code = NULL; -- gchar **list = NULL; -- const gchar *desc; -- -- if (subitem != NULL) -- list = -- (gchar -- **) (g_object_get_data (G_OBJECT (subitem), -- prop_name)); -- if (list == NULL || *list == 0) -- list = -- (gchar -- **) (g_object_get_data (G_OBJECT (item), prop_name)); -- -- /* First try the parent id as such */ -- desc = desc_getter (item->name); -- if (desc != NULL) { -- rv = g_utf8_strup (desc, -1); -- } else { -- code = g_utf8_strup (item->name, -1); -- desc = desc_getter (code); -- if (desc != NULL) { -- rv = g_utf8_strup (desc, -1); -- } -- g_free (code); -- } -- -- if (list == NULL || *list == 0) -- return rv; -- -- while (*list != 0) { -- code = *list++; -- desc = desc_getter (code); -- if (desc != NULL) { -- gchar *udesc = g_utf8_strup (desc, -1); -- if (rv == NULL) { -- rv = udesc; -- } else { -- gchar *orv = rv; -- rv = g_strdup_printf ("%s %s", rv, udesc); -- g_free (orv); -- g_free (udesc); -- } -- } -- } -- return rv; --} -- --static void --xkl_layout_add_to_list (XklConfigRegistry * config, -- const XklConfigItem * item, -- const XklConfigItem * subitem, -- GtkBuilder * chooser_dialog) --{ -- GtkListStore *list_store = -- GTK_LIST_STORE (gtk_builder_get_object (chooser_dialog, -- "layout_list_model")); -- GtkTreeIter iter; -- -- gchar *utf_variant_name = -- subitem ? -- xkb_layout_description_utf8 (gkbd_keyboard_config_merge_items -- (item->name, -- subitem->name)) : -- xci_desc_to_utf8 (item); -- -- const gchar *xkb_id = -- subitem ? gkbd_keyboard_config_merge_items (item->name, -- subitem->name) : -- item->name; -- -- gchar *country_desc = -- xkl_create_description_from_list (item, subitem, -- XCI_PROP_COUNTRY_LIST, -- xkl_get_country_name); -- gchar *language_desc = -- xkl_create_description_from_list (item, subitem, -- XCI_PROP_LANGUAGE_LIST, -- xkl_get_language_name); -- -- gchar *tmp = utf_variant_name; -- utf_variant_name = -- g_regex_replace_literal (left_bracket_regex, tmp, -1, 0, -- "<", 0, NULL); -- g_free (tmp); -- -- if (subitem -- && g_object_get_data (G_OBJECT (subitem), -- XCI_PROP_EXTRA_ITEM)) { -- gchar *buf = -- g_strdup_printf ("<i>%s</i>", utf_variant_name); -- gtk_list_store_insert_with_values (list_store, &iter, -1, -- COMBO_BOX_MODEL_COL_SORT, -- utf_variant_name, -- COMBO_BOX_MODEL_COL_VISIBLE, -- buf, -- COMBO_BOX_MODEL_COL_XKB_ID, -- xkb_id, -- COMBO_BOX_MODEL_COL_COUNTRY_DESC, -- country_desc, -- COMBO_BOX_MODEL_COL_LANGUAGE_DESC, -- language_desc, -1); -- g_free (buf); -- } else -- gtk_list_store_insert_with_values (list_store, &iter, -- -1, -- COMBO_BOX_MODEL_COL_SORT, -- utf_variant_name, -- COMBO_BOX_MODEL_COL_VISIBLE, -- utf_variant_name, -- COMBO_BOX_MODEL_COL_XKB_ID, -- xkb_id, -- COMBO_BOX_MODEL_COL_COUNTRY_DESC, -- country_desc, -- COMBO_BOX_MODEL_COL_LANGUAGE_DESC, -- language_desc, -1); -- g_free (utf_variant_name); -- g_free (country_desc); -- g_free (language_desc); --} -- --static void --xkb_layout_filter_clear (GtkEntry * entry, -- GtkEntryIconPosition icon_pos, -- GdkEvent * event, gpointer user_data) --{ -- gtk_entry_set_text (entry, ""); --} -- --static void --xkb_layout_filter_changed (GtkBuilder * chooser_dialog) --{ -- GtkTreeModelFilter *filtered_model = -- GTK_TREE_MODEL_FILTER (gtk_builder_get_object (chooser_dialog, -- "filtered_layout_list_model")); -- GtkWidget *xkb_layout_filter = CWID ("xkb_layout_filter"); -- const gchar *pattern = -- gtk_entry_get_text (GTK_ENTRY (xkb_layout_filter)); -- gchar *upattern = g_utf8_strup (pattern, -1); -- -- if (!g_strcmp0 (pattern, "")) { -- g_object_set (G_OBJECT (xkb_layout_filter), -- "secondary-icon-name", "edit-find-symbolic", -- "secondary-icon-activatable", FALSE, -- "secondary-icon-sensitive", FALSE, NULL); -- } else { -- g_object_set (G_OBJECT (xkb_layout_filter), -- "secondary-icon-name", "edit-clear-symbolic", -- "secondary-icon-activatable", TRUE, -- "secondary-icon-sensitive", TRUE, NULL); -- } -- -- if (search_pattern_list != NULL) -- g_strfreev (search_pattern_list); -- -- search_pattern_list = g_strsplit (upattern, " ", -1); -- g_free (upattern); -- -- gtk_tree_model_filter_refilter (filtered_model); --} -- --static void --xkb_layout_chooser_selection_changed (GtkTreeSelection * selection, -- GtkBuilder * chooser_dialog) --{ -- GList *selected_layouts = -- gtk_tree_selection_get_selected_rows (selection, NULL); -- GtkWidget *add_button = CWID ("btnOk"); -- GtkWidget *preview_button = CWID ("btnPreview"); -- gboolean anything_selected = g_list_length (selected_layouts) == 1; -- gboolean dupe = -- xkb_layout_chooser_selection_dupe (GTK_DIALOG -- (CWID -- ("xkb_layout_chooser"))); -- -- gtk_widget_set_sensitive (add_button, anything_selected && !dupe); -- gtk_widget_set_sensitive (preview_button, anything_selected); --} -- --static void --xkb_layout_chooser_row_activated (GtkTreeView * tree_view, -- GtkTreePath * path, -- GtkTreeViewColumn * column, -- GtkBuilder * chooser_dialog) --{ -- GtkWidget *add_button = CWID ("btnOk"); -- GtkWidget *dialog = CWID ("xkb_layout_chooser"); -- -- if (gtk_widget_is_sensitive (add_button)) -- gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); --} -- --static gboolean --xkb_filter_layouts (GtkTreeModel * model, -- GtkTreeIter * iter, gpointer data) --{ -- gchar *desc = NULL, *country_desc = NULL, *language_desc = -- NULL, **pattern; -- gboolean rv = TRUE; -- -- if (search_pattern_list == NULL || search_pattern_list[0] == NULL) -- return TRUE; -- -- gtk_tree_model_get (model, iter, -- COMBO_BOX_MODEL_COL_SORT, &desc, -- COMBO_BOX_MODEL_COL_COUNTRY_DESC, -- &country_desc, -- COMBO_BOX_MODEL_COL_LANGUAGE_DESC, -- &language_desc, -1); -- -- pattern = search_pattern_list; -- do { -- gboolean is_pattern_found = FALSE; -- gchar *udesc = g_utf8_strup (desc, -1); -- if (udesc != NULL && g_strstr_len (udesc, -1, *pattern)) { -- is_pattern_found = TRUE; -- } else if (country_desc != NULL -- && g_strstr_len (country_desc, -1, *pattern)) { -- is_pattern_found = TRUE; -- } else if (language_desc != NULL -- && g_strstr_len (language_desc, -1, *pattern)) { -- is_pattern_found = TRUE; -- } -- g_free (udesc); -- -- if (!is_pattern_found) { -- rv = FALSE; -- break; -- } -- -- } while (*++pattern != NULL); -- -- g_free (desc); -- g_free (country_desc); -- g_free (language_desc); -- return rv; --} -- --GtkWidget * --xkb_layout_choose (GtkBuilder * dialog) --{ -- GtkBuilder *chooser_dialog = gtk_builder_new (); -- GtkWidget *chooser, *xkb_filtered_layouts_list, *xkb_layout_filter; -- GtkTreeViewColumn *visible_column; -- GtkTreeSelection *selection; -- GtkListStore *model; -- GtkTreeModelFilter *filtered_model; -- gtk_builder_set_translation_domain (chooser_dialog, GETTEXT_PACKAGE); -- gtk_builder_add_from_file (chooser_dialog, CINNAMONCC_UI_DIR -- "/cinnamon-region-panel-layout-chooser.ui", -- NULL); -- chooser = CWID ("xkb_layout_chooser"); -- xkb_filtered_layouts_list = CWID ("xkb_filtered_layouts_list"); -- xkb_layout_filter = CWID ("xkb_layout_filter"); -- -- g_object_set_data (G_OBJECT (chooser), "xkb_filtered_layouts_list", -- xkb_filtered_layouts_list); -- visible_column = -- gtk_tree_view_column_new_with_attributes ("Layout", -- gtk_cell_renderer_text_new -- (), "markup", -- COMBO_BOX_MODEL_COL_VISIBLE, -- NULL); -- -- gtk_window_set_transient_for (GTK_WINDOW (chooser), -- GTK_WINDOW -- (gtk_widget_get_toplevel -- (WID ("region_notebook")))); -- -- gtk_tree_view_append_column (GTK_TREE_VIEW -- (xkb_filtered_layouts_list), -- visible_column); -- g_signal_connect_swapped (G_OBJECT (xkb_layout_filter), -- "notify::text", -- G_CALLBACK -- (xkb_layout_filter_changed), -- chooser_dialog); -- -- g_signal_connect (G_OBJECT (xkb_layout_filter), "icon-release", -- G_CALLBACK (xkb_layout_filter_clear), NULL); -- -- selection = -- gtk_tree_view_get_selection (GTK_TREE_VIEW -- (xkb_filtered_layouts_list)); -- -- g_signal_connect (G_OBJECT (selection), -- "changed", -- G_CALLBACK -- (xkb_layout_chooser_selection_changed), -- chooser_dialog); -- -- xkb_layout_chooser_selection_changed (selection, chooser_dialog); -- -- g_signal_connect (G_OBJECT (xkb_filtered_layouts_list), -- "row-activated", -- G_CALLBACK (xkb_layout_chooser_row_activated), -- chooser_dialog); -- -- filtered_model = -- GTK_TREE_MODEL_FILTER (gtk_builder_get_object -- (chooser_dialog, -- "filtered_layout_list_model")); -- model = -- GTK_LIST_STORE (gtk_builder_get_object -- (chooser_dialog, "layout_list_model")); -- -- left_bracket_regex = g_regex_new ("<", 0, 0, NULL); -- -- xkl_config_registry_search_by_pattern (config_registry, -- NULL, -- (TwoConfigItemsProcessFunc) -- (xkl_layout_add_to_list), -- chooser_dialog); -- -- g_regex_unref (left_bracket_regex); -- -- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), -- COMBO_BOX_MODEL_COL_SORT, -- GTK_SORT_ASCENDING); -- -- gtk_tree_model_filter_set_visible_func (filtered_model, -- xkb_filter_layouts, -- NULL, NULL); -- -- gtk_widget_grab_focus (xkb_layout_filter); -- -- gtk_widget_show (chooser); -- -- return chooser; --} -- --gchar * --xkb_layout_chooser_get_selected_id (GtkDialog * dialog) --{ -- GtkTreeModel *filtered_list_model; -- GtkWidget *xkb_filtered_layouts_list = -- g_object_get_data (G_OBJECT (dialog), -- "xkb_filtered_layouts_list"); -- GtkTreeIter viter; -- gchar *v_id; -- GtkTreeSelection *selection = -- gtk_tree_view_get_selection (GTK_TREE_VIEW -- (xkb_filtered_layouts_list)); -- GList *selected_layouts = -- gtk_tree_selection_get_selected_rows (selection, -- &filtered_list_model); -- -- if (g_list_length (selected_layouts) != 1) -- return NULL; -- -- gtk_tree_model_get_iter (filtered_list_model, -- &viter, -- (GtkTreePath *) (selected_layouts->data)); -- g_list_foreach (selected_layouts, -- (GFunc) gtk_tree_path_free, NULL); -- g_list_free (selected_layouts); -- -- gtk_tree_model_get (filtered_list_model, &viter, -- COMBO_BOX_MODEL_COL_XKB_ID, &v_id, -1); -- -- return v_id; --} -diff -uNrp a/panels/region/cinnamon-region-panel-xkblt.c b/panels/region/cinnamon-region-panel-xkblt.c ---- a/panels/region/cinnamon-region-panel-xkblt.c 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-xkblt.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,470 +0,0 @@ --/* cinnamon-region-panel-xkblt.c -- * Copyright (C) 2003-2007 Sergey V. Udaltsov -- * -- * Written by: Sergey V. Udaltsov <svu@gnome.org> -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -- * 02110-1335, USA. -- */ -- --#ifdef HAVE_CONFIG_H --# include <config.h> --#endif -- --#include <gdk/gdkx.h> --#include <glib/gi18n-lib.h> -- --#include <libgnomekbd/gkbd-desktop-config.h> --#include <libgnomekbd/gkbd-keyboard-drawing.h> -- --#include "cinnamon-region-panel-xkb.h" -- --enum { -- SEL_LAYOUT_TREE_COL_DESCRIPTION, -- SEL_LAYOUT_TREE_COL_ID, -- SEL_LAYOUT_TREE_COL_ENABLED, -- SEL_LAYOUT_N_COLS --}; -- --static int idx2select = -1; --static int max_selected_layouts = -1; -- --static GtkCellRenderer *text_renderer; -- --static gboolean disable_buttons_sensibility_update = FALSE; -- --static gboolean --get_selected_iter (GtkBuilder *dialog, -- GtkTreeModel **model, -- GtkTreeIter *iter) --{ -- GtkTreeSelection *selection; -- -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("xkb_layouts_selected"))); -- -- return gtk_tree_selection_get_selected (selection, model, iter); --} -- --static void --set_selected_path (GtkBuilder *dialog, -- GtkTreePath *path) --{ -- GtkTreeSelection *selection; -- -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("xkb_layouts_selected"))); -- -- gtk_tree_selection_select_path (selection, path); --} -- --static gint --find_selected_layout_idx (GtkBuilder *dialog) --{ -- GtkTreeIter selected_iter; -- GtkTreeModel *model; -- GtkTreePath *path; -- gint *indices; -- gint rv; -- -- if (!get_selected_iter (dialog, &model, &selected_iter)) -- return -1; -- -- path = gtk_tree_model_get_path (model, &selected_iter); -- if (path == NULL) -- return -1; -- -- indices = gtk_tree_path_get_indices (path); -- rv = indices[0]; -- gtk_tree_path_free (path); -- return rv; --} -- --gchar ** --xkb_layouts_get_selected_list (void) --{ -- gchar **retval; -- -- retval = g_settings_get_strv (xkb_keyboard_settings, -- GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS); -- if (retval == NULL || retval[0] == NULL) { -- g_strfreev (retval); -- retval = g_strdupv (initial_config.layouts_variants); -- } -- -- return retval; --} -- --gint --xkb_get_default_group () --{ -- return g_settings_get_int (xkb_desktop_settings, -- GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP); --} -- --void --xkb_save_default_group (gint default_group) --{ -- g_settings_set_int (xkb_desktop_settings, -- GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP, -- default_group); --} -- --static void --xkb_layouts_enable_disable_buttons (GtkBuilder * dialog) --{ -- GtkWidget *add_layout_btn = WID ("xkb_layouts_add"); -- GtkWidget *show_layout_btn = WID ("xkb_layouts_show"); -- GtkWidget *del_layout_btn = WID ("xkb_layouts_remove"); -- GtkWidget *selected_layouts_tree = WID ("xkb_layouts_selected"); -- GtkWidget *move_up_layout_btn = WID ("xkb_layouts_move_up"); -- GtkWidget *move_down_layout_btn = WID ("xkb_layouts_move_down"); -- -- GtkTreeSelection *s_selection = -- gtk_tree_view_get_selection (GTK_TREE_VIEW -- (selected_layouts_tree)); -- const int n_selected_selected_layouts = -- gtk_tree_selection_count_selected_rows (s_selection); -- GtkTreeModel *selected_layouts_model = gtk_tree_view_get_model -- (GTK_TREE_VIEW (selected_layouts_tree)); -- const int n_selected_layouts = -- gtk_tree_model_iter_n_children (selected_layouts_model, -- NULL); -- gint sidx = find_selected_layout_idx (dialog); -- -- if (disable_buttons_sensibility_update) -- return; -- -- gtk_widget_set_sensitive (add_layout_btn, -- (n_selected_layouts < -- max_selected_layouts -- || max_selected_layouts == 0)); -- gtk_widget_set_sensitive (del_layout_btn, (n_selected_layouts > 1) -- && (n_selected_selected_layouts > 0)); -- gtk_widget_set_sensitive (show_layout_btn, -- (n_selected_selected_layouts > 0)); -- gtk_widget_set_sensitive (move_up_layout_btn, sidx > 0); -- gtk_widget_set_sensitive (move_down_layout_btn, sidx >= 0 -- && sidx < (n_selected_layouts - 1)); --} -- --static void --update_layouts_list (GtkTreeModel *model, -- GtkBuilder *dialog) --{ -- gboolean cont; -- GtkTreeIter iter; -- GPtrArray *array; -- -- array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); -- cont = gtk_tree_model_get_iter_first (model, &iter); -- while (cont) { -- char *id; -- -- gtk_tree_model_get (model, &iter, -- SEL_LAYOUT_TREE_COL_ID, &id, -- -1); -- g_ptr_array_add (array, id); -- cont = gtk_tree_model_iter_next (model, &iter); -- } -- g_ptr_array_add (array, NULL); -- xkb_layouts_set_selected_list (array->pdata); -- g_ptr_array_free (array, TRUE); -- -- xkb_layouts_enable_disable_buttons (dialog); --} -- --static void --xkb_layouts_drag_end (GtkWidget *widget, -- GdkDragContext *drag_context, -- gpointer user_data) --{ -- update_layouts_list (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)), -- GTK_BUILDER (user_data)); --} -- --void --xkb_layouts_prepare_selected_tree (GtkBuilder * dialog) --{ -- GtkListStore *list_store; -- GtkWidget *tree_view = WID ("xkb_layouts_selected"); -- GtkTreeSelection *selection; -- GtkTreeViewColumn *desc_column; -- -- list_store = gtk_list_store_new (SEL_LAYOUT_N_COLS, -- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); -- -- text_renderer = GTK_CELL_RENDERER (gtk_cell_renderer_text_new ()); -- -- desc_column = -- gtk_tree_view_column_new_with_attributes (_("Layout"), -- text_renderer, -- "text", -- SEL_LAYOUT_TREE_COL_DESCRIPTION, -- "sensitive", -- SEL_LAYOUT_TREE_COL_ENABLED, -- NULL); -- selection = -- gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); -- -- gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), -- GTK_TREE_MODEL (list_store)); -- -- gtk_tree_view_column_set_sizing (desc_column, -- GTK_TREE_VIEW_COLUMN_AUTOSIZE); -- gtk_tree_view_column_set_resizable (desc_column, TRUE); -- gtk_tree_view_column_set_expand (desc_column, TRUE); -- -- gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), -- desc_column); -- -- g_signal_connect_swapped (G_OBJECT (selection), "changed", -- G_CALLBACK -- (xkb_layouts_enable_disable_buttons), -- dialog); -- max_selected_layouts = xkl_engine_get_max_num_groups (engine); -- -- /* Setting up DnD */ -- gtk_tree_view_set_reorderable (GTK_TREE_VIEW (tree_view), TRUE); -- g_signal_connect (G_OBJECT (tree_view), "drag-end", -- G_CALLBACK (xkb_layouts_drag_end), dialog); --} -- --gchar * --xkb_layout_description_utf8 (const gchar * visible) --{ -- char *l, *sl, *v, *sv; -- if (gkbd_keyboard_config_get_descriptions -- (config_registry, visible, &sl, &l, &sv, &v)) -- visible = -- gkbd_keyboard_config_format_full_description (l, v); -- return g_strstrip (g_strdup (visible)); --} -- --void --xkb_layouts_fill_selected_tree (GtkBuilder * dialog) --{ -- gchar **layouts = xkb_layouts_get_selected_list (); -- guint i; -- GtkListStore *list_store = -- GTK_LIST_STORE (gtk_tree_view_get_model -- (GTK_TREE_VIEW -- (WID ("xkb_layouts_selected")))); -- -- /* temporarily disable the buttons' status update */ -- disable_buttons_sensibility_update = TRUE; -- -- gtk_list_store_clear (list_store); -- -- for (i = 0; layouts != NULL && layouts[i] != NULL; i++) { -- char *cur_layout = layouts[i]; -- gchar *utf_visible = -- xkb_layout_description_utf8 (cur_layout); -- -- gtk_list_store_insert_with_values (list_store, NULL, G_MAXINT, -- SEL_LAYOUT_TREE_COL_DESCRIPTION, -- utf_visible, -- SEL_LAYOUT_TREE_COL_ID, -- cur_layout, -- SEL_LAYOUT_TREE_COL_ENABLED, -- i < max_selected_layouts, -1); -- g_free (utf_visible); -- } -- -- g_strfreev (layouts); -- -- /* enable the buttons' status update */ -- disable_buttons_sensibility_update = FALSE; -- -- if (idx2select != -1) { -- GtkTreeSelection *selection = -- gtk_tree_view_get_selection ((GTK_TREE_VIEW -- (WID -- ("xkb_layouts_selected")))); -- GtkTreePath *path = -- gtk_tree_path_new_from_indices (idx2select, -1); -- gtk_tree_selection_select_path (selection, path); -- gtk_tree_path_free (path); -- idx2select = -1; -- } else { -- /* if there is nothing to select - just enable/disable the buttons, -- otherwise it would be done by the selection change */ -- xkb_layouts_enable_disable_buttons (dialog); -- } --} -- --static void --add_default_switcher_if_necessary () --{ -- gchar **layouts_list = xkb_layouts_get_selected_list(); -- gchar **options_list = xkb_options_get_selected_list (); -- gboolean was_appended; -- -- options_list = -- gkbd_keyboard_config_add_default_switch_option_if_necessary -- (layouts_list, options_list, &was_appended); -- if (was_appended) -- xkb_options_set_selected_list (options_list); -- g_strfreev (options_list); --} -- --static void --chooser_response (GtkDialog *chooser, -- int response_id, -- GtkBuilder *dialog) --{ -- if (response_id == GTK_RESPONSE_OK) { -- char *id, *name; -- GtkListStore *list_store; -- -- list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (WID ("xkb_layouts_selected")))); -- id = xkb_layout_chooser_get_selected_id (chooser); -- name = xkb_layout_description_utf8 (id); -- gtk_list_store_insert_with_values (list_store, NULL, G_MAXINT, -- SEL_LAYOUT_TREE_COL_DESCRIPTION, name, -- SEL_LAYOUT_TREE_COL_ID, id, -- SEL_LAYOUT_TREE_COL_ENABLED, TRUE, -- -1); -- g_free (name); -- add_default_switcher_if_necessary (); -- update_layouts_list (GTK_TREE_MODEL (list_store), dialog); -- } -- -- xkb_layout_chooser_response (chooser, response_id); --} -- --static void --add_selected_layout (GtkWidget * button, GtkBuilder * dialog) --{ -- GtkWidget *chooser; -- -- chooser = xkb_layout_choose (dialog); -- g_signal_connect (G_OBJECT (chooser), "response", -- G_CALLBACK (chooser_response), dialog); --} -- --static void --show_selected_layout (GtkWidget * button, GtkBuilder * dialog) --{ -- gint idx = find_selected_layout_idx (dialog); -- -- if (idx != -1) { -- GtkWidget *parent = WID ("region_notebook"); -- GtkWidget *popup = gkbd_keyboard_drawing_dialog_new (); -- gkbd_keyboard_drawing_dialog_set_group (popup, -- config_registry, -- idx); -- gtk_window_set_transient_for (GTK_WINDOW (popup), -- GTK_WINDOW -- (gtk_widget_get_toplevel -- (parent))); -- gtk_widget_show_all (popup); -- } --} -- --static void --remove_selected_layout (GtkWidget * button, GtkBuilder * dialog) --{ -- GtkTreeModel *model; -- GtkTreeIter iter; -- -- if (get_selected_iter (dialog, &model, &iter) == FALSE) -- return; -- -- gtk_list_store_remove (GTK_LIST_STORE (model), &iter); -- update_layouts_list (model, dialog); --} -- --static void --move_up_selected_layout (GtkWidget * button, GtkBuilder * dialog) --{ -- GtkTreeModel *model; -- GtkTreeIter iter, prev; -- GtkTreePath *path; -- -- if (get_selected_iter (dialog, &model, &iter) == FALSE) -- return; -- -- prev = iter; -- if (!gtk_tree_model_iter_previous (model, &prev)) -- return; -- -- path = gtk_tree_model_get_path (model, &prev); -- -- gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &prev); -- -- update_layouts_list (model, dialog); -- -- set_selected_path (dialog, path); -- -- gtk_tree_path_free (path); --} -- --static void --move_down_selected_layout (GtkWidget * button, GtkBuilder * dialog) --{ -- GtkTreeModel *model; -- GtkTreeIter iter, next; -- GtkTreePath *path; -- -- if (get_selected_iter (dialog, &model, &iter) == FALSE) -- return; -- -- next = iter; -- if (!gtk_tree_model_iter_next (model, &next)) -- return; -- -- path = gtk_tree_model_get_path (model, &next); -- -- gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &next); -- -- update_layouts_list (model, dialog); -- -- set_selected_path (dialog, path); -- -- gtk_tree_path_free (path); --} -- --void --xkb_layouts_register_buttons_handlers (GtkBuilder * dialog) --{ -- g_signal_connect (G_OBJECT (WID ("xkb_layouts_add")), "clicked", -- G_CALLBACK (add_selected_layout), dialog); -- g_signal_connect (G_OBJECT (WID ("xkb_layouts_show")), "clicked", -- G_CALLBACK (show_selected_layout), dialog); -- g_signal_connect (G_OBJECT (WID ("xkb_layouts_remove")), "clicked", -- G_CALLBACK (remove_selected_layout), dialog); -- g_signal_connect (G_OBJECT (WID ("xkb_layouts_move_up")), -- "clicked", G_CALLBACK (move_up_selected_layout), -- dialog); -- g_signal_connect (G_OBJECT (WID ("xkb_layouts_move_down")), -- "clicked", -- G_CALLBACK (move_down_selected_layout), dialog); --} -- --static void --xkb_layouts_update_list (GSettings * settings, -- gchar * key, GtkBuilder * dialog) --{ -- if (strcmp (key, GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS) == 0) { -- xkb_layouts_fill_selected_tree (dialog); -- enable_disable_restoring (dialog); -- } --} -- --void --xkb_layouts_register_conf_listener (GtkBuilder * dialog) --{ -- g_signal_connect (xkb_keyboard_settings, "changed", -- G_CALLBACK (xkb_layouts_update_list), dialog); --} -diff -uNrp a/panels/region/cinnamon-region-panel-xkbot.c b/panels/region/cinnamon-region-panel-xkbot.c ---- a/panels/region/cinnamon-region-panel-xkbot.c 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-xkbot.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,516 +0,0 @@ --/* cinnamon-region-panel-xkbot.c -- * Copyright (C) 2003-2007 Sergey V. Udaltsov -- * -- * Written by: Sergey V. Udaltsov <svu@gnome.org> -- * John Spray <spray_john@users.sourceforge.net> -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -- * 02110-1335, USA. -- */ -- --#ifdef HAVE_CONFIG_H --# include <config.h> --#endif -- --#include <glib/gi18n-lib.h> --#include <string.h> -- --#include "cinnamon-region-panel-xkb.h" -- --static GtkBuilder *chooser_dialog = NULL; --static const char *current1st_level_id = NULL; --static GSList *option_checks_list = NULL; --static GtkWidget *current_none_radio = NULL; --static GtkWidget *current_expander = NULL; --static gboolean current_multi_select = FALSE; --static GSList *current_radio_group = NULL; -- --#define OPTION_ID_PROP "optionID" --#define SELCOUNTER_PROP "selectionCounter" --#define GCONFSTATE_PROP "gconfState" --#define EXPANDERS_PROP "expandersList" -- --gchar ** --xkb_options_get_selected_list (void) --{ -- gchar **retval; -- -- retval = -- g_settings_get_strv (xkb_keyboard_settings, -- GKBD_KEYBOARD_CONFIG_KEY_OPTIONS); -- if (retval == NULL) { -- retval = g_strdupv (initial_config.options); -- } -- -- return retval; --} -- --/* Returns the selection counter of the expander (static current_expander) */ --static int --xkb_options_expander_selcounter_get (void) --{ -- return -- GPOINTER_TO_INT (g_object_get_data -- (G_OBJECT (current_expander), -- SELCOUNTER_PROP)); --} -- --/* Increments the selection counter in the expander (static current_expander) -- using the value (can be 0)*/ --static void --xkb_options_expander_selcounter_add (int value) --{ -- g_object_set_data (G_OBJECT (current_expander), SELCOUNTER_PROP, -- GINT_TO_POINTER -- (xkb_options_expander_selcounter_get () -- + value)); --} -- --/* Resets the seletion counter in the expander (static current_expander) */ --static void --xkb_options_expander_selcounter_reset (void) --{ -- g_object_set_data (G_OBJECT (current_expander), SELCOUNTER_PROP, -- GINT_TO_POINTER (0)); --} -- --/* Formats the expander (static current_expander), based on the selection counter */ --static void --xkb_options_expander_highlight (void) --{ -- char *utf_group_name = -- g_object_get_data (G_OBJECT (current_expander), -- "utfGroupName"); -- int counter = xkb_options_expander_selcounter_get (); -- if (utf_group_name != NULL) { -- gchar *titlemarkup = -- g_strconcat (counter > -- 0 ? "<span weight=\"bold\">" : "<span>", -- utf_group_name, "</span>", NULL); -- gtk_expander_set_label (GTK_EXPANDER (current_expander), -- titlemarkup); -- g_free (titlemarkup); -- } --} -- --/* Add optionname from the backend's selection list if it's not -- already in there. */ --static void --xkb_options_select (gchar * optionname) --{ -- gboolean already_selected = FALSE; -- gchar **options_list; -- guint i; -- -- options_list = xkb_options_get_selected_list (); -- for (i = 0; options_list != NULL && options_list[i] != NULL; i++) { -- gchar *option = options_list[i]; -- if (!strcmp (option, optionname)) { -- already_selected = TRUE; -- break; -- } -- } -- -- if (!already_selected) { -- options_list = -- gkbd_strv_append (options_list, g_strdup (optionname)); -- xkb_options_set_selected_list (options_list); -- } -- -- g_strfreev (options_list); --} -- --/* Remove all occurences of optionname from the backend's selection list */ --static void --xkb_options_deselect (gchar * optionname) --{ -- gchar **options_list = xkb_options_get_selected_list (); -- if (options_list != NULL) { -- gchar **option = options_list; -- while (*option != NULL) { -- gchar *id = *option; -- if (!strcmp (id, optionname)) { -- gkbd_strv_behead (option); -- } else -- option++; -- } -- xkb_options_set_selected_list (options_list); -- } -- g_strfreev (options_list); --} -- --/* Return true if optionname describes a string already in the backend's -- list of selected options */ --static gboolean --xkb_options_is_selected (gchar * optionname) --{ -- gboolean retval = FALSE; -- gchar **options_list = xkb_options_get_selected_list (); -- if (options_list != NULL) { -- gchar **option = options_list; -- while (*option != NULL) { -- if (!strcmp (*option, optionname)) { -- retval = TRUE; -- break; -- } -- option++; -- } -- } -- g_strfreev (options_list); -- return retval; --} -- --/* Make sure selected options stay visible when navigating with the keyboard */ --static gboolean --option_focused_cb (GtkWidget * widget, GdkEventFocus * event, -- gpointer data) --{ -- GtkScrolledWindow *win = GTK_SCROLLED_WINDOW (data); -- GtkAllocation alloc; -- GtkAdjustment *adj; -- -- gtk_widget_get_allocation (widget, &alloc); -- adj = gtk_scrolled_window_get_vadjustment (win); -- gtk_adjustment_clamp_page (adj, alloc.y, alloc.y + alloc.height); -- -- return FALSE; --} -- --/* Update xkb backend to reflect the new UI state */ --static void --option_toggled_cb (GtkWidget * checkbutton, gpointer data) --{ -- gpointer optionID = -- g_object_get_data (G_OBJECT (checkbutton), OPTION_ID_PROP); -- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton))) -- xkb_options_select (optionID); -- else -- xkb_options_deselect (optionID); --} -- --/* Add a check_button or radio_button to control a particular option -- This function makes particular use of the current... variables at -- the top of this file. */ --static void --xkb_options_add_option (XklConfigRegistry * config_registry, -- XklConfigItem * config_item, GtkBuilder * dialog) --{ -- GtkWidget *option_check; -- gchar *utf_option_name = xci_desc_to_utf8 (config_item); -- /* Copy this out because we'll load it into the widget with set_data */ -- gchar *full_option_name = -- g_strdup (gkbd_keyboard_config_merge_items -- (current1st_level_id, config_item->name)); -- gboolean initial_state; -- -- if (current_multi_select) -- option_check = -- gtk_check_button_new_with_label (utf_option_name); -- else { -- if (current_radio_group == NULL) { -- /* The first radio in a group is to be "Default", meaning none of -- the below options are to be included in the selected list. -- This is a HIG-compliant alternative to allowing no -- selection in the group. */ -- option_check = -- gtk_radio_button_new_with_label -- (current_radio_group, _("Default")); -- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON -- (option_check), -- TRUE); -- /* Make option name underscore - -- to enforce its first position in the list */ -- g_object_set_data_full (G_OBJECT (option_check), -- "utfOptionName", -- g_strdup (" "), g_free); -- option_checks_list = -- g_slist_append (option_checks_list, -- option_check); -- current_radio_group = -- gtk_radio_button_get_group (GTK_RADIO_BUTTON -- (option_check)); -- current_none_radio = option_check; -- -- g_signal_connect (option_check, "focus-in-event", -- G_CALLBACK (option_focused_cb), -- WID ("options_scroll")); -- } -- option_check = -- gtk_radio_button_new_with_label (current_radio_group, -- utf_option_name); -- current_radio_group = -- gtk_radio_button_get_group (GTK_RADIO_BUTTON -- (option_check)); -- g_object_set_data (G_OBJECT (option_check), "NoneRadio", -- current_none_radio); -- } -- -- initial_state = xkb_options_is_selected (full_option_name); -- -- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (option_check), -- initial_state); -- -- g_object_set_data_full (G_OBJECT (option_check), OPTION_ID_PROP, -- full_option_name, g_free); -- g_object_set_data_full (G_OBJECT (option_check), "utfOptionName", -- utf_option_name, g_free); -- -- g_signal_connect (option_check, "toggled", -- G_CALLBACK (option_toggled_cb), NULL); -- -- option_checks_list = -- g_slist_append (option_checks_list, option_check); -- -- g_signal_connect (option_check, "focus-in-event", -- G_CALLBACK (option_focused_cb), -- WID ("options_scroll")); -- -- xkb_options_expander_selcounter_add (initial_state); -- g_object_set_data (G_OBJECT (option_check), GCONFSTATE_PROP, -- GINT_TO_POINTER (initial_state)); --} -- --static gint --xkb_option_checks_compare (GtkWidget * chk1, GtkWidget * chk2) --{ -- const gchar *t1 = -- g_object_get_data (G_OBJECT (chk1), "utfOptionName"); -- const gchar *t2 = -- g_object_get_data (G_OBJECT (chk2), "utfOptionName"); -- return g_utf8_collate (t1, t2); --} -- --/* Add a group of options: create title and layout widgets and then -- add widgets for all the options in the group. */ --static void --xkb_options_add_group (XklConfigRegistry * config_registry, -- XklConfigItem * config_item, GtkBuilder * dialog) --{ -- GtkWidget *align, *vbox, *option_check; -- gboolean allow_multiple_selection = -- GPOINTER_TO_INT (g_object_get_data (G_OBJECT (config_item), -- XCI_PROP_ALLOW_MULTIPLE_SELECTION)); -- -- GSList *expanders_list = -- g_object_get_data (G_OBJECT (dialog), EXPANDERS_PROP); -- -- gchar *utf_group_name = xci_desc_to_utf8 (config_item); -- gchar *titlemarkup = -- g_strconcat ("<span>", utf_group_name, "</span>", NULL); -- -- current_expander = gtk_expander_new (titlemarkup); -- gtk_expander_set_use_markup (GTK_EXPANDER (current_expander), -- TRUE); -- g_object_set_data_full (G_OBJECT (current_expander), -- "utfGroupName", utf_group_name, g_free); -- g_object_set_data_full (G_OBJECT (current_expander), "groupId", -- g_strdup (config_item->name), g_free); -- -- g_free (titlemarkup); -- align = gtk_alignment_new (0, 0, 1, 1); -- gtk_alignment_set_padding (GTK_ALIGNMENT (align), 6, 12, 12, 0); -- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); -- gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE); -- gtk_container_add (GTK_CONTAINER (align), vbox); -- gtk_container_add (GTK_CONTAINER (current_expander), align); -- -- current_multi_select = (gboolean) allow_multiple_selection; -- current_radio_group = NULL; -- current1st_level_id = config_item->name; -- -- option_checks_list = NULL; -- -- xkl_config_registry_foreach_option (config_registry, -- config_item->name, -- (ConfigItemProcessFunc) -- xkb_options_add_option, -- dialog); -- /* sort it */ -- option_checks_list = -- g_slist_sort (option_checks_list, -- (GCompareFunc) xkb_option_checks_compare); -- while (option_checks_list) { -- option_check = GTK_WIDGET (option_checks_list->data); -- gtk_box_pack_start (GTK_BOX (vbox), option_check, TRUE, -- TRUE, 0); -- option_checks_list = option_checks_list->next; -- } -- /* free it */ -- g_slist_free (option_checks_list); -- option_checks_list = NULL; -- -- xkb_options_expander_highlight (); -- -- expanders_list = g_slist_append (expanders_list, current_expander); -- g_object_set_data (G_OBJECT (dialog), EXPANDERS_PROP, -- expanders_list); -- -- g_signal_connect (current_expander, "focus-in-event", -- G_CALLBACK (option_focused_cb), -- WID ("options_scroll")); --} -- --static gint --xkb_options_expanders_compare (GtkWidget * expander1, -- GtkWidget * expander2) --{ -- const gchar *t1 = -- g_object_get_data (G_OBJECT (expander1), "utfGroupName"); -- const gchar *t2 = -- g_object_get_data (G_OBJECT (expander2), "utfGroupName"); -- return g_utf8_collate (t1, t2); --} -- --/* Create widgets to represent the options made available by the backend */ --void --xkb_options_load_options (GtkBuilder * dialog) --{ -- GtkWidget *opts_vbox = WID ("options_vbox"); -- GtkWidget *dialog_vbox = WID ("dialog_vbox"); -- GtkWidget *options_scroll = WID ("options_scroll"); -- GtkWidget *expander; -- GSList *expanders_list; -- -- current1st_level_id = NULL; -- current_none_radio = NULL; -- current_multi_select = FALSE; -- current_radio_group = NULL; -- -- /* fill the list */ -- xkl_config_registry_foreach_option_group (config_registry, -- (ConfigItemProcessFunc) -- xkb_options_add_group, -- dialog); -- /* sort it */ -- expanders_list = -- g_object_get_data (G_OBJECT (dialog), EXPANDERS_PROP); -- expanders_list = -- g_slist_sort (expanders_list, -- (GCompareFunc) xkb_options_expanders_compare); -- g_object_set_data (G_OBJECT (dialog), EXPANDERS_PROP, -- expanders_list); -- while (expanders_list) { -- expander = GTK_WIDGET (expanders_list->data); -- gtk_box_pack_start (GTK_BOX (opts_vbox), expander, FALSE, -- FALSE, 0); -- expanders_list = expanders_list->next; -- } -- -- /* Somewhere in gtk3 the top vbox in dialog is made non-expandable */ -- gtk_box_set_child_packing (GTK_BOX (dialog_vbox), options_scroll, -- TRUE, TRUE, 0, GTK_PACK_START); -- gtk_widget_show_all (dialog_vbox); --} -- --static void --chooser_response_cb (GtkDialog * dialog, gint response, gpointer data) --{ -- switch (response) { -- case GTK_RESPONSE_DELETE_EVENT: -- case GTK_RESPONSE_CLOSE: { -- /* just cleanup */ -- GSList *expanders_list = -- g_object_get_data (G_OBJECT (dialog), -- EXPANDERS_PROP); -- g_object_set_data (G_OBJECT (dialog), -- EXPANDERS_PROP, NULL); -- g_slist_free (expanders_list); -- -- gtk_widget_destroy (GTK_WIDGET (dialog)); -- chooser_dialog = NULL; -- } -- break; -- } --} -- --/* Create popup dialog */ --void --xkb_options_popup_dialog (GtkBuilder * dialog) --{ -- GtkWidget *chooser; -- -- chooser_dialog = gtk_builder_new (); -- gtk_builder_set_translation_domain (chooser_dialog, GETTEXT_PACKAGE); -- gtk_builder_add_from_file (chooser_dialog, CINNAMONCC_UI_DIR -- "/cinnamon-region-panel-options-dialog.ui", -- NULL); -- -- chooser = CWID ("xkb_options_dialog"); -- gtk_window_set_transient_for (GTK_WINDOW (chooser), -- GTK_WINDOW (gtk_widget_get_toplevel (WID ("region_notebook")))); -- gtk_window_set_modal (GTK_WINDOW (chooser), TRUE); -- xkb_options_load_options (chooser_dialog); -- -- g_signal_connect (chooser, "response", -- G_CALLBACK (chooser_response_cb), dialog); -- gtk_widget_show (chooser); --} -- --/* Update selected option counters for a group-bound expander */ --static void --xkb_options_update_option_counters (XklConfigRegistry * config_registry, -- XklConfigItem * config_item) --{ -- gchar *full_option_name = -- g_strdup (gkbd_keyboard_config_merge_items -- (current1st_level_id, config_item->name)); -- gboolean current_state = -- xkb_options_is_selected (full_option_name); -- g_free (full_option_name); -- -- xkb_options_expander_selcounter_add (current_state); --} -- --/* Respond to a change in the xkb gconf settings */ --static void --xkb_options_update (GSettings * settings, gchar * key, GtkBuilder * dialog) --{ -- if (!strcmp (key, GKBD_KEYBOARD_CONFIG_KEY_OPTIONS)) { -- /* Updating options is handled by gconf notifies for each widget -- This is here to avoid calling it N_OPTIONS times for each gconf -- change. */ -- enable_disable_restoring (dialog); -- -- if (chooser_dialog != NULL) { -- GSList *expanders_list = -- g_object_get_data (G_OBJECT (chooser_dialog), -- EXPANDERS_PROP); -- while (expanders_list) { -- current_expander = -- GTK_WIDGET (expanders_list->data); -- gchar *group_id = -- g_object_get_data (G_OBJECT -- (current_expander), -- "groupId"); -- current1st_level_id = group_id; -- xkb_options_expander_selcounter_reset (); -- xkl_config_registry_foreach_option -- (config_registry, group_id, -- (ConfigItemProcessFunc) -- xkb_options_update_option_counters, -- current_expander); -- xkb_options_expander_highlight (); -- expanders_list = expanders_list->next; -- } -- } -- } --} -- --void --xkb_options_register_conf_listener (GtkBuilder * dialog) --{ -- g_signal_connect (xkb_keyboard_settings, "changed", -- G_CALLBACK (xkb_options_update), dialog); --} -diff -uNrp a/panels/region/cinnamon-region-panel-xkbpv.c b/panels/region/cinnamon-region-panel-xkbpv.c ---- a/panels/region/cinnamon-region-panel-xkbpv.c 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/cinnamon-region-panel-xkbpv.c 1970-01-01 01:00:00.000000000 +0100 -@@ -1,120 +0,0 @@ --/* cinnamon-region-panel-xkbpv.c -- * Copyright (C) 2003-2007 Sergey V. Udaltsov -- * -- * Written by: Sergey V. Udaltsov <svu@gnome.org> -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA -- * 02110-1335, USA. -- */ -- --#ifdef HAVE_CONFIG_H --# include <config.h> --#endif -- --#include <libgnomekbd/gkbd-keyboard-drawing.h> -- --#include "cinnamon-region-panel-xkb.h" -- --#ifdef HAVE_X11_EXTENSIONS_XKB_H --#include "X11/XKBlib.h" --/** -- * BAD STYLE: Taken from xklavier_private_xkb.h -- * Any ideas on architectural improvements are WELCOME -- */ --extern gboolean xkl_xkb_config_native_prepare (XklEngine * engine, -- const XklConfigRec * data, -- XkbComponentNamesPtr -- component_names); -- --extern void xkl_xkb_config_native_cleanup (XklEngine * engine, -- XkbComponentNamesPtr -- component_names); -- --/* */ --#endif -- --static GkbdKeyboardDrawingGroupLevel groupsLevels[] = -- { {0, 1}, {0, 3}, {0, 0}, {0, 2} }; --static GkbdKeyboardDrawingGroupLevel *pGroupsLevels[] = { -- groupsLevels, groupsLevels + 1, groupsLevels + 2, groupsLevels + 3 --}; -- --GtkWidget * --xkb_layout_preview_create_widget (GtkBuilder * chooserDialog) --{ -- GtkWidget *kbdraw = gkbd_keyboard_drawing_new (); -- -- gkbd_keyboard_drawing_set_groups_levels (GKBD_KEYBOARD_DRAWING -- (kbdraw), pGroupsLevels); -- return kbdraw; --} -- --void --xkb_layout_preview_set_drawing_layout (GtkWidget * kbdraw, -- const gchar * id) --{ --#ifdef HAVE_X11_EXTENSIONS_XKB_H -- if (kbdraw != NULL) { -- if (id != NULL) { -- XklConfigRec *data; -- char **p, *layout, *variant; -- XkbComponentNamesRec component_names; -- -- data = xkl_config_rec_new (); -- if (xkl_config_rec_get_from_server (data, engine)) { -- if ((p = data->layouts) != NULL) -- g_strfreev (data->layouts); -- -- if ((p = data->variants) != NULL) -- g_strfreev (data->variants); -- -- data->layouts = g_new0 (char *, 2); -- data->variants = g_new0 (char *, 2); -- if (gkbd_keyboard_config_split_items -- (id, &layout, &variant) -- && variant != NULL) { -- data->layouts[0] = -- (layout == -- NULL) ? NULL : -- g_strdup (layout); -- data->variants[0] = -- (variant == -- NULL) ? NULL : -- g_strdup (variant); -- } else { -- data->layouts[0] = -- (id == -- NULL) ? NULL : g_strdup (id); -- data->variants[0] = NULL; -- } -- -- if (xkl_xkb_config_native_prepare -- (engine, data, &component_names)) { -- gkbd_keyboard_drawing_set_keyboard -- (GKBD_KEYBOARD_DRAWING -- (kbdraw), &component_names); -- -- xkl_xkb_config_native_cleanup -- (engine, &component_names); -- } -- } -- g_object_unref (G_OBJECT (data)); -- } else -- gkbd_keyboard_drawing_set_keyboard -- (GKBD_KEYBOARD_DRAWING (kbdraw), NULL); -- -- } --#endif --} -diff -uNrp a/panels/region/.indent.pro b/panels/region/.indent.pro ---- a/panels/region/.indent.pro 1970-01-01 01:00:00.000000000 +0100 -+++ b/panels/region/.indent.pro 2013-08-25 16:50:30.000000000 +0100 -@@ -0,0 +1,2 @@ -+-kr -i8 -pcs -lps -psl -+ -diff -uNrp a/panels/region/Makefile.am b/panels/region/Makefile.am ---- a/panels/region/Makefile.am 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/Makefile.am 2013-09-21 13:24:15.347949247 +0100 -@@ -23,12 +23,9 @@ libregion_la_SOURCES = \ - cinnamon-region-panel-lang.h \ - cinnamon-region-panel-system.c \ - cinnamon-region-panel-system.h \ -- cinnamon-region-panel-xkb.c \ -- cinnamon-region-panel-xkblt.c \ -- cinnamon-region-panel-xkbltadd.c \ -- cinnamon-region-panel-xkbot.c \ -- cinnamon-region-panel-xkbpv.c \ -- cinnamon-region-panel-xkb.h -+ cinnamon-region-panel-input.c \ -+ cinnamon-region-panel-input.h \ -+ $(NULL) - - libregion_la_LIBADD = $(PANEL_LIBS) $(REGION_PANEL_LIBS) $(builddir)/../common/liblanguage.la - -@@ -39,8 +36,8 @@ libregion_la_LDFLAGS = $(PANEL_LDFLAGS) - uidir = $(pkgdatadir)/ui - ui_DATA = \ - cinnamon-region-panel.ui \ -- cinnamon-region-panel-layout-chooser.ui \ -- cinnamon-region-panel-options-dialog.ui -+ cinnamon-region-panel-input-chooser.ui \ -+ $(NULL) - - desktopdir = $(datadir)/applications - Desktop_in_files = cinnamon-region-panel.desktop.in -diff -uNrp a/panels/region/region-module.c b/panels/region/region-module.c ---- a/panels/region/region-module.c 2013-08-25 14:40:14.000000000 +0100 -+++ b/panels/region/region-module.c 2013-09-21 13:24:15.347949247 +0100 -@@ -28,6 +28,7 @@ - void - g_io_module_load (GIOModule * module) - { -+ - /* register the panel */ - cc_region_panel_register (module); - } diff --git a/pkgs/desktops/cinnamon/remove-sessionmigration.patch b/pkgs/desktops/cinnamon/remove-sessionmigration.patch deleted file mode 100644 index 92e63549d964..000000000000 --- a/pkgs/desktops/cinnamon/remove-sessionmigration.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/cinnamon-session/csm-session-fill.c -+++ b/cinnamon-session/csm-session-fill.c -@@ -228,15 +228,6 @@ - load_standard_apps (CsmManager *manager, - GKeyFile *keyfile) - { -- GError *error; -- -- g_debug ("fill: *** Executing user migration"); -- error = NULL; -- if(!g_spawn_command_line_sync ("session-migration", NULL, NULL, NULL, &error)) { -- g_warning ("Error while executing session-migration: %s", error->message); -- g_error_free (error); -- } -- - g_debug ("fill: *** Adding required components"); - handle_required_components (keyfile, !csm_manager_get_failsafe (manager), - append_required_components_helper, manager); - diff --git a/pkgs/desktops/cinnamon/systemd-support.patch b/pkgs/desktops/cinnamon/systemd-support.patch deleted file mode 100644 index feceaf05f7b6..000000000000 --- a/pkgs/desktops/cinnamon/systemd-support.patch +++ /dev/null @@ -1,536 +0,0 @@ - -diff --git a/plugins/media-keys/csd-media-keys-manager.c b/plugins/media-keys/csd-media-keys-manager.c -index 02930a3..7c1c519 100644 ---- a/plugins/media-keys/csd-media-keys-manager.c -+++ b/plugins/media-keys/csd-media-keys-manager.c -@@ -39,6 +39,7 @@ - #include <gdk/gdkx.h> - #include <gtk/gtk.h> - #include <gio/gdesktopappinfo.h> -+#include <gio/gunixfdlist.h> - - #ifdef HAVE_GUDEV - #include <gudev/gudev.h> -@@ -121,6 +122,10 @@ static const gchar kb_introspection_xml[] = - #define VOLUME_STEP 5 /* percents for one volume button press */ - #define MAX_VOLUME 65536.0 - -+#define SYSTEMD_DBUS_NAME "org.freedesktop.login1" -+#define SYSTEMD_DBUS_PATH "/org/freedesktop/login1" -+#define SYSTEMD_DBUS_INTERFACE "org.freedesktop.login1.Manager" -+ - #define CSD_MEDIA_KEYS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_MEDIA_KEYS_MANAGER, CsdMediaKeysManagerPrivate)) - - typedef struct { -@@ -167,6 +172,10 @@ struct CsdMediaKeysManagerPrivate - GDBusProxy *power_screen_proxy; - GDBusProxy *power_keyboard_proxy; - -+ /* systemd stuff */ -+ GDBusProxy *logind_proxy; -+ gint inhibit_keys_fd; -+ - /* Multihead stuff */ - GdkScreen *current_screen; - GSList *screens; -@@ -2213,6 +2222,11 @@ csd_media_keys_manager_stop (CsdMediaKeysManager *manager) - } - #endif /* HAVE_GUDEV */ - -+ if (priv->logind_proxy) { -+ g_object_unref (priv->logind_proxy); -+ priv->logind_proxy = NULL; -+ } -+ - if (priv->settings) { - g_object_unref (priv->settings); - priv->settings = NULL; -@@ -2356,9 +2370,85 @@ csd_media_keys_manager_class_init (CsdMediaKeysManagerClass *klass) - } - - static void -+inhibit_done (GObject *source, -+ GAsyncResult *result, -+ gpointer user_data) -+{ -+ GDBusProxy *proxy = G_DBUS_PROXY (source); -+ CsdMediaKeysManager *manager = CSD_MEDIA_KEYS_MANAGER (user_data); -+ GError *error = NULL; -+ GVariant *res; -+ GUnixFDList *fd_list = NULL; -+ gint idx; -+ -+ res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error); -+ if (res == NULL) { -+ g_warning ("Unable to inhibit keypresses: %s", error->message); -+ g_error_free (error); -+ } else { -+ g_variant_get (res, "(h)", &idx); -+ manager->priv->inhibit_keys_fd = g_unix_fd_list_get (fd_list, idx, &error); -+ if (manager->priv->inhibit_keys_fd == -1) { -+ g_warning ("Failed to receive system inhibitor fd: %s", error->message); -+ g_error_free (error); -+ } -+ g_debug ("System inhibitor fd is %d", manager->priv->inhibit_keys_fd); -+ g_object_unref (fd_list); -+ g_variant_unref (res); -+ } -+} -+ -+static void - csd_media_keys_manager_init (CsdMediaKeysManager *manager) - { -+ GError *error; -+ GDBusConnection *bus; -+ -+ error = NULL; - manager->priv = CSD_MEDIA_KEYS_MANAGER_GET_PRIVATE (manager); -+ -+ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); -+ if (bus == NULL) { -+ g_warning ("Failed to connect to system bus: %s", -+ error->message); -+ g_error_free (error); -+ return; -+ } -+ -+ manager->priv->logind_proxy = -+ g_dbus_proxy_new_sync (bus, -+ 0, -+ NULL, -+ SYSTEMD_DBUS_NAME, -+ SYSTEMD_DBUS_PATH, -+ SYSTEMD_DBUS_INTERFACE, -+ NULL, -+ &error); -+ -+ if (manager->priv->logind_proxy == NULL) { -+ g_warning ("Failed to connect to systemd: %s", -+ error->message); -+ g_error_free (error); -+ } -+ -+ g_object_unref (bus); -+ -+ g_debug ("Adding system inhibitors for power keys"); -+ manager->priv->inhibit_keys_fd = -1; -+ g_dbus_proxy_call_with_unix_fd_list (manager->priv->logind_proxy, -+ "Inhibit", -+ g_variant_new ("(ssss)", -+ "handle-power-key:handle-suspend-key:handle-hibernate-key", -+ g_get_user_name (), -+ "Cinnamon handling keypresses", -+ "block"), -+ 0, -+ G_MAXINT, -+ NULL, -+ NULL, -+ inhibit_done, -+ manager); -+ - } - - static void -@@ -2375,6 +2465,8 @@ csd_media_keys_manager_finalize (GObject *object) - - if (media_keys_manager->priv->start_idle_id != 0) - g_source_remove (media_keys_manager->priv->start_idle_id); -+ if (media_keys_manager->priv->inhibit_keys_fd != -1) -+ close (media_keys_manager->priv->inhibit_keys_fd); - - G_OBJECT_CLASS (csd_media_keys_manager_parent_class)->finalize (object); - } -diff --git a/plugins/power/csd-power-manager.c b/plugins/power/csd-power-manager.c -index b54cb5b..b9c5429 100644 ---- a/plugins/power/csd-power-manager.c -+++ b/plugins/power/csd-power-manager.c -@@ -32,6 +32,7 @@ - #include <libupower-glib/upower.h> - #include <libnotify/notify.h> - #include <canberra-gtk.h> -+#include <gio/gunixfdlist.h> - - #include <X11/extensions/dpms.h> - -@@ -79,6 +80,10 @@ - #define CSD_POWER_MANAGER_CRITICAL_ALERT_TIMEOUT 5 /* seconds */ - #define CSD_POWER_MANAGER_LID_CLOSE_SAFETY_TIMEOUT 30 /* seconds */ - -+#define SYSTEMD_DBUS_NAME "org.freedesktop.login1" -+#define SYSTEMD_DBUS_PATH "/org/freedesktop/login1" -+#define SYSTEMD_DBUS_INTERFACE "org.freedesktop.login1.Manager" -+ - /* Keep this in sync with gnome-shell */ - #define SCREENSAVER_FADE_TIME 10 /* seconds */ - -@@ -203,6 +208,13 @@ struct CsdPowerManagerPrivate - GtkStatusIcon *status_icon; - guint xscreensaver_watchdog_timer_id; - gboolean is_virtual_machine; -+ -+ /* systemd stuff */ -+ GDBusProxy *logind_proxy; -+ gint inhibit_lid_switch_fd; -+ gboolean inhibit_lid_switch_taken; -+ gint inhibit_suspend_fd; -+ gboolean inhibit_suspend_taken; - }; - - enum { -@@ -3350,30 +3362,6 @@ lock_screensaver (CsdPowerManager *manager) - if (!do_lock) - return; - -- /* connect to the screensaver first */ -- g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, -- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, -- NULL, -- GS_DBUS_NAME, -- GS_DBUS_PATH, -- GS_DBUS_INTERFACE, -- NULL, -- sleep_cb_screensaver_proxy_ready_cb, -- manager); --} -- --static void --upower_notify_sleep_cb (UpClient *client, -- UpSleepKind sleep_kind, -- CsdPowerManager *manager) --{ -- gboolean do_lock; -- -- do_lock = g_settings_get_boolean (manager->priv->settings, -- "lock-on-suspend"); -- if (!do_lock) -- return; -- - /* connect to the screensaver first */ - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, -@@ -3384,46 +3372,6 @@ upower_notify_sleep_cb (UpClient *client, - NULL, - sleep_cb_screensaver_proxy_ready_cb, - manager); -- --} -- --static void --upower_notify_resume_cb (UpClient *client, -- UpSleepKind sleep_kind, -- CsdPowerManager *manager) --{ -- gboolean ret; -- GError *error = NULL; -- -- /* this displays the unlock dialogue so the user doesn't have -- * to move the mouse or press any key before the window comes up */ -- if (manager->priv->screensaver_proxy != NULL) { -- g_dbus_proxy_call (manager->priv->screensaver_proxy, -- "SimulateUserActivity", -- NULL, -- G_DBUS_CALL_FLAGS_NONE, -- -1, NULL, NULL, NULL); -- } -- -- if (manager->priv->screensaver_proxy != NULL) { -- g_object_unref (manager->priv->screensaver_proxy); -- manager->priv->screensaver_proxy = NULL; -- } -- -- /* close existing notifications on resume, the system power -- * state is probably different now */ -- notify_close_if_showing (manager->priv->notification_low); -- notify_close_if_showing (manager->priv->notification_discharging); -- -- /* ensure we turn the panel back on after resume */ -- ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen, -- GNOME_RR_DPMS_ON, -- &error); -- if (!ret) { -- g_warning ("failed to turn the panel on after resume: %s", -- error->message); -- g_error_free (error); -- } - } - - static void -@@ -3582,6 +3530,219 @@ disable_builtin_screensaver (gpointer unused) - return TRUE; - } - -+static void -+inhibit_lid_switch_done (GObject *source, -+ GAsyncResult *result, -+ gpointer user_data) -+{ -+ GDBusProxy *proxy = G_DBUS_PROXY (source); -+ CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); -+ GError *error = NULL; -+ GVariant *res; -+ GUnixFDList *fd_list = NULL; -+ gint idx; -+ -+ res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error); -+ if (res == NULL) { -+ g_warning ("Unable to inhibit lid switch: %s", error->message); -+ g_error_free (error); -+ } else { -+ g_variant_get (res, "(h)", &idx); -+ manager->priv->inhibit_lid_switch_fd = g_unix_fd_list_get (fd_list, idx, &error); -+ if (manager->priv->inhibit_lid_switch_fd == -1) { -+ g_warning ("Failed to receive system inhibitor fd: %s", error->message); -+ g_error_free (error); -+ } -+ g_debug ("System inhibitor fd is %d", manager->priv->inhibit_lid_switch_fd); -+ g_object_unref (fd_list); -+ g_variant_unref (res); -+ } -+} -+ -+static void -+inhibit_lid_switch (CsdPowerManager *manager) -+{ -+ GVariant *params; -+ -+ if (manager->priv->inhibit_lid_switch_taken) { -+ g_debug ("already inhibited lid-switch"); -+ return; -+ } -+ g_debug ("Adding lid switch system inhibitor"); -+ manager->priv->inhibit_lid_switch_taken = TRUE; -+ -+ params = g_variant_new ("(ssss)", -+ "handle-lid-switch", -+ g_get_user_name (), -+ "Multiple displays attached", -+ "block"); -+ g_dbus_proxy_call_with_unix_fd_list (manager->priv->logind_proxy, -+ "Inhibit", -+ params, -+ 0, -+ G_MAXINT, -+ NULL, -+ NULL, -+ inhibit_lid_switch_done, -+ manager); -+} -+ -+static void -+inhibit_suspend_done (GObject *source, -+ GAsyncResult *result, -+ gpointer user_data) -+{ -+ GDBusProxy *proxy = G_DBUS_PROXY (source); -+ CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); -+ GError *error = NULL; -+ GVariant *res; -+ GUnixFDList *fd_list = NULL; -+ gint idx; -+ -+ res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error); -+ if (res == NULL) { -+ g_warning ("Unable to inhibit suspend: %s", error->message); -+ g_error_free (error); -+ } else { -+ g_variant_get (res, "(h)", &idx); -+ manager->priv->inhibit_suspend_fd = g_unix_fd_list_get (fd_list, idx, &error); -+ if (manager->priv->inhibit_suspend_fd == -1) { -+ g_warning ("Failed to receive system inhibitor fd: %s", error->message); -+ g_error_free (error); -+ } -+ g_debug ("System inhibitor fd is %d", manager->priv->inhibit_suspend_fd); -+ g_object_unref (fd_list); -+ g_variant_unref (res); -+ } -+} -+ -+/* We take a delay inhibitor here, which causes logind to send a -+ * PrepareToSleep signal, which gives us a chance to lock the screen -+ * and do some other preparations. -+ */ -+static void -+inhibit_suspend (CsdPowerManager *manager) -+{ -+ if (manager->priv->inhibit_suspend_taken) { -+ g_debug ("already inhibited lid-switch"); -+ return; -+ } -+ g_debug ("Adding suspend delay inhibitor"); -+ manager->priv->inhibit_suspend_taken = TRUE; -+ g_dbus_proxy_call_with_unix_fd_list (manager->priv->logind_proxy, -+ "Inhibit", -+ g_variant_new ("(ssss)", -+ "sleep", -+ g_get_user_name (), -+ "Cinnamon needs to lock the screen", -+ "delay"), -+ 0, -+ G_MAXINT, -+ NULL, -+ NULL, -+ inhibit_suspend_done, -+ manager); -+} -+ -+static void -+uninhibit_suspend (CsdPowerManager *manager) -+{ -+ if (manager->priv->inhibit_suspend_fd == -1) { -+ g_debug ("no suspend delay inhibitor"); -+ return; -+ } -+ g_debug ("Removing suspend delay inhibitor"); -+ close (manager->priv->inhibit_suspend_fd); -+ manager->priv->inhibit_suspend_fd = -1; -+ manager->priv->inhibit_suspend_taken = FALSE; -+} -+ -+static void -+handle_suspend_actions (CsdPowerManager *manager) -+{ -+ gboolean do_lock; -+ -+ do_lock = g_settings_get_boolean (manager->priv->settings, -+ "lock-on-suspend"); -+ if (do_lock) -+ lock_screensaver (manager); -+ -+ /* lift the delay inhibit, so logind can proceed */ -+ uninhibit_suspend (manager); -+} -+ -+static void -+handle_resume_actions (CsdPowerManager *manager) -+{ -+ gboolean ret; -+ GError *error = NULL; -+ -+ /* this displays the unlock dialogue so the user doesn't have -+ * to move the mouse or press any key before the window comes up */ -+ g_dbus_connection_call (manager->priv->connection, -+ GS_DBUS_NAME, -+ GS_DBUS_PATH, -+ GS_DBUS_INTERFACE, -+ "SimulateUserActivity", -+ NULL, NULL, -+ G_DBUS_CALL_FLAGS_NONE, -1, -+ NULL, NULL, NULL); -+ -+ /* close existing notifications on resume, the system power -+ * state is probably different now */ -+ notify_close_if_showing (manager->priv->notification_low); -+ notify_close_if_showing (manager->priv->notification_discharging); -+ -+ /* ensure we turn the panel back on after resume */ -+ ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen, -+ GNOME_RR_DPMS_ON, -+ &error); -+ if (!ret) { -+ g_warning ("failed to turn the panel on after resume: %s", -+ error->message); -+ g_error_free (error); -+ } -+ -+ /* set up the delay again */ -+ inhibit_suspend (manager); -+} -+ -+static void -+upower_notify_sleep_cb (UpClient *client, -+ UpSleepKind sleep_kind, -+ CsdPowerManager *manager) -+{ -+ handle_suspend_actions (manager); -+} -+ -+static void -+upower_notify_resume_cb (UpClient *client, -+ UpSleepKind sleep_kind, -+ CsdPowerManager *manager) -+{ -+ handle_resume_actions (manager); -+} -+ -+static void -+logind_proxy_signal_cb (GDBusProxy *proxy, -+ const gchar *sender_name, -+ const gchar *signal_name, -+ GVariant *parameters, -+ gpointer user_data) -+{ -+ CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); -+ gboolean is_about_to_suspend; -+ -+ if (g_strcmp0 (signal_name, "PrepareForSleep") != 0) -+ return; -+ g_variant_get (parameters, "(b)", &is_about_to_suspend); -+ if (is_about_to_suspend) { -+ handle_suspend_actions (manager); -+ } else { -+ handle_resume_actions (manager); -+ } -+} -+ - static gboolean - is_hardware_a_virtual_machine (void) - { -@@ -3647,6 +3808,26 @@ csd_power_manager_start (CsdPowerManager *manager, - if (manager->priv->x11_screen == NULL) - return FALSE; - -+ /* Set up the logind proxy */ -+ manager->priv->logind_proxy = -+ g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, -+ 0, -+ NULL, -+ SYSTEMD_DBUS_NAME, -+ SYSTEMD_DBUS_PATH, -+ SYSTEMD_DBUS_INTERFACE, -+ NULL, -+ error); -+ g_signal_connect (manager->priv->logind_proxy, "g-signal", -+ G_CALLBACK (logind_proxy_signal_cb), -+ manager); -+ -+ /* Set up a delay inhibitor to be informed about suspend attempts */ -+ inhibit_suspend (manager); -+ -+ /* Disable logind's lid handling while g-s-d is active */ -+ inhibit_lid_switch (manager); -+ - /* track the active session */ - manager->priv->session = cinnamon_settings_session_new (); - g_signal_connect (manager->priv->session, "notify::state", -@@ -3856,6 +4037,22 @@ csd_power_manager_stop (CsdPowerManager *manager) - manager->priv->up_client = NULL; - } - -+ if (manager->priv->inhibit_lid_switch_fd != -1) { -+ close (manager->priv->inhibit_lid_switch_fd); -+ manager->priv->inhibit_lid_switch_fd = -1; -+ manager->priv->inhibit_lid_switch_taken = FALSE; -+ } -+ if (manager->priv->inhibit_suspend_fd != -1) { -+ close (manager->priv->inhibit_suspend_fd); -+ manager->priv->inhibit_suspend_fd = -1; -+ manager->priv->inhibit_suspend_taken = FALSE; -+ } -+ -+ if (manager->priv->logind_proxy != NULL) { -+ g_object_unref (manager->priv->logind_proxy); -+ manager->priv->logind_proxy = NULL; -+ } -+ - if (manager->priv->x11_screen != NULL) { - g_object_unref (manager->priv->x11_screen); - manager->priv->x11_screen = NULL; -@@ -3928,6 +4125,8 @@ static void - csd_power_manager_init (CsdPowerManager *manager) - { - manager->priv = CSD_POWER_MANAGER_GET_PRIVATE (manager); -+ manager->priv->inhibit_lid_switch_fd = -1; -+ manager->priv->inhibit_suspend_fd = -1; - } - - static void diff --git a/pkgs/desktops/cinnamon/timeout.patch b/pkgs/desktops/cinnamon/timeout.patch deleted file mode 100644 index 59d1f9ab5f37..000000000000 --- a/pkgs/desktops/cinnamon/timeout.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff -u -r cinnamon-session-3.4.2/cinnamon-session/csm-session-fill.c cinnamon-session-3.4.2-timeout/cinnamon-session/csm-session-fill.c ---- cinnamon-session-3.4.2/cinnamon-session/csm-session-fill.c 2012-02-02 15:33:01.000000000 +0100 -+++ cinnamon-session-3.4.2-timeout/cinnamon-session/csm-session-fill.c 2012-06-10 02:39:46.184348462 +0200 -@@ -36,7 +36,7 @@ - #define CSM_KEYFILE_DEFAULT_PROVIDER_PREFIX "DefaultProvider" - - /* See https://bugzilla.gnome.org/show_bug.cgi?id=641992 for discussion */ --#define CSM_RUNNABLE_HELPER_TIMEOUT 3000 /* ms */ -+#define CSM_RUNNABLE_HELPER_TIMEOUT 10000 /* ms */ - - typedef void (*GsmFillHandleProvider) (const char *provides, - const char *default_provider, -diff -u -r cinnamon-session-3.4.2/tools/cinnamon-session-check-accelerated.c -cinnamon-session-3.4.2-timeout/tools/cinnamon-session-check-accelerated.c ---- cinnamon-session-3.4.2/tools/cinnamon-session-check-accelerated.c 2011-03-22 21:31:43.000000000 +0100 -+++ cinnamon-session-3.4.2-timeout/tools/cinnamon-session-check-accelerated.c 2012-06-10 02:42:08.013218006 +0200 -@@ -30,7 +30,7 @@ - #include <X11/Xatom.h> - - /* Wait up to this long for a running check to finish */ --#define PROPERTY_CHANGE_TIMEOUT 5000 -+#define PROPERTY_CHANGE_TIMEOUT 12000 - - /* Values used for the _GNOME_SESSION_ACCELERATED root window property */ - #define NO_ACCEL 0 - diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 8a07b7d2a98e..e839286b74a1 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -14491,25 +14491,6 @@ let ### DESKTOP ENVIRONMENTS - cinnamon = recurseIntoAttrs rec { - callPackage = newScope pkgs.cinnamon; - inherit (gnome3) gnome_common libgnomekbd gnome-menus zenity; - - muffin = callPackage ../desktops/cinnamon/muffin.nix { } ; - - cinnamon-control-center = callPackage ../desktops/cinnamon/cinnamon-control-center.nix{ }; - - cinnamon-settings-daemon = callPackage ../desktops/cinnamon/cinnamon-settings-daemon.nix{ }; - - cinnamon-session = callPackage ../desktops/cinnamon/cinnamon-session.nix{ } ; - - cinnamon-desktop = callPackage ../desktops/cinnamon/cinnamon-desktop.nix { }; - - cinnamon-translations = callPackage ../desktops/cinnamon/cinnamon-translations.nix { }; - - cjs = callPackage ../desktops/cinnamon/cjs.nix { }; - }; - clearlooks-phenix = callPackage ../misc/themes/gtk3/clearlooks-phenix { }; enlightenment = callPackage ../desktops/enlightenment { }; |