diff --git a/configure.ac.in b/configure.ac.in index 0f5f215..e63d890 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -12,7 +12,8 @@ m4_define([xfwm4_version], [xfwm4_version_major().xfwm4_version_minor().xfwm4_ve m4_define([gtk_minimum_version], [2.10.0]) m4_define([xfce_minimum_version], [4.5.91]) -m4_define([libxfcegui4_minimum_version], [4.5.91svn-r28280]) +m4_define([libxfcegui4_minimum_version], [4.5.91svn-r28487]) +m4_define([libxfce4kbd_private_minimum_version], [4.5.91svn-r28487]) m4_define([xfconf_minimum_version], [4.5.91]) m4_define([xcomposite_minimum_version], [0.2]) m4_define([wnck_minimum_version], [2.12]) @@ -73,6 +74,7 @@ XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [gtk_minimum_version]) XDT_CHECK_PACKAGE([GLADE], [libglade-2.0], [2.0.0]) XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [xfce_minimum_version]) XDT_CHECK_PACKAGE([LIBXFCEGUI4], libxfcegui4-1.0, [libxfcegui4_minimum_version]) +XDT_CHECK_PACKAGE([LIBXFCE4KBD_PRIVATE], libxfce4kbd-private-1.0, [libxfce4kbd_private_minimum_version]) XDT_CHECK_PACKAGE([LIBXFCONF], libxfconf-0, [xfconf_minimum_version]) XDT_CHECK_PACKAGE([LIBWNCK], [libwnck-1.0], [wnck_minimum_version]) XDT_CHECK_PACKAGE([DBUS], [dbus-1], [1.0.0]) diff --git a/src/Makefile.am b/src/Makefile.am index 7137cf5..d7013b4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -79,6 +79,7 @@ xfwm4_CFLAGS = \ $(LIBXFCONF_CFLAGS) \ $(LIBXFCE4UTIL_CFLAGS) \ $(LIBXFCEGUI4_CFLAGS) \ + $(LIBXFCE4KBD_PRIVATE_CFLAGS) \ $(RENDER_CFLAGS) \ $(LIBSTARTUP_NOTIFICATION_CFLAGS) \ $(COMPOSITOR_CFLAGS) \ @@ -96,6 +97,7 @@ xfwm4_LDADD = \ $(LIBXFCONF_LIBS) \ $(LIBXFCE4UTIL_LIBS) \ $(LIBXFCEGUI4_LIBS) \ + $(LIBXFCE4KBD_PRIVATE_LIBS) \ $(LIBSTARTUP_NOTIFICATION_LIBS) \ $(RENDER_LIBS) \ $(COMPOSITOR_LIBS) \ diff --git a/src/event_filter.c b/src/event_filter.c index c571631..80d613b 100644 --- a/src/event_filter.c +++ b/src/event_filter.c @@ -127,9 +127,6 @@ default_event_filter (XEvent * xevent, gpointer data) case ColormapNotify: TRACE ("Unhandled ColormapNotify event"); break; - case MappingNotify: - TRACE ("Unhandled MappingNotify event"); - break; default: TRACE ("Unhandled Unknown event"); break; diff --git a/src/events.c b/src/events.c index fdbe870..1498db2 100644 --- a/src/events.c +++ b/src/events.c @@ -2220,31 +2220,6 @@ handleColormapNotify (DisplayInfo *display_info, XColormapEvent * ev) } static eventFilterStatus -handleMappingNotify (DisplayInfo *display_info, XMappingEvent * ev) -{ - TRACE ("entering handleMappingNotify"); - - /* Refreshes the stored modifier and keymap information */ - XRefreshKeyboardMapping (ev); - - /* Update internal modifiers masks if necessary */ - if (ev->request == MappingModifier) - { - TRACE ("handleMappingNotify: modifiers mapping has changed"); - initModifiers (display_info->dpy); - } - - /* Regrab all keys if the notify is for keyboard (ie not pointer) */ - if (ev->request != MappingPointer) - { - TRACE ("handleMappingNotify: Reload settings"); - reloadSettings (display_info, UPDATE_BUTTON_GRABS); - } - - return EVENT_FILTER_PASS; -} - -static eventFilterStatus handleReparentNotify (DisplayInfo *display_info, XReparentEvent * ev) { TRACE ("entering handleReparentNotify, 0x%lx reparented in 0x%lx", ev->window, ev->parent); @@ -2346,9 +2321,6 @@ handleEvent (DisplayInfo *display_info, XEvent * ev) case ColormapNotify: handleColormapNotify (display_info, (XColormapEvent *) ev); break; - case MappingNotify: - status = handleMappingNotify (display_info, (XMappingEvent *) ev); - break; case ReparentNotify: status = handleReparentNotify (display_info, (XReparentEvent *) ev); break; diff --git a/src/keyboard.c b/src/keyboard.c index 0792935..50d9792 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -27,12 +27,29 @@ #include #include +#include #include #include #include #include #include "keyboard.h" +#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 | \ + NumLockMask | \ + ScrollLockMask) + unsigned int AltMask; unsigned int MetaMask; unsigned int NumLockMask; @@ -40,85 +57,38 @@ unsigned int ScrollLockMask; unsigned int SuperMask; unsigned int HyperMask; -static gboolean -getKeycode (Display *dpy, const char *str, KeyCode *keycode) +static KeyCode +getKeycode (Display *dpy, const char *str) { - unsigned int value; - KeySym keysym; + GdkModifierType keysym; - keysym = XStringToKeysym (str); - if (keysym == NoSymbol) - { - if (sscanf (str, "0x%X", (unsigned int *) &value) != 1) - { - *keycode = 0; - return FALSE; - } - *keycode = (KeyCode) value; - } - else - { - *keycode = XKeysymToKeycode (dpy, keysym); - } - return TRUE; + gtk_accelerator_parse (str, &keysym, NULL); + return XKeysymToKeycode (dpy, keysym); } -int +guint getModifierMap (const char *str) { - gchar *tmp; - int map; + guint map; - tmp = g_ascii_strdown ((gchar *) str, strlen (str)); - map = 0; + gtk_accelerator_parse (str, NULL, &map); - if (strstr (tmp, "shift")) - { - map |= ShiftMask; - } - if (strstr (tmp, "control")) - { - map |= ControlMask; - } - if (strstr (tmp, "alt")) - { - map |= AltMask; - } - if (strstr (tmp, "meta")) - { - map |= MetaMask; - } - if (strstr (tmp, "super")) + if ((map & GDK_SUPER_MASK) == GDK_SUPER_MASK) { map |= SuperMask; } - if (strstr (tmp, "hyper")) + + if ((map & GDK_HYPER_MASK) == GDK_HYPER_MASK) { map |= HyperMask; } - if (strstr (tmp, "mod1")) - { - map |= Mod1Mask; - } - if (strstr (tmp, "mod2")) - { - map |= Mod2Mask; - } - if (strstr (tmp, "mod3")) - { - map |= Mod3Mask; - } - if (strstr (tmp, "mod4")) - { - map |= Mod4Mask; - } - if (strstr (tmp, "mod5")) + + if ((map & GDK_META_MASK) == GDK_META_MASK) { - map |= Mod5Mask; + map |= MetaMask; } - g_free (tmp); - return map; + return map & MODIFIER_MASK & ~IGNORE_MASK; } void @@ -134,25 +104,20 @@ parseKeyString (Display * dpy, MyKey * key, const char *str) key->keycode = 0; key->modifier = 0; - g_return_if_fail (str != NULL); - - if (!g_ascii_strcasecmp (str, "none")) + if (str == NULL) { return; } - k = strrchr (str, '+'); - if (k) - { - /* There is a modifier */ - getKeycode (dpy, ++k, &key->keycode); - key->modifier = getModifierMap (str); - } - else + if (!g_ascii_strcasecmp (str, "none")) { - getKeycode (dpy, str, &key->keycode); - key->modifier = 0; + return; } + + key->keycode = getKeycode (dpy, str); + key->modifier = getModifierMap (str); + + TRACE ("keycode = 0x%x, modifier = 0x%x", key->keycode, key->modifier); } gboolean diff --git a/src/keyboard.h b/src/keyboard.h index b6549df..faad8a6 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -35,6 +35,7 @@ struct _MyKey { KeyCode keycode; int modifier; + gchar *internal_name; }; extern unsigned int AltMask; @@ -44,7 +45,7 @@ extern unsigned int ScrollLockMask; extern unsigned int SuperMask; extern unsigned int HyperMask; -int getModifierMap (const char *); +guint getModifierMap (const char *); void parseKeyString (Display *, MyKey *, const char *); diff --git a/src/screen.h b/src/screen.h index dae3878..c15c78b 100644 --- a/src/screen.h +++ b/src/screen.h @@ -30,6 +30,8 @@ #include #include #include +#include + #ifdef HAVE_LIBSTARTUP_NOTIFICATION #define SN_API_NOT_YET_FROZEN @@ -117,7 +119,9 @@ struct _ScreenInfo /* xfconf */ XfconfChannel *xfwm4_channel; - XfconfChannel *keys_channel; + + /* Shortcuts */ + XfceShortcutsProvider *shortcuts_provider; /* Per screen parameters */ XfwmParams *params; diff --git a/src/settings.c b/src/settings.c index 0e8b302..715109f 100644 --- a/src/settings.c +++ b/src/settings.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "screen.h" #include "hints.h" @@ -41,8 +42,7 @@ #include "compositor.h" #include "ui_style.h" -#define CHANNEL1 "xfwm4" -#define CHANNEL2 "xfwm4_keys" +#define CHANNEL_XFWM "xfwm4" #define DEFAULT_KEYTHEME "Default" #define KEYTHEMERC "keythemerc" @@ -61,16 +61,30 @@ static void loadRcData (ScreenInfo *, Settings *); static void loadTheme (ScreenInfo *, Settings *); -static gboolean loadKeyBindings (ScreenInfo *, - Settings *); +static void loadKeyBindings (ScreenInfo *); static void unloadTheme (ScreenInfo *); +static void unloadKeyBindings (ScreenInfo *); static void unloadSettings (ScreenInfo *); static gboolean reloadScreenSettings (ScreenInfo *, int); +static void parseShortcut (ScreenInfo *, + int, + const gchar *, + GList *); +static const gchar *getShortcut (const gchar *, + GList *); static void cb_xfwm4_channel_property_changed (XfconfChannel *, const gchar *, const GValue *, ScreenInfo *); +static void cb_keys_changed (GdkKeymap *, + ScreenInfo *); +static void cb_shortcut_added (XfceShortcutsProvider *, + const gchar *, + ScreenInfo *); +static void cb_shortcut_removed (XfceShortcutsProvider *, + const gchar *, + ScreenInfo *); static void update_grabs (ScreenInfo *screen_info) @@ -129,6 +143,8 @@ set_settings_margin (ScreenInfo *screen_info, int idx, int value) static void set_easy_click (ScreenInfo *screen_info, const char *modifier) { + gchar *modstr; + g_return_if_fail (screen_info != NULL); g_return_if_fail (modifier != NULL); @@ -138,7 +154,9 @@ set_easy_click (ScreenInfo *screen_info, const char *modifier) } else { - screen_info->params->easy_click = getModifierMap (modifier); + modstr = g_strdup_printf ("<%s>", modifier); + screen_info->params->easy_click = getModifierMap (modstr); + g_free (modstr); } } @@ -535,9 +553,10 @@ loadTheme (ScreenInfo *screen_info, Settings *rc) g_free (theme); } -static gboolean -loadKeyBindings (ScreenInfo *screen_info, Settings *rc) +static void +loadKeyBindings (ScreenInfo *screen_info) { + GList *shortcuts; gchar keyname[30]; Display *dpy; gchar *keytheme; @@ -545,86 +564,65 @@ loadKeyBindings (ScreenInfo *screen_info, Settings *rc) guint i; dpy = myScreenGetXDisplay (screen_info); - /* - Load defaults keytheme so that even if there are - missing shortcuts in an older user defined key theme - the missing keys will be taken from the default - */ - keytheme = getThemeDir (DEFAULT_KEYTHEME, KEYTHEMERC); - parseRc (KEYTHEMERC, keytheme, rc); - g_free (keytheme); - keythemevalue = getStringValue ("keytheme", rc); - if (keythemevalue) - { - keytheme = getThemeDir (keythemevalue, KEYTHEMERC); - if (!parseRc (KEYTHEMERC, keytheme, rc)) - { - g_warning ("Specified key theme \"%s\" missing, using default", keythemevalue); - } - g_free (keytheme); - - if (!checkRc (rc)) - { - g_warning ("Missing values in defaults file"); - return FALSE; - } - } - - parseKeyString (dpy, &screen_info->params->keys[KEY_CANCEL], getStringValue ("cancel_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_DOWN], getStringValue ("down_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_LEFT], getStringValue ("left_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_RIGHT], getStringValue ("right_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_UP], getStringValue ("up_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_ADD_WORKSPACE], getStringValue ("add_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_ADD_ADJACENT_WORKSPACE], getStringValue ("add_adjacent_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_CLOSE_WINDOW], getStringValue ("close_window_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_CYCLE_WINDOWS], getStringValue ("cycle_windows_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_DEL_WORKSPACE], getStringValue ("del_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_DEL_ACTIVE_WORKSPACE], getStringValue ("del_active_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_DOWN_WORKSPACE], getStringValue ("down_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_FILL_HORIZ], getStringValue ("fill_horiz_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_FILL_VERT], getStringValue ("fill_vert_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_FILL_WINDOW], getStringValue ("fill_window_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_HIDE_WINDOW], getStringValue ("hide_window_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_LEFT_WORKSPACE], getStringValue ("left_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_LOWER_WINDOW], getStringValue ("lower_window_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_MOVE], getStringValue ("move_window_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_MAXIMIZE_HORIZ], getStringValue ("maximize_horiz_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_MAXIMIZE_VERT], getStringValue ("maximize_vert_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_MAXIMIZE_WINDOW], getStringValue ("maximize_window_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_MOVE_DOWN_WORKSPACE], getStringValue ("move_window_down_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_MOVE_LEFT_WORKSPACE], getStringValue ("move_window_left_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_MOVE_NEXT_WORKSPACE], getStringValue ("move_window_next_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_MOVE_PREV_WORKSPACE], getStringValue ("move_window_prev_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_MOVE_RIGHT_WORKSPACE], getStringValue ("move_window_right_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_MOVE_UP_WORKSPACE], getStringValue ("move_window_up_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_NEXT_WORKSPACE], getStringValue ("next_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_POPUP_MENU], getStringValue ("popup_menu_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_PREV_WORKSPACE], getStringValue ("prev_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_RAISE_WINDOW], getStringValue ("raise_window_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_RESIZE], getStringValue ("resize_window_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_RIGHT_WORKSPACE], getStringValue ("right_workspace_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_SHADE_WINDOW], getStringValue ("shade_window_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_SHOW_DESKTOP], getStringValue("show_desktop_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_STICK_WINDOW], getStringValue ("stick_window_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_TOGGLE_ABOVE], getStringValue ("above_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_TOGGLE_FULLSCREEN], getStringValue ("fullscreen_key", rc)); - parseKeyString (dpy, &screen_info->params->keys[KEY_UP_WORKSPACE], getStringValue ("up_workspace_key", rc)); + shortcuts = xfce_shortcuts_provider_get_shortcuts (screen_info->shortcuts_provider); + + parseShortcut (screen_info, KEY_CANCEL, "cancel_key", shortcuts); + parseShortcut (screen_info, KEY_DOWN, "down_key", shortcuts); + parseShortcut (screen_info, KEY_LEFT, "left_key", shortcuts); + parseShortcut (screen_info, KEY_RIGHT, "right_key", shortcuts); + parseShortcut (screen_info, KEY_UP, "up_key", shortcuts); + parseShortcut (screen_info, KEY_ADD_WORKSPACE, "add_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_ADD_ADJACENT_WORKSPACE, "add_adjacent_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_CLOSE_WINDOW, "close_window_key", shortcuts); + parseShortcut (screen_info, KEY_CYCLE_WINDOWS, "cycle_windows_key", shortcuts); + parseShortcut (screen_info, KEY_DEL_WORKSPACE, "del_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_DEL_ACTIVE_WORKSPACE, "del_active_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_DOWN_WORKSPACE, "down_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_FILL_HORIZ, "fill_horiz_key", shortcuts); + parseShortcut (screen_info, KEY_FILL_VERT, "fill_vert_key", shortcuts); + parseShortcut (screen_info, KEY_FILL_WINDOW, "fill_window_key", shortcuts); + parseShortcut (screen_info, KEY_HIDE_WINDOW, "hide_window_key", shortcuts); + parseShortcut (screen_info, KEY_LEFT_WORKSPACE, "left_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_LOWER_WINDOW, "lower_window_key", shortcuts); + parseShortcut (screen_info, KEY_MOVE, "move_window_key", shortcuts); + parseShortcut (screen_info, KEY_MAXIMIZE_HORIZ, "maximize_horiz_key", shortcuts); + parseShortcut (screen_info, KEY_MAXIMIZE_VERT, "maximize_vert_key", shortcuts); + parseShortcut (screen_info, KEY_MAXIMIZE_WINDOW, "maximize_window_key", shortcuts); + parseShortcut (screen_info, KEY_MOVE_DOWN_WORKSPACE, "move_window_down_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_MOVE_LEFT_WORKSPACE, "move_window_left_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_MOVE_NEXT_WORKSPACE, "move_window_next_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_MOVE_PREV_WORKSPACE, "move_window_prev_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_MOVE_RIGHT_WORKSPACE, "move_window_right_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_MOVE_UP_WORKSPACE, "move_window_up_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_NEXT_WORKSPACE, "next_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_POPUP_MENU, "popup_menu_key", shortcuts); + parseShortcut (screen_info, KEY_PREV_WORKSPACE, "prev_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_RAISE_WINDOW, "raise_window_key", shortcuts); + parseShortcut (screen_info, KEY_RESIZE, "resize_window_key", shortcuts); + parseShortcut (screen_info, KEY_RIGHT_WORKSPACE, "right_workspace_key", shortcuts); + parseShortcut (screen_info, KEY_SHADE_WINDOW, "shade_window_key", shortcuts); + parseShortcut (screen_info, KEY_SHOW_DESKTOP, "show_desktop_key", shortcuts); + parseShortcut (screen_info, KEY_STICK_WINDOW, "stick_window_key", shortcuts); + parseShortcut (screen_info, KEY_TOGGLE_ABOVE, "above_key", shortcuts); + parseShortcut (screen_info, KEY_TOGGLE_FULLSCREEN, "fullscreen_key", shortcuts); + parseShortcut (screen_info, KEY_UP_WORKSPACE, "up_workspace_key", shortcuts); for (i = 0; i < 12; i++) { g_snprintf(keyname, sizeof (keyname), "move_window_workspace_%d_key", i + 1); - parseKeyString (dpy, &screen_info->params->keys[KEY_MOVE_WORKSPACE_1 + i], getStringValue (keyname, rc)); + parseShortcut (screen_info, KEY_MOVE_WORKSPACE_1 + i, keyname, shortcuts); g_snprintf(keyname, sizeof (keyname), "workspace_%d_key", i + 1); - parseKeyString (dpy, &screen_info->params->keys[KEY_WORKSPACE_1 + i], getStringValue (keyname, rc)); + parseShortcut (screen_info, KEY_WORKSPACE_1 + i, keyname, shortcuts); } + xfce_shortcuts_free (shortcuts); + myScreenUngrabKeys (screen_info); myScreenGrabKeys (screen_info); - return TRUE; + return; } gboolean @@ -802,11 +800,7 @@ loadSettings (ScreenInfo *screen_info) loadTheme (screen_info, rc); update_grabs (screen_info); - if (!loadKeyBindings (screen_info, rc)) - { - freeRc (rc); - return FALSE; - } + loadKeyBindings (screen_info); screen_info->params->borderless_maximize = getBoolValue ("borderless_maximize", rc); @@ -978,6 +972,20 @@ unloadTheme (ScreenInfo *screen_info) } } + +static void +unloadKeyBindings (ScreenInfo *screen_info) +{ + int i; + + g_return_if_fail (screen_info); + + for (i = 0; i < KEY_COUNT; ++i) + { + g_free (screen_info->params->keys[i].internal_name); + } +} + static void unloadSettings (ScreenInfo *screen_info) { @@ -986,6 +994,7 @@ unloadSettings (ScreenInfo *screen_info) TRACE ("entering unloadSettings"); unloadTheme (screen_info); + unloadKeyBindings (screen_info); } static gboolean @@ -1035,6 +1044,7 @@ reloadSettings (DisplayInfo *display_info, int mask) gboolean initSettings (ScreenInfo *screen_info) { + GdkKeymap *keymap; DisplayInfo *display_info; char **names; long val; @@ -1050,17 +1060,24 @@ initSettings (ScreenInfo *screen_info) return FALSE; } - display_info = screen_info->display_info; names = NULL; val = 0; i = 0; - screen_info->xfwm4_channel = xfconf_channel_new(CHANNEL1); - screen_info->keys_channel = xfconf_channel_new(CHANNEL2); + screen_info->xfwm4_channel = xfconf_channel_new(CHANNEL_XFWM); + g_signal_connect (screen_info->xfwm4_channel, "property-changed", + G_CALLBACK (cb_xfwm4_channel_property_changed), screen_info); - g_signal_connect (G_OBJECT(screen_info->xfwm4_channel), "property-changed", (GCallback)cb_xfwm4_channel_property_changed, screen_info); + keymap = gdk_keymap_get_default (); + g_signal_connect (keymap, "keys-changed", + G_CALLBACK (cb_keys_changed), screen_info); + screen_info->shortcuts_provider = xfce_shortcuts_provider_new ("xfwm4"); + g_signal_connect (screen_info->shortcuts_provider, "shortcut-added", + G_CALLBACK (cb_shortcut_added), screen_info); + g_signal_connect (screen_info->shortcuts_provider, "shortcut-removed", + G_CALLBACK (cb_shortcut_removed), screen_info); if (!loadSettings (screen_info)) { @@ -1360,3 +1377,115 @@ cb_xfwm4_channel_property_changed(XfconfChannel *channel, const gchar *property_ } } } + +static void +cb_keys_changed (GdkKeymap *keymap, ScreenInfo *screen_info) +{ + initModifiers (myScreenGetXDisplay (screen_info)); + reloadSettings (screen_info->display_info, UPDATE_BUTTON_GRABS); +} + +static void +cb_shortcut_added (XfceShortcutsProvider *provider, const gchar *shortcut, + ScreenInfo *screen_info) +{ + XfceShortcut *sc; + Display *dpy; + int i; + + g_return_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider)); + g_return_if_fail (shortcut); + g_return_if_fail (screen_info); + + sc = xfce_shortcuts_provider_get_shortcut (provider, shortcut); + + if (sc == NULL) + { + return; + } + + dpy = myScreenGetXDisplay (screen_info); + + for (i = 0; i < KEY_COUNT; ++i) + { + if (g_str_equal (screen_info->params->keys[i].internal_name, sc->command)) + { + parseKeyString (dpy, &screen_info->params->keys[i], shortcut); + + myScreenUngrabKeys (screen_info); + myScreenGrabKeys (screen_info); + break; + } + } + + xfce_shortcut_free (sc); +} + +static void +cb_shortcut_removed (XfceShortcutsProvider *provider, const gchar *shortcut, + ScreenInfo *screen_info) +{ + MyKey key; + Display *dpy; + int i; + + g_return_if_fail (XFCE_IS_SHORTCUTS_PROVIDER (provider)); + g_return_if_fail (screen_info); + g_return_if_fail (shortcut); + + dpy = myScreenGetXDisplay (screen_info); + + parseKeyString (dpy, &key, shortcut); + + for (i = 0; i < KEY_COUNT; ++i) + { + if (screen_info->params->keys[i].keycode == key.keycode && + screen_info->params->keys[i].modifier == key.modifier) + { + screen_info->params->keys[i].keycode = 0; + screen_info->params->keys[i].modifier = 0; + + myScreenUngrabKeys (screen_info); + myScreenGrabKeys (screen_info); + break; + } + } +} + +static void +parseShortcut (ScreenInfo *screen_info, int index, const gchar *name, + GList *shortcuts) +{ + Display *dpy; + const gchar *shortcut; + + g_return_if_fail (screen_info); + g_return_if_fail (index >= 0 && index < KEY_COUNT); + + dpy = myScreenGetXDisplay (screen_info); + shortcut = getShortcut (name, shortcuts); + parseKeyString (dpy, &screen_info->params->keys[index], shortcut); + + screen_info->params->keys[index].internal_name = g_strdup (name); +} + +static const gchar * +getShortcut (const gchar *name, GList *shortcuts) +{ + XfceShortcut *shortcut; + GList *iter; + const gchar *result = NULL; + + for (iter = shortcuts; iter != NULL; iter = g_list_next (iter)) + { + shortcut = iter->data; + + if (g_str_equal (shortcut->command, name)) + { + result = shortcut->shortcut; + break; + } + } + + return result; +}