[Xfce4-commits] r30222 - in libxfce4ui/trunk: . libxfce4kbd-private libxfce4ui po

Nick Schermer nick at xfce.org
Wed Jul 8 19:31:05 CEST 2009


Author: nick
Date: 2009-07-08 17:31:05 +0000 (Wed, 08 Jul 2009)
New Revision: 30222

Added:
   libxfce4ui/trunk/libxfce4kbd-private/
   libxfce4ui/trunk/libxfce4kbd-private/Makefile.am
   libxfce4ui/trunk/libxfce4kbd-private/libxfce4kbd-private-2.pc.in
   libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcut-dialog.c
   libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcut-dialog.h
   libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-grabber.c
   libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-grabber.h
   libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-provider.c
   libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-provider.h
   libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts.c
   libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts.h
   libxfce4ui/trunk/libxfce4kbd-private/xfce4-keyboard-shortcuts.xml
Modified:
   libxfce4ui/trunk/AUTHORS
   libxfce4ui/trunk/Makefile.am
   libxfce4ui/trunk/configure.in.in
   libxfce4ui/trunk/libxfce4ui/Makefile.am
   libxfce4ui/trunk/libxfce4ui/libxfce4ui-1.pc.in
   libxfce4ui/trunk/po/POTFILES.in
Log:
Import libxfce4kbd library into 4ui.

Only file conflict is the xfconf xml defaults file,
but that is unavoidable for now.


Modified: libxfce4ui/trunk/AUTHORS
===================================================================
--- libxfce4ui/trunk/AUTHORS	2009-07-08 16:45:16 UTC (rev 30221)
+++ libxfce4ui/trunk/AUTHORS	2009-07-08 17:31:05 UTC (rev 30222)
@@ -1,5 +1,6 @@
 Benedikt Meurer <benny at xfce.org>
 Brian Tarricone <bjt23 at cornell.edu>
+Jannis Pohlmann <jannis at xfce.org>
 Jasper Huijsmans <jasper at xfce.org>
 Nick Schermer <nick at xfce.org>
 Olivier Fourdan <fourdan at xfce.org>

Modified: libxfce4ui/trunk/Makefile.am
===================================================================
--- libxfce4ui/trunk/Makefile.am	2009-07-08 16:45:16 UTC (rev 30221)
+++ libxfce4ui/trunk/Makefile.am	2009-07-08 17:31:05 UTC (rev 30222)
@@ -2,6 +2,7 @@
 
 SUBDIRS = \
 	libxfce4ui \
+	libxfce4kbd-private \
 	glade \
 	docs \
 	po
@@ -26,6 +27,7 @@
 	intltool-update
 
 DISTCHECK_CONFIGURE_FLAGS = \
-	--enable-gtk-doc
+	--enable-gtk-doc \
+	--disable-gladeui
 
 # vi:set ts=8 sw=8 noet ai nocindent syntax=automake:

Modified: libxfce4ui/trunk/configure.in.in
===================================================================
--- libxfce4ui/trunk/configure.in.in	2009-07-08 16:45:16 UTC (rev 30221)
+++ libxfce4ui/trunk/configure.in.in	2009-07-08 17:31:05 UTC (rev 30222)
@@ -16,6 +16,8 @@
 m4_define([libxfce4ui_version_tag], [svn])
 m4_define([libxfce4ui_version], [libxfce4ui_version_major().libxfce4ui_version_minor().libxfce4ui_version_micro()ifelse(libxfce4ui_version_nano(), [], [], [.libxfce4ui_version_nano()])ifelse(libxfce4ui_version_tag(), [svn], [libxfce4ui_version_tag()-libxfce4ui_version_build()], [libxfce4ui_version_tag()])])
 
+m4_define([libxfce4kbd_private_verinfo], [0:0:0])
+m4_define([libxfce4kbd_private_version_api], [2])
 
 dnl # DO NOT MODIFY ANYTHING BELOW THIS LINE, UNLESS YOU KNOW WHAT
 dnl # YOU ARE DOING.
@@ -72,11 +74,15 @@
 LIBXFCE4UI_VERSION_MAJOR=libxfce4ui_version_major()
 LIBXFCE4UI_VERSION_MINOR=libxfce4ui_version_minor()
 LIBXFCE4UI_VERSION_MICRO=libxfce4ui_version_micro()
+LIBXFCE4KBD_PRIVATE_VERINFO=libxfce4kbd_private_verinfo()
+LIBXFCE4KBD_PRIVATE_VERSION_API=libxfce4kbd_private_version_api()
 AC_SUBST([LIBXFCE4UI_VERINFO])
 AC_SUBST([LIBXFCE4UI_VERSION_API])
 AC_SUBST([LIBXFCE4UI_VERSION_MAJOR])
 AC_SUBST([LIBXFCE4UI_VERSION_MINOR])
 AC_SUBST([LIBXFCE4UI_VERSION_MICRO])
+AC_SUBST([LIBXFCE4KBD_PRIVATE_VERINFO])
+AC_SUBST([LIBXFCE4KBD_PRIVATE_VERSION_API])
 
 dnl ***************************************
 dnl *** Check for standard header files ***
@@ -115,6 +121,19 @@
                            [0.4], [startup-notification],
                            [startup notification library])
 
+dnl **************************************************
+dnl *** Check whether to build the keyboard libary ***
+dnl **************************************************
+AC_ARG_ENABLE([keyboard-library],
+              [AC_HELP_STRING([--disable-keyboard-library],
+                              [Do not compile the keyboard library needed by xfwm4 and xfce4-settings (default=enabled)])],
+              [enable_keyboard_library=$enableval], [enable_keyboard_library=yes])
+if test "x$enable_keyboard_library" = "xyes"; then
+  XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.6.0])
+fi
+AM_CONDITIONAL([ENABLE_KEYBOARD_LIBRARY], [test "x$enable_keyboard_library" = "xyes"])
+
+
 dnl *********************************************************
 dnl *** Optional support for the Glade Interface Designer ***
 dnl *********************************************************
@@ -268,6 +287,8 @@
 glade/icons/Makefile
 glade/icons/16x16/Makefile
 glade/icons/22x22/Makefile
+libxfce4kbd-private/libxfce4kbd-private-2.pc
+libxfce4kbd-private/Makefile
 libxfce4ui.spec
 libxfce4ui/libxfce4ui-1.pc
 libxfce4ui/libxfce4ui-config.h
@@ -290,6 +311,12 @@
 echo "* Glade Interface Designer:  no"
 fi
 echo
+if test x"$enable_keyboard_library" = x"yes"; then
+echo "* Keyboard library support:  yes"
+else
+echo "* Keyboard library support:  no"
+fi
+echo
 if test x"$LIBSTARTUP_NOTIFICATION_FOUND" = x"yes"; then
 echo "* Startup Notification:      yes"
 else

Added: libxfce4ui/trunk/libxfce4kbd-private/Makefile.am
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/Makefile.am	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/Makefile.am	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,71 @@
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
+
+if ENABLE_KEYBOARD_LIBRARY
+
+INCLUDES = \
+	-I$(top_builddir) \
+	-I$(top_srcdir) \
+	-DDATADIR=\"$(datadir)\" \
+	-DG_LOG_DOMAIN=\"libxfce4kbd-private\" \
+	-DPACKAGE_LOCALE_DIR=\"$(localedir)\" \
+	-DPREFIX=\"$(prefix)\" \
+	$(PLATFORM_CPPFLAGS)
+
+lib_LTLIBRARIES = libxfce4kbd-private-2.la
+
+libxfce4kbd_headers = \
+	xfce-shortcuts-provider.h \
+	xfce-shortcuts-grabber.h \
+	xfce-shortcut-dialog.h \
+	xfce-shortcuts.h
+
+libxfce4kbd_private_includedir = \
+	$(includedir)/xfce4/libxfce4kbd-private-$(LIBXFCE4KBD_PRIVATE_VERSION_API)/libxfce4kbd-private
+
+libxfce4kbd_private_include_HEADERS = \
+	$(libxfce4kbd_headers)
+
+libxfce4kbd_private_2_la_SOURCES = \
+	$(libxfce4kbd_headers) \
+  xfce-shortcuts-provider.c \
+	xfce-shortcuts-grabber.c \
+	xfce-shortcut-dialog.c \
+	xfce-shortcuts.c
+
+libxfce4kbd_private_2_la_CFLAGS = \
+	$(PLATFORM_CFLAGS) \
+	$(GLIB_CFLAGS)  \
+	$(GTK_CFLAGS) \
+	$(LIBX11_CFLAGS) \
+	$(LIBXFCE4UTIL_CFLAGS) \
+	$(XFCONF_CFLAGS)
+
+libxfce4kbd_private_2_la_LDFLAGS = \
+	-export-dynamic \
+	-version-info $(LIBXFCE4KBD_PRIVATE_VERINFO) \
+	-export-symbols-regex "^[^_].*" \
+	-no-undefined \
+	$(LIBX11_LDFLAGS)
+
+libxfce4kbd_private_2_la_LIBADD = \
+	$(top_builddir)/libxfce4ui/libxfce4ui-$(LIBXFCE4UI_VERSION_API).la \
+	$(PLATFORM_LDFLAGS) \
+	$(GLIB_LIBS) \
+	$(GTK_LIBS) \
+	$(LIBX11_LIBS) \
+	$(LIBXFCE4UTIL_LIBS) \
+	$(XFCONF_LIBS)
+
+settingsdir = $(sysconfdir)/xdg/xfce4/xfconf/xfce-perchannel-xml
+settings_DATA = xfce4-keyboard-shortcuts.xml
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libxfce4kbd-private-2.pc
+
+EXTRA_DIST = \
+	$(settings_DATA)
+
+# required for gtk-doc
+dist-hook: all
+
+endif # ENABLE_KEYBOARD_LIBRARY

Added: libxfce4ui/trunk/libxfce4kbd-private/libxfce4kbd-private-2.pc.in
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/libxfce4kbd-private-2.pc.in	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/libxfce4kbd-private-2.pc.in	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libxfce4kbd-private
+Description: Private Xfce library for shared code between xfwm4 and xfce4-settings
+Requires: gdk-2.0 gtk+-2.0 libxfce4util-1.0 libxfconf-0 libxfce4ui-1
+Version: @PACKAGE_VERSION@
+Libs: @LIBX11_LDFLAGS@ -L${libdir} -lxfce4kbd-private- at LIBXFCE4KBD_PRIVATE_VERSION_API@
+Cflags: @LIBX11_CFLAGS@ -I${includedir}/xfce4/libxfce4kbd-private- at LIBXFCE4KBD_PRIVATE_VERSION_API@

Added: libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcut-dialog.c
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcut-dialog.c	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcut-dialog.c	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,469 @@
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+
+#include <libxfce4kbd-private/xfce-shortcuts.h>
+#include <libxfce4kbd-private/xfce-shortcut-dialog.h>
+
+
+
+static void     xfce_shortcut_dialog_finalize         (GObject                 *object);
+static void     xfce_shortcut_dialog_create_contents  (XfceShortcutDialog      *dialog,
+                                                       const gchar             *provider,
+                                                       const gchar             *action_name,
+                                                       const gchar             *action);
+static gboolean xfce_shortcut_dialog_key_pressed      (XfceShortcutDialog      *dialog,
+                                                       GdkEventKey             *event);
+static gboolean xfce_shortcut_dialog_key_released     (XfceShortcutDialog      *dialog,
+                                                       GdkEventKey             *event);
+static gchar   *xfce_shortcut_dialog_shortcut_name    (XfceShortcutDialog      *dialog,
+                                                       guint                    keyval,
+                                                       guint                    modifiers);
+
+
+
+struct _XfceShortcutDialogClass
+{
+  XfceTitledDialogClass __parent__;
+
+  gboolean (*validate_shortcut) (XfceShortcutDialog *dialog,
+                                 const gchar        *shortcut,
+                                 gpointer            user_data);
+
+  gint validate_shortcut_signal;
+};
+
+struct _XfceShortcutDialog
+{
+  XfceTitledDialog __parent__;
+
+  GtkWidget *shortcut_label;
+
+  gchar     *action_name;
+  gchar     *action;
+  gchar     *shortcut;
+};
+
+
+
+G_DEFINE_TYPE (XfceShortcutDialog, xfce_shortcut_dialog, XFCE_TYPE_TITLED_DIALOG)
+
+
+
+/**
+ * Taken from GTK+ (_gtk_marshal_BOOLEAN__SRING). Credits go out to the
+ * GTK+ devs for this.
+ */
+static void
+marshal_BOOLEAN__STRING (GClosure     *closure,
+                         GValue       *return_value G_GNUC_UNUSED,
+                         guint         n_param_values,
+                         const GValue *param_values,
+                         gpointer      invocation_hint G_GNUC_UNUSED,
+                         gpointer      marshal_data)
+{
+  typedef gboolean (*GMarshalFunc_BOOLEAN__STRING) (gpointer data1,
+                                                    gpointer arg_1,
+                                                    gpointer data2);
+  register GMarshalFunc_BOOLEAN__STRING callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+  gboolean v_return;
+
+  g_return_if_fail (return_value != NULL);
+  g_return_if_fail (n_param_values == 2);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+
+  callback = (GMarshalFunc_BOOLEAN__STRING) (marshal_data ? marshal_data : cc->callback);
+
+  #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+  v_return = callback (data1, g_marshal_value_peek_string (param_values + 1), data2);
+
+  g_value_set_boolean (return_value, v_return);
+}
+
+
+
+
+static void
+xfce_shortcut_dialog_class_init (XfceShortcutDialogClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* Make sure to use the translations from libxfce4ui */
+  xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = xfce_shortcut_dialog_finalize;
+
+  klass->validate_shortcut = NULL;
+
+  /* Create 'validate-shortcut' signal */
+  klass->validate_shortcut_signal = g_signal_new ("validate-shortcut",
+                                                  G_TYPE_FROM_CLASS (klass),
+                                                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                                                  G_STRUCT_OFFSET (XfceShortcutDialogClass, validate_shortcut),
+                                                  NULL,
+                                                  NULL,
+                                                  marshal_BOOLEAN__STRING,
+                                                  G_TYPE_BOOLEAN,
+                                                  1,
+                                                  G_TYPE_STRING);
+}
+
+
+
+static void
+xfce_shortcut_dialog_init (XfceShortcutDialog *dialog)
+{
+  dialog->shortcut = NULL;
+}
+
+
+
+static void
+xfce_shortcut_dialog_finalize (GObject *object)
+{
+  XfceShortcutDialog *dialog = XFCE_SHORTCUT_DIALOG (object);
+
+  g_free (dialog->action_name);
+  g_free (dialog->action);
+  g_free (dialog->shortcut);
+
+  (*G_OBJECT_CLASS (xfce_shortcut_dialog_parent_class)->finalize) (object);
+}
+
+
+
+GtkWidget*
+xfce_shortcut_dialog_new (const gchar *provider,
+                          const gchar *action_name,
+                          const gchar *action)
+{
+  XfceShortcutDialog *dialog;
+
+  dialog = g_object_new (XFCE_TYPE_SHORTCUT_DIALOG, NULL);
+  dialog->action_name = g_strdup (action_name);
+  dialog->action = g_strdup (action);
+
+  xfce_shortcut_dialog_create_contents (dialog, provider, action_name, action);
+
+  return GTK_WIDGET (dialog);
+}
+
+
+
+static void
+xfce_shortcut_dialog_create_contents (XfceShortcutDialog *dialog,
+                                      const gchar        *provider,
+                                      const gchar        *action_name,
+                                      const gchar        *action)
+{
+  GtkWidget   *button;
+  GtkWidget   *table;
+  GtkWidget   *label;
+  const gchar *title;
+  const gchar *action_label;
+
+  if (g_utf8_collate (provider, "xfwm4") == 0)
+    {
+      title = _("Window Manager Action Shortcut");
+      action_label = _("Action:");
+    }
+  else if (g_utf8_collate (provider, "commands") == 0)
+    {
+      title = _("Command Shortcut");
+      action_label = _("Command:");
+    }
+  else
+    {
+      title = _("Shortcut");
+      action_label = _("Action:");
+    }
+
+  /* Set dialog title */
+  gtk_window_set_title (GTK_WINDOW (dialog), title);
+  gtk_window_set_icon_name (GTK_WINDOW (dialog), "input-keyboard");
+
+  /* Configure dialog */
+  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+
+  /* Create clear button for xfwm4 */
+  if (g_utf8_collate (provider, "xfwm4") == 0)
+    {
+      button = gtk_button_new_from_stock (GTK_STOCK_CLEAR);
+      gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_REJECT);
+      gtk_widget_show (button);
+    }
+
+  /* Create cancel button */
+  button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+  gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_CANCEL);
+  gtk_widget_show (button);
+
+  table = gtk_table_new (2, 2, FALSE);
+  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+  gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+  gtk_container_set_border_width (GTK_CONTAINER (table), 12);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), table);
+  gtk_widget_show (table);
+
+  label = gtk_label_new (action_label);
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+  gtk_widget_show (label);
+
+  label = gtk_label_new (action_name);
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 0, 1);
+  gtk_widget_show (label);
+
+  label = gtk_label_new (_("Shortcut:"));
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+  gtk_widget_show (label);
+
+  dialog->shortcut_label = gtk_label_new (NULL);
+  gtk_misc_set_alignment (GTK_MISC (dialog->shortcut_label), 0.0, 0.5);
+  gtk_table_attach_defaults (GTK_TABLE (table), dialog->shortcut_label, 1, 2, 1, 2);
+  gtk_widget_show (dialog->shortcut_label);
+
+  /* Connect to key release signal for determining the new shortcut */
+  g_signal_connect_swapped (dialog, "key-press-event", G_CALLBACK (xfce_shortcut_dialog_key_pressed), dialog);
+  g_signal_connect_swapped (dialog, "key-release-event", G_CALLBACK (xfce_shortcut_dialog_key_released), dialog);
+}
+
+
+
+gint
+xfce_shortcut_dialog_run (XfceShortcutDialog *dialog,
+                          GtkWidget          *parent)
+{
+  gint response = GTK_RESPONSE_CANCEL;
+
+  g_return_val_if_fail (XFCE_IS_SHORTCUT_DIALOG (dialog), GTK_RESPONSE_CANCEL);
+
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
+  gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+
+  /* Take control on the keyboard */
+  if (G_LIKELY (gdk_keyboard_grab (gtk_widget_get_root_window (GTK_WIDGET (dialog)), TRUE, GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS))
+    {
+      /* Run the dialog and wait for the user to enter a valid shortcut */
+      response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+      /* Clear shortcut if requested by the user */
+      if (G_UNLIKELY (response == GTK_RESPONSE_NO))
+        {
+          g_free (dialog->shortcut);
+          dialog->shortcut = g_strdup ("");
+        }
+
+      /* Release keyboard */
+      gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+    }
+  else
+    g_warning ("%s", _("Could not grab the keyboard."));
+
+  /* Return the response ID */
+  return response;
+}
+
+
+
+static gboolean
+xfce_shortcut_dialog_key_pressed (XfceShortcutDialog *dialog,
+                                  GdkEventKey        *event)
+{
+  gchar *text;
+  gchar *shortcut;
+
+  g_free (dialog->shortcut);
+
+  /* Determine and remember the current shortcut */
+  dialog->shortcut = xfce_shortcut_dialog_shortcut_name (dialog, event->keyval, event->state);
+
+  shortcut = g_markup_escape_text (dialog->shortcut, -1);
+  text = g_strdup_printf (_("<span size='large'><b>%s</b></span>"), shortcut);
+
+  gtk_label_set_markup (GTK_LABEL (dialog->shortcut_label), text);
+
+  g_free (text);
+  g_free (shortcut);
+
+  return FALSE;
+}
+
+
+
+static gboolean
+xfce_shortcut_dialog_key_released (XfceShortcutDialog *dialog,
+                                   GdkEventKey        *event)
+{
+  gboolean shortcut_accepted = FALSE;
+
+  /* Let 'validate-shortcut' listeners decide whether this shortcut is ok or not */
+  g_signal_emit_by_name (dialog, "validate-shortcut", dialog->shortcut, &shortcut_accepted);
+
+  /* Check if the shortcut was accepted */
+  if (G_LIKELY (shortcut_accepted))
+    {
+      /* Release keyboard */
+      gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+
+      /* Exit dialog with positive response */
+      gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+    }
+  else
+    {
+      /* Clear label */
+      gtk_label_set_markup (GTK_LABEL (dialog->shortcut_label), "");
+    }
+
+  return FALSE;
+}
+
+
+
+static gchar *
+xfce_shortcut_dialog_shortcut_name (XfceShortcutDialog *dialog,
+                                    guint               keyval,
+                                    guint               modifiers)
+{
+  XModifierKeymap *modmap;
+  Display         *display;
+  const KeySym    *keysyms;
+  KeyCode          keycode;
+  KeySym          *keymap;
+  gint             keysyms_per_keycode = 0;
+  gint             min_keycode = 0;
+  gint             max_keycode = 0;
+  gint             mask;
+  gint             i;
+  gint             j;
+
+  g_return_val_if_fail (XFCE_IS_SHORTCUT_DIALOG (dialog), NULL);
+
+  display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+
+  gdk_error_trap_push ();
+
+  XDisplayKeycodes (display, &min_keycode, &max_keycode);
+
+  keymap = XGetKeyboardMapping (display, min_keycode, max_keycode - min_keycode + 1, &keysyms_per_keycode);
+
+  if (G_LIKELY (keymap != NULL))
+    {
+      modmap = XGetModifierMapping (display);
+
+      if (G_LIKELY (modmap != NULL))
+        {
+          for (i = 0; i < 8 * modmap->max_keypermod; ++i)
+            {
+              keycode = modmap->modifiermap[i];
+
+              if (keycode == 0 || keycode < min_keycode || keycode > max_keycode)
+                continue;
+
+              keysyms = keymap + (keycode - min_keycode) * keysyms_per_keycode;
+              mask = 1 << (i / modmap->max_keypermod);
+
+              for (j = 0; j < keysyms_per_keycode; ++j)
+                {
+                  if (keysyms[j] == GDK_Super_L || keysyms[j] == GDK_Super_R)
+                    modifiers &= ~mask;
+
+#if 0
+                  if (keysyms[j] == GDK_Meta_L || keysyms[j] == GDK_Meta_R)
+                    modifiers &= ~mask;
+#endif
+
+                  if (keysyms[j] == GDK_Hyper_L || keysyms[j] == GDK_Hyper_R)
+                    modifiers &= ~mask;
+
+                  if (keysyms[j] == GDK_Scroll_Lock)
+                    modifiers &= ~mask;
+
+                  if (keysyms[j] == GDK_Num_Lock)
+                    modifiers &= ~mask;
+
+                  if (keysyms[j] == GDK_Caps_Lock)
+                    modifiers &= ~mask;
+                }
+            }
+
+          XFreeModifiermap (modmap);
+        }
+
+      XFree (keymap);
+    }
+
+  gdk_flush ();
+  gdk_error_trap_pop ();
+
+  return gtk_accelerator_name (keyval, modifiers);
+}
+
+
+
+const gchar*
+xfce_shortcut_dialog_get_shortcut (XfceShortcutDialog *dialog)
+{
+  g_return_val_if_fail (XFCE_IS_SHORTCUT_DIALOG (dialog), NULL);
+  return dialog->shortcut;
+}
+
+
+
+const gchar *
+xfce_shortcut_dialog_get_action (XfceShortcutDialog *dialog)
+{
+  g_return_val_if_fail (XFCE_IS_SHORTCUT_DIALOG (dialog), NULL);
+  return dialog->action;
+}
+
+
+
+const gchar *
+xfce_shortcut_dialog_get_action_name (XfceShortcutDialog *dialog)
+{
+  g_return_val_if_fail (XFCE_IS_SHORTCUT_DIALOG (dialog), NULL);
+  return dialog->action_name;
+}

Added: libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcut-dialog.h
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcut-dialog.h	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcut-dialog.h	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,53 @@
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __XFCE_SHORTCUT_DIALOG_H__
+#define __XFCE_SHORTCUT_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+#include <libxfce4kbd-private/xfce-shortcuts.h>
+
+G_BEGIN_DECLS
+
+typedef struct _XfceShortcutDialogClass XfceShortcutDialogClass;
+typedef struct _XfceShortcutDialog      XfceShortcutDialog;
+
+#define XFCE_TYPE_SHORTCUT_DIALOG            (xfce_shortcut_dialog_get_type ())
+#define XFCE_SHORTCUT_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_SHORTCUT_DIALOG, XfceShortcutDialog))
+#define XFCE_SHORTCUT_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_SHORTCUT_DIALOG, XfceShortcutDialogClass))
+#define XFCE_IS_SHORTCUT_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_SHORTCUT_DIALOG))
+#define XFCE_IS_SHORTCUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_SHORTCUT_DIALOG))
+#define XFCE_SHORTCUT_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_SHORTCUT_DIALOG, XfceShortcutDialogClass))
+
+GType        xfce_shortcut_dialog_get_type        (void) G_GNUC_CONST;
+
+GtkWidget   *xfce_shortcut_dialog_new             (const gchar        *provider,
+                                                   const gchar        *action_name,
+                                                   const gchar        *action) G_GNUC_MALLOC;
+gint         xfce_shortcut_dialog_run             (XfceShortcutDialog *dialog,
+                                                   GtkWidget          *parent);
+const gchar *xfce_shortcut_dialog_get_shortcut    (XfceShortcutDialog *dialog);
+const gchar *xfce_shortcut_dialog_get_action      (XfceShortcutDialog *action);
+const gchar *xfce_shortcut_dialog_get_action_name (XfceShortcutDialog *action);
+
+G_END_DECLS
+
+#endif /* !__XFCE_SHORTCUT_DIALOG_H__ */

Added: libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-grabber.c
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-grabber.c	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-grabber.c	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,662 @@
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <X11/Xlib.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <gtk/gtk.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include <libxfce4kbd-private/xfce-shortcuts-grabber.h>
+
+
+
+#define XFCE_SHORTCUTS_GRABBER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), XFCE_TYPE_SHORTCUTS_GRABBER, XfceShortcutsGrabberPrivate))
+
+
+
+#define MODIFIER_MASK (GDK_SHIFT_MASK | \
+                       GDK_CONTROL_MASK | \
+                       GDK_MOD1_MASK | \
+                       GDK_MOD2_MASK | \
+                       GDK_MOD3_MASK | \
+                       GDK_MOD4_MASK | \
+                       GDK_MOD5_MASK)
+
+#define IGNORE_MASK   (0x2000 | \
+                       GDK_LOCK_MASK | \
+                       GDK_HYPER_MASK | \
+                       GDK_SUPER_MASK | \
+                       GDK_META_MASK)
+
+
+
+/* Property identifiers */
+enum
+{
+  PROP_0,
+};
+
+
+
+/* Cache indices for modifiers */
+enum
+{
+  CACHE_SUPER,
+  CACHE_HYPER,
+  CACHE_META,
+  CACHE_CAPS_LOCK,
+  CACHE_NUM_LOCK,
+  CACHE_SCROLL_LOCK,
+  CACHE_LAST,
+};
+
+
+
+typedef struct _XfceKey XfceKey;
+
+
+
+static void            xfce_shortcuts_grabber_constructed      (GObject                   *object);
+static void            xfce_shortcuts_grabber_finalize         (GObject                   *object);
+static void            xfce_shortcuts_grabber_get_property     (GObject                   *object,
+                                                                guint                      prop_id,
+                                                                GValue                    *value,
+                                                                GParamSpec                *pspec);
+static void            xfce_shortcuts_grabber_set_property     (GObject                   *object,
+                                                                guint                      prop_id,
+                                                                const GValue              *value,
+                                                                GParamSpec                *pspec);
+static void            xfce_shortcuts_grabber_keys_changed     (GdkKeymap                 *keymap,
+                                                                XfceShortcutsGrabber      *grabber);
+static void            xfce_shortcuts_grabber_grab_all         (XfceShortcutsGrabber      *grabber);
+static void            xfce_shortcuts_grabber_ungrab_all       (XfceShortcutsGrabber      *grabber);
+static void            xfce_shortcuts_grabber_reload_modifiers (XfceShortcutsGrabber      *grabber);
+static void            xfce_shortcuts_grabber_parse_shortcut   (XfceShortcutsGrabber      *grabber,
+                                                                const gchar               *shortcut,
+                                                                guint                     *keycode,
+                                                                guint                     *modifiers);
+static void            xfce_shortcuts_grabber_grab             (XfceShortcutsGrabber      *grabber,
+                                                                XfceKey                   *key,
+                                                                gboolean                   grab);
+static guint           xfce_shortcuts_grabber_get_ignore_mask  (XfceShortcutsGrabber      *grabber);
+static GdkFilterReturn xfce_shortcuts_grabber_event_filter     (GdkXEvent                 *gdk_xevent,
+                                                                GdkEvent                  *event,
+                                                                XfceShortcutsGrabber      *grabber);
+
+
+
+struct _XfceShortcutsGrabberPrivate
+{
+  GHashTable *keys;
+  guint       modifiers[CACHE_LAST];
+};
+
+struct _XfceKey
+{
+  guint keycode;
+  guint modifiers;
+};
+
+
+
+G_DEFINE_TYPE (XfceShortcutsGrabber, xfce_shortcuts_grabber, G_TYPE_OBJECT)
+
+
+
+static void
+xfce_shortcuts_grabber_class_init (XfceShortcutsGrabberClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  g_type_class_add_private (klass, sizeof (XfceShortcutsGrabberPrivate));
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->constructed = xfce_shortcuts_grabber_constructed;
+  gobject_class->finalize = xfce_shortcuts_grabber_finalize;
+  gobject_class->get_property = xfce_shortcuts_grabber_get_property;
+  gobject_class->set_property = xfce_shortcuts_grabber_set_property;
+
+  g_signal_new ("shortcut-activated",
+                XFCE_TYPE_SHORTCUTS_GRABBER,
+                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                0,
+                NULL,
+                NULL,
+                g_cclosure_marshal_VOID__STRING,
+                G_TYPE_NONE,
+                1,
+                G_TYPE_STRING);
+}
+
+
+
+static void
+xfce_shortcuts_grabber_init (XfceShortcutsGrabber *grabber)
+{
+  grabber->priv = XFCE_SHORTCUTS_GRABBER_GET_PRIVATE (grabber);
+  grabber->priv->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+  xfce_shortcuts_grabber_reload_modifiers (grabber);
+}
+
+
+
+static void
+xfce_shortcuts_grabber_constructed (GObject *object)
+{
+  GdkDisplay *display;
+  GdkKeymap  *keymap;
+
+  XfceShortcutsGrabber *grabber = XFCE_SHORTCUTS_GRABBER (object);
+
+  keymap = gdk_keymap_get_default ();
+  g_signal_connect (keymap, "keys-changed", G_CALLBACK (xfce_shortcuts_grabber_keys_changed),
+                    grabber);
+
+  display = gdk_display_get_default ();
+
+  /* Flush events before adding the event filter */
+  XAllowEvents (GDK_DISPLAY_XDISPLAY (display), AsyncBoth, CurrentTime);
+
+  /* Add event filter */
+  gdk_window_add_filter (NULL, (GdkFilterFunc) xfce_shortcuts_grabber_event_filter, grabber);
+}
+
+
+
+static void
+xfce_shortcuts_grabber_finalize (GObject *object)
+{
+  XfceShortcutsGrabber *grabber = XFCE_SHORTCUTS_GRABBER (object);
+
+  xfce_shortcuts_grabber_ungrab_all (grabber);
+  g_hash_table_unref (grabber->priv->keys);
+
+  (*G_OBJECT_CLASS (xfce_shortcuts_grabber_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfce_shortcuts_grabber_get_property (GObject    *object,
+                                     guint       prop_id,
+                                     GValue     *value,
+                                     GParamSpec *pspec)
+{
+#if 0
+  XfceShortcutsGrabber *grabber = XFCE_SHORTCUTS_GRABBER (object);
+#endif
+
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+xfce_shortcuts_grabber_set_property (GObject      *object,
+                                     guint         prop_id,
+                                     const GValue *value,
+                                     GParamSpec   *pspec)
+{
+#if 0
+  XfceShortcutsGrabber *grabber = XFCE_SHORTCUTS_GRABBER (object);
+#endif
+
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+xfce_shortcuts_grabber_keys_changed (GdkKeymap            *keymap,
+                                     XfceShortcutsGrabber *grabber)
+{
+  g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber));
+
+  xfce_shortcuts_grabber_ungrab_all (grabber);
+  xfce_shortcuts_grabber_reload_modifiers (grabber);
+  xfce_shortcuts_grabber_grab_all (grabber);
+}
+
+
+
+static gboolean
+grab_key (const gchar          *shortcut,
+          XfceKey              *key,
+          XfceShortcutsGrabber *grabber)
+{
+  xfce_shortcuts_grabber_grab (grabber, key, TRUE);
+  return FALSE;
+}
+
+
+
+static void
+xfce_shortcuts_grabber_grab_all (XfceShortcutsGrabber *grabber)
+{
+  g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber));
+  g_hash_table_foreach (grabber->priv->keys, (GHFunc) grab_key, grabber);
+}
+
+
+
+static gboolean
+ungrab_key (const gchar          *shortcut,
+            XfceKey              *key,
+            XfceShortcutsGrabber *grabber)
+{
+  xfce_shortcuts_grabber_grab (grabber, key, FALSE);
+  return FALSE;
+}
+
+
+
+static void
+xfce_shortcuts_grabber_ungrab_all (XfceShortcutsGrabber *grabber)
+{
+  g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber));
+  g_hash_table_foreach (grabber->priv->keys, (GHFunc) ungrab_key, grabber);
+}
+
+
+
+static void
+xfce_shortcuts_grabber_reload_modifiers (XfceShortcutsGrabber *grabber)
+{
+  XModifierKeymap *modmap;
+  const KeySym    *keysyms;
+  Display         *display;
+  KeyCode          keycode;
+  KeySym          *keymap;
+  gint             keysyms_per_keycode = 0;
+  gint             min_keycode = 0;
+  gint             max_keycode = 0;
+  gint             mask;
+  gint             i;
+  gint             j;
+
+  g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber));
+
+  for (i = 0; i < CACHE_LAST; ++i)
+    grabber->priv->modifiers[i] = 0;
+
+  display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+
+  gdk_error_trap_push ();
+
+  XDisplayKeycodes (display, &min_keycode, &max_keycode);
+
+  keymap = XGetKeyboardMapping (display, min_keycode, max_keycode - min_keycode + 1,
+                                &keysyms_per_keycode);
+
+  if (G_UNLIKELY (keymap == NULL))
+    return;
+
+  modmap = XGetModifierMapping (display);
+
+  if (G_UNLIKELY (modmap == NULL))
+    {
+      XFree (keymap);
+      return;
+    }
+
+  for (i = 0; i < 8 * modmap->max_keypermod; ++i)
+    {
+      keycode = modmap->modifiermap[i];
+
+      if (keycode == 0 || keycode < min_keycode || keycode > max_keycode)
+        continue;
+
+      keysyms = keymap + (keycode - min_keycode) * keysyms_per_keycode;
+      mask = 1 << (i / modmap->max_keypermod);
+
+      for (j = 0; j < keysyms_per_keycode; ++j)
+        {
+          if (keysyms[j] == GDK_Super_L || keysyms[j] == GDK_Super_R)
+            grabber->priv->modifiers[CACHE_SUPER] = mask;
+
+          if (keysyms[j] == GDK_Meta_L || keysyms[j] == GDK_Meta_R)
+            grabber->priv->modifiers[CACHE_META] = mask;
+
+          if (keysyms[j] == GDK_Hyper_L || keysyms[j] == GDK_Hyper_R)
+            grabber->priv->modifiers[CACHE_HYPER] = mask;
+
+          if (keysyms[j] == GDK_Scroll_Lock)
+            grabber->priv->modifiers[CACHE_SCROLL_LOCK] = mask;
+
+          if (keysyms[j] == GDK_Num_Lock)
+            grabber->priv->modifiers[CACHE_NUM_LOCK] = mask;
+
+          if (keysyms[j] == GDK_Caps_Lock)
+            grabber->priv->modifiers[CACHE_CAPS_LOCK] = mask;
+        }
+    }
+
+  XFreeModifiermap (modmap);
+  XFree (keymap);
+
+  gdk_flush ();
+  gdk_error_trap_pop ();
+}
+
+
+
+static void
+xfce_shortcuts_grabber_parse_shortcut (XfceShortcutsGrabber *grabber,
+                                       const gchar          *shortcut,
+                                       guint                *keycode,
+                                       guint                *modifiers)
+{
+  guint keyval;
+
+  g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber));
+
+  gtk_accelerator_parse (shortcut, &keyval, modifiers);
+
+  *keycode = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), keyval);
+
+  if ((*modifiers & GDK_SUPER_MASK) == GDK_SUPER_MASK)
+    {
+      *modifiers |= grabber->priv->modifiers[CACHE_SUPER];
+      *modifiers ^= GDK_SUPER_MASK;
+    }
+
+  if ((*modifiers & GDK_HYPER_MASK) == GDK_HYPER_MASK)
+    {
+      *modifiers |= grabber->priv->modifiers[CACHE_HYPER];
+      *modifiers ^= GDK_HYPER_MASK;
+    }
+
+  if ((*modifiers & GDK_META_MASK) == GDK_META_MASK)
+    {
+      *modifiers |= grabber->priv->modifiers[CACHE_META];
+      *modifiers ^= GDK_META_MASK;
+    }
+
+  *modifiers &= MODIFIER_MASK;
+  *modifiers &= ~xfce_shortcuts_grabber_get_ignore_mask (grabber);
+}
+
+
+
+gchar *
+xfce_shortcuts_grabber_shortcut_name (XfceShortcutsGrabber *grabber,
+                                      guint                 keycode,
+                                      guint                 modifiers)
+{
+  Display *display;
+  KeySym   keysym;
+
+  g_return_val_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber), NULL);
+
+  display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+  keysym = XKeycodeToKeysym (display, keycode, 0);
+
+  modifiers &= MODIFIER_MASK;
+  modifiers &= ~xfce_shortcuts_grabber_get_ignore_mask (grabber);
+
+  if ((modifiers & grabber->priv->modifiers[CACHE_SUPER]) != 0)
+    {
+      modifiers |= GDK_SUPER_MASK;
+      modifiers ^= grabber->priv->modifiers[CACHE_SUPER];
+    }
+
+  if ((modifiers & grabber->priv->modifiers[CACHE_HYPER]) != 0)
+    {
+      modifiers |= GDK_HYPER_MASK;
+      modifiers ^= grabber->priv->modifiers[CACHE_HYPER];
+    }
+
+#if 0
+  if ((modifiers & grabber->priv->modifiers[CACHE_META]) != 0)
+    {
+      modifiers |= GDK_META_MASK;
+      modifiers ^= grabber->priv->modifiers[CACHE_META];
+    }
+#endif
+
+  return gtk_accelerator_name (keysym, modifiers);
+}
+
+
+
+static void
+xfce_shortcuts_grabber_grab (XfceShortcutsGrabber *grabber,
+                             XfceKey              *key,
+                             gboolean              grab)
+{
+  GdkDisplay *display;
+  GdkScreen  *screen;
+  Window      window;
+  guint       bits[32];
+  guint       current_mask;
+  guint       n_bits;
+  guint       screens;
+  guint       modifiers;
+  guint       ignored_modifiers = 0;
+  gint        i;
+  guint       j;
+  guint       k;
+
+  g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber));
+  g_return_if_fail (key != NULL);
+
+  display = gdk_display_get_default ();
+  screens = gdk_display_get_n_screens (display);
+
+  ignored_modifiers = xfce_shortcuts_grabber_get_ignore_mask (grabber);
+
+  modifiers = key->modifiers & MODIFIER_MASK & ~ignored_modifiers;
+
+  /* Store indices of all the set bits of the ignore mask in an array */
+  for (i = 0, n_bits = 0; i < 32; ++i, ignored_modifiers >>= 1)
+    if ((ignored_modifiers & 0x1) == 0x1)
+      bits[n_bits++] = i;
+
+  for (i = 0; i < (1 << n_bits); ++i)
+    {
+      /* Map bits in the counter to those in the mask and thereby retrieve all ignored bit
+       * mask combinations */
+      for (current_mask = 0, j = 0; j < n_bits; ++j)
+        if ((i & (1 << j)) != 0)
+          current_mask |= (1 << bits[j]);
+
+      /* Grab key on all screens */
+      for (k = 0; k < screens; ++k)
+        {
+          /* Get current screen and X root window */
+          screen = gdk_display_get_screen (display, k);
+          window = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
+
+          gdk_error_trap_push ();
+
+          if (grab)
+            {
+              XGrabKey (GDK_DISPLAY_XDISPLAY (display), key->keycode, current_mask | modifiers,
+                        window, FALSE, GrabModeAsync, GrabModeAsync);
+            }
+          else
+            XUngrabKey (GDK_DISPLAY_XDISPLAY (display), key->keycode, current_mask | modifiers,
+                        window);
+
+          gdk_flush ();
+          gdk_error_trap_pop ();
+        }
+    }
+}
+
+
+
+static guint
+xfce_shortcuts_grabber_get_ignore_mask (XfceShortcutsGrabber *grabber)
+{
+  guint mask = 0;
+
+  g_return_val_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber), 0);
+
+  mask |= 0x200 | GDK_LOCK_MASK | GDK_HYPER_MASK | GDK_SUPER_MASK | GDK_META_MASK;
+  mask |= grabber->priv->modifiers[CACHE_CAPS_LOCK];
+  mask |= grabber->priv->modifiers[CACHE_NUM_LOCK];
+  mask |= grabber->priv->modifiers[CACHE_SCROLL_LOCK];
+
+  return mask;
+}
+
+
+
+struct EventKeyFindContext
+{
+  XfceShortcutsGrabber *grabber;
+  XKeyEvent            *xevent;
+  const gchar          *result;
+};
+
+
+
+static gboolean
+find_event_key (const gchar                *shortcut,
+                XfceKey                    *key,
+                struct EventKeyFindContext *context)
+{
+  gchar   *name;
+  gboolean result = FALSE;
+
+  g_return_val_if_fail (context != NULL, TRUE);
+  g_return_val_if_fail (context->xevent != NULL, TRUE);
+
+  gdk_error_trap_push ();
+
+  name = xfce_shortcuts_grabber_shortcut_name (context->grabber, context->xevent->keycode,
+                                               context->xevent->state);
+
+  if (G_UNLIKELY (g_str_equal (shortcut, name)))
+    {
+      context->result = shortcut;
+      result = TRUE;
+    }
+
+  g_free (name);
+
+  gdk_flush ();
+  gdk_error_trap_pop ();
+
+  return result;
+}
+
+
+
+static GdkFilterReturn
+xfce_shortcuts_grabber_event_filter (GdkXEvent            *gdk_xevent,
+                                     GdkEvent             *event,
+                                     XfceShortcutsGrabber *grabber)
+{
+  struct EventKeyFindContext context;
+  XEvent                    *xevent;
+
+  g_return_val_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber), GDK_FILTER_CONTINUE);
+
+  xevent = (XEvent *) gdk_xevent;
+
+  if (xevent->type != KeyPress)
+    return GDK_FILTER_CONTINUE;
+
+  context.grabber = grabber;
+  context.xevent = (XKeyEvent *) xevent;
+  context.result = NULL;
+
+  g_hash_table_foreach (grabber->priv->keys, (GHFunc) find_event_key, &context);
+
+  if (G_LIKELY (context.result != NULL))
+    g_signal_emit_by_name (grabber, "shortcut-activated", context.result);
+
+  return GDK_FILTER_CONTINUE;
+}
+
+
+
+XfceShortcutsGrabber *
+xfce_shortcuts_grabber_new (void)
+{
+  return g_object_new (XFCE_TYPE_SHORTCUTS_GRABBER, NULL);
+}
+
+
+
+void
+xfce_shortcuts_grabber_add (XfceShortcutsGrabber *grabber,
+                            const gchar          *shortcut)
+{
+  XfceKey *key;
+
+  g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber));
+  g_return_if_fail (shortcut != NULL);
+
+  key = g_new0 (XfceKey, 1);
+
+  xfce_shortcuts_grabber_parse_shortcut (grabber, shortcut, &key->keycode, &key->modifiers);
+
+  if (G_LIKELY (key->keycode != 0))
+    {
+      xfce_shortcuts_grabber_grab (grabber, key, TRUE);
+      g_hash_table_insert (grabber->priv->keys, g_strdup (shortcut), key);
+    }
+}
+
+
+
+void
+xfce_shortcuts_grabber_remove (XfceShortcutsGrabber *grabber,
+                               const gchar          *shortcut)
+{
+  XfceKey *key;
+
+  g_return_if_fail (XFCE_IS_SHORTCUTS_GRABBER (grabber));
+  g_return_if_fail (shortcut != NULL);
+
+  key = g_hash_table_lookup (grabber->priv->keys, shortcut);
+
+  if (G_LIKELY (key != NULL))
+    {
+      xfce_shortcuts_grabber_grab (grabber, key, FALSE);
+      g_hash_table_remove (grabber->priv->keys, shortcut);
+    }
+}

Added: libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-grabber.h
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-grabber.h	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-grabber.h	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,66 @@
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __XFCE_SHORTCUTS_GRABBER_H__
+#define __XFCE_SHORTCUTS_GRABBER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _XfceShortcutsGrabberPrivate XfceShortcutsGrabberPrivate;
+typedef struct _XfceShortcutsGrabberClass   XfceShortcutsGrabberClass;
+typedef struct _XfceShortcutsGrabber        XfceShortcutsGrabber;
+
+#define XFCE_TYPE_SHORTCUTS_GRABBER            (xfce_shortcuts_grabber_get_type ())
+#define XFCE_SHORTCUTS_GRABBER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_SHORTCUTS_GRABBER, XfceShortcutsGrabber))
+#define XFCE_SHORTCUTS_GRABBER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_SHORTCUTS_GRABBER, XfceShortcutsGrabberClass))
+#define XFCE_IS_SHORTCUTS_GRABBER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_SHORTCUTS_GRABBER))
+#define XFCE_IS_SHORTCUTS_GRABBER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_SHORTCUTS_GRABBER)
+#define XFCE_SHORTCUTS_GRABBER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_SHORTCUTS_GRABBER, XfceShortcutsGrabberClass))
+
+GType                 xfce_shortcuts_grabber_get_type      (void) G_GNUC_CONST;
+
+XfceShortcutsGrabber *xfce_shortcuts_grabber_new           (void) G_GNUC_MALLOC;
+gchar                *xfce_shortcuts_grabber_shortcut_name (XfceShortcutsGrabber *grabber,
+                                                            guint                 keycode,
+                                                            guint                 modifiers);
+void                  xfce_shortcuts_grabber_add           (XfceShortcutsGrabber *grabber,
+                                                            const gchar          *shortcut);
+void                  xfce_shortcuts_grabber_remove        (XfceShortcutsGrabber *grabber,
+                                                            const gchar          *shortcut);
+
+
+
+struct _XfceShortcutsGrabberClass
+{
+  GObjectClass __parent__;
+};
+
+struct _XfceShortcutsGrabber
+{
+  GObject __parent__;
+
+  XfceShortcutsGrabberPrivate *priv;
+};
+
+G_END_DECLS
+
+#endif /* !__XFCE_SHORTCUTS_GRABBER_H__ */

Added: libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-provider.c
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-provider.c	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-provider.c	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,636 @@
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <xfconf/xfconf.h>
+
+#include <libxfce4kbd-private/xfce-shortcuts-provider.h>
+
+
+
+#define XFCE_SHORTCUTS_PROVIDER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+    XFCE_TYPE_SHORTCUTS_PROVIDER, XfceShortcutsProviderPrivate))
+
+
+
+/* Property identifiers */
+enum
+{
+  PROP_0,
+  PROP_NAME,
+};
+
+
+
+typedef struct _XfceShortcutsProviderContext XfceShortcutsProviderContext;
+
+
+
+static void xfce_shortcuts_provider_constructed      (GObject                    *object);
+static void xfce_shortcuts_provider_finalize         (GObject                    *object);
+static void xfce_shortcuts_provider_get_property     (GObject                    *object,
+                                                      guint                       prop_id,
+                                                      GValue                     *value,
+                                                      GParamSpec                 *pspec);
+static void xfce_shortcuts_provider_set_property     (GObject                    *object,
+                                                      guint                       prop_id,
+                                                      const GValue               *value,
+                                                      GParamSpec                 *pspec);
+static void xfce_shortcuts_provider_register         (XfceShortcutsProvider      *provider);
+static void xfce_shortcuts_provider_property_changed (XfconfChannel              *channel,
+                                                      gchar                      *property,
+                                                      GValue                     *value,
+                                                      XfceShortcutsProvider      *provider);
+
+
+
+struct _XfceShortcutsProviderPrivate
+{
+  XfconfChannel *channel;
+  gchar         *name;
+  gchar         *default_base_property;
+  gchar         *custom_base_property;
+};
+
+struct _XfceShortcutsProviderContext
+{
+  XfceShortcutsProvider *provider;
+  GList                 *list;
+  const gchar           *base_property;
+};
+
+
+
+G_DEFINE_TYPE (XfceShortcutsProvider, xfce_shortcuts_provider, G_TYPE_OBJECT)
+
+
+
+static void
+xfce_shortcuts_provider_class_init (XfceShortcutsProviderClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  g_type_class_add_private (klass, sizeof (XfceShortcutsProviderPrivate));
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->constructed = xfce_shortcuts_provider_constructed;
+  gobject_class->finalize = xfce_shortcuts_provider_finalize;
+  gobject_class->get_property = xfce_shortcuts_provider_get_property;
+  gobject_class->set_property = xfce_shortcuts_provider_set_property;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_NAME,
+                                   g_param_spec_string ("name",
+                                                        "name",
+                                                        "name",
+                                                        NULL,
+                                                        G_PARAM_READWRITE
+                                                        | G_PARAM_CONSTRUCT_ONLY
+                                                        | G_PARAM_STATIC_STRINGS));
+
+  g_signal_new ("shortcut-removed",
+                XFCE_TYPE_SHORTCUTS_PROVIDER,
+                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                0,
+                NULL,
+                NULL,
+                g_cclosure_marshal_VOID__STRING,
+                G_TYPE_NONE,
+                1,
+                G_TYPE_STRING);
+
+  g_signal_new ("shortcut-added",
+                XFCE_TYPE_SHORTCUTS_PROVIDER,
+                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                0,
+                NULL,
+                NULL,
+                g_cclosure_marshal_VOID__STRING,
+                G_TYPE_NONE,
+                1,
+                G_TYPE_STRING);
+}
+
+
+
+static void
+xfce_shortcuts_provider_init (XfceShortcutsProvider *provider)
+{
+  provider->priv = XFCE_SHORTCUTS_PROVIDER_GET_PRIVATE (provider);
+
+  provider->priv->channel = xfconf_channel_new ("xfce4-keyboard-shortcuts");
+
+  g_signal_connect (provider->priv->channel, "property-changed",
+                    G_CALLBACK (xfce_shortcuts_provider_property_changed), provider);
+}
+
+
+
+static void
+xfce_shortcuts_provider_constructed (GObject *object)
+{
+  XfceShortcutsProvider *provider = XFCE_SHORTCUTS_PROVIDER (object);
+
+  xfce_shortcuts_provider_register (provider);
+
+  provider->priv->default_base_property = g_strdup_printf ("/%s/default", provider->priv->name);
+  provider->priv->custom_base_property = g_strdup_printf ("/%s/custom", provider->priv->name);
+
+  if (!xfce_shortcuts_provider_is_custom (provider))
+    xfce_shortcuts_provider_reset_to_defaults (provider);
+}
+
+
+
+static void
+xfce_shortcuts_provider_finalize (GObject *object)
+{
+  XfceShortcutsProvider *provider = XFCE_SHORTCUTS_PROVIDER (object);
+
+  g_free (provider->priv->name);
+  g_free (provider->priv->custom_base_property);
+  g_free (provider->priv->default_base_property);
+
+  g_object_unref (provider->priv->channel);
+
+  (*G_OBJECT_CLASS (xfce_shortcuts_provider_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfce_shortcuts_provider_get_property (GObject    *object,
+                                      guint       prop_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  XfceShortcutsProvider *provider = XFCE_SHORTCUTS_PROVIDER (object);
+
+  switch (prop_id)
+    {
+    case PROP_NAME:
+      g_value_set_string (value, provider->priv->name);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+xfce_shortcuts_provider_set_property (GObject      *object,
+                                      guint         prop_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+  XfceShortcutsProvider *provider = XFCE_SHORTCUTS_PROVIDER (object);
+
+  switch (prop_id)
+    {
+    case PROP_NAME:
+      g_free (provider->priv->name);
+      provider->priv->name = g_strdup (g_value_get_string (value));
+      g_object_notify (object, "name");
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+xfce_shortcuts_provider_register (XfceShortcutsProvider *provider)
+{
+  gchar       **provider_names;
+  const gchar **names;
+  gboolean      already_registered = FALSE;
+  gint          length;
+  gint          i;
+
+  g_return_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider));
+
+  provider_names = xfconf_channel_get_string_list (provider->priv->channel, "/providers");
+
+  for (i = 0; provider_names != NULL && provider_names[i] != NULL; ++i)
+    if (G_UNLIKELY (g_str_equal (provider_names[i], xfce_shortcuts_provider_get_name (provider))))
+      {
+        already_registered = TRUE;
+        break;
+      }
+
+  length = i;
+
+  if (G_UNLIKELY (!already_registered))
+    {
+      names = g_new0 (const gchar *, length + 1);
+      for (i = 0; provider_names != NULL && provider_names[i] != NULL; ++i)
+        names[i] = provider_names[i];
+      names[i++] = xfce_shortcuts_provider_get_name (provider);
+      names[i] = NULL;
+
+      xfconf_channel_set_string_list (provider->priv->channel, "/providers", names);
+
+      g_free (names);
+    }
+
+  g_strfreev (provider_names);
+}
+
+
+
+static void
+xfce_shortcuts_provider_property_changed (XfconfChannel         *channel,
+                                          gchar                 *property,
+                                          GValue                *value,
+                                          XfceShortcutsProvider *provider)
+{
+  const gchar *shortcut;
+  gchar       *override_property;
+
+  g_return_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider));
+
+  DBG ("property = %s", property);
+
+  if (!g_str_has_prefix (property, provider->priv->custom_base_property))
+    return;
+
+  override_property = g_strconcat (provider->priv->custom_base_property, "/override", NULL);
+
+  if (G_UNLIKELY (g_utf8_collate (property, override_property) == 0))
+    {
+      g_free (override_property);
+      return;
+    }
+  g_free (override_property);
+
+  shortcut = property + strlen (provider->priv->custom_base_property) + strlen ("/");
+
+  if (G_VALUE_TYPE (value) != G_TYPE_INVALID)
+    g_signal_emit_by_name (provider, "shortcut-added", shortcut);
+  else
+    g_signal_emit_by_name (provider, "shortcut-removed", shortcut);
+}
+
+
+
+XfceShortcutsProvider *
+xfce_shortcuts_provider_new (const gchar *name)
+{
+  return g_object_new (XFCE_TYPE_SHORTCUTS_PROVIDER, "name", name, NULL);
+}
+
+
+
+GList *
+xfce_shortcuts_provider_get_providers (void)
+{
+  GList         *providers = NULL;
+  XfconfChannel *channel;
+  gchar        **names;
+  gint           i;
+
+  channel = xfconf_channel_get ("xfce4-keyboard-shortcuts");
+  names = xfconf_channel_get_string_list (channel, "/providers");
+
+  if (G_LIKELY (names != NULL))
+    {
+      for (i = 0; names[i] != NULL; ++i)
+        providers = g_list_append (providers, xfce_shortcuts_provider_new (names[i]));
+      g_strfreev (names);
+    }
+
+  return providers;
+}
+
+
+
+void
+xfce_shortcuts_provider_free_providers (GList *providers)
+{
+  GList *iter;
+
+  for (iter = g_list_first (providers); iter != NULL; iter = g_list_next (iter))
+    g_object_unref (iter->data);
+
+  g_list_free (providers);
+}
+
+
+
+const gchar *
+xfce_shortcuts_provider_get_name (XfceShortcutsProvider *provider)
+{
+  g_return_val_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider), NULL);
+  return provider->priv->name;
+}
+
+
+
+gboolean
+xfce_shortcuts_provider_is_custom (XfceShortcutsProvider *provider)
+{
+  gchar   *property;
+  gboolean override;
+
+  g_return_val_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider), FALSE);
+  g_return_val_if_fail (XFCONF_IS_CHANNEL (provider->priv->channel), FALSE);
+
+  property = g_strconcat (provider->priv->custom_base_property, "/override", NULL);
+  override = xfconf_channel_get_bool (provider->priv->channel, property, FALSE);
+  g_free (property);
+
+  return override;
+}
+
+
+
+void
+xfce_shortcuts_provider_reset_to_defaults (XfceShortcutsProvider *provider)
+{
+  g_return_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider));
+  g_return_if_fail (XFCONF_IS_CHANNEL (provider->priv->channel));
+
+  DBG ("property = %s", provider->priv->custom_base_property);
+
+  xfconf_channel_reset_property (provider->priv->channel, provider->priv->custom_base_property, TRUE);
+  xfce_shortcuts_provider_clone_defaults (provider);
+}
+
+
+
+static gboolean
+_xfce_shortcuts_provider_clone_default (const gchar           *property,
+                                        const GValue          *value,
+                                        XfceShortcutsProvider *provider)
+{
+  const gchar *shortcut;
+  const gchar *command;
+  gchar       *custom_property;
+
+  g_return_val_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider), TRUE);
+  g_return_val_if_fail (XFCONF_IS_CHANNEL (provider->priv->channel), TRUE);
+
+  if (G_UNLIKELY (!G_IS_VALUE (value) || G_VALUE_TYPE (value) != G_TYPE_STRING))
+    return FALSE;
+
+  shortcut = property + strlen (provider->priv->default_base_property) + strlen ("/");
+  command = g_value_get_string (value);
+
+  DBG ("shortcut = %s, command = %s", shortcut, command);
+
+  custom_property = g_strconcat (provider->priv->custom_base_property, "/", shortcut, NULL);
+  xfconf_channel_set_string (provider->priv->channel, custom_property, command);
+  g_free (custom_property);
+
+  return FALSE;
+}
+
+
+
+void
+xfce_shortcuts_provider_clone_defaults (XfceShortcutsProvider *provider)
+{
+  GHashTable *properties;
+  gchar      *property;
+
+  g_return_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider));
+  g_return_if_fail (XFCONF_IS_CHANNEL (provider->priv->channel));
+
+  /* Get default command shortcuts */
+  properties = xfconf_channel_get_properties (provider->priv->channel, provider->priv->default_base_property);
+
+  if (G_LIKELY (properties != NULL))
+    {
+      /* Copy from /commands/default to /commands/custom property by property */
+      g_hash_table_foreach (properties, (GHFunc) _xfce_shortcuts_provider_clone_default, provider);
+
+      g_hash_table_destroy (properties);
+    }
+
+  DBG ("adding override property");
+
+  /* Add the override property */
+  property = g_strconcat (provider->priv->custom_base_property, "/override", NULL);
+  xfconf_channel_set_bool (provider->priv->channel, property, TRUE);
+  g_free (property);
+}
+
+
+
+static gboolean
+_xfce_shortcuts_provider_get_shortcut (const gchar                  *property,
+                                       const GValue                 *value,
+                                       XfceShortcutsProviderContext *context)
+{
+  XfceShortcut *sc;
+  const gchar  *shortcut;
+  const gchar  *command;
+
+  g_return_val_if_fail (context != NULL, TRUE);
+  g_return_val_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (context->provider), TRUE);
+
+  if (G_VALUE_TYPE (value) != G_TYPE_STRING)
+    return FALSE;
+
+  if (!g_str_has_prefix (property, context->provider->priv->custom_base_property))
+    return FALSE;
+
+  shortcut = property + strlen (context->provider->priv->custom_base_property) + strlen ("/");
+  command = g_value_get_string (value);
+
+  if (G_LIKELY (shortcut != NULL && command != NULL && g_utf8_strlen (shortcut, -1) > 0 && g_utf8_strlen (command, -1) > 0))
+    {
+      sc = g_slice_new0 (XfceShortcut);
+
+      sc->property_name = g_strdup (property);
+      sc->shortcut = g_strdup (shortcut);
+      sc->command = g_strdup (command);
+
+      context->list = g_list_append (context->list, sc);
+    }
+
+  return FALSE;
+}
+
+
+
+GList *
+xfce_shortcuts_provider_get_shortcuts (XfceShortcutsProvider *provider)
+{
+  XfceShortcutsProviderContext context;
+  GHashTable                  *properties;
+
+  g_return_val_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider), NULL);
+  g_return_val_if_fail (XFCONF_IS_CHANNEL (provider->priv->channel), NULL);
+
+  properties = xfconf_channel_get_properties (provider->priv->channel, provider->priv->custom_base_property);
+
+  context.provider = provider;
+  context.list = NULL;
+
+  if (G_LIKELY (properties != NULL))
+    g_hash_table_foreach (properties, (GHFunc) _xfce_shortcuts_provider_get_shortcut, &context);
+
+  return context.list;
+}
+
+
+
+XfceShortcut *
+xfce_shortcuts_provider_get_shortcut (XfceShortcutsProvider *provider,
+                                      const gchar           *shortcut)
+{
+  XfceShortcut *sc = NULL;
+  gchar        *base_property;
+  gchar        *property;
+  gchar        *command;
+
+  g_return_val_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider), NULL);
+  g_return_val_if_fail (XFCONF_IS_CHANNEL (provider->priv->channel), NULL);
+
+  if (G_LIKELY (xfce_shortcuts_provider_is_custom (provider)))
+    base_property = provider->priv->custom_base_property;
+  else
+    base_property = provider->priv->default_base_property;
+
+  property = g_strconcat (base_property, "/", shortcut, NULL);
+  command = xfconf_channel_get_string (provider->priv->channel, property, NULL);
+
+  if (G_LIKELY (command != NULL))
+    {
+      sc = g_slice_new0 (XfceShortcut);
+      sc->command = command;
+      sc->property_name = g_strdup (property);
+      sc->shortcut = g_strdup (shortcut);
+    }
+
+  g_free (property);
+
+  return sc;
+}
+
+
+
+gboolean
+xfce_shortcuts_provider_has_shortcut (XfceShortcutsProvider *provider,
+                                      const gchar           *shortcut)
+{
+  gchar   *base_property;
+  gchar   *property;
+  gboolean has_property;
+
+  g_return_val_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider), FALSE);
+  g_return_val_if_fail (XFCONF_IS_CHANNEL (provider->priv->channel), FALSE);
+
+  if (G_LIKELY (xfce_shortcuts_provider_is_custom (provider)))
+    base_property = provider->priv->custom_base_property;
+  else
+    base_property = provider->priv->default_base_property;
+
+  property = g_strconcat (base_property, "/", shortcut, NULL);
+  has_property = xfconf_channel_has_property (provider->priv->channel, property);
+  g_free (property);
+
+  return has_property;
+}
+
+
+
+void
+xfce_shortcuts_provider_set_shortcut (XfceShortcutsProvider *provider,
+                                      const gchar           *shortcut,
+                                      const gchar           *command)
+{
+  gchar *property;
+
+  g_return_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider));
+  g_return_if_fail (XFCONF_IS_CHANNEL (provider->priv->channel));
+  g_return_if_fail (shortcut != NULL && command != NULL);
+
+  /* Only allow custom shortcuts to be changed */
+  if (G_UNLIKELY (!xfce_shortcuts_provider_is_custom (provider)))
+    return;
+
+  property = g_strconcat (provider->priv->custom_base_property, "/", shortcut, NULL);
+
+  if (xfconf_channel_has_property (provider->priv->channel, property))
+    xfconf_channel_reset_property (provider->priv->channel, property, FALSE);
+
+  xfconf_channel_set_string (provider->priv->channel, property, command);
+
+  g_free (property);
+}
+
+
+
+void
+xfce_shortcuts_provider_reset_shortcut (XfceShortcutsProvider *provider,
+                                        const gchar           *shortcut)
+{
+  gchar *property;
+
+  g_return_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider));
+  g_return_if_fail (XFCONF_IS_CHANNEL (provider->priv->channel));
+  g_return_if_fail (shortcut != NULL);
+
+  property = g_strconcat (provider->priv->custom_base_property, "/", shortcut, NULL);
+
+  DBG ("property = %s", property);
+
+  xfconf_channel_reset_property (provider->priv->channel, property, FALSE);
+  g_free (property);
+}
+
+
+
+void
+xfce_shortcuts_free (GList *shortcuts)
+{
+  g_list_foreach (shortcuts, (GFunc) xfce_shortcut_free, NULL);
+}
+
+
+
+void
+xfce_shortcut_free (XfceShortcut *shortcut)
+{
+  if (G_UNLIKELY (shortcut == NULL))
+    return;
+
+  g_free (shortcut->property_name);
+  g_free (shortcut->shortcut);
+  g_free (shortcut->command);
+  g_slice_free (XfceShortcut, shortcut);
+}

Added: libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-provider.h
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-provider.h	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts-provider.h	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,87 @@
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __XFCE_SHORTCUTS_PROVIDER_H__
+#define __XFCE_SHORTCUTS_PROVIDER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _XfceShortcut                 XfceShortcut;
+
+typedef struct _XfceShortcutsProviderPrivate XfceShortcutsProviderPrivate;
+typedef struct _XfceShortcutsProviderClass   XfceShortcutsProviderClass;
+typedef struct _XfceShortcutsProvider        XfceShortcutsProvider;
+
+#define XFCE_TYPE_SHORTCUTS_PROVIDER            (xfce_shortcuts_provider_get_type ())
+#define XFCE_SHORTCUTS_PROVIDER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_SHORTCUTS_PROVIDER, XfceShortcutsProvider))
+#define XFCE_SHORTCUTS_PROVIDER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_SHORTCUTS_PROVIDER, XfceShortcutsProviderClass))
+#define XFCE_IS_SHORTCUTS_PROVIDER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_SHORTCUTS_PROVIDER))
+#define XFCE_IS_SHORTCUTS_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_SHORTCUTS_PROVIDER)
+#define XFCE_SHORTCUTS_PROVIDER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_SHORTCUTS_PROVIDER, XfceShortcutsProviderClass))
+
+GType xfce_shortcuts_provider_get_type (void) G_GNUC_CONST;
+
+XfceShortcutsProvider  *xfce_shortcuts_provider_new               (const gchar           *name) G_GNUC_MALLOC;
+GList                  *xfce_shortcuts_provider_get_providers     (void) G_GNUC_MALLOC;
+void                    xfce_shortcuts_provider_free_providers    (GList                 *providers);
+const gchar            *xfce_shortcuts_provider_get_name          (XfceShortcutsProvider *provider);
+gboolean                xfce_shortcuts_provider_is_custom         (XfceShortcutsProvider *provider);
+void                    xfce_shortcuts_provider_reset_to_defaults (XfceShortcutsProvider *provider);
+void                    xfce_shortcuts_provider_clone_defaults    (XfceShortcutsProvider *provider);
+GList                  *xfce_shortcuts_provider_get_shortcuts     (XfceShortcutsProvider *provider);
+XfceShortcut           *xfce_shortcuts_provider_get_shortcut      (XfceShortcutsProvider *provider,
+                                                                   const gchar           *shortcut);
+gboolean                xfce_shortcuts_provider_has_shortcut      (XfceShortcutsProvider *provider,
+                                                                   const gchar           *shortcut);
+void                    xfce_shortcuts_provider_set_shortcut      (XfceShortcutsProvider *provider,
+                                                                   const gchar           *shortcut,
+                                                                   const gchar           *command);
+void                    xfce_shortcuts_provider_reset_shortcut    (XfceShortcutsProvider *provider,
+                                                                   const gchar           *shortcut);
+
+void                    xfce_shortcuts_free                       (GList                 *shortcuts);
+void                    xfce_shortcut_free                        (XfceShortcut          *shortcut);
+
+
+
+struct _XfceShortcutsProviderClass
+{
+  GObjectClass __parent__;
+};
+
+struct _XfceShortcutsProvider
+{
+  GObject __parent__;
+
+  XfceShortcutsProviderPrivate *priv;
+};
+
+struct _XfceShortcut
+{
+  gchar *property_name;
+  gchar *shortcut;
+  gchar *command;
+};
+
+G_END_DECLS
+
+#endif /* !__XFCE_SHORTCUTS_PROVIDER_H__ */

Added: libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts.c
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts.c	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts.c	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,136 @@
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+
+#include <X11/Xlib.h>
+
+#include <gtk/gtk.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+#include <xfconf/xfconf.h>
+
+#include <libxfce4kbd-private/xfce-shortcuts.h>
+
+
+
+typedef struct
+{
+  const gchar *owner_name;
+  const gchar *other_name;
+  const gchar *message;
+  const gchar *owner_button_text;
+  const gchar *other_button_text;
+} XfceShortcutConflictMessage;
+
+
+
+static XfceShortcutConflictMessage conflict_messages[] = {
+  { "xfwm4", "xfwm4",
+    N_("This shortcut is already being used for another window manager action. Which action do you want to use?"),
+    N_("Use '%s'"), N_("Keep the other one") },
+  { "xfwm4", "commands",
+    N_("This shortcut is already being used for the command '%s'. Which action do you want to use?"),
+    N_("Use '%s'"), N_("Keep '%s'") },
+  { "commands","commands",
+    N_("This shortcut is already being used for the command '%s'. Which action do you want to use?"),
+    N_("Use '%s'"), N_("Keep '%s'") },
+  { "commands", "xfwm4",
+    N_("This shortcut is already being used by a window manager action. Which action do you want to use?"),
+    N_("Use '%s'"), N_("Keep the window manager action") },
+  { 0, 0, NULL, NULL, NULL },
+};
+
+
+
+gint
+xfce_shortcut_conflict_dialog (const gchar *owner,
+                               const gchar *other,
+                               const gchar *shortcut,
+                               const gchar *owner_action,
+                               const gchar *other_action,
+                               gboolean     ignore_same_provider)
+{
+  gchar   *title;
+  gchar   *secondary_text;
+  gchar   *owner_action_name;
+  gchar   *other_action_name;
+  gchar   *owner_button_text;
+  gchar   *other_button_text;
+  gboolean handled = FALSE;
+  gint     response = GTK_RESPONSE_ACCEPT;
+  gint     i;
+
+  /* Make sure to use the translations from libxfce4ui */
+  xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+  if (g_utf8_collate (owner, other) == 0 && ignore_same_provider)
+    return GTK_RESPONSE_ACCEPT;
+
+  if (g_utf8_collate (owner, other) == 0 && g_utf8_collate (owner_action, other_action) == 0)
+    return GTK_RESPONSE_ACCEPT;
+
+  title = g_strdup_printf (_("Conflicting actions for %s"), shortcut);
+
+  for (i = 0; conflict_messages[i].message != NULL; ++i)
+    if (g_utf8_collate (conflict_messages[i].owner_name, owner) == 0 &&
+        g_utf8_collate (conflict_messages[i].other_name, other) == 0)
+      {
+        owner_action_name = owner_action == NULL ? NULL : g_markup_escape_text (owner_action, -1);
+        other_action_name = other_action == NULL ? NULL : g_markup_escape_text (other_action, -1);
+
+        secondary_text = g_strdup_printf (_(conflict_messages[i].message), other_action_name);
+
+        owner_button_text = g_markup_printf_escaped (_(conflict_messages[i].owner_button_text), owner_action_name);
+        other_button_text = g_markup_printf_escaped (_(conflict_messages[i].other_button_text), other_action_name);
+
+        response = xfce_message_dialog (NULL, title, GTK_STOCK_DIALOG_QUESTION,
+                                        title, secondary_text,
+                                        XFCE_BUTTON_TYPE_MIXED, owner_button_text, GTK_RESPONSE_ACCEPT,
+                                        XFCE_BUTTON_TYPE_MIXED, other_button_text, GTK_RESPONSE_REJECT,
+                                        NULL);
+
+        g_free (other_button_text);
+        g_free (owner_button_text);
+        g_free (secondary_text);
+        g_free (other_action_name);
+        g_free (owner_action_name);
+
+        handled = TRUE;
+        break;
+      }
+
+  if (G_UNLIKELY (!handled))
+    {
+      xfce_message_dialog (NULL, title, GTK_STOCK_DIALOG_ERROR,
+                           title, _("This shortcut is already being used for something else."),
+                           GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
+      response = GTK_RESPONSE_REJECT;
+    }
+
+  g_free (title);
+
+  return response;
+}

Added: libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts.h
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts.h	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/xfce-shortcuts.h	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,38 @@
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __XFCE_SHORTCUTS_H__
+#define __XFCE_SHORTCUTS_H__
+
+#include <X11/Xlib.h>
+#include <xfconf/xfconf.h>
+
+G_BEGIN_DECLS
+
+gboolean xfce_shortcut_conflict_dialog (const gchar *owner,
+                                        const gchar *other,
+                                        const gchar *shortcut,
+                                        const gchar *owner_action,
+                                        const gchar *other_action,
+                                        gboolean     ignore_same_provider);
+
+G_END_DECLS
+
+#endif /* !__XFCE_SHORTCUTS_H__ */

Added: libxfce4ui/trunk/libxfce4kbd-private/xfce4-keyboard-shortcuts.xml
===================================================================
--- libxfce4ui/trunk/libxfce4kbd-private/xfce4-keyboard-shortcuts.xml	                        (rev 0)
+++ libxfce4ui/trunk/libxfce4kbd-private/xfce4-keyboard-shortcuts.xml	2009-07-08 17:31:05 UTC (rev 30222)
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<channel name="xfce4-keyboard-shortcuts" version="1.0">
+  <property name="commands" type="empty">
+    <property name="default" type="empty">
+      <property name="<Alt>F2" type="string" value="xfrun4"/>
+      <property name="<Control><Alt>Delete" type="string" value="xflock4"/>
+      <property name="XF86Display" type="string" value="xrandr --auto"/>
+    </property>
+  </property>
+  <property name="xfwm4" type="empty">
+    <property name="default" type="empty">
+      <property name="<Alt>Insert" type="string" value="add_workspace_key"/>
+      <property name="Escape" type="string" value="cancel_key"/>
+      <property name="Left" type="string" value="left_key"/>
+      <property name="Right" type="string" value="right_key"/>
+      <property name="Up" type="string" value="up_key"/>
+      <property name="Down" type="string" value="down_key"/>
+      <property name="<Alt>Tab" type="string" value="cycle_windows_key"/>
+      <property name="<Alt><Shift>Tab" type="string" value="cycle_reverse_windows_key"/>
+      <property name="<Alt>Delete" type="string" value="del_workspace_key"/>
+      <property name="<Control><Alt>Down" type="string" value="down_workspace_key"/>
+      <property name="<Control><Alt>Left" type="string" value="left_workspace_key"/>
+      <property name="<Shift><Alt>Page_Down" type="string" value="lower_window_key"/>
+      <property name="<Alt>F4" type="string" value="close_window_key"/>
+      <property name="<Alt>F6" type="string" value="stick_window_key"/>
+      <property name="<Alt>F7" type="string" value="move_window_key"/>
+      <property name="<Alt>F8" type="string" value="resize_window_key"/>
+      <property name="<Alt>F9" type="string" value="hide_window_key"/>
+      <property name="<Alt>F10" type="string" value="maximize_window_key"/>
+      <property name="<Alt>F11" type="string" value="fullscreen_key"/>
+      <property name="<Alt>F12" type="string" value="above_key"/>
+      <property name="<Control><Shift><Alt>Left" type="string" value="move_window_left_key"/>
+      <property name="<Alt><Control>End" type="string" value="move_window_next_workspace_key"/>
+      <property name="<Alt><Control>Home" type="string" value="move_window_prev_workspace_key"/>
+      <property name="<Control><Shift><Alt>Right" type="string" value="move_window_right_key"/>
+      <property name="<Control><Shift><Alt>Up" type="string" value="move_window_up_key"/>
+      <property name="<Alt><Control>KP_1" type="string" value="move_window_workspace_1_key"/>
+      <property name="<Alt><Control>KP_2" type="string" value="move_window_workspace_2_key"/>
+      <property name="<Alt><Control>KP_3" type="string" value="move_window_workspace_3_key"/>
+      <property name="<Alt><Control>KP_4" type="string" value="move_window_workspace_4_key"/>
+      <property name="<Alt><Control>KP_5" type="string" value="move_window_workspace_5_key"/>
+      <property name="<Alt><Control>KP_6" type="string" value="move_window_workspace_6_key"/>
+      <property name="<Alt><Control>KP_7" type="string" value="move_window_workspace_7_key"/>
+      <property name="<Alt><Control>KP_8" type="string" value="move_window_workspace_8_key"/>
+      <property name="<Alt><Control>KP_9" type="string" value="move_window_workspace_9_key"/>
+      <property name="<Alt>space" type="string" value="popup_menu_key"/>
+      <property name="<Shift><Alt>Page_Up" type="string" value="raise_window_key"/>
+      <property name="<Control><Alt>Right" type="string" value="right_workspace_key"/>
+      <property name="<Control><Alt>d" type="string" value="show_desktop_key"/>
+      <property name="<Control><Alt>Up" type="string" value="up_workspace_key"/>
+      <property name="<Control>F1" type="string" value="workspace_1_key"/>
+      <property name="<Control>F2" type="string" value="workspace_2_key"/>
+      <property name="<Control>F3" type="string" value="workspace_3_key"/>
+      <property name="<Control>F4" type="string" value="workspace_4_key"/>
+      <property name="<Control>F5" type="string" value="workspace_5_key"/>
+      <property name="<Control>F6" type="string" value="workspace_6_key"/>
+      <property name="<Control>F7" type="string" value="workspace_7_key"/>
+      <property name="<Control>F8" type="string" value="workspace_8_key"/>
+      <property name="<Control>F9" type="string" value="workspace_9_key"/>
+      <property name="<Control>F10" type="string" value="workspace_10_key"/>
+      <property name="<Control>F11" type="string" value="workspace_11_key"/>
+      <property name="<Control>F12" type="string" value="workspace_12_key"/>
+    </property>
+  </property>
+</channel>

Modified: libxfce4ui/trunk/libxfce4ui/Makefile.am
===================================================================
--- libxfce4ui/trunk/libxfce4ui/Makefile.am	2009-07-08 16:45:16 UTC (rev 30221)
+++ libxfce4ui/trunk/libxfce4ui/Makefile.am	2009-07-08 17:31:05 UTC (rev 30222)
@@ -14,6 +14,8 @@
 lib_LTLIBRARIES = libxfce4ui-1.la
 
 libxfce4ui_headers = \
+	libxfce4ui.h \
+	libxfce4ui-config.h \
 	xfce-dialogs.h \
 	xfce-gdk-extensions.h \
 	xfce-gtk-extensions.h \
@@ -25,15 +27,13 @@
 	libxfce4ui-aliasdef.c
 
 libxfce4ui_includedir = \
-	$(includedir)/libxfce4ui-1/libxfce4ui
+	$(includedir)/xfce4/libxfce4ui-$(LIBXFCE4UI_VERSION_API)/libxfce4ui
 
 libxfce4ui_include_HEADERS = \
-	$(libxfce4ui_headers) \
-	libxfce4ui.h \
-	libxfce4ui-config.h
+	$(libxfce4ui_headers)
 
 libxfce4ui_1_la_SOURCES = \
-	$(libxfce4uiinclude_HEADERS) \
+	$(libxfce4ui_headers) \
 	$(libxfce4ui_built_sources) \
 	libxfce4ui-config.c \
 	libxfce4ui-private.h \

Modified: libxfce4ui/trunk/libxfce4ui/libxfce4ui-1.pc.in
===================================================================
--- libxfce4ui/trunk/libxfce4ui/libxfce4ui-1.pc.in	2009-07-08 16:45:16 UTC (rev 30221)
+++ libxfce4ui/trunk/libxfce4ui/libxfce4ui-1.pc.in	2009-07-08 17:31:05 UTC (rev 30222)
@@ -8,4 +8,4 @@
 Requires: gtk+-2.0 libxfce4util-1.0
 Version: @PACKAGE_VERSION@
 Libs: -L${libdir} -lxfce4ui- at LIBXFCE4UI_VERSION_API@
-Cflags: -I${includedir}/libxfce4ui- at LIBXFCE4UI_VERSION_API@
+Cflags: -I${includedir}/xfce4/libxfce4ui- at LIBXFCE4UI_VERSION_API@

Modified: libxfce4ui/trunk/po/POTFILES.in
===================================================================
--- libxfce4ui/trunk/po/POTFILES.in	2009-07-08 16:45:16 UTC (rev 30221)
+++ libxfce4ui/trunk/po/POTFILES.in	2009-07-08 17:31:05 UTC (rev 30222)
@@ -1,13 +1,24 @@
 #
-# Sources
+# Libxfce4ui sources
 #
 libxfce4ui/libxfce4ui-config.c
 libxfce4ui/xfce-dialogs.c
-libxfce4ui/xfce-execute.c
 libxfce4ui/xfce-gdk-extensions.c
 libxfce4ui/xfce-gtk-extensions.c
 libxfce4ui/xfce-heading.c
+libxfce4ui/xfce-spawn.c
 libxfce4ui/xfce-titled-dialog.c
 
+#
+# Libxfce4kbd-private sources
+#
+libxfce4kbd-private/xfce-shortcuts.c
+libxfce4kbd-private/xfce-shortcut-dialog.c
+libxfce4kbd-private/xfce-shortcuts-grabber.c
+libxfce4kbd-private/xfce-shortcuts-provider.c
+
+#
+# Support for GtkBuilder
+#
 glade/libxfce4ui-glade.c
 glade/libxfce4ui.xml.in




More information about the Xfce4-commits mailing list