Skip to content

Mouse button may stuck due to a race condition on Windows #1433

Description

@xmcp

Is there an existing issue for this?

  • I have searched the existing issues

Is your issue described in the documentation?

  • I have read the documentation

Is your issue present in the nightly release?

  • This issue is present in the nightly release

Describe the Bug

If I tap on the screen (on an iOS moonlight client), the mouse button occasionally stucks at the pressed state until next click.
When this happens, the log says Warning: Button state of mouse_button [1] does not match the desired state.
The frequency of this symptom increases when there are other programs listening for the mouse input (e.g., AutoHotkey scripts, keyboard/mouse overlay for streaming software, companion apps from Logitech).

Expected Behavior

The mouse button should release as soon as my finger leaves the screen.

Additional Context

The button_mouse function (in src/platform/windows/input.cpp) checks for the original button state (via GetAsyncKeyState) before pressing/releasing it (via SendInput).
If the button is already pressed/released, current action will be ignored with a warning message.

However, the SendInput function is asynchronous (confirmed by Microsoft), so it is possible that GetAsyncKeyState says a button is still pressed/released shortly after releasing/pressing this button via SendInput. I come into this race condition more frequently than others possibly because I run an AutoHotkey script in the backgruound that causes some delay of the mouse queue.

So this is what happens:

  • My finger taps on the screen
    • Sunshine receives a "press left button" packet
      • It calls platf::button_mouse(platf_input, BUTTON_LEFT, /* release= */false)
        • GetAsyncKeyState(VK_LBUTTON) says the button is released, which is expected
        • SendInput(...) presses the left button
    • Sunshine immediately receives another "release left button" packet
      • It calls platf::button_mouse(platf_input, BUTTON_LEFT, /* release= */true)
        • GetAsyncKeyState(VK_LBUTTON) says the button is released, because the previous SendInput request is still in the mouse queue
        • The function logs a warning and then returns, never releasing the button

I would personally recommend removing the GetAsyncKeyState check in button_mouse to fix this bug, or at least remove the return; while keeping the warning message.

Host Operating System

Windows

Operating System Version

Windows 10 22H2 (19045.3086)

Architecture

64 bit

Sunshine commit or version

c972fa8

Package

Windows - portable

GPU Type

AMD

GPU Model

Ryzen 6800H integrated

GPU Driver/Mesa Version

23.7.1

Capture Method (Linux Only)

No response

Config

min_log_level = 1

Apps

No response

Relevant log output

[2023:07:08:21:48:27]: Debug: --begin absolute mouse move packet--
x      [1095]
y      [673]
width  [1193]
height [745]
--end absolute mouse move packet--
[2023:07:08:21:48:27]: Debug: --begin mouse button packet--
action [00000008]
button [01]
--end mouse button packet--
[2023:07:08:21:48:27]: Debug: --begin mouse button packet--
action [00000009]
button [01]
--end mouse button packet--
[2023:07:08:21:48:27]: Warning: Button state of mouse_button [1] does not match the desired state

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions