Any help is appreciated, a working solution im willing to paypal bounty of 40 bucks.
The use case is that im using a windows start menu alternative named Flow Launcher. That program wants a Keybinding to open, but it cant be the windows key for whatever reason.
So currently its set to ctrl+space. However my muscle memory often still hits the windows key, and i want to fix that.
So i wrote a script that whenever i press the windows key, it will send ctrl+space.
But if i used the windows key to open file explorer (windows+e) or move windows around (windows+arrowright) i wanted that to still work.
I found that using KeyAwait created problems, so i switched to a manual form of KeyAwait using timers.
Right now the below code works, the only problem is that
- If i press Windows+E , it sends an E in whatever application im in (say an code editor)
- It doesnt work on the first keypress, only after the 2nd. (only Seems to be an issue with windows+e, not with windows+arrowright somehow?)
lwin down
e down
e up
lwin up
result=nothing, except an e typed in whatever app im in]
lwindown
e down
e up
e down
e up
lwin up
result = windows file explorer opens, but an e is left behind in the previous app
I know the below code is probably overengineerd to hell, but if someone could provide some help with a working solution
im willing to send you a bounty of 40 bucks via paypal.
Code: Select all
#InstallKeybdHook
DetectHiddenWindows, On
SetTitleMatchMode, 2
toggleState := false
currentWindowTitle := ""
ProcessExist(Name){
Process,Exist,%Name%
return Errorlevel
}
debugToFile(variable) {
FileAppend, % variable "`n", debug.log
}
keys := "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,0,1,2,3,4,5,6,7,8,9,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,Enter,Space,Tab,Shift,Control,Alt,Escape,Up,Down,Left,Right,Backspace,Delete,Insert,Home,End,PageUp,PageDown,PrintScreen,CapsLock,NumLock,ScrollLock,Pause,Divide,Multiply,Subtract,Add,Enter,Numpad0,Numpad1,Numpad2,Numpad3,Numpad4,Numpad5,Numpad6,Numpad7,Numpad8,Numpad9"
LWin::
debugToFile("LWin pressed")
;;Check if we have overflow running, if we do not then just make Lwin behave normally
if ProcessExist("Flow.Launcher.exe")
{
; Start a timer to keep track of how long the windows Key is being held down.
AnyKeyPressed := false
PressedKey := "" ; Initialize to empty string
Duration=0
Loop
{
;Increment the time
Duration ++
debugToFile(Duration)
;;Check if another key is being pressed in combination with the windows key, if so stop the timer
Loop, Parse, keys, `, ; Loop over keys
{
if (A_LoopField != "LWin") && GetKeyState(A_LoopField, "P") ; exclude LWin key
{
debugToFile(A_LoopField . " key pressed, stop the 'LWin' timer")
AnyKeyPressed := true
PressedKey := A_LoopField ; Store the pressed key
;;break the subloop
Break
}
}
;;Break the main loop if another key is pressed in combination with the windows key
If AnyKeyPressed
{
debugToFile("A key was pressed together with the windows key")
Break
}
;;If the windows key is released, stop the timer
If !GetKeyState("LWin","P")
{
debugToFile("LWin key released, stopping the timer, you probably want to open the windows menu")
Break
}
;;This makes the loop check itself every 10 miliseconds
Sleep, 10
}
debugToFile("State of Anykeypressed: " . AnyKeyPressed)
debugToFile("State of Duration: " . Duration)
If (Duration <= 20 && AnyKeyPressed == 0)
{
debugToFile("Opening overflow search")
Send ^{space}
}
else if (AnyKeyPressed == 1)
{
debugToFile("LWin key held for more than 200 milliseconds. duration:[" . Duration . "] anykeypressed: [" . AnyKeyPressed . "] pressedKey: [" . PressedKey . "]")
; if another key is pressed or LWin is held down for more than 2000 milliseconds, the Windows key willSorry for the abrupt cut-off. Here's the remaining part of the script:
lastPressedKeyWePressed := "" ; Initialize a variable to remember the last key we pressedeE
Duration=0
Loop
{
; Check if ANykey is pressed, if so
Loop, Parse, keys, `, ; Loop over keys
{
if (A_LoopField != "LWin") && GetKeyState(A_LoopField, "P") ; exclude LWin key
{
; Detect which Anykey was PressedKey
PressedKey := A_LoopField ; Store the pressed key
; press that key only if it wasn't the last key we pressed
if (PressedKey != lastPressedKeyWePressed) {
; function like normal
SendInput , {LWin Down}
debugToFile(A_LoopField . " alternate key pressed while holding down lwin")
lastPressedKeyWePressed := PressedKey
SendEvent , {%PressedKey% Down}
}
}
}
;; in this interval start waiting for the physical keystate to be released for that SPECIFIC key
; if its released send a PressedKey up
if (PressedKey != "" && !GetKeyState(PressedKey, "P")) ; If PressedKey is not empty and it's not pressed
{
debugToFile("User released the pressed key: [" . PressedKey . "]")
SendEvent , {%PressedKey% Up}
PressedKey := "" ; Reset PressedKey
}
; Also at the end wait for the keystae of Win to be released and send that up
if (!GetKeyState("LWin","P")) ; If LWin key is not pressed
{
debugToFile("User released the LWin key")
SendInput , {LWin Up}
Break ; Exit the loop
}
Sleep 10
Duration ++
}
}
else {
debugToFile("You probably want to open the windows menu, sending Lwinkeydown, and waiting for Lwin to be released, which is weird because our previous state said it was released.")
Send, {LWin Down}
; KeyWait, LWin
Send, {LWin Up}
}
}
else
{
; if the process doesn't exist, the Windows key will function like normal
Send, {LWin Down}
KeyWait, LWin
Send, {LWin Up}
}
return