Help with mouse gestures

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Pilou42
Posts: 5
Joined: 18 Oct 2017, 17:03

Help with mouse gestures

19 Oct 2017, 11:50

Hello,

I'm trying to write a basic mouse gestures with wheel support, and as a beginner, I don't manager to find the right way to do it.

Code: Select all

#IfWinActive ahk_class Chrome_WidgetWin_1

RButton::
{
        MouseGetPos PL1, PL2
        Send {RButton down}
        return
}

RButton Up::
{
MouseGetPos PL3, PL4
if (abs(PL4-PL2)>300)
     {
     if (PL4>PL2)
     {
     Send ^r
     return
     }
     if (PL4<PL2)
     {
     return
     }
    }
if (abs(PL3-PL1)>100)
     {
     if (PL3>PL1)
     {
     Send ^+t
     return
     }
     if (PL3<PL1)
     {
     Send ^w
     return
     }
     }
Send {RButton}
return
}
This code works, but I have the feeling it is not correct. Sometimes the contextual menu does not appear outside of window.
Plus when I try to integrate mousewheel support, I cannot, since GetKeyState, PLR2, RButton always result in "U" state.
I've tried to read some mouse gestures scripts but they are too complicated for me.

What is the best way to do stuff when Rbutton is down ? And when RButton is up, I'd like either it fires the normal contextual menu, either it fires another event without breaking right click (like if RButton got stuck in "D" state).

If someone can give me some clues, I'd really like to understand it.
Last edited by Pilou42 on 20 Oct 2017, 13:02, edited 1 time in total.
GEV
Posts: 1002
Joined: 25 Feb 2014, 00:50

Re: Help with mouse gestures

19 Oct 2017, 13:19

Try

Code: Select all

#IfWinActive ahk_class Chrome_WidgetWin_1

	~RButton::
	mX1 := ""
	mX2 := ""
	mY1 := ""
	mY2 := ""
	MouseGetPos, mX1, mY1
	KeyWait, RButton
	return


	~RButton Up::
	Send, {RButton Up}
	MouseGetPos, mX2, mY2
	If (abs(mX2-mX1) < 50) and (abs(mY2-mY1) < 50) 	; Gesture_Range
		return
	; otherwise:
	Send {Esc} ; Close context menu
	If(Abs(mY1-mY2) > 50 and Abs(mX1-mX2) > 50)
	{
		If ((mX2 < mX1)  and (mY2 < mY1)) 	; Gesture_UL
			ToolTip, Gesture_UL
		else
		If ((mX2 > mX1)  and (mY2 < mY1)) 	; Gesture_UR
			ToolTip Gesture_UR
		else
		If ((mX2 < mX1)  and (mY2 > mY1)) 	; Gesture_DL
			ToolTip Gesture_DL
		else 
		If ((mX2 > mX1)  and (mY2 > mY1)) 	; Gesture_DR
			ToolTip Gesture_DR	
	}
	else
	If (mY1 < (mX1-(mX2-mY2))) and !(mY1 < ((mX2+mY2)-mX1))
	{
		If (mX2 < mX1) 	; Gesture_L
			ToolTip Gesture_L	
	}
	else
	If (mY2 < (mX2-(mX1-mY1))) and !(mY2 < ((mX1+mY1)-mX2))
	{
		If (mX2 > mX1) 	; Gesture_R
			ToolTip Gesture_R
	}
	else
	If !(mY2 < (mX2-(mX1-mY1))) and (mY2 > ((mX1+mY1)-mX2))
	{
		If (mY2 > mY1)		; Gesture_D
			ToolTip Gesture_D
	}
	else		; Gesture_U
	If (mY2 < mY1)
		ToolTip Gesture_U
	return

#IfWinActive
Pilou42
Posts: 5
Joined: 18 Oct 2017, 17:03

Re: Help with mouse gestures

19 Oct 2017, 13:57

Thanks for this code, I'll try to study this KeyWait function.
Unfortunately, the "Esc" key to remove context menu is not what I desire. I'd really like to tell system the "U" state of Rbutton without triggering {Rbutton Up} (and then no contextual menu or whatever).
GEV
Posts: 1002
Joined: 25 Feb 2014, 00:50

Re: Help with mouse gestures

19 Oct 2017, 16:01

What about this

Code: Select all

#NoEnv
#SingleInstance Force

#If WinActive("ahk_class Chrome_WidgetWin_1")

	*RButton::
	mX1 := ""
	mX2 := ""
	mY1 := ""
	mY2 := ""
	MouseGetPos, mX1, mY1
	KeyWait, RButton, T0.05 ; times out in 500 ms
	if (ErrorLevel)
	{
		No_context_menu := true		
		KeyWait, RButton
		MouseGetPos, mX2, mY2
		If (abs(mX2-mX1) < 50) and (abs(mY2-mY1) < 50) 	; Gesture_Range
		{
			No_context_menu := false
			Send, {RButton Down}
			KeyWait, RButton
			Send, {RButton Up}
				return
		}
		; otherwise:
		If(Abs(mY1-mY2) > 50 and Abs(mX1-mX2) > 50)
		{
			If ((mX2 < mX1)  and (mY2 < mY1)) 	; Gesture_UL
				ToolTip, Gesture_UL
			else
			If ((mX2 > mX1)  and (mY2 < mY1)) 	; Gesture_UR
				ToolTip Gesture_UR
			else
			If ((mX2 < mX1)  and (mY2 > mY1)) 	; Gesture_DL
				ToolTip Gesture_DL
			else 
			If ((mX2 > mX1)  and (mY2 > mY1)) 	; Gesture_DR
				ToolTip Gesture_DR	
		}
		else
		If (mY1 < (mX1-(mX2-mY2))) and !(mY1 < ((mX2+mY2)-mX1))
		{
			If (mX2 < mX1) 	; Gesture_L
				ToolTip Gesture_L	
		}
		else
		If (mY2 < (mX2-(mX1-mY1))) and !(mY2 < ((mX1+mY1)-mX2))
		{
			If (mX2 > mX1) 	; Gesture_R
				ToolTip Gesture_R
		}
		else
		If !(mY2 < (mX2-(mX1-mY1))) and (mY2 > ((mX1+mY1)-mX2))
		{
			If (mY2 > mY1)		; Gesture_D
				ToolTip Gesture_D
		}
		else		; Gesture_U
		If (mY2 < mY1)
			ToolTip Gesture_U
		else	
			Send, {RButton Up}
		No_context_menu := false 
	}
	else
	{
		No_context_menu := false 
		Send, {RButton Up}
	}
	return

#If (No_context_menu)

	~*RButton:: return
	
#If
Last edited by GEV on 20 Oct 2017, 01:36, edited 2 times in total.
Pilou42
Posts: 5
Joined: 18 Oct 2017, 17:03

Re: Help with mouse gestures

19 Oct 2017, 19:14

I think I understood the logic, but the contextual menu does not work as it should with this solution:
1) contextual menu does not work on toolbar
2) if I do 5 right click at 5 different positions, contextual menu is shown only at the first position. Without script, you'll have 5 contextual menus, at 5 different positions.
GEV
Posts: 1002
Joined: 25 Feb 2014, 00:50

Re: Help with mouse gestures

20 Oct 2017, 01:28

I edited my last answer. Try it again.
Pilou42
Posts: 5
Joined: 18 Oct 2017, 17:03

Re: Help with mouse gestures

20 Oct 2017, 12:59

It works indeed. So many little thing to understand. ~* for example (I did not know it could be combined). But I'll try to read more and to really understand both.
If you're still motivated, Is there an easy way to add wheel gestures, like KeyWait, Wheeldown and KeyWait, Wheelup ?
No problem if you don't want. I'll try with what you taught me.
Pilou42
Posts: 5
Joined: 18 Oct 2017, 17:03

Re: Help with mouse gestures

21 Oct 2017, 11:56

Finally, I understood the complete logic. The thing I was not able to understand is the fact when you want to deal with Rbutton (right click), you must NOT send Rbutton down, or else you won't be able to avoid contextual menu, since for each Rbutton Down you need a Rbutton Up or OS goes crazy (since waiting for his Rbutton Up). You'll send Rbutton per cases.
Unfortunately, if you don't send Rbutton Down, it means Rbutton state is always Up, that's why you need to use a variable to replace GetKeyState ("RighClickDown" in my case).

Thanks GEV for your help !

Here is the final script of what I wanted:

Code: Select all

#NoEnv
SendMode Input

#If WinActive("ahk_class Chrome_WidgetWin_1")
Rbutton::
	mX1 := ""
	mX2 := ""
	mY1 := ""
	mY2 := ""
	RighClickDown := true
	MouseGetPos, mX1, mY1
	KeyWait, Rbutton
	RighClickDown:= false
	if (WheelDone)
		{
		WheelDone := false
		}
	else
		{
		MouseGetPos, mX2, mY2
		If (abs(mX2-mX1) < 150) and (abs(mY2-mY1) < 150)
			{			
				Send {RButton}
			}
		else ;gesture range
			{
			If (abs(mY2-mY1) > abs(mX2-mX1))
				{
				If ((mY2-mY1) > 0)
					{
					ToolTip Down
					}
				else
					{
					ToolTip Up
					}
				}
			else
				{
				If ((mX2-mX1) > 0)
					{
					ToolTip Right
					}
				else
					{
					ToolTip Left
					}
				}		
			}
		}
		return

WheelDown::
	if (RighClickDown)
		{
		Tooltip Wheel Down Ready !
		WheelDone := true
		}
	else
		{
		Send {WheelDown}
		}
	return

WheelUp::
	if (RighClickDown)
		{
		Tooltip Wheel Up Ready !
		WheelDone := true
		}
	else
		{
		Send {WheelUp}
		}
	return

#If
I'm still concerned by CPU resources with mouse binds especially with wheel. If somebody has something which is more CPU optimized, I'm interested.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 220 guests