KeyPress before/after MouseClick(and hold) // remapping "RButton Down" Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
qqtm
Posts: 10
Joined: 17 Apr 2018, 19:14

KeyPress before/after MouseClick(and hold) // remapping "RButton Down"

17 Apr 2018, 19:42

Hello!

I need a key pressed before the mouse clicks and pressed it again when the mousebutton is released.
In detail:
My hand just clicks, holds then releases the button. The application should receive keypress (down and up) then mouse button down, hold, release and finally keypress again.

It should work like this (but ofc it doesn't):

Code: Select all

#UseHook On

SetTitleMatchMode, 3

#IfWinActive, MyApplication
{
  RButton Down::
     Send {z}
     Send {RButton down} 
  return
  
  RButton Up::
     Send {RButton up} 
	 Send {z}
  return
}
Most of search results are related remapping the other direction (tons of 'em). But few pointed somewhat to my problem.
So a hint to something i should search/read and you know that solves this is appreciated as well!
(a fish is nice but a fishing-rod does the same for me =] )
qqtm
Posts: 10
Joined: 17 Apr 2018, 19:14

Re: KeyPress before/after MouseClick(and hold) // remapping "RButton Down"

18 Apr 2018, 10:21

Yes, I know there is no "RButton Down", that is exactly the point and why Topic says ' remapping "RButton Down" '
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: KeyPress before/after MouseClick(and hold) // remapping "RButton Down"

18 Apr 2018, 10:57

What evilC means is that RButton IS "RButton Down".
qqtm
Posts: 10
Joined: 17 Apr 2018, 19:14

Re: KeyPress before/after MouseClick(and hold) // remapping "RButton Down"

18 Apr 2018, 11:07

Yes i got that and this made me remember how VisualBasic handles inputs, things are clear now.
Thanks! This pointed me to the solution...almost:

I realized that the application was the problem: it has no event driven input detection but a timed loop (ugly...)

This solved it:

Code: Select all

RButton::
     Send {z down}
	 sleep 100
	 Send {z up}
  return
  
  RButton Up::
	 Send {z down}
	 sleep 100
	 Send {z up}
  return
Thank you! Workflow is flawless now :dance:

Edit: To make it clear: This does not hit Z before MouseDown and not after MouseUp as i was thinking it has to be; but in this application it works, because (i guess) the timed loop 'realizes' the Mouse'Events' in the next loop.
qqtm
Posts: 10
Joined: 17 Apr 2018, 19:14

Re: KeyPress before/after MouseClick(and hold) // remapping "RButton Down"

18 Apr 2018, 12:23

Yes, I know about that. But this is a global setting and i need it only in this place (so far). But i forgot about 'hotkey stacking' - makes code more readable and elegant. Thanks for the input!
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: KeyPress before/after MouseClick(and hold) // remapping "RButton Down"

18 Apr 2018, 12:36

Also bear in mind though that if you press and then release within 100ms, it may well fire {z down}{z down}{z up}{z up}, because the release hotkey would interrupt the press hotkey. Once this has happened, the press hotkey code would not resume until the release hotkey code ended (Sleep is a blocking call, AHK will not service other pseudo-threads whilst the current pseudeo-thread is sleeping)

Demo (Tap F1 quickly):

Code: Select all

#SingleInstance, force

F1::
    ToolTip, % "PRESS START @ " A_TickCount, 0, 0, 1
    Sleep 1000
    ToolTip, % "PRESS END @ " A_TickCount, 0, 0, 1
    return

F1 up::
    ToolTip, % "RELEASE START @ " A_TickCount, 0, 30, 2
    Sleep 1000
    ToolTip, % "RELEASE END @ " A_TickCount, 0, 30, 2
    return

^Esc::
ExitApp
qqtm
Posts: 10
Joined: 17 Apr 2018, 19:14

Re: KeyPress before/after MouseClick(and hold) // remapping "RButton Down"

18 Apr 2018, 12:53

Good point. Didn't think so far. I'm sure this would have happened from time to time. Thanks again!

(Just tested it by 'clicking like mad' and it happens easier as expected. So hotkey-stacking IS the way to go! (and not just for eyes :crazy: hehe)
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: KeyPress before/after MouseClick(and hold) // remapping "RButton Down"

18 Apr 2018, 14:11

Stacking hotkeys does not alter this behavior at all. Multiple threads can be processing the same line of code, but only one thread can be active at once.

Code: Select all

F1::
F1 up::
    ToolTip, % A_ThisHotkey " START @ " A_TickCount, 0, 0, 1
    Sleep 1000
    ToolTip, % A_ThisHotkey " END @ " A_TickCount, 0, 0, 1
    return

^Esc::
ExitApp
qqtm
Posts: 10
Joined: 17 Apr 2018, 19:14

Re: KeyPress before/after MouseClick(and hold) // remapping "RButton Down"

20 Apr 2018, 02:45

Yep, after thinking about it's obvious. But it works well so far. Question would be if there is an option to control threads in some way, but that's - indeed interesting but - not required for my solution.

I did some testing with different SetKeyDelay values and the loop of the application seems to run faster than each 50ms. I was checking how fast i could press the MouseButton in normal workflow and it's at 80ms (used a mouse recorder for some hours and searched the lowest value). So i set the value to 60ms and i can reproduce the "thread-interception" now only by "brute-force".

I'd like a more solid solution but I'm fine with this "workaround".
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: KeyPress before/after MouseClick(and hold) // remapping "RButton Down"

20 Apr 2018, 05:55

It's not that trivial TBH, but here is some code that removes all the sleeps.
Not sure if it will behave any differently though, it will probably need some more work to handle the case when you re-press a button within the timeout time (While the timer is running)

Code: Select all

#SingleInstance force

; Block RButton press and send keys before
RButton::
	Send {z down}
	fn := Func("Release").Bind(1)
	SetTimer, % fn, -100
	return

; Do not block RButton up, as the keys need to be sent after the button release
~RButton Up::
	Send {z down}
	fn := Func("Release").Bind(0)
	SetTimer, % fn, -100
	return

; Handles the delayed actions
; On press of RMB (State 1), sends z up followed by RMB down
; On release of RMB (State 0), sends z up
Release(state){
	Send {z up}
	if (state){
		Send {RButton down}
	}
	return
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Xtra and 270 guests