[Xfce4-commits] r27292 - in xfce4-settings/trunk: . xfce4-settings-helper
Jannis Pohlmann
jannis at xfce.org
Tue Jul 15 12:25:25 CEST 2008
Author: jannis
Date: 2008-07-15 10:25:25 +0000 (Tue, 15 Jul 2008)
New Revision: 27292
Added:
xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.c
xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.h
Modified:
xfce4-settings/trunk/ChangeLog
xfce4-settings/trunk/xfce4-settings-helper/Makefile.am
xfce4-settings/trunk/xfce4-settings-helper/main.c
Log:
* xfce4-settings-helper/keyboard-shortcuts{c,h},
xfce4-settings-helper/Makefile.am,
xfce4-settings-helper/main.c: Add support for keyboard shortcuts.
Shortcuts are loaded, passive keyboard grabs are performed and
events with different modifier combinations are handled. The code
related to modifiers might not be sane, but it works quite well
here, even with changes made in .Xmodmap. I'd be curious to know
what happens if you change the keymap at runtime though.
xfce4-settings-helper/main.c: Add same and improved error
* xfce4-settings-helper/accessx.c,
* dialogs/keyboard-settings/main.c,
loading, saving, modifying and removing shortcuts. Not
supported yet: Adding new ones.
* AUTHORS: I took the liberty to add my name here.
* xfce4-settings-manager/xfce-settings-manager-dialog.c:
toplevel boxes inside notebooks to 12px for the sake of
* dialogs/keyboard-settings/keyboard-dialog.glade: Same
Modified: xfce4-settings/trunk/ChangeLog
===================================================================
--- xfce4-settings/trunk/ChangeLog 2008-07-15 02:37:23 UTC (rev 27291)
+++ xfce4-settings/trunk/ChangeLog 2008-07-15 10:25:25 UTC (rev 27292)
@@ -1,3 +1,14 @@
+2008-07-15 Jannis Pohlmann <jannis at xfce.org>
+
+ * xfce4-settings-helper/keyboard-shortcuts{c,h},
+ xfce4-settings-helper/Makefile.am,
+ xfce4-settings-helper/main.c: Add support for keyboard shortcuts.
+ Shortcuts are loaded, passive keyboard grabs are performed and
+ events with different modifier combinations are handled. The code
+ related to modifiers might not be sane, but it works quite well
+ here, even with changes made in .Xmodmap. I'd be curious to know
+ what happens if you change the keymap at runtime though.
+
2008-07-14 Nick Schermer <nick at xfce.org>
* dialogs/display-settings/, dialogs/Makefile.am,
@@ -43,7 +54,7 @@
dialogs/mouse-settings/main.c,
dialogs/appearance-settings/main.c,
dialogs/keyboard-settings/main.c,
- xfce4-settings-helper/main.c: Add same and improved error
+ xfce4-settings-helper/main.c: Add same and improved error
messages and version information.
2008-07-13 Nick Schermer <nick at xfce.org>
@@ -61,7 +72,7 @@
branch code.
* dialogs/keyboard-settings/main.c: Release the channels
after running the dialog.
- * xfce4-settings-helper/accessx.c,
+ * xfce4-settings-helper/accessx.c,
xfce4-settings-helper/accessx.h,
xfce4-settings-helper/xkb.c,
xfce4-settings-helper/xkb.h: Move code into objects. Will
@@ -91,7 +102,7 @@
plug a stupid leak.
* dialogs/appearance-settings/appearance-dialog.glade: Redesign
the dialog a bit, a notebook inside a notebook is not practical.
- * dialogs/keyboard-settings/main.c,
+ * dialogs/keyboard-settings/main.c,
dialogs/keyboard-settings/shortcut-dialog.c: Fix includes to make
it compile.
@@ -115,8 +126,8 @@
dialogs/keyboard-settings/shortcut-dialog.{c,h}:
Revamped the dialog a bit. Add dialog widget for entering
shortcuts. Rewrite the settings dialog and add support for
- loading, saving, modifying and removing shortcuts. Not
- supported yet: Adding new ones.
+ loading, saving, modifying and removing shortcuts. Not
+ supported yet: Adding new ones.
2008-07-04 Nick Schermer <nick at xfce.org>
@@ -128,7 +139,7 @@
* dialogs/appearance-dialog/main.c: Only add the icon theme
to the check list when it's actually added to the store.
Revert strcmp to g_utf8_collate. Strip trailing spaces.
-
+
Both fixes where mentioned by Jannis, thanks for that.
2008-07-03 Nick Schermer <nick at xfce.org>
@@ -160,7 +171,7 @@
* dialogs/appearance-settings/main.c: Load icon themes properly.
I used some of the code from the old mcs ui plugin.
- * AUTHORS: I took the liberty to add my name here.
+ * AUTHORS: I took the liberty to add my name here.
2008-07-01 Nick Schermer <nick at xfce.org>
@@ -181,7 +192,7 @@
2008-06-29 Jannis Pohlmann <jannis at xfce.org>
- * xfce4-settings-manager/xfce-settings-manager-dialog.c:
+ * xfce4-settings-manager/xfce-settings-manager-dialog.c:
Add 6px border to the scrolled window in order to align it
with the dialog buttons.
@@ -191,7 +202,7 @@
dialogs/appearance-settings/appearance-dialog.glade,
dialogs/keyboard-settings/keyboard-dialog.glade,
dialogs/mouse-settings/mouse-dialog.glade: Change border of
- toplevel boxes inside notebooks to 12px for the sake of
+ toplevel boxes inside notebooks to 12px for the sake of
consistency (thunar does the same). Add bottom padding of
alignments below section titles to 6px.
@@ -223,7 +234,7 @@
2008-06-28 Jannis Pohlmann <jannis at xfce.org>
- * dialogs/keyboard-settings/keyboard-dialog.glade: Same
+ * dialogs/keyboard-settings/keyboard-dialog.glade: Same
procedure as before.
2008-06-28 Jannis Pohlmann <jannis at xfce.org>
Modified: xfce4-settings/trunk/xfce4-settings-helper/Makefile.am
===================================================================
--- xfce4-settings/trunk/xfce4-settings-helper/Makefile.am 2008-07-15 02:37:23 UTC (rev 27291)
+++ xfce4-settings/trunk/xfce4-settings-helper/Makefile.am 2008-07-15 10:25:25 UTC (rev 27292)
@@ -18,7 +18,9 @@
xkb.c \
xkb.h \
pointers.c \
- pointers.h
+ pointers.h \
+ keyboard-shortcuts.c \
+ keyboard-shortcuts.h
xfce4_settings_helper_CFLAGS = \
$(GTK_CFLAGS) \
@@ -27,6 +29,7 @@
$(DBUS_GLIB_CFLAGS) \
$(XFCONF_CFLAGS) \
$(LIBXFCE4UTIL_CFLAGS) \
+ $(LIBXFCEGUI4_CFLAGS) \
$(XI_CFLAGS) \
$(LIBX11_CFLAGS)
@@ -41,6 +44,7 @@
$(DBUS_GLIB_LIBS) \
$(XFCONF_LIBS) \
$(LIBXFCE4UTIL_LIBS) \
+ $(LIBXFCEGUI4_LIBS) \
$(XI_LIBS) \
$(LIBX11_LIBS)
Added: xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.c
===================================================================
--- xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.c (rev 0)
+++ xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.c 2008-07-15 10:25:25 UTC (rev 27292)
@@ -0,0 +1,543 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.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 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/Xlib.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include <xfconf/xfconf.h>
+#include <libxfcegui4/libxfcegui4.h>
+
+#include "keyboard-shortcuts.h"
+
+
+
+/* Modifiers to be ignored (0x2000 is an Xkb modifier) */
+#define IGNORED_MODIFIERS (0x2000 | GDK_LOCK_MASK | GDK_HYPER_MASK)
+
+/* Modifiers to be used */
+#define USED_MODIFIERS (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_SUPER_MASK | GDK_META_MASK | \
+ GDK_MOD1_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK)
+
+
+
+
+/* Property identifiers */
+enum
+{
+ PROP_0,
+};
+
+
+
+static void xfce_keyboard_shortcuts_helper_class_init (XfceKeyboardShortcutsHelperClass *klass);
+static void xfce_keyboard_shortcuts_helper_init (XfceKeyboardShortcutsHelper *helper);
+static void xfce_keyboard_shortcuts_helper_finalize (GObject *object);
+static void xfce_keyboard_shortcuts_helper_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void xfce_keyboard_shortcuts_helper_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void xfce_keyboard_shortcuts_helper_add_filter (XfceKeyboardShortcutsHelper *helper);
+static GdkFilterReturn xfce_keyboard_shortcuts_helper_filter (GdkXEvent *gdk_xevent,
+ GdkEvent *event,
+ XfceKeyboardShortcutsHelper *helper);
+static void xfce_keyboard_shortcuts_helper_load_shortcut (const gchar *key,
+ const GValue *value,
+ XfceKeyboardShortcutsHelper *helper);
+static gboolean xfce_keyboard_shortcuts_helper_grab_shortcut (XfceKeyboardShortcutsHelper *helper,
+ const char *shortcut,
+ gboolean grab);
+static gboolean xfce_keyboard_shortcuts_helper_parse_shortcut (XfceKeyboardShortcutsHelper *helper,
+ GdkDisplay *display,
+ const gchar *shortcut,
+ guint *keyval,
+ GdkModifierType *modifiers,
+ KeyCode *keycode,
+ guint *grab_mask);
+static gboolean xfce_keyboard_shortcuts_helper_grab_real (XfceKeyboardShortcutsHelper *helper,
+ KeyCode keycode,
+ guint modifiers,
+ Display *display,
+ Window window,
+ gboolean grab);
+static void xfce_keyboard_shortcuts_helper_handle_key_press (XfceKeyboardShortcutsHelper *helper,
+ XKeyEvent *xevent);
+
+
+
+struct _XfceKeyboardShortcutsHelperClass
+{
+ GObjectClass __parent__;
+};
+
+struct _XfceKeyboardShortcutsHelper
+{
+ GObject __parent__;
+
+ /* Xfconf channel used for managing the keyboard shortcuts */
+ XfconfChannel *channel;
+
+ /* Hash table for (shortcut -> action) mapping */
+ GHashTable *shortcuts;
+
+ /* Flag to avoid handling multiple key press events at the same time */
+ gboolean waiting_for_key_release;
+};
+
+
+
+static GObjectClass *xfce_keyboard_shortcuts_helper_parent_class = NULL;
+
+
+
+GType
+xfce_keyboard_shortcuts_helper_get_type (void)
+{
+ static GType type = G_TYPE_INVALID;
+
+ if (G_UNLIKELY (type == G_TYPE_INVALID))
+ {
+ static const GTypeInfo info =
+ {
+ sizeof (XfceKeyboardShortcutsHelperClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) xfce_keyboard_shortcuts_helper_class_init,
+ NULL,
+ NULL,
+ sizeof (XfceKeyboardShortcutsHelper),
+ 0,
+ (GInstanceInitFunc) xfce_keyboard_shortcuts_helper_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT, "XfceKeyboardShortcutsHelper", &info, 0);
+ }
+
+ return type;
+}
+
+
+
+static void
+xfce_keyboard_shortcuts_helper_class_init (XfceKeyboardShortcutsHelperClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ /* Determine the parent type class */
+ xfce_keyboard_shortcuts_helper_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = xfce_keyboard_shortcuts_helper_finalize;
+ gobject_class->get_property = xfce_keyboard_shortcuts_helper_get_property;
+ gobject_class->set_property = xfce_keyboard_shortcuts_helper_set_property;
+}
+
+
+
+static void
+xfce_keyboard_shortcuts_helper_init (XfceKeyboardShortcutsHelper *helper)
+{
+ GHashTable *properties;
+
+ helper->waiting_for_key_release = FALSE;
+
+ /* Get Xfconf channel */
+ helper->channel = xfconf_channel_new ("xfce4-keyboard-shortcuts");
+
+ /* Create hash table for (shortcut -> command) mapping */
+ helper->shortcuts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+ /* Get all properties of the channel */
+ properties = xfconf_channel_get_all (helper->channel);
+
+ if (G_LIKELY (properties != NULL))
+ {
+ /* Filter shortcuts */
+ g_hash_table_foreach (properties, (GHFunc) xfce_keyboard_shortcuts_helper_load_shortcut, helper);
+
+ /* Destroy properties */
+ g_hash_table_destroy (properties);
+ }
+
+ xfce_keyboard_shortcuts_helper_add_filter (helper);
+}
+
+
+
+static void
+xfce_keyboard_shortcuts_helper_finalize (GObject *object)
+{
+ XfceKeyboardShortcutsHelper *helper = XFCE_KEYBOARD_SHORTCUTS_HELPER (object);
+
+ /* Free shortcuts hash table */
+ g_hash_table_destroy (helper->shortcuts);
+
+ /* Free Xfconf channel */
+ g_object_unref (helper->channel);
+
+ (*G_OBJECT_CLASS (xfce_keyboard_shortcuts_helper_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfce_keyboard_shortcuts_helper_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ XfceKeyboardShortcutsHelper *helper = XFCE_KEYBOARD_SHORTCUTS_HELPER (object);
+
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+static void
+xfce_keyboard_shortcuts_helper_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ XfceKeyboardShortcutsHelper *helper = XFCE_KEYBOARD_SHORTCUTS_HELPER (object);
+
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+static void
+xfce_keyboard_shortcuts_helper_add_filter (XfceKeyboardShortcutsHelper *helper)
+{
+ GdkDisplay *display;
+ GdkScreen *screen;
+ gint screens;
+ gint i;
+
+ g_return_if_fail (XFCE_IS_KEYBOARD_SHORTCUTS_HELPER (helper));
+
+ display = gdk_display_get_default ();
+ screens = gdk_display_get_n_screens (display);
+
+ /* Flush events before adding the event filter */
+ XAllowEvents (GDK_DISPLAY_XDISPLAY (display), AsyncBoth, CurrentTime);
+
+ /* Add event filter to the root window of each screen. FIXME: I'm not
+ * exactly sure which one of these two options I should use: */
+#if 0
+ for (i = 0; i < screens; ++i)
+ {
+ screen = gdk_display_get_screen (display, i);
+ gdk_window_add_filter (gdk_screen_get_root_window (screen), (GdkFilterFunc) xfce_keyboard_shortcuts_helper_filter, helper);
+ }
+#else
+ gdk_window_add_filter (NULL, (GdkFilterFunc) xfce_keyboard_shortcuts_helper_filter, helper);
+#endif
+}
+
+
+
+static GdkFilterReturn
+xfce_keyboard_shortcuts_helper_filter (GdkXEvent *gdk_xevent,
+ GdkEvent *event,
+ XfceKeyboardShortcutsHelper *helper)
+{
+ XEvent *xevent = (XEvent *) gdk_xevent;
+
+ g_return_if_fail (XFCE_IS_KEYBOARD_SHORTCUTS_HELPER (helper));
+
+ switch (xevent->type)
+ {
+ case KeyPress:
+ xfce_keyboard_shortcuts_helper_handle_key_press (helper, (XKeyEvent *) xevent);
+ break;
+ case KeyRelease:
+ helper->waiting_for_key_release = FALSE;
+ break;
+ case MappingNotify:
+ break;
+ default:
+ break;
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+
+
+static void
+xfce_keyboard_shortcuts_helper_load_shortcut (const gchar *key,
+ const GValue *value,
+ XfceKeyboardShortcutsHelper *helper)
+{
+ const GPtrArray *array;
+ const GValue *type_value;
+ const GValue *action_value;
+ const gchar *type;
+ const gchar *action;
+ GtkTreeIter iter;
+
+ g_return_if_fail (XFCE_IS_KEYBOARD_SHORTCUTS_HELPER (helper));
+
+ /* MAke sure we only load shortcuts from string arrays */
+ if (G_UNLIKELY (G_VALUE_TYPE (value) != dbus_g_type_get_collection ("GPtrArray", G_TYPE_VALUE)))
+ return;
+
+ /* Get the pointer array */
+ array = g_value_get_boxed (value);
+
+ /* Make sure the array has exactly two members */
+ if (G_UNLIKELY (array->len != 2))
+ return;
+
+ /* Get GValues for the array members */
+ type_value = g_ptr_array_index (array, 0);
+ action_value = g_ptr_array_index (array, 1);
+
+ /* Make sure both are string values */
+ if (G_UNLIKELY (G_VALUE_TYPE (type_value) != G_TYPE_STRING || G_VALUE_TYPE (action_value) != G_TYPE_STRING))
+ return;
+
+ /* Get shortcut type and action */
+ type = g_value_get_string (type_value);
+ action = g_value_get_string (action_value);
+
+ /* Only add shortcuts of type 'execute' */
+ if (g_utf8_collate (type, "execute") == 0)
+ {
+ /* Establish passive grab on the shortcut and add it to the hash table */
+ if (G_LIKELY (xfce_keyboard_shortcuts_helper_grab_shortcut (helper, key + 1, TRUE)))
+ {
+ /* Add shortcut -> action pair to the hash table */
+ g_hash_table_insert (helper->shortcuts, g_strdup (key + 1), g_strdup (action));
+ }
+ else
+ g_warning ("Failed to load shortcut '%s'", key + 1);
+ }
+}
+
+
+
+static gboolean
+xfce_keyboard_shortcuts_helper_grab_shortcut (XfceKeyboardShortcutsHelper *helper,
+ const char *shortcut,
+ gboolean grab)
+{
+ GdkModifierType modifiers;
+ GdkDisplay *display;
+ GdkScreen *screen;
+ Display *xdisplay;
+ KeyCode keycode;
+ Window xwindow;
+ guint grab_mask;
+ guint keyval;
+ gint bits[32];
+ gint current_mask;
+ gint ignore_mask;
+ gint screens;
+ gint n_bits;
+ gint i;
+ gint j;
+ gint k;
+
+ display = gdk_display_get_default ();
+ screens = gdk_display_get_n_screens (display);
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ /* Parse the shortcut and abort if that fails */
+ if (G_UNLIKELY (!xfce_keyboard_shortcuts_helper_parse_shortcut (helper, display, shortcut, &keyval, &modifiers, &keycode, &grab_mask)))
+ {
+ g_warning ("Could not parse shortcut '%s', most likely because it is invalid", shortcut);
+ return FALSE ;
+ }
+
+ /* Create mask containing ignored modifier bits set which are not set in the grab_mask already */
+ ignore_mask = IGNORED_MODIFIERS & ~grab_mask & GDK_MODIFIER_MASK;
+
+ /* Store indices of all set bits of the ignore mask in an array */
+ for (i = 0, n_bits = 0; ignore_mask != 0; ++i, ignore_mask >>= 1)
+ if ((ignore_mask & 0x1) != 0)
+ 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 root X window */
+ screen = gdk_display_get_screen (display, k);
+ xwindow = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
+
+ /* Really grab or ungrab the key now */
+ if (G_UNLIKELY (!xfce_keyboard_shortcuts_helper_grab_real (helper, keycode, current_mask | grab_mask, xdisplay, xwindow, grab)))
+ {
+ g_warning ("Could not grab shortcut '%s'. It might be used by another application already.", shortcut);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+
+static gboolean
+xfce_keyboard_shortcuts_helper_parse_shortcut (XfceKeyboardShortcutsHelper *helper,
+ GdkDisplay *display,
+ const gchar *shortcut,
+ guint *keyval,
+ GdkModifierType *modifiers,
+ KeyCode *keycode,
+ guint *grab_mask)
+{
+ g_return_if_fail (XFCE_IS_KEYBOARD_SHORTCUTS_HELPER (helper));
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+
+ /* Reset keycode and grab mask */
+ *keycode = 0;
+ *grab_mask = 0;
+
+ /* Parse the GTK+ accelerator string */
+ gtk_accelerator_parse (shortcut, keyval, modifiers);
+
+ /* Abort when the accelerator string is invalid */
+ if (G_LIKELY (*keyval == 0 && *modifiers == 0))
+ return FALSE;
+
+ /* Try to convert the keyval into a X11 keycode */
+ if ((*keycode = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (display), *keyval)) == 0)
+ return FALSE;
+
+ /* FIXME: I'm not really sure about this */
+ *grab_mask = *modifiers;
+
+ return TRUE;
+}
+
+
+
+static gboolean
+xfce_keyboard_shortcuts_helper_grab_real (XfceKeyboardShortcutsHelper *helper,
+ KeyCode keycode,
+ guint modifiers,
+ Display *display,
+ Window window,
+ gboolean grab)
+{
+ gdk_error_trap_push ();
+
+ if (G_LIKELY (grab))
+ XGrabKey (display, keycode, modifiers, window, FALSE, GrabModeAsync, GrabModeAsync);
+ else
+ XUngrabKey (display, keycode, modifiers, window);
+
+ gdk_flush ();
+
+ return gdk_error_trap_pop () == 0;
+}
+
+
+
+static void
+xfce_keyboard_shortcuts_helper_handle_key_press (XfceKeyboardShortcutsHelper *helper,
+ XKeyEvent *xevent)
+{
+ GdkDisplay *display;
+ GdkScreen *screen;
+ GError *error = NULL;
+ KeySym keysym;
+ gchar *accelerator_name;
+ const gchar *key;
+ const gchar *value;
+ gint monitor;
+ gint modifiers;
+
+ g_return_if_fail (XFCE_IS_KEYBOARD_SHORTCUTS_HELPER (helper));
+
+ /* Don't handle multiple key press events in parallel (avoid weird behaviour) */
+ if (G_UNLIKELY (helper->waiting_for_key_release))
+ return;
+
+ /* Get display information */
+ display = gdk_display_get_default ();
+
+ /* Convert event keycode to keysym */
+ keysym = XKeycodeToKeysym (GDK_DISPLAY_XDISPLAY (display), xevent->keycode, 0);
+
+ /* Remove ignored modifiers and non-modifier keys from the event state mask */
+ modifiers = xevent->state & ~IGNORED_MODIFIERS & GDK_MODIFIER_MASK;
+
+ /* Get accelerator string for the pressed keys */
+ accelerator_name = gtk_accelerator_name (keysym, modifiers);
+
+ /* Perform accelerator lookup */
+ if (G_LIKELY (g_hash_table_lookup_extended (helper->shortcuts, accelerator_name, (gpointer) &key, (gpointer) &value)))
+ {
+ /* We have to wait for a release event before handling another key press event */
+ helper->waiting_for_key_release = TRUE;
+
+ /* Determine active monitor */
+ screen = xfce_gdk_display_locate_monitor_with_pointer (display, &monitor);
+
+ /* Spawn command */
+ if (G_UNLIKELY (!xfce_gdk_spawn_command_line_on_screen (screen, value, &error)))
+ {
+ if (G_LIKELY (error != NULL))
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+ }
+ }
+
+ /* Free accelerator string */
+ g_free (accelerator_name);
+}
Added: xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.h
===================================================================
--- xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.h (rev 0)
+++ xfce4-settings/trunk/xfce4-settings-helper/keyboard-shortcuts.h 2008-07-15 10:25:25 UTC (rev 27292)
@@ -0,0 +1,42 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.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 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
+ */
+
+#ifndef __XFCE_KEYBOARD_SHORTCUTS_HELPER_H__
+#define __XFCE_KEYBOARD_SHORTCUTS_HELPER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _XfceKeyboardShortcutsHelperClass XfceKeyboardShortcutsHelperClass;
+typedef struct _XfceKeyboardShortcutsHelper XfceKeyboardShortcutsHelper;
+
+#define XFCE_TYPE_KEYBOARD_SHORTCUTS_HELPER (xfce_keyboard_shortcuts_helper_get_type ())
+#define XFCE_KEYBOARD_SHORTCUTS_HELPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_KEYBOARD_SHORTCUTS_HELPER, XfceKeyboardShortcutsHelper))
+#define XFCE_KEYBOARD_SHORTCUTS_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_KEYBOARD_SHORTCUTS_HELPER, XfceKeyboardShortcutsHelperClass))
+#define XFCE_IS_KEYBOARD_SHORTCUTS_HELPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_KEYBOARD_SHORTCUTS_HELPER))
+#define XFCE_IS_KEYBOARD_SHORTCUTS_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_KEYBOARD_SHORTCUTS_HELPER)
+#define XFCE_KEYBOARD_SHORTCUTS_HELPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_KEYBOARD_SHORTCUTS_HELPER, XfceKeyboardShortcutsHelperClass))
+
+GType xfce_keyboard_shortcuts_helper_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS;
+
+#endif /* !__XFCE_KEYBOARD_SHORTCUTS_HELPER_H__ */
Modified: xfce4-settings/trunk/xfce4-settings-helper/main.c
===================================================================
--- xfce4-settings/trunk/xfce4-settings-helper/main.c 2008-07-15 02:37:23 UTC (rev 27291)
+++ xfce4-settings/trunk/xfce4-settings-helper/main.c 2008-07-15 10:25:25 UTC (rev 27292)
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2008 Stephan Arts <stephan at xfce.org>
* Copyright (c) 2008 Nick Schermer <nick at xfce.org>
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.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
@@ -35,9 +36,10 @@
#include <xfconf/xfconf.h>
#include <libxfce4util/libxfce4util.h>
-#include <xfce4-settings-helper/pointers.h>
-#include <xfce4-settings-helper/xkb.h>
-#include <xfce4-settings-helper/accessx.h>
+#include "pointers.h"
+#include "xkb.h"
+#include "accessx.h"
+#include "keyboard-shortcuts.h"
@@ -59,6 +61,7 @@
GObject *pointer_helper;
GObject *xkb_helper;
GObject *accessx_helper;
+ GObject *shortcuts_helper;
pid_t pid;
/* setup translation domain */
@@ -133,7 +136,9 @@
pointer_helper = g_object_new (XFCE_TYPE_POINTERS_HELPER, NULL);
xkb_helper = g_object_new (XFCE_TYPE_XKB_HELPER, NULL);
accessx_helper = g_object_new (XFCE_TYPE_ACCESSX_HELPER, NULL);
+ shortcuts_helper = g_object_new (XFCE_TYPE_KEYBOARD_SHORTCUTS_HELPER, NULL);
+
/* enter the main loop */
gtk_main();
@@ -141,6 +146,7 @@
g_object_unref (G_OBJECT (pointer_helper));
g_object_unref (G_OBJECT (xkb_helper));
g_object_unref (G_OBJECT (accessx_helper));
+ g_object_unref (G_OBJECT (shortcuts_helper));
/* shutdown xfconf */
xfconf_shutdown ();
More information about the Xfce4-commits
mailing list