The window menu displays the shortcut key for operations with a
shortcut, but does not display the modifiers. This reduces the utility
of the display as it's hard to know whether "h" means "Mod4+h" or
"Ctrl+Mod4+h" or something else.

This patch prefixes those shortcut displays with the modifier names,
e.g. Ctrl+Mod4+h, and adds a preference ModifierKeyLabels to allow
overriding this, e.g. to "⌃◇h". It doesn't add this preference to
WPrefs, if someone else wants to do that feel free.

Signed-off-by: Brad Jorsch <[email protected]>
---
 src/WindowMaker.h |    1 +
 src/defaults.c    |   34 +++++++++++++++++++++
 src/funcs.h       |    2 +
 src/winmenu.c     |   84 ++++++++++++++++++++++++----------------------------
 4 files changed, 76 insertions(+), 45 deletions(-)

diff --git a/src/WindowMaker.h b/src/WindowMaker.h
index 358a7b2..8293985 100644
--- a/src/WindowMaker.h
+++ b/src/WindowMaker.h
@@ -370,6 +370,7 @@ typedef struct WPreferences {
     signed char menu_style;           /* menu decoration style */
     signed char workspace_name_display_position;
     unsigned int modifier_mask;               /* mask to use as kbd modifier */
+    char *modifier_labels[7];          /* Names of the modifiers */
 
 
     char ws_advance;                   /* Create new workspace and advance */
diff --git a/src/defaults.c b/src/defaults.c
index 89b315e..9f953b1 100644
--- a/src/defaults.c
+++ b/src/defaults.c
@@ -147,6 +147,8 @@ static int setMenuStyle();
 static int setSwPOptions();
 static int updateUsableArea();
 
+static int setModifierKeyLabels();
+
 extern Cursor wCursor[WCUR_LAST];
 static int getCursor();
 static int setCursor();
@@ -511,6 +513,8 @@ WDefaultEntry optionList[] = {
            NULL, getColor, setIconTitleBack, NULL, NULL},
        {"SwitchPanelImages", "(swtile.png, swback.png, 30, 40)", &wPreferences,
            NULL, getPropList, setSwPOptions, NULL, NULL},
+       {"ModifierKeyLabels", "(\"Shift+\", \"Ctrl+\", \"Mod1+\", \"Mod2+\", 
\"Mod3+\", \"Mod4+\", \"Mod5+\")", &wPreferences,
+           NULL, getPropList, setModifierKeyLabels, NULL, NULL},
 
        /* keybindings */
 
@@ -2998,6 +3002,36 @@ static int setSwPOptions(WScreen * scr, WDefaultEntry * 
entry, WMPropList * arra
        return 0;
 }
 
+static int setModifierKeyLabels(WScreen * scr, WDefaultEntry * entry, 
WMPropList * array, void *foo)
+{
+       int i;
+       WPreferences *prefs = (WPreferences *) foo;
+
+       if (!WMIsPLArray(array) || WMGetPropListItemCount(array) != 7) {
+               wwarning(_("Value for option \"%s\" must be an array of 7 
strings"), entry->key);
+               WMReleasePropList(array);
+               return 0;
+       }
+
+       DestroyWindowMenu(scr);
+
+       for (i = 0; i < 7; i++) {
+               if (prefs->modifier_labels[i])
+                       wfree(prefs->modifier_labels[i]);
+
+               if (WMIsPLString(WMGetFromPLArray(array, i))) {
+                       prefs->modifier_labels[i] = 
wstrdup(WMGetFromPLString(WMGetFromPLArray(array, i)));
+               } else {
+                       wwarning(_("Invalid argument for option \"%s\" item 
%d"), entry->key, i);
+                       prefs->modifier_labels[i] = NULL;
+               }
+       }
+
+       WMReleasePropList(array);
+
+       return 0;
+}
+
 /*
  * Very ugly kluge.
  * Need access to the double click variables, so that all widgets in
diff --git a/src/funcs.h b/src/funcs.h
index 8b2b050..5d813ea 100644
--- a/src/funcs.h
+++ b/src/funcs.h
@@ -65,6 +65,8 @@ void OpenWorkspaceMenu(WScreen *scr, int x, int y);
 
 void CloseWindowMenu(WScreen *scr);
 
+void DestroyWindowMenu(WScreen *scr);
+
 WMagicNumber wAddDeathHandler(pid_t pid, WDeathHandler *callback, void *cdata);
 
 void wColormapInstallForWindow(WScreen *scr, WWindow *wwin);
diff --git a/src/winmenu.c b/src/winmenu.c
index 3598d5a..8e657e6 100644
--- a/src/winmenu.c
+++ b/src/winmenu.c
@@ -238,6 +238,25 @@ static void updateWorkspaceMenu(WMenu * menu)
                wMenuRealize(menu);
 }
 
+static char *getShortcutString(WShortKey key)
+{
+       char *tmp = NULL;
+       char *k = XKeysymToString(XKeycodeToKeysym(dpy, key.keycode, 0));
+       if (!k) return NULL;
+
+       char **m = wPreferences.modifier_labels;
+       if (key.modifier & ControlMask) tmp = wstrappend(tmp, m[1] ? m[1] : 
"Ctrl+");
+       if (key.modifier & ShiftMask)   tmp = wstrappend(tmp, m[0] ? m[0] : 
"Shift+");
+       if (key.modifier & Mod1Mask)    tmp = wstrappend(tmp, m[2] ? m[2] : 
"Mod1+");
+       if (key.modifier & Mod2Mask)    tmp = wstrappend(tmp, m[3] ? m[3] : 
"Mod2+");
+       if (key.modifier & Mod3Mask)    tmp = wstrappend(tmp, m[4] ? m[4] : 
"Mod3+");
+       if (key.modifier & Mod4Mask)    tmp = wstrappend(tmp, m[5] ? m[5] : 
"Mod4+");
+       if (key.modifier & Mod5Mask)    tmp = wstrappend(tmp, m[6] ? m[6] : 
"Mod5+");
+       tmp = wstrappend(tmp, k);
+
+       return tmp;
+}
+
 static void updateMakeShortcutMenu(WMenu * menu, WWindow * wwin)
 {
        WMenu *smenu = menu->cascades[menu->entries[MC_SHORTCUT]->cascade];
@@ -279,11 +298,11 @@ static void updateMakeShortcutMenu(WMenu * menu, WWindow 
* wwin)
                kcode = wKeyBindings[WKBD_WINDOW1 + shortcutNo].keycode;
 
                if (kcode) {
-                       if ((tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 
0)))
+                       if ((tmp = getShortcutString(wKeyBindings[WKBD_WINDOW1 
+ shortcutNo]))
                            && (!entry->rtext || strcmp(tmp, entry->rtext) != 
0)) {
                                if (entry->rtext)
                                        wfree(entry->rtext);
-                               entry->rtext = wstrdup(tmp);
+                               entry->rtext = tmp;
                                smenu->flags.realized = 0;
                        }
                        wMenuSetEnabled(smenu, i, True);
@@ -394,9 +413,7 @@ static WMenu *makeOptionsMenu(WScreen * scr)
 static WMenu *createWindowMenu(WScreen * scr)
 {
        WMenu *menu;
-       KeyCode kcode;
        WMenuEntry *entry;
-       char *tmp;
 
        menu = wMenuCreate(scr, NULL, False);
        /*
@@ -405,52 +422,22 @@ static WMenu *createWindowMenu(WScreen * scr)
         * this file.
         */
        entry = wMenuAddCallback(menu, _("Maximize"), execMenuCommand, NULL);
-       if (wKeyBindings[WKBD_MAXIMIZE].keycode != 0) {
-               kcode = wKeyBindings[WKBD_MAXIMIZE].keycode;
-
-               if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, 
kcode, 0))))
-                       entry->rtext = wstrdup(tmp);
-       }
+       entry->rtext = getShortcutString(wKeyBindings[WKBD_MAXIMIZE]);
 
        entry = wMenuAddCallback(menu, _("Miniaturize"), execMenuCommand, NULL);
-       if (wKeyBindings[WKBD_MINIATURIZE].keycode != 0) {
-               kcode = wKeyBindings[WKBD_MINIATURIZE].keycode;
-
-               if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, 
kcode, 0))))
-                       entry->rtext = wstrdup(tmp);
-       }
+       entry->rtext = getShortcutString(wKeyBindings[WKBD_MINIATURIZE]);
 
        entry = wMenuAddCallback(menu, _("Shade"), execMenuCommand, NULL);
-       if (wKeyBindings[WKBD_SHADE].keycode != 0) {
-               kcode = wKeyBindings[WKBD_SHADE].keycode;
-
-               if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, 
kcode, 0))))
-                       entry->rtext = wstrdup(tmp);
-       }
+       entry->rtext = getShortcutString(wKeyBindings[WKBD_SHADE]);
 
        entry = wMenuAddCallback(menu, _("Hide"), execMenuCommand, NULL);
-       if (wKeyBindings[WKBD_HIDE].keycode != 0) {
-               kcode = wKeyBindings[WKBD_HIDE].keycode;
-
-               if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, 
kcode, 0))))
-                       entry->rtext = wstrdup(tmp);
-       }
+       entry->rtext = getShortcutString(wKeyBindings[WKBD_HIDE]);
 
        entry = wMenuAddCallback(menu, _("Resize/Move"), execMenuCommand, NULL);
-       if (wKeyBindings[WKBD_MOVERESIZE].keycode != 0) {
-               kcode = wKeyBindings[WKBD_MOVERESIZE].keycode;
-
-               if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, 
kcode, 0))))
-                       entry->rtext = wstrdup(tmp);
-       }
+       entry->rtext = getShortcutString(wKeyBindings[WKBD_MOVERESIZE]);
 
        entry = wMenuAddCallback(menu, _("Select"), execMenuCommand, NULL);
-       if (wKeyBindings[WKBD_SELECT].keycode != 0) {
-               kcode = wKeyBindings[WKBD_SELECT].keycode;
-
-               if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, 
kcode, 0))))
-                       entry->rtext = wstrdup(tmp);
-       }
+       entry->rtext = getShortcutString(wKeyBindings[WKBD_SELECT]);
 
        entry = wMenuAddCallback(menu, _("Move To"), NULL, NULL);
        scr->workspace_submenu = makeWorkspaceMenu(scr);
@@ -468,11 +455,7 @@ static WMenu *createWindowMenu(WScreen * scr)
         */
 
        entry = wMenuAddCallback(menu, _("Close"), execMenuCommand, NULL);
-       if (wKeyBindings[WKBD_CLOSE].keycode != 0) {
-               kcode = wKeyBindings[WKBD_CLOSE].keycode;
-               if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, 
kcode, 0))))
-                       entry->rtext = wstrdup(tmp);
-       }
+       entry->rtext = getShortcutString(wKeyBindings[WKBD_CLOSE]);
 
        entry = wMenuAddCallback(menu, _("Kill"), execMenuCommand, NULL);
 
@@ -711,3 +694,14 @@ void OpenMiniwindowMenu(WWindow * wwin, int x, int y)
 
        wMenuMapAt(menu, x, y, False);
 }
+
+void DestroyWindowMenu(WScreen *scr)
+{
+       if (scr->window_menu) {
+               scr->window_menu->entries[MC_MINIATURIZE]->text = NULL;
+               scr->window_menu->entries[MC_MAXIMIZE]->text = NULL;
+               scr->window_menu->entries[MC_SHADE]->text = NULL;
+               wMenuDestroy(scr->window_menu, True);
+               scr->window_menu = NULL;
+       }
+}
-- 
1.7.2.3


-- 
To unsubscribe, send mail to [email protected].

Reply via email to