Avoid sliding clicks

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
entretoize
Posts: 11
Joined: 17 Feb 2018, 09:03

Avoid sliding clicks

17 Feb 2018, 09:07

Hello, I have a graphic tablet and sometimes when moving the stylus over the tablet the tip touches it producing an unwanted click.
I thought about that and in fact I never need a click to happen while I'm moving the stylus except when drawing.
But I don't know AHK enough to create that script, my idea is to watch the mouse moves and keeping the last speed and if there's a click down, validate it if the speed is very low and cancel it if it is not.

Thanks in advance for any help.
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Avoid sliding clicks

17 Feb 2018, 09:26

Try this. It will ignore clicks if the mouse has moved in the last 50 ms, which basically means that you can only click when the mouse isn't moving.

Code: Select all

CoordMode, Mouse, Screen
SetTimer, MonitorMouse, 50
return

MonitorMouse:
	MouseGetPos, CurX, CurY
	MouseMoving := (CurX != OldX) || (CurY != OldY)
	OldX := CurX
	OldY := CurY
return

#If MouseMoving
LButton::return
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Avoid sliding clicks

17 Feb 2018, 09:32

This version will let you click when the mouse speed is low but blocks clicks when it's moving faster.

Code: Select all

CoordMode, Mouse, Screen
SetTimer, MonitorMouse, 50
return

MonitorMouse:
	MouseGetPos, CurX, CurY
	MouseSpeed := Sqrt((CurX - OldX) **2 + (CurY - OldY) ** 2)
	OldX := CurX
	OldY := CurY
return

#If MouseSpeed > 5
LButton::return
entretoize
Posts: 11
Joined: 17 Feb 2018, 09:03

Re: Avoid sliding clicks

17 Feb 2018, 13:01

Yeah, it works.
But I can't use it with buggy-mouse.ahk, do you have an idea ?
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Avoid sliding clicks

17 Feb 2018, 15:37

No, I don't know anything about it.
entretoize
Posts: 11
Joined: 17 Feb 2018, 09:03

Re: Avoid sliding clicks

17 Feb 2018, 15:56

This is the code:

Code: Select all

#SingleInstance force
OnExit, OnExit

;// **************************** Settings ****************************

;// Minimum double-click time. Any lower & it will be blocked (as being inhumanly fast).
DoubleClickMin_ms:=90

;// *** DISABLED *** ;// Minimum click after mouse-up time. Any lower & it will be blocked (as being inhumanly fast).
;// *** DISABLED *** ClickAfterMouseUpMin_ms:=100

;// **************************** /Settings ****************************

;// **************************** Advanded Settings ****************************

;// Enable logging if you need to report a bug.
;// Default (Disabled): Log=0
Log=0

;// Enable debugging if you want to see blocked/allowed clicks.
;// Default (Disabled): Debug=0
Debug=0

;// Enable this if you only want to see blocked clicks (when debugging is enabled).
;// Default (Enabled): Debug_OnlyBlocked=1
;// Note: Requires Debug (above) to be enabled (or no debugging will happen at all)
Debug_OnlyBlocked=1

;// **************************** /Advanded Settings ****************************

Gosub, OnStartup

;// *** Build Tray Menu ***

Text_ClicksBlocked=Clicks Blocked
Text_Debug=Debug
Text_Debug_OnlyBlocked=Debug (only blocked)

Menu, Tray, Add, %Text_ClicksBlocked%, BuggyMouse_MenuSelect_ClicksBlocked
	Text_ClicksBlocked_MenuCurrent:=Text_ClicksBlocked
	Menu, Tray, Default, %Text_ClicksBlocked%
Menu, Tray, Add, %Text_Debug%, BuggyMouse_MenuSelect_Debug
Menu, Tray, Add, %Text_Debug_OnlyBlocked%, BuggyMouse_MenuSelect_Debug_OnlyBlocked
	Menu, Tray, Disable, %Text_Debug_OnlyBlocked%

Menu, Tray, MainWindow
Menu, Tray, NoStandard
Menu, Tray, Add
Menu, Tray, Standard

;// *** /Build Tray Menu ***

;// BuggyMouse_Debug:=1
;// BuggyMouse_Debug_OnlyBlocked:=1
if (Debug) {
	Gosub, BuggyMouse_MenuSelect_Debug
}

if (Debug_OnlyBlocked) {
	Gosub, BuggyMouse_MenuSelect_Debug_OnlyBlocked
}
return

OnStartup:
logdir=%A_ScriptDir%
logfilename=%A_ScriptName%.log
logfile=%logdir%\%logfilename%

time:=time()
logmsg=
(LTrim
	%A_ScriptName%   Started`t`t%time%
	`  Status`t`tUpDn`t  Key`t`t`tReason`t`t`t`tWindow`n
)
log(logmsg)
return

OnExit:
time:=time()
logmsg=
(LTrim
	%A_ScriptName%    Exited`t`t%time%`n`n
)
log(logmsg)
ExitApp

*LButton::
*MButton::
*RButton::

A_ThisHotkey_VarSafe:=Hotkey_MakeVarSafe(A_ThisHotkey, "*")
A_ThisHotkey_NoModifiers:=Hotkey_RemoveModifiers(A_ThisHotkey)
;// A_ThisHotkey_Modifiers:=Hotkey_GetModifiers(A_ThisHotkey)
A_ThisHotkey_KeyName:=Hotkey_GetKeyName(A_ThisHotkey)

log_key:="Down`t" A_ThisHotkey "`t"
Critical
di++

TimeSinceLastMouseDown:=A_TickCount-LastMouseDown_ts

;// TimeSinceLastMouseUp:=A_TickCount-LastMouseUp_ts

DoubleClickTooFast:=TimeSinceLastMouseDown<=DoubleClickMin_ms

;// *** DISABLED *** ClickAfterMouseUpTooSoon:=(ClickAfterMouseUpMin_ms!="" && TimeSinceLastMouseUp<=ClickAfterMouseUpMin_ms)
;// if ((A_ThisHotkey==LastMouseDown && DoubleClickTooFast) || ClickAfterMouseUpTooSoon) {
if (A_ThisHotkey==LastMouseDown && (DoubleClickTooFast || ClickAfterMouseUpTooSoon)) {
;// if (A_TimeSincePriorHotkey<=DoubleClickMin_ms) {
	reason:=DoubleClickTooFast ? "DoubleClickTooFast" "(" TimeSinceLastMouseDown ")" "(" DoubleClickMin_ms ")"
			: ClickAfterMouseUpTooSoon ? "ClickAfterMouseUpTooSoon" "(" TimeSinceLastMouseUp ")" "(" ClickAfterMouseUpMin_ms ")"
			: "Unknown"
	msg=`nblocked (%reason%)
	blockeddown:=1
	BlockedCount_Down++
	BlockedCount_%A_ThisHotkey_VarSafe%++
	Gosub, BuggyMouse_UpdateStatus_ClicksBlocked

	log_action:="BLOCKED`t"
} else {
	reason:=""
	Send, {Blind}{%A_ThisHotkey_KeyName% DownTemp}
	msg=`nSent, {Blind}{%A_ThisHotkey_KeyName% DownTemp}`n`n
	(LTrim C
		if (%A_ThisHotkey%==%LastMouseDown% && (%DoubleClickTooFast% || %ClickAfterMouseUpTooSoon%))
	)

	log_action:="`tallowed"
}
	BuggyMouse_DebugMsg_down=%di%: %A_ThisHotkey%(%TimeSinceLastMouseDown%)%LastMouseDown%%msg%
	msg=
	Gosub, BuggyMouse_Debug
LastMouseDown:=A_ThisHotkey
LastMouseDown_ts:=A_TickCount

wininfo:=WinGetInfo("a")
log(log_action "`t`t" log_key "`t`t" reason "`t`t`t`t`t" wininfo "`n")
return

*LButton up::
*MButton up::
*RButton up::

A_ThisHotkey_VarSafe:=Hotkey_MakeVarSafe(A_ThisHotkey, "*")
A_ThisHotkey_NoModifiers:=Hotkey_RemoveModifiers(A_ThisHotkey)
;// A_ThisHotkey_Modifiers:=Hotkey_GetModifiers(A_ThisHotkey)
A_ThisHotkey_KeyName:=Hotkey_GetKeyName(A_ThisHotkey)

log_key:=" Up `t" A_ThisHotkey
Critical
ui++
TimeSinceLastMouseUp:=A_TickCount-LastMouseUp_ts
;// if (A_ThisHotkey=A_PriorHotkey && A_TimeSincePriorHotkey<=DoubleClickMin_ms) {
;// if (A_ThisHotkey=LastMouseUp && A_TimeSincePriorHotkey<=DoubleClickMin_ms) {
if (blockeddown) {
	msg=`nblocked
	blockedup:=1
	BlockedCount_Up++
	BlockedCount_%A_ThisHotkey_VarSafe%++
	Gosub, BuggyMouse_UpdateStatus_ClicksBlocked

	log_action:="BLOCKED`t"
} else {
	Send, {Blind}{%A_ThisHotkey_KeyName% up}
	msg=`nSent, {Blind}{%A_ThisHotkey_KeyName% up}
	log_action:="`tallowed"
}
;// if (BuggyMouse_Debug) {
	BuggyMouse_DebugMsg_up=%ui%: %A_ThisHotkey%(%TimeSinceLastMouseUp%)%LastMouseUp%%msg%
	msg=
	Gosub, BuggyMouse_Debug
;// }
blockeddown=
blockedup=
LastMouseUp:=A_ThisHotkey
LastMouseUp_ts:=A_TickCount

wininfo:=WinGetInfo("a")
log(log_action "`t`t" log_key "`t`t" reason "`t`t`t`t`t" wininfo "`n")
return

BuggyMouse_Debug_ShowLastMsg:
;// BuggyMouse_Debug_ShowLastMsg=1
BuggyMouse_Debug:
CoordMode, Tooltip
if (A_ThisLabel="BuggyMouse_Debug_ShowLastMsg"
		|| (BuggyMouse_Debug && (!BuggyMouse_Debug_OnlyBlocked
			|| (BuggyMouse_Debug_OnlyBlocked && (blockeddown||blockedup))))) {
	Tooltip, %BuggyMouse_DebugMsg_down%`n`n%BuggyMouse_DebugMsg_up%, 819, 619
} else {
	Tooltip
}
return

BuggyMouse_UpdateStatus_ClicksBlocked:
BlockedCount_Total:=BlockedCount_Down+BlockedCount_Up
Text_ClicksBlocked_MenuNew=%Text_ClicksBlocked%: %BlockedCount_Total%
Menu, Tray, Rename, %Text_ClicksBlocked_MenuCurrent%, %Text_ClicksBlocked_MenuNew%
Text_ClicksBlocked_MenuCurrent:=Text_ClicksBlocked_MenuNew
Menu, Tray, Tip, %Text_ClicksBlocked_MenuCurrent% - %A_ScriptName%
return

BuggyMouse_MenuSelect_ClicksBlocked:
msgbox, 64, ,
(LTrim C
	%Text_ClicksBlocked_MenuCurrent%

	Down(%BlockedCount_Down%)
	Up(%BlockedCount_Up%)

	LButton(%BlockedCount_LButton%)
	MButton(%BlockedCount_MButton%)
	RButton(%BlockedCount_RButton%)

	LButton up(%BlockedCount_LButton_up%)
	MButton up(%BlockedCount_MButton_up%)
	RButton up(%BlockedCount_RButton_up%)
)
return

BuggyMouse_MenuSelect_Debug:
BuggyMouse_Debug:=!BuggyMouse_Debug
Menu, Tray, ToggleCheck, %Text_Debug%
Menu, Tray, ToggleEnable, %Text_Debug_OnlyBlocked%
Tooltip
return

BuggyMouse_MenuSelect_Debug_OnlyBlocked:
BuggyMouse_Debug_OnlyBlocked:=!BuggyMouse_Debug_OnlyBlocked
Menu, Tray, ToggleCheck, %Text_Debug_OnlyBlocked%
Tooltip
return

Hotkey_MakeVarSafe(p_hotkey, p_ignorechars="") {
	replace:=p_hotkey

	StringReplace, replace, replace, $, % !InStr(p_ignorechars, "$") ? "KH_":""
	StringReplace, replace, replace, ~, % !InStr(p_ignorechars, "~") ? "PT_":""
	StringReplace, replace, replace, *, % !InStr(p_ignorechars, "*") ? "WC_":""

	StringReplace, replace, replace, <^>!, AltGr_
	StringReplace, replace, replace, <, L, a
	StringReplace, replace, replace, >, R, a
	StringReplace, replace, replace, &, and

	StringReplace, replace, replace, ^, Ctrl_, a
	StringReplace, replace, replace, +, Shift_, a
	StringReplace, replace, replace, #, Win_, a
	StringReplace, replace, replace, !, Alt_, a

	replace:=RegExReplace(replace, "i)[^a-z0-9_]", "_")

	p_hotkey:=replace

	return p_hotkey
}

Hotkey_GetModifiers(p_hotkey) {
	return RegExReplace(p_hotkey, "i)[\w\s]+$")
}

Hotkey_RemoveModifiers(p_hotkey) {
	return RegExReplace(p_hotkey, "i)^[^a-z0-9_]+")
}

Hotkey_GetKeyName(p_hotkey) {

	p_hotkey:=Hotkey_RemoveModifiers(p_hotkey)

	;// Get string before 1st space...(removes "up" or "down" from name of key)
	Loop, Parse, p_hotkey, " "
	{
		p_hotkey:=A_LoopField
		break
	}

	return p_hotkey
}

log(p_msg, p_file="") {
	Global Log, logfile
	if (!Log) {
		return
	}
	if (p_file="") {
		p_file:=logfile
	}
	FileAppend, %p_msg%, %p_file%
}

time() {
	FormatTime, time, L1033, ddd, MMM d, yyyy --- M/d/yy h:mm:sstt
	return time
}

WinGetInfo(p_win, ByRef r_win_title="", ByRef r_win_class="") {
	WinGetTitle, win_title, %p_win%
	WinGetClass, win_class, %p_win%

	r_win_title:=(win_title ? win_title:"<no-title-info>")
	r_win_class:=(win_class ? win_class:"<no-class-info>")

	;// wininfo:=(win_title ? win_title:"<no-title-info>") " - " (win_class ? win_class:"<no-class-info>")
	wininfo:=(win_class ? win_class:"<no-class-info>") ": " (win_title ? win_title:"<no-title-info>")
	return wininfo
}

;// #ScrollLock::log("*** PROBLEM ***`n")
^+#!F8::Gosub, BuggyMouse_Debug_ShowLastMsg
^+#!F9::Suspend
^+#!F12::ExitApp


User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Avoid sliding clicks

17 Feb 2018, 17:28

I wouldn't expect two scripts that are both meant to block mouse clicks under certain conditions to work well together. It looks like buggy-mouse has a lot of code for user interface and stuff. Too much to wade through. If you use it just to avoid accidental double-clicks, it should be easy to add to my above script with a handful of lines. I don't know how you indicate an intended double-click, though.
entretoize
Posts: 11
Joined: 17 Feb 2018, 09:03

Re: Avoid sliding clicks

18 Feb 2018, 02:36

I don't need the interface, just fast double clicks filter...
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Avoid sliding clicks

18 Feb 2018, 08:45

Just add this to the bottom of my prior script:

Code: Select all

#If
LButton::
if (A_TimeSincePriorHotkey > 200)
	Click
return
entretoize
Posts: 11
Joined: 17 Feb 2018, 09:03

Re: Avoid sliding clicks

18 Feb 2018, 09:55

Doesn't seem to work, I can't double click at all even by reducing from to 1, also I can't select by sliding...
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Avoid sliding clicks

18 Feb 2018, 10:31

Works for me. You're not still running the buggy-mouse script, are you? Perhaps show the whole script that you are now running.
entretoize
Posts: 11
Joined: 17 Feb 2018, 09:03

Re: Avoid sliding clicks

18 Feb 2018, 15:16

No I removed the buggy mouse script.
Here is the code:

Code: Select all

CoordMode, Mouse, Screen
SetTimer, MonitorMouse, 50
return

MonitorMouse:
	MouseGetPos, CurX, CurY
	MouseSpeed := Sqrt((CurX - OldX) **2 + (CurY - OldY) ** 2)
	OldX := CurX
	OldY := CurY
return

#If MouseSpeed > 5
LButton::return

#If
LButton::
if (A_TimeSincePriorHotkey > 200)
	Click
return
What means this #if with nothing after ?
gregster
Posts: 8916
Joined: 30 Sep 2013, 06:48

Re: Avoid sliding clicks

18 Feb 2018, 15:28

entretoize wrote:What means this #if with nothing after ?
It turns off the context sensitivity for hotkeys that was activated by #If MouseSpeed > 5
(btw, if you want to find out something like that: the #If in the code box is clickable and opens the docs for this directive)
User avatar
boiler
Posts: 16767
Joined: 21 Dec 2014, 02:44

Re: Avoid sliding clicks

18 Feb 2018, 17:22

Maybe there's some hook left from the buggy-mouse script. Try a fresh Windows restart without ever having opened that script since you restarted.

Based on what you described, it doesn't look like this is your problem, but you might want to try to run the script as admin in case what you're trying to click on is an elevated process so it's not accepting clicks sent from a non-elevated one.

Not sure what to suggest other than that since I can't reproduce your problem. It may be hardware-specific to your tablet.
entretoize
Posts: 11
Joined: 17 Feb 2018, 09:03

Re: Avoid sliding clicks

19 Feb 2018, 02:05

I restarted after having disconnected my tablet, no script is run at startup, and I get the same issue...
I'll try to create a c++ program to see. Thanks for your help.
entretoize
Posts: 11
Joined: 17 Feb 2018, 09:03

Re: Avoid sliding clicks

19 Feb 2018, 04:57

I built a small program in c++ that works, so either AHK is buggy or your code is not correct, anyway it's ok for me... Thanks again for you time.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 140 guests