AutoHotkey repeated key sequences, detecting KEYUP and KEYDOWN for modifiers - unicode

Similar to what this question covers, I'm trying to bind two sequences of keys.
Ideally I'd like to bind Alt DOWN,-,-,-,Alt UP to an em-dash (—) and Alt DOWN,-,-,Alt UP to an en-dash (–).
What I have almost works for em-dashes but not quite:
; Em-dash
!-::
Input Key, L1
if Key=-
Input Key, L1
if Key=-
Send {ASC 0151}
return
; En-dash
;!-::
;Input Key, L1
;if Key=-
;Send {ASC 0150}
;return
The em-dash sequence works like Alt+-,-,-, instead of what I'm trying to match. I'm not sure how to only test for Alt DOWN and Alt UP. The en-dash sequence fails altogether to bind because !- has already been bound.

Have a look at this one:
dashCount := 0
!-::
dashCount++
if(dashCount = 1) {
SetTimer, WaitForAlt, -1
}
return
WaitForAlt:
KeyWait, Alt
if(dashCount = 2) {
Send {ASC 0150}
} else if(dashCount = 3) {
Send {ASC 0151}
}
dashCount := 0
return
It seems to do the job well. The code works by counting each time Alt + - gets pressed. Concurrently, a pseudo-thread is spawned that waits for Alt to be released and then sends the appropriate dash, depending on the counter.

Related

Why autohotkey deos not send Ctrl-Space where Space is an input

Consider the following assignment:
When I type - followed by a key, the result is Ctrl-key. This work for ordinary keys.
But when the key is whitespace, it does not work.
Any idea why this happens? And how to fix the code?
-::
Input, key, L1,{LCtrl}
send, ^{%key%}
return
Edit.
Try to run the above script a program which has Ctrl-Space as a shortcut to see that it does not work. In fact, if you press - followed by Space, the script is suppose to call Ctrl-Space but it is not the case. For example:
In Microsoft Excel or in Libreoffice Calc, Ctrl-Space can select the current column.
In Emacs Ctrl-Space is reserved for setting a Mark.
Use SendInput instead.
Tested in Excel to mimic ^a, ^x, ^v, ^space
-::
Input, key, L1,{LCtrl}
SendInput, ^%key%
Return
If you want to handle "special" keys, add those keys to the list of endkeys using this syntax
Input [, OutputVar, Options, EndKeys, MatchList]
And then check to see which endkey was pressed
Tested in Firefox to mimic ^PgDn, ^PgUp
Input, key, L1,{LCtrl}{PgUp}{PgDn}
If (ErrorLevel = "EndKey:PgUp") {
SendInput ^{PgUp}
}
Else If (ErrorLevel = "EndKey:PgDn") {
SendInput ^{PgDn}
}
Else If (ErrorLevel = "EndKey:LCtrl") {
Return ;assumed you just want to abort input with the control key
}
Else {
SendInput, ^%key%
}
Return

AutoHotkey - Detect double press of AltGr

I want to detect double press on AltGr.
According to documentation:
; Example #4: Detects when a key has been double-pressed (similar to double-click).
; KeyWait is used to stop the keyboard's auto-repeat feature from creating an unwanted
; double-press when you hold down the RControl key to modify another key. It does this by
; keeping the hotkey's thread running, which blocks the auto-repeats by relying upon
; #MaxThreadsPerHotkey being at its default setting of 1.
; Note: There is a more elaborate script to distinguish between single, double, and
; triple-presses at the bottom of the SetTimer page.
~RControl::
if (A_PriorHotkey <> "~RControl" or A_TimeSincePriorHotkey > 400)
{
; Too much time between presses, so this isn't a double-press.
KeyWait, RControl
return
}
MsgBox You double-pressed the right control key.
return
AltGr is actually a combination of LControl & RAlt. So, for AltGr, script should be something like this:
~LControl & RAlt::
if (A_PriorHotkey <> "~LControl & RAlt" or A_TimeSincePriorHotkey > 400)
{
click
KeyWait, LControl & RAlt
return
}
click 2
return
But when I try to load this script, AutoHotkey gives an error:
Maybe there is a way to make an alias for key combinations.
As mentioned in the comments, KeyWait can only wait on one key (not hotkey) at a time. You only need to wait for RAlt to be released, not the combination of LCtrl and RAlt.
This works:
~LControl & RAlt::
if (A_PriorHotkey <> "~LControl & RAlt" or A_TimeSincePriorHotkey > 400)
{
KeyWait, RAlt
return
}
MsgBox Double-click
return
However, in this case KeyWait is only being used (in combination with the default #MaxThreadsPerHotkey setting of 1) to prevent key-repeat from activating the hotkey. You can remove KeyWait and it will still detect double-presses; but it will also activate if you hold AltGr down until it auto-repeats.
Note that in your case, double-pressing the hotkey would click three times: once on the first press and an additional two times on the second press.
If you just want to use AltGr as a mouse button and allow double-click, all you need is <^RAlt::Click.
If you want to perform two different actions depending on whether it is a single or double click, you must delay the response to the first click until you know whether there's a second click. For example:
<^RAlt::
KeyWait RAlt
KeyWait RAlt, D T0.4
if ErrorLevel
MsgBox Single
else
MsgBox Double
return

Can I send special operators in autohotkey?

I want an AHK script which when I press NumPad7 returns {.
Now, in my keyboard { is Ctrl + Alt + ´
But the script
`NumPad7::
Send, ^!´
return`
does nothing for some reason.
Update: It does work with regular keys like this:
p::
Send; ^!´
return
Edit 2:
NumLock had to be on, now it works fine.
This script gives you { from 7 on numeric keypad regardless of NumLock state:
NumPad7::
NumPadHome::
SendRaw {
Return

AutoHotkey's for the arrow keys

I would like to hold
alt + spacebar + U for the up key
alt + spacebar + H for the left arrow key
alt + spacebar + J for the right arrow key
alt +spacebar + N for the down arrow
is this possible to do with AutoHotkey?
Hello and welcome to AutoHotkey,
you might want to have a look at the basic introduction to the heart of AHK, Hotkeys:
https://www.autohotkey.com/docs/Hotkeys.htm
Configuring hotkeys which do nothing but send another key is fairly simple. For example, alt + spacebar for the up key could be translated into
!Space::
send {up}
return
(note that alt is a modifier and can be written as !)
or short form:
!Space::send {up}
spacebar + U for the up key would be Space & U::send {up}.
But you are seeking for 2 keys PLUS a modifier (alt). For a hotkeylabel triggered by more than just two keys (alt + space + u), you'll need a workaround:
!Space:: ; once alt + space was pressed, ...
while(getKeyState("alt") || getKeyState("space") || getKeyState("u")) { ; ... while either of these is being pressed down, ...
hotKey, *u, altSpaceU, ON ; u should now send {up}
}
hotKey, *u, altSpaceU, OFF
return
altSpaceU: ; note: this is a label, no hotkey
send {up}
return
Please, don't be undeterred by this. AutoHotkey is actually quite powerful and easy to learn. Sadly, (afaik) this is the only working way to solve more-than-two-key-hotkeys.
EDIT
jesus why didnt anybody tell me..
#if getkeystate("alt")
!space::send {up}
#if
is obviously a way better solution
this was the solution
!Space::
send {up}
return

AutoHotKey KeyWait statements

I'm using AutoHotKey and I want to achieve something particular.
I have an hotkey that should perform a certain action, inside this hotkey, I would like to code something to detect if I only press the "C" key, or if I press "C" then "L" keys.
If there is only the "C" key pressed, then it should perform an action, otherwise , if "C" then "L" keys are pressed it should do another action.
But I can't do this as I don't really understand KeyWait, I mean how can I do something like that :
if(KeyWait, C){
firstAction
else {
if(KeyWait, C){
if(KeyWait, L){
anotherAction
}
}
Solved using the input function.
; Get one character and store it in the Character variable
Input, Character, L1
If Character = C
{
; Give up to half of one second to type L
Input, Character, L1 T0.5
If Character = L
MsgBox % "We have C and L"
else
MsgBox % "Just C here, give an L next time"
}