Autohotkey check for Ctrl pressed error - keypress

I've only recently gotten back into using AHK after taking a break from it for a few years, so forgive me if there's a very easy answer for this.
I'm writing a script which tracks keypresses while control is held down, and then allows one of 9 hotkeys to be used with 2 keypresses, so that pressing Q twice will activate the 1-1 hotkey, W then Q will activate the 1-2 hotkey etc.
my problem is that checking if Control is pressed using a hotkey for LControl blocks LControl being sent to the system, so things like Ctrl+A don't work anymore.
the only solution i've been able to think of would be to have Q W and E mapped as a hotkey only once, with a bunch of logic inside each of them.
Is there a better way I can do this?
LControl:: Set:=4
LControl Up:: Set:=0
#If (Set=4)
{
q:: Set:=1
w:: Set:=2
e:: Set:=3
}
#If (Set=1)
{
q:: SendEvent Different Words Here
w:: SendEvent Different Words Here
e:: SendEvent Different Words Here
}
#If (Set=2)
{
q:: SendEvent Different Words Here
w:: SendEvent Different Words Here
e:: SendEvent Different Words Here
}
#If (Set=3)
{
q:: SendEvent Different Words Here
w:: SendEvent Different Words Here
e:: SendEvent Different Words Here
}
Basically, how can I stop LControl:: Blocking the sending of Ctrl to the system.

Figured it out.
LControl:: ;if ctrl is pressed
Set:=4 ;enter first selection group
SendEvent {Ctrl Down} ;don't interrupt normal hotkeys
Return
LControl Up:: ;if ctrl is released
Set:=0 ;"unbind" q/w/e hotkeys
SendEvent {Ctrl Up} ;and inform the system
Return
#If (Set=4)
{
^q:: Set:=1
^w:: Set:=2
^e:: Set:=3
}

Related

AutoHotKey If Key pressed while win11 TaskView is open syntax

I've recently been using Gnome 41.5 and fell in love with the way the Activities menu works
So I am trying to use AHK to create a script that when I press the windows key it opens Task View - then if Task View is open and I start to type, (to search for an application) I want AHK to open the start menu so that I can utilize its search function
My rough outline for how I imagine it would work below - I've been trying to learn but got stuck here
Lwin::
Send, #{Tab}
if (""taskview is open"" + ""any char pressed"") {
Send, Rctrl + Esc
}
In the future I'd love to have the start button just appear on the Task View screen so that it's almost just like Gnome
i wanted to do the same thing and got this so far, i like how this works tbh, but you might wanna add RWin as well (i don't have it, so i didn't)
before task view appears the start menu flashes shortly, but the activation timing keeps shortcuts working without opening task view, so it's a good tradeoff imo.
;couldn't check these names bc the names are different based on system language
;double click on the script in the task tray and hit CTRL+K to figure out the correct name
taskView := "Task View" ;these 2 names are guesses
search := "Search"
;----------------------------------------------------------------------
;Hotkey function hotkeys have to be created first
Hotkey, ~*LButton, mousedown, off
Hotkey, ~*RButton, mousedown, off
Hotkey, ~*MButton, mousedown, off
Hotkey, ~LWin, showTask
;checks every half second if you're in task view to activate the key logging
SetTimer, taskInput, 500
return
showTask:
;prevent repeats
keywait, LWin
;cancel if a different key got pressed while win was held down
if (A_PriorKey != "LWin") {
return
}
if WinActive(taskView){
sleep 1
send {Esc}
return
}
else send #{tab}
taskInput:
if (!WinActive(taskView)){
return
}
Mouse_Flag = 0
Hotkey, ~*LButton, on
Hotkey, ~*RButton, on
Hotkey, ~*MButton, on
;wait for any key
Input, key, L1 V, {VK0E}{LWin}{RWin}{Home}{End}{PgUp}{PgDn}{Del}{Ins}{BS}{Pause} ;excluded: {LControl}{RControl}{LAlt}{RAlt}{LShift}{RShift}{CapsLock}{NumLock}{PrintScreen}{Left}{Right}{Up}{Down}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}
if WinActive(taskView){
if (key = LWin) {
keywait, LWin
sleep 1
send {Esc}
}
else if (Mouse_Flag || key = Chr(27)) { ;chr 27 = blank space character, matches some characters specified in the any key input check, notably Esc
;nothing/return
}
else {
;open search
send #s
WinWaitActive %search%
if("LWin" != A_PriorKey && key != A_PriorKey){ ;slight fix if you type very fast and the letters get jumbled bc winwaitactive takes too long
send {BS}
send {%key%}
send {%A_PriorKey%}
}
else send {%key%}
}
}
Hotkey, ~*LButton, off
Hotkey, ~*RButton, off
Hotkey, ~*MButton, off
Return
mousedown:
Mouse_Flag = 1
sendevent, {Blind}{VK0E} ;unused virtual key
return

AutoHotKey: Toggle RAlt to Mouse Hotkey with Another Hotkey

I'm trying to create a Hotkey (Win+Shift+Q) that toggles on/off another Hotkey that changes the right Alt key to a left mouse click; however, I can't get it to work.
Expected Behavior:
Pressing Windows+Shift+Q will initially toggle the Right-Alt key to act as a left mouse click.
Pressing Windows+Shift+Q again will toggle the Right-Alt key back to acting as a Right-Alt key.
Pressing Windows+Shift+Q again will revert to the left-click behavior (see #1). And so on.
Here's the most current iteration of my code:
Hotkey, RAlt, MyClick, On
#+Q:: ;Win+Shift+Q :: ::Right-Alt acts as a left mouse button click
switch := !switch
MsgBox %switch%
Hotkey RAlt, % (switch ? "Off": "On")
Return
MyClick:
MouseClick
Return
When I run my script I get the following error after clicking OK on the MsgBox and the script quits:
Error: Nonexistent hotkey
Specifically: RAlt
Line#
141: Hotkey,RAlt,MyClick,On
143: switch:=!switch
144: MsgBox %switch%
-->145: Hotkey RAlt, % (switch ? "Off": "On")
146: Return
149: MouseClick
150: Return
The current thread will exit.
Most of the other posts that might relate (Can AutoHotKey toggle keymapping?, Autohotkey: Toggle a set of keybinds on and off) only deal with key to key mapping and not key to mouse mapping. I can't tell if that is the cause of my issues or not.
Previously I had this, but the Win+Shift+Q didn't toggle the behavior, RAlt always acted as a left-click so I commented it out:
#+Q:: ;Win+Shift+Q :: ::Right-Alt acts as a left mouse button click
RAlt::LButton
;Hotkey, RAlt, Toggle ;Does not work for some reason
int += 1
test := mod(int, 2) = 0
if (test) {
msgbox on
Hotkey, RAlt, On
}
else {
msgbox off
Hotkey, leftClick, Off
}
Return
I'll also add that I would like this behavior across Windows, not just a single application (which also seems to be a topic in other posts that allows for the #IfWinActive-type suggestions/solutions).
I tried your current iteration of code in AutoHotkey v1.1.13.01 Unicode 32-bit and I don't have any errors after pressing OK on the message box, the script works as advertised.
Try updating your AutoHotkey version here: http://ahkscript.org/download/ and see if the problem persists.
bState:=False
#If bState
RAlt::Click
#If
#+vk51:: ; win + shift + q
KeyWait, vk51
TrayTip, % "state of switch", % (bState:=!bState) ? "on":"off"
Return

Cancel an existing key remap in autohotkey

I have a AutoHotKey script that asks me if I want to remap my Win keys to Ctrl or cancel their remapping, thus making them Win keys again.
However I cannot find a way to cancel the remap. If I use the command LWin::Lwin I get the error message that there is a "duplicate key".
I'm new to AutoHotKey, but I did search first, so please don't bite my head off is this is a stupid question. (It is a Lenovo laptop with Windows7-64).
Here's the script:
MsgBox, 4, , Remap CTRL for Desktop Keyboard?
IfMsgBox, Yes
LWin::LCtrl
RWin::RCtrl
return
; Otherwise, the user picked No
; LWin::LWin
; RWin::RWin
; return
Various ways.
Create a hotkey to close ahk, e.g. ^!x::ExitApp = [Ctrl]+[Alt]+[x]
Create a hotkey to disable/enable all hotkeys e.g. f12::suspend
Create hotkeys that ONLY work in a specific appliaction.
Here are all suggestions combined.
Under normal circumstances: LWin::LCtrl and RWin::RCtrl are active, Unless you pressed F12. You can in AHK_L set variables that can be used in #If (Var = 1), where you can define Hotkeys that only work when that variable is set to 1 (true).
SetTitleMatchMode, 2 ; Allow the use of a portion of the wintitle
F12::
Suspend
If A_IsSuspended
TrayTip, HotKeys, Off, 3, 0
Else
TrayTip, HotKeys, On, 3, 0
Return
^!x::ExitApp
LWin::LCtrl
RWin::RCtrl
F1::MsgBox, Normal Mode
#IfWinActive, Window title
F1::MsgBox, Window X is active
F2::MsgBox, You pressed F2 inside Window x
#IfWinActive
Toggle := False
F10::Toggle := !Toggle ; Turns Mouse button ON|Off
#if Toggle ; ONLY worls in AHK_L
LButton::Return ; Disables Mouse button
#if
Here's a version you can drive from the command line:
; Allow the script to be reloaded multiple times
#SingleInstance force
; Check the command line for input
NumberOfParameters = %0%
; If any command line param was passed then just unload the mappings
If ( NumberOfParameters > 0 )
{
MsgBox Command line parameter was passed, unloading...
ExitApp
}
Else
{
; Let's ask the user what they want to do
MsgBox, 4, , Remap CTRL for Desktop Keyboard?
IfMsgBox, Yes
{
; If yes, then remap
MsgBox Keys have been mapped.
}
Else
{
; If no, then unload
MsgBox Unloading mapping.
ExitApp
}
}
; Keys will be mapped so long as the script remains resident
LWin::LCtrl
RWin::RCtrl

Fix multiple middle mouse click

Basically I have an issue where the middle mouse button when clicked does multiple very fast middle mouses. For example, if I open a link in a new tab with middle mouse it will open about 10 of that tab. I have tried all of the conventional methods to fix it, ie. driver fixes etc. What I want to try now is a bit of mouse debouncing with AHK (Auto Hot Key) for windows.
Essentially what I am thinking is to do this:
while (forever)
if( capture the middle mouse)
sleep 500 ms
mouse click
end
end
Can anyone give some advice with this approach?
Alternatively i thought about making a middle mouse hotkey:
$MButton::
Loop
{
sleep 500
if not GetKeyState("MButton", "P")
break ; Break out of the loop.
}
send {MButton}
return
Can anyone see any problems with this?
You can have a much simpler solution without a delay.
This will ignore middle click if the last click was 50 ms ago.
#Persistent
global pressed_g := 0
global delay_g := 50 ; delay in miliseconds, increase this value if your multiple click take longer than delay_g time
return
MButton::
if( pressed_g = 0 )
{
Send, {MButton}
tooltip,sent
pressed_g := 1
}
SetTimer, Countdown , Off
SetTimer, Countdown , -%delay_g%
return
Countdown:
pressed_g := 0
return
Could it be that you are looking for this? You press the MButton and while you keep the MButton pressed, the script will continue to fire MButton.
#Persistent
MButton::
while GetKeyState("MButton", "P") ; While the Middle Mouse button key is being held down
{
Send, {MButton}
}
return

Assign hotkeys to windows (and remember size & location). AHK

I have found the following script for dynamically assigning hotkeys to already open windows:
Code (Expand):
Loop 10
{
i := A_Index - 1
HotKey #^%i%,DynHotkey
HotKey #%i%, DynHotkey
HotKey #!%i%,DynHotkey
}
Exit
DynHotkey:
StringRight i, A_ThisHotKey, 1
StringMid what,A_ThisHotKey, 2, 1
var := var%i%
IfEqual what, ^, WinGet var%i%, ID, A ; Save ID
Else IfEqual what,!, WinMinimizeAll ; MinimizeAll
WinRestore ahk_id %var%
WinActivate ahk_id %var% ; Switch
Return
(the code was copied from this thread http://www.autohotkey.com/forum/topic38773.html&highlight=dynamic+hot+key)
With the above script you can:
Use Win+Ctrl+0..9 to attach hotkey to current active window.
Use Win+0..9 to switch to correspoding window.
However, if I assign a hotkey to a given window (using Win+Ctrl+0..9), and then I want I want to go back to that window (Win+0..9), the window is reset to a new size & location.
Is there way of saving the size & location of the window along with it's ID?
If so, what would the script look like?
I am running the above script on Windows 7 64-bit.
Thanks a lot,
You dont need to complicate the code :)
Quick question: if your window is minimized you dont have any problems right?
The "problem" on the code is the WinRestore.
The thing is that if the window is not minimized and then you do a WinRestore it will change the size and position to the "not maximized" version of it.
WinActivate automatically does a WinRestore only if the window is minimized, so you can safely remove line 16 (the WinRestore one) since WinActivate will do what you need.
--edit--
this is how the code should look:
Loop 10
{
i := A_Index - 1
HotKey #^%i%,DynHotkey
HotKey #%i%, DynHotkey
HotKey #!%i%,DynHotkey
}
Exit
DynHotkey:
StringRight i, A_ThisHotKey, 1
StringMid what,A_ThisHotKey, 2, 1
var := var%i%
IfEqual what, ^, WinGet var%i%, ID, A ; Save ID
Else IfEqual what,!, WinMinimizeAll ; MinimizeAll
WinActivate ahk_id %var% ; Switch
Return
I tested it, it works perfectly.
You can use WinGetPos to read the actual position and save it. Then you can use WinMove to set the position. Here is a function list: http://www.autohotkey.com/docs/commands.htm.

Resources