Mouseclick command doesn't check if mouse is already pressed when activating

Report problems with documented functionality
taltamir
Posts: 6
Joined: 14 Oct 2017, 07:46

Mouseclick command doesn't check if mouse is already pressed when activating

14 Oct 2017, 08:01

Lets say I have two browser pages set side by side. on the left side I have an open page that I automated via an AHK script that uses mouseclick every now and then (about 10 minutes)
On the right side I am actively doing something.

If the click on the left page happens while I am holding down the mouse button on the right page for some reason (typically, because I am clicking something at the moment, yes even though a click is fast, it is still long enough to cause this issue). than it will effectively drag my current page over from the right page to the left page. causing the browser on the left to navigate away to the same address as the page on the right.

Over the last few days it happened to me many times. with multiple sites.

I think the solution would be to do a check to see if the mouse is currently clicked and if it is then delay or skip. Maybe default to skip with an option to change behavior to wait instead

A similar issue is if I happen to be moving the mouse when AHK tries to click a spot. Because I am actively moving the mouse when AHK triggers, AHK will often miss the the spot it is programmed to click.

For that the solution would be to check to see if the mouse is currently moving. and again, either skip or wait. and/or have the mouse input be disabled, execute the command, and then reenable mouse input.

Honestly, mouseclick (not mousemove) should probably also automatically record the current location and then return to it when its done clicking before reenabling user mouse control.
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Mouseclick command doesn't check if mouse is already pressed when activating

14 Oct 2017, 15:07

I think it offers more flexibility for a command to not make the assumptions you'd like here. All of this can be addressed by AHK anyway, and use conditional If statements to decide to do an action or not. As such, I do not believe this is a bug at all. Does the AHK documentation suggest the command should behave differently than what you are seeing? MouseClick.

As is, this topic seems more like a help request. Hopefully this information helps you:

If GetKeyState("LButton","D") should check if the user is doing a left click at the moment.

As for mouse moving, that's a lot trickier. You can try to capture the mouse position with MouseGetPos and then a split second later check it again and see if they differ. And if they do not, I would then recommend using BlockInput to prevent the user from interacting with the mouse when the MouseClick command is being executed. (There is still the slight possibility the user can click before the BlockInput command, so then combine with the above check.)

But the same point of returning to the starting location can be done by using MouseGetPos, then MouseClick, then MouseMove.

You may however be interested in using ControlClick. This basically tells the target window a click happened, without "hijacking" the mouse cursor.
taltamir
Posts: 6
Joined: 14 Oct 2017, 07:46

Re: Mouseclick command doesn't check if mouse is already pressed when activating

17 Oct 2017, 07:47

I have only made two assumptions
1. That if giving the command "click at coordinate x,y" you want it to actually be x y and not some other coordinate.
2. That when sending the command "left click", and not a drag and drop command (which exists), then you want it to perform a left click as explicitly ordered it to.

Not a "left click 99% of the time, but sometimes drag and drop instead and sometimes misclick". The fact that it is unreliable on when it performs what is the crux of the issue. If someone wants to perform a drag and drop, they would actually tell AHK to drag and drop and not to perform a left click while hoping they can synchronize their manual clicking with it.

I believe both of these are very reasonable assumptions. and there are no situations where they are false. Nor does ensuring they happen detract from the flexibility of the command.

I also specifically suggested that my ideas be implemented in the form of option. With the a logical default, but the ability to change it (or turn it off).

In regards to controlclick, I don't find it useful since it is too dependent on specific windows, and I need something that handles the whole screen without any regard to which window something appears in.

Thank you for pointing out "If GetKeyState("LButton","D")" to me, I will use it to program a manual check for such a thing.
However, even though this "resolves" my own issue, it is definitely an implementation error that it is not performed by default, or even as an option one could toggle to. Since without it the default state is that mouseclick is unreliable and inconsistent.

edit, here is my script below before adding in the "if getkeystate" thing.

Code: Select all

#SingleInstance force ; allows only one instance of this script, and automatically reloads without asking when launched while already running.
CoordMode, Pixel , Screen ; makes image search functions apply to entire screen instead of only selected window.
CoordMode, Mouse , Screen ; makes mouse functions apply to entire screen instead of only selected window.
SendMode Input ; changes all key and mouse events to use input method instead of event method. this appears to be much much quicker and significantly reduces the time where the program is moving the mouse across the screen.

Loop
{
sleep, 5000  ;wait 5 sec

ImageSearch, img_x, img_y, 0, 0, A_ScreenWidth, A_ScreenHeight, *32 button.png
If(ErrorLevel = 0)
ClickImage(img_x,img_y)

}

ClickImage(img_x,img_y)
{
MouseGetPos, x_original, y_original ; get original location of mouse, so it can return there after clicking.

target_x := img_x + 5
target_y := img_y + 5
; image search gives the leftmost corner pixel found. the above two lines shift it by 5 pixels

Click %target_x% %target_y%            ; click the image
MouseMove, x_original, y_original    ; return the mouse to original location

sleep, 200  ;wait 0.2 sec             ; adds a delay before the loop continues
return
}
taltamir
Posts: 6
Joined: 14 Oct 2017, 07:46

Re: Mouseclick command doesn't check if mouse is already pressed when activating

17 Oct 2017, 08:52

Exaskryz wrote:If GetKeyState("LButton","D") should check if the user is doing a left click at the moment.
Thank you for the suggestion. After some testing and then reading through the documentation, I found out that it needs to be

Code: Select all

If !GetKeyState("LButton")
the D and U are used in a different syntax, in the syntax you used it in, you can either send "P" (checks for physical clicks) or "T" (check OS toggle state). Putting a D there is a mistake. leaving it blank is fine too (defaults to T).

It also needs to have a not or ! because the result is "true" if the button is clicked. and I only want to perform an action if the button is not clicked, so I need it to be false. hence the ! to switch the result of that function.

Or even better, make my own function that calls on getkeystate in order to verify none of the mouse button are pressed (left, right, and middle)

Here is my tested to be working code which integrates that line in case someone wants to use it

Code: Select all

#SingleInstance force ; allows only one instance of this script, and automatically reloads without asking when launched while already running.
CoordMode, Pixel , Screen ; makes image search functions apply to entire screen instead of only selected window.
CoordMode, Mouse , Screen ; makes mouse functions apply to entire screen instead of only selected window.
SendMode Input ; changes all key and mouse events to use input method instead of event method. this appears to be much much quicker and significantly reduces the time where the program is moving the mouse across the screen.

Loop
{
sleep, 5000  ;wait 5 sec

ImageSearch, img_x, img_y, 0, 0, A_ScreenWidth, A_ScreenHeight, *32 button.png
If(ErrorLevel = 0)
ClickImage(img_x,img_y)

}

ClickImage(img_x,img_y)
{
MouseGetPos, x_original, y_original ; get original location of mouse, so it can return there after clicking.

target_x := img_x + 5
target_y := img_y + 5
; image search gives the leftmost corner pixel found. the above two lines shift it by 5 pixels

; if statement below checks that the mouse is currently not being clicked by the user. if it is then click command  would result in drag and drop instead of a click.
If is_mouse_free()
{
Click %target_x% %target_y%            ; click the image
MouseMove, x_original, y_original    ; return the mouse to original location
}

sleep, 200  ;wait 0.2 sec             ; adds a delay before the loop continues
return
}

is_mouse_free()
{
If !GetKeyState("LButton")
If !GetKeyState("RButton")
If !GetKeyState("MButton")
return 1
}

F9::Pause
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Mouseclick command doesn't check if mouse is already pressed when activating

17 Oct 2017, 10:46

In regards to my typo on the GetKeyState() function, yep, I meant to put P. (Typing this out, I Typed "I meant to put D"... which again was wrong. I really mean P.) So apologies on that. And it is true the ! would be necessary depending on how you wanted to handle the logic.

I don't think the assumptions you made are entirely infallible. There may be some creative minds that may want to have some kind of drag to their command. I think they're reasonable assumptions, but again there are methods for forcing the clicks to behave differently to match your expectations. If you think these should be options, can you describe how they should be implemented or what syntax you envision? And actually, can you describe what that second assumption really means?

I noticed your code uses Click, not MouseClick. MouseClick has a speed parameter which may be of interest.
taltamir
Posts: 6
Joined: 14 Oct 2017, 07:46

Re: Mouseclick command doesn't check if mouse is already pressed when activating

05 Feb 2018, 09:40

Exaskryz wrote:I don't think the assumptions you made are entirely infallible. There may be some creative minds that may want to have some kind of drag to their command. I think they're reasonable assumptions, but again there are methods for forcing the clicks to behave differently to match your expectations. If you think these should be options, can you describe how they should be implemented or what syntax you envision? And actually, can you describe what that second assumption really means?
This doesn't make any sense, at all.

1. It is not a reliable drag command. If a person actually want a drag command they will execute a drag command that works 100% of the time instead of executing a click command that does a click 99% of the time and a dragon 1% of the time.

2. A drag command already exists. This specific command is not it, it is a click command, and it's ability to drag under rare circumstances is not documented
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Mouseclick command doesn't check if mouse is already pressed when activating

05 Feb 2018, 15:16

I may not be understanding properly, but it appears it is your code that you designed to have a small chance of a drag. Just don't hold your mouse down when your code executes, and it should be fine.

When I run a Click, 500, 500 command while holding down the mouse, it drag-highlights 100% of the time. When I run a Click, 500, 500 command while not holding down the mouse, it does not drag-highlight and just clicks. Should it be documented that if the mouse is currently in a down state (whether physically, or artificially with a Click, Down command)? It wouldn't hurt.

This was my exact code in testing:

Code: Select all

XButton1::Click Down
XButton2::Click 500, 500
Unlike Send, Click does not automatically release the modifier keys (Control, Alt, Shift, and Win). For example, if the Control key is currently down, Click would produce a control-click but Send {Click} would produce a normal click.
-- From the Click documentation.

I don't think it would be a bad idea to add that it won't release the mouse clicks either, or possibly other keyboard keys, depending on what current state really is. Feel free to put that in the docs suggestions thread with how you would want it phrased. But this also gives a suggestion that you can work around this issue by using Send.

Additionally, I recently came up with code for a similar situation because ControlClick/ControlSend doesn't work in my target program. I used A_TimeIdlePhysical and made sure I haven't been taking any action in the last few sections before I run any automated commands that can interfere with my clicks. (And also replace my clipboard, because my automation works on copying contents to the clipboard.) Coming in v1.1.28 will be additional built-in variables particular to the mouse that can be of interest to you.
taltamir
Posts: 6
Joined: 14 Oct 2017, 07:46

Re: Mouseclick command doesn't check if mouse is already pressed when activating

06 Feb 2018, 19:32

Exaskryz wrote:I may not be understanding properly, but it appears it is your code that you designed to have a small chance of a drag
The opposite. My code is designed to eliminate the chance of a drag. However it is impossible to eliminate it completely because the current implementation
Exaskryz wrote:Just don't hold your mouse down when your code executes, and it should be fine.
The only way to do that is to run AHK on a computer that is not being used.
If you are using it, then whatever automation you created might coincide with a click through sheer coincidence, although the chances of it happening are very low, they add up over thousands of clicks and eventually it happens.
Exaskryz wrote:When I run a Click, 500, 500 command while holding down the mouse
The only way to realistically coordinate between user button click and AHK code based click is if you make the user button click the trigger for the code. And if that is what you wanted, you could still just use a drag select command even if it was triggered by your click.
Instead of relying on the user to hold down the mouse button physically while the AHK code executes the move but not the holding down.
Exaskryz wrote:This was my exact code in testing
This is specifically code for intentionally drag selecting.
If someone wants to write a script where they want AHK to drag select for them, then they will specifically use one of the multiple methods to ordered AHK to drag select. instead of a script which relies on them holding down the mouse button at exactly the right fraction of a second to coincide with AHK moving the pointer.

For example, if I used the code

Code: Select all

XButton2::Click 500, 500
without the preceding "down" line. I set this to run once every 10 minutes.

This 10 minutes thing happens during the fraction of the second where I just happened to be clicking on something else because I am actively using the computer, then it will drag select instead of performing a mere click, via the way user generated input and ahk generated input overlaps (the user is holding down the physical button, while AHK is moving a virtual mouse and then clicking it).

This overlap on inputs is impossible to prevent. The check I put where it aborts or delays the AHK execution if the user is currently clicking helps a lot, but does not eliminate 100% of this overlap (since my physical click can finish registering after AHK ran the verification code, but before it executed it. much more rare, but still can happen)

Also, there are built in options to perform a drag select, but there is no option to avoid accidental drag selecting due to user physical mouse given input
taltamir
Posts: 6
Joined: 14 Oct 2017, 07:46

Re: Mouseclick command doesn't check if mouse is already pressed when activating

17 Aug 2019, 18:54

SL5 wrote:
07 Feb 2018, 02:13
GetKeyState("LButton")
addressed in 4th post. I am already using it in my code, although it is not perfect, it is workable. And should be part of the default command since there is explicitly a different command used for intentional dragging.
lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: Mouseclick command doesn't check if mouse is already pressed when activating

17 Aug 2019, 20:06

I think the solution would be to do a check to see if the mouse is currently clicked and if it is then delay or skip.
This is not what I would expect to happen. How often should it check for activity? Should it wait indefinitely?

I would expect it to click. If there is a conflict with active user input, I would expect either the current behaviour (conflict not resolved) or for the mouse button to be released prior to moving, to allow the command to perform as requested. We can't have two users on one mouse at the same time. The command cannot be expected to handle conflicts reliably. By doing only the minimum, it can be combined with other script code to do whatever you want without having to work around unwanted "intelligent behaviour".

If you are automating a task independently of user activity (not in response to hotkeys), it does not make sense to be automatically moving the mouse (or changing the keyboard focus). There are generally better methods of automation that will work in the background.
A similar issue is if I happen to be moving the mouse when AHK tries to click a spot. Because I am actively moving the mouse when AHK triggers, AHK will often miss the the spot it is programmed to click.
This is what BlockInput MouseMove is for.

I assume the Mouse commands calculate the required movement up-front. In theory, they could be improved to actively track the mouse position, but if the user is actively trying to use the mouse for something else, it is still a problem.
Honestly, mouseclick (not mousemove) should probably also automatically record the current location and then return to it when its done clicking before reenabling user mouse control.
This is rarely what I would want. You can do it with MouseGetPos and MouseMove.
A drag command already exists. This specific command is not it, it is a click command, and it's ability to drag under rare circumstances is not documented
I assume "under rare circumstances" means "if the user has already pressed the mouse button down". I agree that it is generally undesirable if a down-and-up click was requested.

By contrast, Click, MouseClick and MouseMove are often used to drag the mouse from one position to another, utilizing the D/Down/U/Up options or previous mouse button state (e.g. responding to ~LButton::). MouseClickDrag is only ideal if the mouse needs to be moved twice and/or the button is not already down. It doesn't need to be documented that Click/MouseClick can "drag" the mouse, because it is obvious that it can perform each of the component actions.
MouseClickDrag wrote:Clicks and holds the specified mouse button, moves the mouse to the destination coordinates, then releases the button.
If we assume that Click/MouseClick should "click", and that "click" means the mouse button must transition from up to down and back up, then presumably we must release the mouse button first if it is down. However, Click Down sends that message regardless of the current button state, and may have an effect useful to the user. It is also possible that the user just wants the button in the down state. It is not necessarily true that the button should be released first.

Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 30 guests