diff --git a/capsicain/capsicain.cpp b/capsicain/capsicain.cpp index 4c189c1..a277a7e 100644 --- a/capsicain/capsicain.cpp +++ b/capsicain/capsicain.cpp @@ -41,6 +41,7 @@ struct Globals int capsicainOnOffKey = -1; bool protectConsole = true; //drop Pause and Break signals when console is foreground bool translateMessyKeys = true; //translate various DOS keys (e.g. Ctrl+Pause=SC_Break -> SC_Pause, Alt+Print=SC_altprint -> sc_print) + bool deactivateWinkeyStartmenu = false; } globals; static const struct Globals defaultGlobals; @@ -108,6 +109,7 @@ struct GlobalState int keysDownSentCounter = 0; //tracks how many keys are actually down that Windows knows about bool keysDownSent[256] = { false }; //Remember all forwarded to Windows. Sent keys must be 8 bit bool keysDownTempReleased[256] = { false }; //Remember all keys that were temporarily released, e.g. to send an Alt-Numpad combo + VKeyEvent lastSentKeyEvent = { SC_NOP, 0 }; //Remember the last key sent to Windows (to detect tapping of a rewired Win key) bool secretSequenceRecording = false; bool secretSequencePlayback = false; @@ -262,6 +264,7 @@ int main() while (true) { //remember previous two keys to detect tapping and Pause sequence + //convert with convertIkstroke2VKeyEvent(interceptionState.previousIKstroke1) before using, or you get problems with codes >=0x80 interceptionState.previousIKstroke2 = interceptionState.previousIKstroke1; interceptionState.previousIKstroke1 = interceptionState.currentIKstroke; @@ -1182,6 +1185,8 @@ void parseIniGlobals() globals.translateMessyKeys = false; else if (token == "dontprotectconsole") globals.protectConsole = false; + else if (token == "deactivatewinkeystartmenu") + globals.deactivateWinkeyStartmenu = true; else if ((token == "activeconfigonstartup") || (token == "activelayeronstartup")) cout << endl; else @@ -2047,10 +2052,20 @@ void sendVKeyEvent(VKeyEvent keyEvent) if (!keyEvent.isDownstroke && !globalState.keysDownSent[scancode]) //ignore up when key is already up { - IFDEBUG cout << " {blocked " << PRETTY_VK_LABELS[scancode] << " UP: was not down}"; + IFDEBUG cout << " {blocked " << PRETTY_VK_LABELS[scancode] << " UP: was not down.}"; return; } + //Cancel the tapped LWIN opening the pesky Start menu + if (globals.deactivateWinkeyStartmenu + && scancode == SC_LWIN && !keyEvent.isDownstroke && globalState.keysDownSent[SC_LWIN] + && ( globalState.lastSentKeyEvent.vcode == SC_LWIN) + ) + { + IFDEBUG cout << " { test WINKEY NO MENU send shift down up" << "}"; + SendShiftDownUp(); + } + //consistency check if (globalState.keysDownSent[scancode] == 0 && keyEvent.isDownstroke) globalState.keysDownSentCounter++; @@ -2090,6 +2105,7 @@ void sendVKeyEvent(VKeyEvent keyEvent) cout << " {" << PRETTY_VK_LABELS[keyEvent.vcode] << (keyEvent.isDownstroke ? "v" : "^") << " #" << globalState.keysDownSentCounter << "}"; interception_send(interceptionState.interceptionContext, interceptionState.interceptionDevice, (InterceptionStroke *)&iks, 1); + globalState.lastSentKeyEvent = keyEvent; //restore LEDs for ON/OFF indication? if (globals.capsicainOnOffKey >0 @@ -2104,6 +2120,17 @@ void sendVKeyEvent(VKeyEvent keyEvent) } } +//send shift down+up keystrokes; used to break the hardwired tapped Win -> start menu combo +void SendShiftDownUp() +{ + IFDEBUG cout << " { LSHFv^ to deactivateWinkeyStartmenu } "; + InterceptionKeyStroke iks = convertVkeyEvent2ikstroke({ SC_LSHIFT , true }); + iks.state = 0; + interception_send(interceptionState.interceptionContext, interceptionState.interceptionDevice, (InterceptionStroke*)&iks, 1); + iks.state = 1; + interception_send(interceptionState.interceptionContext, interceptionState.interceptionDevice, (InterceptionStroke*)&iks, 1); +} + void keySequenceAppendMakeKey(unsigned short scancode, vector &sequence) { diff --git a/capsicain/capsicain.h b/capsicain/capsicain.h index dfa867e..e513b18 100644 --- a/capsicain/capsicain.h +++ b/capsicain/capsicain.h @@ -5,7 +5,7 @@ #include "traybar.h" #define IFDEBUG if(options.debug && !globalState.secretSequenceRecording) -#define IFTRACE if(false) +#define IFTRACE if(false) //set to (true) for extra detail output #define IFPROF if(false) //measuring time takes some time @@ -41,6 +41,8 @@ void printOptions(); void sendVKeyEvent(VKeyEvent keyEvent); +void SendShiftDownUp(); + void sendResultingKeyOrSequence(); VKeyEvent convertIkstroke2VKeyEvent(InterceptionKeyStroke ikStroke); diff --git a/capsicain/capsicain.ini b/capsicain/capsicain.ini index 9a9fe68..3c638d0 100644 --- a/capsicain/capsicain.ini +++ b/capsicain/capsicain.ini @@ -52,10 +52,12 @@ #i69: define combos for macros #i70: allow ALT+NumPad combo for virtual numpad (e.g. with Alt+Tab+M=NP1) #i71: record macros with Ctrl+Caps+Number, play with Ctrl+TapCaps+Number -#i72: new GLOBALS DontTranslateMessyKeys, DontProtectConsole +#i72: new GLOBAL DontTranslateMessyKeys +#i72: new GLOBAL DontProtectConsole #i73: ctrl+both shift for Caps toggle (needed in case of Linux VM with grabbed keyboard) +#i74: new GLOBAL deactivateWinkeyStartmenu -GLOBAL IniVersion ini73c-test +GLOBAL IniVersion ini74 #any string, so you can check with Status [ESC]+[S] if you're using the right config @@ -90,6 +92,9 @@ GLOBAL capsicainOnOffKey SCRLOCK #GLOBAL DontTranslateMessyKeys #don't touch PRINT, SCRLOCK and PAUSE +GLOBAL DeactivateWinkeyStartmenu + #if LWIN key is tapped, press and release LSHF before releasing LWIN, so that the Start menu does not come up. You can still open it with Ctrl+Esc + [CONFIG_1] #OPTION debug OPTION configName QwertzJ-KingCon @@ -145,20 +150,9 @@ combo pause [&.&&] > moddedkey(B + .) [CONFIG_8] #TESTING OPTION ConfigName Testing OPTION debug -REWIRE TAB MOD12 NOP -COMBO M [&^^^ .... ....] > sequence (&LSHF_&M_^M_^LSHF_&I_^I_&T_^T_&SPACE_^SPACE_&F_^F_&R_&E_^R_^E_&U_^U_&N_^N_&D_^D_&L_^L_&I_&C_&H_^I_^C_^H_&E_&N_^E_^N_&SPACE_^SPACE_&RSHF_&G_^RSHF_^G_&R_^R_&RALT_&NP1_^NP1_&NP2_^NP2_&NP9_^NP9_^RALT_&S_^S_&S_&E_^S_&N_^E_^N_&RET_^RET) - -COMBO F1 [...& .... ....] > configSwitch(1) -COMBO F2 [...& .... ....] > configSwitch(2) -COMBO F3 [...& .... ....] > configSwitch(3) -COMBO F4 [...& .... ....] > configSwitch(4) -COMBO F5 [...& .... ....] > configSwitch(5) -COMBO F6 [...& .... ....] > configSwitch(6) -COMBO F7 [...& .... ....] > configSwitch(7) -COMBO F8 [...& .... ....] > configSwitch(8) -COMBO F9 [...& .... ....] > configSwitch(9) -COMBO F10 [...& .... ....] > layerSwitch(0) //layerSwitch is now configSwitch, but still supported -COMBO F12 [...& .... ....] > configPrevious() + +REWIRE w LWIN w + [CONFIG_9] #TEST error handling OPTION ConfigName Test diff --git a/capsicain/constants.h b/capsicain/constants.h index 3a73b16..feffe22 100644 --- a/capsicain/constants.h +++ b/capsicain/constants.h @@ -1,6 +1,6 @@ #pragma once -#define VERSION "96" +#define VERSION "97" //arbitray limits #define MAX_VCODES 0x121 //biggest defined code in scancodes.h must be smaller than this diff --git a/capsicain/scancodes.h b/capsicain/scancodes.h index 8d234ce..664b073 100644 --- a/capsicain/scancodes.h +++ b/capsicain/scancodes.h @@ -9,6 +9,7 @@ int getVcode(std::string label, std::string prettyVKLabels[]); //Physical Keyboard scan codes and their labels. //These labels are only visible while coding. +//scancodes are NOT Ascii codes //Put a space after every SC_X, and do NOT put a second SC_ into a line, not in the comments either enum ScanCode { diff --git a/x64/Release/capsicain.exe b/x64/Release/capsicain.exe index 73094b1..e7e3ca7 100644 Binary files a/x64/Release/capsicain.exe and b/x64/Release/capsicain.exe differ