Window becomes "permanently active" when activating it with XButton1 or XButton2

Report problems with documented functionality
qazqi
Posts: 1
Joined: 19 Apr 2022, 12:28

Window becomes "permanently active" when activating it with XButton1 or XButton2

Post by qazqi » 19 Apr 2022, 13:01

The following is a minimal reproduction of this issue, also available as an attached file:

Code: Select all

F2::XButton1

#IfWinActive File Explorer
    F2::F5
Reproduction steps:
  1. Download the attachment or create a script with the contents above and run it.
  2. Open a fresh instance of File Explorer (the default one on Windows). Ensure the title of the window matches the script. File Explorer is an arbitrary choice here.
  3. Verify that pressing F2 with File Explorer active refreshes the view.
  4. Click any other window that does not have elevated privileges, such as this browser window. Keep File Explorer at least partially visible.
  5. Hover the mouse cursor over File Explorer and then press F2.
Reproduction rate:
100%

Expectation:
Due to the above script, the XButton1 press should activate File Explorer and input should work normally after that.

Actual behaviour:
The File Explorer window becomes active, but then stays active. Mouse clicks on other windows do not activate that window. Mouse clicks on the File Explorer window still act normally.

Keyboard input works normally. You can alt-tab to a different window and then provide keyboard input. From this state, clicking any window that is not the File Explorer window will cause the active window to become null (verified with the Win32 API GetForegroundWindow).

To easily restore the system to a normal state, press ctrl-alt-del to go to the secure desktop and then exit back to the regular desktop and click a couple times.

First noticed:
I've had this issue for approximately 1-2 years until now figuring out how to reproduce it, but as linked below, it seems someone had the same issue in 2012. I set this script up in about December 2019, so probably then.

Environment info:
Windows 11 21H2. Also happened throughout Windows 10 in the last 1-2 years.
AHK: 1.1.33.02, also reproduced in 1.1.33.10.
Reproduced in 2.0 beta 3 by changing the #IfWinActive line to #HotIf WinActive("File Explorer").

Speculation:
This appears to be caused by a weird interaction of rebinding to a standard mouse button, causing it to activate the window under the cursor, and then changing that bind once the new window is activated via the conditional hotkey. I speculate that the system gets an {XButton1 down}, but not an {XButton1 up}, and that this triggers Windows to get into the above state that IMO should never be allowed by the OS unless an app is specifically trying to keep a window active (so AHK isn't entirely to blame here).

With this in mind, I've made the following bandaid fix to my actual script, and it seems to work:

Code: Select all

F2::XButton1

#IfWinActive File Explorer
    F2::
        Send {XButton1 up}
        Send {F5}
        Return
This bandaid fix was also tested with the minimal reproduction and appeared to work there too.

Actual use case:
My real script is simply to rebind my extra 12 mouse buttons based on the active window. Synapse offers the ability to switch presets based on the active window, but appears to make server calls while doing so, ultimately freezing my cursor for around 1 second.

I bind these buttons to F13-F24 in Synapse and then use AHK to rebind those. By default, I have the mousepad4 button bound to XButton1 (back) and the mousepad6 button bound to XButton2 (forward). In MMOs, I rebind these to Numpad4 and Numpad6 respectively. Activating the game window by pressing mousepad4 or mousepad6 triggers this bug.

See also:
There is a help post from 2012 with what appears to be the same issue: https://www.autohotkey.com/board/topic/83560-mouse-keys-are-stuck-in-windows-after-execution-of-script/
Attachments
active-window-bug.ahk
(51 Bytes) Downloaded 21 times

lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: Window becomes "permanently active" when activating it with XButton1 or XButton2

Post by lexikos » 24 May 2022, 04:09

When a script is launched, each remapping is translated into a pair of hotkeys.
Source: Remapping Keys (Keyboard, Mouse and Joystick) | AutoHotkey
(Follow the link for more details.) There is no "rebinding" and no "changing that bind". There are just just two hotkeys: *F2 and *F2 up. Each of these two hotkeys is context-sensitive, and the conditions are evaluated immediately before each hotkey fires, not just when the key is pressed down. If conditions change while the key is held down, a different key-up variant may fire. It is also possible for one "half" of the pair to fire a different variant without the conditions changing, if there are overlapping conditions. For example, with a window titled "This PC":

Code: Select all

SetTitleMatchMode 2
#IfWinActive This
*F2 up::ToolTip F2 up (This)
#IfWinActive PC
*F2::ToolTip F2 down (PC)
*F2 up::ToolTip F2 up (PC)
Using F2::F5 instead of the second set of hotkeys will give a similar result, causing F5 to stick down because {F5 up} is never sent, but you might never notice since holding F5 doesn't have much effect without key-repeat.

When you press a mouse button down, generally the target window is activated and captures the mouse, causing all mouse input to be directed to that window. Releasing the mouse button will cause it to release the mouse, allowing you to click on other windows again. In this case, the button is not released because of the change in conditions. Pressing the actual XButton1 would cause it to be released (unless it's also a hotkey). You or an application can activate another window, but the original window will still have the mouse capture until you release XButton1.

lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: Window becomes "permanently active" when activating it with XButton1 or XButton2

Post by lexikos » 24 May 2022, 04:14

Another workaround is to simply send XButton down-and-up in one go.

Code: Select all

F2::Click X2

Code: Select all

F2::Send {XButton2}

Post Reply

Return to “Bug Reports”