From a0e770d2a006aa9d6c2703960c68fb607a378039 Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Sat, 26 Jan 2008 00:36:58 +0100 Subject: [PATCH] fix remaining NumLock problems by teaching tk to detect the Alt modifier --- res/weditor.tcl | 8 +++--- res/whead.tcl | 30 ++++++++++----------- res/wmap.tcl | 8 +++--- src/tk/tkbind.c | 66 +++++++++++++++++++++++++++++++++++++++-------- src/tk/tkint.h | 6 +++++ src/tk/tkwindow.c | 3 +++ 6 files changed, 87 insertions(+), 34 deletions(-) diff --git a/res/weditor.tcl b/res/weditor.tcl index 0d407d2..36f2571 100644 --- a/res/weditor.tcl +++ b/res/weditor.tcl @@ -120,7 +120,7 @@ if {0} { -relief flat tk_bindForTraversal $win.topframe.controls.update bind $win.topframe.controls.update {tk_firstMenu %W} - bind $win.topframe.controls.update {tk_traverseToMenu %W %A} + bind $win.topframe.controls.update {tk_traverseToMenu %W %A} tk_menus $win $win.topframe.controls.update SetHelp $win.topframe.controls.update Editor.Display @@ -129,7 +129,7 @@ if {0} { -font [Font $win Medium] tk_bindForTraversal $win.topframe.controls.update.m bind $win.topframe.controls.update.m {tk_firstMenu %W} - bind $win.topframe.controls.update.m {tk_traverseToMenu %W %A} + bind $win.topframe.controls.update.m {tk_traverseToMenu %W %A} $win.topframe.controls.update.m add radiobutton\ -label {Always}\ -variable Skip.$win\ @@ -166,7 +166,7 @@ menubutton $win.topframe.controls.options\ -relief flat tk_bindForTraversal $win.topframe.controls.options bind $win.topframe.controls.options {tk_firstMenu %W} -bind $win.topframe.controls.options {tk_traverseToMenu %W %A} +bind $win.topframe.controls.options {tk_traverseToMenu %W %A} tk_menus $win $win.topframe.controls.options SetHelp $win.topframe.controls.options Editor.Options @@ -175,7 +175,7 @@ menu $win.topframe.controls.options.m\ -font [Font $win Medium] tk_bindForTraversal $win.topframe.controls.options.m bind $win.topframe.controls.options.m {tk_firstMenu %W} -bind $win.topframe.controls.options.m {tk_traverseToMenu %W %A} +bind $win.topframe.controls.options.m {tk_traverseToMenu %W %A} $win.topframe.controls.options.m add checkbutton\ -label {Auto Goto}\ -variable AutoGoto.$win\ diff --git a/res/whead.tcl b/res/whead.tcl index 7e9df1f..e782f90 100644 --- a/res/whead.tcl +++ b/res/whead.tcl @@ -121,7 +121,7 @@ LinkWindow $win.ask {} tk_bindForTraversal $win bind $win {tk_firstMenu %W} -bind $win {tk_traverseToMenu %W %A} +bind $win {tk_traverseToMenu %W %A} wm title $win "Micropolis Controls" wm iconname $win {Micropolis Controls} @@ -151,7 +151,7 @@ frame $win.col1.w1.f1\ -relief raised tk_bindForTraversal $win.col1.w1.f1 bind $win.col1.w1.f1 {tk_firstMenu %W} -bind $win.col1.w1.f1 {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1 {tk_traverseToMenu %W %A} SetHelp $win.col1.w1.f1.micropolis Head.MicropolisMenu @@ -162,7 +162,7 @@ menubutton $win.col1.w1.f1.micropolis\ -variable $win.postedMenu tk_bindForTraversal $win.col1.w1.f1.micropolis bind $win.col1.w1.f1.micropolis {tk_firstMenu %W} -bind $win.col1.w1.f1.micropolis {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1.micropolis {tk_traverseToMenu %W %A} tk_menus $win $win.col1.w1.f1.micropolis @@ -170,7 +170,7 @@ menu $win.col1.w1.f1.micropolis.m\ -font [Font $win Medium] tk_bindForTraversal $win.col1.w1.f1.micropolis.m bind $win.col1.w1.f1.micropolis.m {tk_firstMenu %W} -bind $win.col1.w1.f1.micropolis.m {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1.micropolis.m {tk_traverseToMenu %W %A} $win.col1.w1.f1.micropolis.m add command\ -label {About...}\ -command "UIShowPicture 300" @@ -201,7 +201,7 @@ menubutton $win.col1.w1.f1.options\ -variable $win.postedMenu tk_bindForTraversal $win.col1.w1.f1.options bind $win.col1.w1.f1.options {tk_firstMenu %W} -bind $win.col1.w1.f1.options {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1.options {tk_traverseToMenu %W %A} tk_menus $win $win.col1.w1.f1.options @@ -209,7 +209,7 @@ menu $win.col1.w1.f1.options.m\ -font [Font $win Medium] tk_bindForTraversal $win.col1.w1.f1.options.m bind $win.col1.w1.f1.options.m {tk_firstMenu %W} -bind $win.col1.w1.f1.options.m {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1.options.m {tk_traverseToMenu %W %A} $win.col1.w1.f1.options.m add checkbutton\ -label {Auto Budget}\ -variable AutoBudget\ @@ -248,7 +248,7 @@ menubutton $win.col1.w1.f1.disasters\ -variable $win.postedMenu tk_bindForTraversal $win.col1.w1.f1.disasters bind $win.col1.w1.f1.disasters {tk_firstMenu %W} -bind $win.col1.w1.f1.disasters {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1.disasters {tk_traverseToMenu %W %A} tk_menus $win $win.col1.w1.f1.disasters @@ -256,7 +256,7 @@ menu $win.col1.w1.f1.disasters.m\ -font [Font $win Medium] tk_bindForTraversal $win.col1.w1.f1.disasters.m bind $win.col1.w1.f1.disasters.m {tk_firstMenu %W} -bind $win.col1.w1.f1.disasters.m {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1.disasters.m {tk_traverseToMenu %W %A} $win.col1.w1.f1.disasters.m add command\ -label {Monster}\ -command "UIDisaster $win \"UIMakeMonster\" \"release a monster?\"" @@ -290,7 +290,7 @@ menubutton $win.col1.w1.f1.priority\ -variable $win.postedMenu tk_bindForTraversal $win.col1.w1.f1.priority bind $win.col1.w1.f1.priority {tk_firstMenu %W} -bind $win.col1.w1.f1.priority {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1.priority {tk_traverseToMenu %W %A} tk_menus $win $win.col1.w1.f1.priority @@ -298,7 +298,7 @@ menu $win.col1.w1.f1.priority.m\ -font [Font $win Medium] tk_bindForTraversal $win.col1.w1.f1.priority.m bind $win.col1.w1.f1.priority.m {tk_firstMenu %W} -bind $win.col1.w1.f1.priority.m {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1.priority.m {tk_traverseToMenu %W %A} $win.col1.w1.f1.priority.m add radiobutton\ -label {Super Fast}\ -command {SetPriority 4}\ @@ -334,7 +334,7 @@ menubutton $win.col1.w1.f1.windows\ -variable $win.postedMenu tk_bindForTraversal $win.col1.w1.f1.windows bind $win.col1.w1.f1.windows {tk_firstMenu %W} -bind $win.col1.w1.f1.windows {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1.windows {tk_traverseToMenu %W %A} tk_menus $win $win.col1.w1.f1.windows @@ -342,7 +342,7 @@ menu $win.col1.w1.f1.windows.m\ -font [Font $win Medium] tk_bindForTraversal $win.col1.w1.f1.windows.m bind $win.col1.w1.f1.windows.m {tk_firstMenu %W} -bind $win.col1.w1.f1.windows.m {tk_traverseToMenu %W %A} +bind $win.col1.w1.f1.windows.m {tk_traverseToMenu %W %A} $win.col1.w1.f1.windows.m add command\ -label {Budget}\ -command "UIShowBudgetAndWait" @@ -530,7 +530,7 @@ frame $win.col1.w1.f2.f2\ -relief flat tk_bindForTraversal $win.col1.w1.f2.f2 bind $win.col1.w1.f2.f2 {tk_firstMenu %W} -bind $win.col1.w1.f2.f2 {tk_traverseToMenu %W %A} +bind $win.col1.w1.f2.f2 {tk_traverseToMenu %W %A} SetHelp $win.col1.w1.f2.f2 Head.Log @@ -572,7 +572,7 @@ if {[sim MultiPlayerMode]} { -relief flat tk_bindForTraversal $win.col1.w1.f2.f3 bind $win.col1.w1.f2.f3 {tk_firstMenu %W} - bind $win.col1.w1.f2.f3 {tk_traverseToMenu %W %A} + bind $win.col1.w1.f2.f3 {tk_traverseToMenu %W %A} button $win.col1.w1.f2.f3.chat \ -font [Font $win Large] \ @@ -595,7 +595,7 @@ if {[sim MultiPlayerMode]} { set $win.col1.w1.f2.f3.entry.value "" tk_bindForTraversal $win.col1.w1.f2.f3.entry bind $win.col1.w1.f2.f3.entry {tk_firstMenu %W} - bind $win.col1.w1.f2.f3.entry {tk_traverseToMenu %W %A} + bind $win.col1.w1.f2.f3.entry {tk_traverseToMenu %W %A} bind $win.col1.w1.f2.f3.entry "DoEnterMessage %W %W.value" bind $win.col1.w1.f2.f3.entry "DoEvalMessage %W %W.value" bind $win.col1.w1.f2.f3.entry {focus %W} diff --git a/res/wmap.tcl b/res/wmap.tcl index 73e7d6f..b497c35 100644 --- a/res/wmap.tcl +++ b/res/wmap.tcl @@ -124,7 +124,7 @@ menubutton $win.topframe.zones\ LinkWindow $win.zones $win.topframe.zones tk_bindForTraversal $win.topframe.zones bind $win.topframe.zones {tk_firstMenu %W} -bind $win.topframe.zones {tk_traverseToMenu %W %A} +bind $win.topframe.zones {tk_traverseToMenu %W %A} tk_menus $win $win.topframe.zones SetHelp $win.topframe.zones Map.Zones @@ -133,7 +133,7 @@ menu $win.topframe.zones.m\ -font [Font $win Medium] tk_bindForTraversal $win.topframe.zones.m bind $win.topframe.zones.m {tk_firstMenu %W} -bind $win.topframe.zones.m {tk_traverseToMenu %W %A} +bind $win.topframe.zones.m {tk_traverseToMenu %W %A} $win.topframe.zones.m add radiobutton\ -label {All}\ -variable MapState.$win\ @@ -176,7 +176,7 @@ menubutton $win.topframe.overlays\ LinkWindow $win.overlays $win.topframe.overlays tk_bindForTraversal $win.topframe.overlays bind $win.topframe.overlays {tk_firstMenu %W} -bind $win.topframe.overlays {tk_traverseToMenu %W %A} +bind $win.topframe.overlays {tk_traverseToMenu %W %A} tk_menus $win $win.topframe.overlays SetHelp $win.topframe.overlays Map.Overlays @@ -185,7 +185,7 @@ menu $win.topframe.overlays.m\ -font [Font $win Medium] tk_bindForTraversal $win.topframe.overlays.m bind $win.topframe.overlays.m {tk_firstMenu %W} -bind $win.topframe.overlays.m {tk_traverseToMenu %W %A} +bind $win.topframe.overlays.m {tk_traverseToMenu %W %A} $win.topframe.overlays.m add radiobutton\ -label {Population Density}\ -variable MapState.$win\ diff --git a/src/tk/tkbind.c b/src/tk/tkbind.c index 14cad9f..d32d8c9 100644 --- a/src/tk/tkbind.c +++ b/src/tk/tkbind.c @@ -229,11 +229,11 @@ static ModInfo modArray[] = { "Button5", Button5Mask, 0, "Mod1", Mod1Mask, 0, "M1", Mod1Mask, 0, - "Meta", Mod1Mask, 0, - "M", Mod1Mask, 0, + "Meta", META_MASK, 0, + "M", META_MASK, 0, "Mod2", Mod2Mask, 0, "M2", Mod2Mask, 0, - "Alt", Mod2Mask, 0, + "Alt", ALT_MASK, 0, "Mod3", Mod3Mask, 0, "M3", Mod3Mask, 0, "Mod4", Mod4Mask, 0, @@ -383,8 +383,8 @@ static PatSeq * FindSequence _ANSI_ARGS_((Tcl_Interp *interp, static char * GetField _ANSI_ARGS_((char *p, char *copy, int size)); static KeySym GetKeySym _ANSI_ARGS_((TkDisplay *dispPtr, XEvent *eventPtr)); -static PatSeq * MatchPatterns _ANSI_ARGS_((BindingTable *bindPtr, - PatSeq *psPtr)); +static PatSeq * MatchPatterns _ANSI_ARGS_((TkDisplay *dispPtr, + BindingTable *bindPtr, PatSeq *psPtr)); /* *-------------------------------------------------------------- @@ -1034,14 +1034,14 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) key.detail = detail; hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key); if (hPtr != NULL) { - matchPtr = MatchPatterns(bindPtr, + matchPtr = MatchPatterns(dispPtr, bindPtr, (PatSeq *) Tcl_GetHashValue(hPtr)); } if ((detail != 0) && (matchPtr == NULL)) { key.detail = 0; hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key); if (hPtr != NULL) { - matchPtr = MatchPatterns(bindPtr, + matchPtr = MatchPatterns(dispPtr, bindPtr, (PatSeq *) Tcl_GetHashValue(hPtr)); } } @@ -1576,7 +1576,8 @@ GetKeySym(dispPtr, eventPtr) */ static PatSeq * -MatchPatterns(bindPtr, psPtr) +MatchPatterns(dispPtr, bindPtr, psPtr) + TkDisplay *dispPtr; BindingTable *bindPtr; /* Information about binding table, such * as ring of recent events. */ register PatSeq *psPtr; /* List of pattern sequences. */ @@ -1640,9 +1641,52 @@ MatchPatterns(bindPtr, psPtr) } else { state = 0; } - if ((state & patPtr->needMods) - != patPtr->needMods) { - goto nextSequence; + if (patPtr->needMods != 0) { + int modMask = patPtr->needMods; + + if (!dispPtr->metaModMask && !dispPtr->altModMask && !dispPtr->modeModMask) { + int i, max; + XModifierKeymap *modMapPtr; + KeyCode *codePtr; + KeySym keysym; + + modMapPtr = XGetModifierMapping(dispPtr->display); + codePtr = modMapPtr->modifiermap; + max = 8*modMapPtr->max_keypermod; + + for (i = 0; i < max; i++, codePtr++) { + if (*codePtr == 0) { + continue; + } + keysym = XKeycodeToKeysym(dispPtr->display, *codePtr, 0); + if (keysym == XK_Mode_switch) { + dispPtr->modeModMask |= ShiftMask << (i/modMapPtr->max_keypermod); + } + if ((keysym == XK_Meta_L) || (keysym == XK_Meta_R)) { + dispPtr->metaModMask |= ShiftMask << (i/modMapPtr->max_keypermod); + } + if ((keysym == XK_Alt_L) || (keysym == XK_Alt_R)) { + dispPtr->altModMask |= ShiftMask << (i/modMapPtr->max_keypermod); + } + } + } + if ((modMask & META_MASK) && (dispPtr->metaModMask != 0)) { + modMask = (modMask & ~META_MASK) | dispPtr->metaModMask; + } + if ((modMask & ALT_MASK) && (dispPtr->altModMask != 0)) { + modMask = (modMask & ~ALT_MASK) | dispPtr->altModMask; + } + + if ((state & META_MASK) && (dispPtr->metaModMask != 0)) { + state = (state & ~META_MASK) | dispPtr->metaModMask; + } + if ((state & ALT_MASK) && (dispPtr->altModMask != 0)) { + state = (state & ~ALT_MASK) | dispPtr->altModMask; + } + + if ((state & modMask) != modMask) { + goto nextSequence; + } } #if 0 if ((state & patPtr->hateMods) != 0) { diff --git a/src/tk/tkint.h b/src/tk/tkint.h index e2c7b7e..a5cc780 100644 --- a/src/tk/tkint.h +++ b/src/tk/tkint.h @@ -38,6 +38,9 @@ #include "tclhash.h" #endif +#define META_MASK (AnyModifier<<1) +#define ALT_MASK (AnyModifier<<2) + /* * One of the following structures is maintained for each display * containing a window managed by Tk: @@ -76,6 +79,9 @@ typedef struct TkDisplay { * retrieved from the server yet. */ KeySym *keySyms; /* Array of KeySyms, returned by * XGetKeyboardMapping. */ + unsigned int modeModMask; + unsigned int metaModMask; + unsigned int altModMask; /* * Information used by tkError.c only: diff --git a/src/tk/tkwindow.c b/src/tk/tkwindow.c index 77e0b77..05029aa 100644 --- a/src/tk/tkwindow.c +++ b/src/tk/tkwindow.c @@ -360,6 +360,9 @@ GetScreen(interp, screenName, screenPtr) dispPtr->selectionSerial = 0; dispPtr->multipleAtom = None; dispPtr->atomInit = 0; + dispPtr->modeModMask = 0; + dispPtr->metaModMask = 0; + dispPtr->altModMask = 0; dispPtr->cursorFont = None; dispPtr->grabWinPtr = NULL; dispPtr->ungrabWinPtr = NULL; -- 2.39.5