What is the best way to write "layers" in AHK? Ideally, with TapHoldManager.

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
hotter
Posts: 9
Joined: 27 Nov 2022, 17:20

What is the best way to write "layers" in AHK? Ideally, with TapHoldManager.

Post by hotter » 28 Nov 2022, 13:28

I want to make a "layer" (combinations of pressing 2 or more keys) out of the CapsLock key. So that the behavior of Caps Lock is similar to the Ctrl, Alt, Shift, Win keys.
This is can be done simply:

Code: Select all

CapsLock & q::Send <some logic>
CapsLock & w::Send <some logic>
CapsLock & e::Send <some logic>
CapsLock & r::Send <some logic>
CapsLock::Send {CapsLock} ; so normal click would also work
But at the same time I also want to implement the capabilities of the TapHoldManager (click control library).
Good example of THM work: [youtube]https://youtu.be/gZxebHjsXyw?t=1628[/youtube]

Implementing THM look like this, but i dont know where to pput "hold" logic. How to check for "Caps+W" is "W" also held?

Code: Select all

thm := new TapHoldManager() 
thm.Add("CapsLock", Func("CapsLock_Handle"))
CapsLock_Handle(isHold, taps, isPressed){	
	if isPressed = false
		return
	
	if isHold{
		ToolTip, CapsLock_%taps%_clicks_AND_HELD
		if taps = 1
		{
			if is_W_Pressed() ; how to check "W" exacly?	
				CapsLock_W_Handle();
		}
		else if taps = 2
		{
			if is_W_Pressed() 	
				double_CapsLock_W_Handle();
		}		
	}
	else
		ToolTip, CapsLock_%taps%_clicks
		if taps = 1
			handleNormalClick()
		else if taps = 2
			handleDoubleClick()
		; ... and so on
	return
}
is_W_Pressed(){
	; help. How to check is W was pressed while CapsLock helded?
}
I would like to have a script where I can
1. bind simple combination like hold CapsLock + W
2. bind THM specific combo like Caps Lock 1st click, Caps Lock 2nd click, Caps Lock Hold.
3. bind complex combinations like Caps Lock click, short pause, hold CapsLock + W
4. bind complex combinations with standart modificators like Alt or Shift: Alt + Shift + CapsLock + W


In short my questions is:
A. How to connect layers and THM in code?
B. I have not found a single framework for creating "layers" in AHK. Are there any such code libraries at all? Has anyone tried to do this?

NexusP
Posts: 27
Joined: 26 Nov 2020, 09:01

Re: What is the best way to write "layers" in AHK? Ideally, with TapHoldManager.

Post by NexusP » 29 Nov 2022, 09:40

I use tapHoldManager daily with commands mapped to mouse button 2. When i hold the button on a single folder item (isHold)>(taps == 1), and then select another item in any location on the list (ishold again), both items remain selected (Control + Left Mouse). Double tap selects all fold items (Shift + A)(taps == 2). If I Single click (not held) on a single folder item, and then click on another further down or further up on the list, all items in-between are selected (Shift+Left Mouse)(taps == 1).

Code: Select all


thm.Add("XButton2", Func("MB2"))

MB2(isHold, taps, state)
{
	if !(state) 
		return
	if (ishold) 
	{
		if (taps = 1) 
			send ^{LButton}
	}
	else 
	{
		if (taps = 1)
			send +{LButton}
		else if (taps = 2)
			send ^{a}	
		}
	}
}
Toggle Key:

Code: Select all


gosub, ctrlkeysub

MB2(isHold, taps, state)
{
	if (!state) 
		return  
	if (ishold) 
  {
	if (taps == 1) 
		gosub, ctrlkeysub
} 
  else 
  	if (taps == 1)
		sendinput {mButton}		
}

ctrlkeysub:
KeyDown := !KeyDown
if !KeyDown 
	SendInput {ctrl down}
else 
	SendInput {ctrl up}
	return
Last edited by NexusP on 30 Nov 2022, 03:58, edited 5 times in total.

hotter
Posts: 9
Joined: 27 Nov 2022, 17:20

Re: What is the best way to write "layers" in AHK? Ideally, with TapHoldManager.

Post by hotter » 29 Nov 2022, 12:36

@NexusP , how you will code in THM something like: (pseudocode)

Code: Select all

if "a" clicked and XButton2 holded
	Send, ^a

if "c" clicked and XButton2 holded
	Send, ^c

if "v" clicked and XButton2 holded
	Send, ^v
?
Obviously, There is a way like

Code: Select all

#include <TapHoldManager> 
thm := new TapHoldManager() 
thm.Add("a", Func("a_keyHandler"))
thm.Add("c", Func("c_keyHandler"))
thm.Add("v", Func("v_keyHandler"))
return

v_keyHandler(isHold, taps, state){
	if (!state) 	{		return	}

	if (taps > 0)
	{
	 	GetKeyState, XButton2_State, XButton2
		if state = D
			Send, ^v
	}
}
... and similar for c_keyHandler a_keyHandler
code above not tested

But its look clumsy. And it probably will slow down system, if there are too many keys subscribed? Does THM good optimized?

I feel like there must be a way to write better code for combo like XButton2 holded + x clicked. Where subscription will be only for thm.Add("XButton2", Func("XButton2_keyHandler")), not for all keys

Post Reply

Return to “Ask for Help (v1)”