Skip to content

Prevent restarting haptic playback from gamepad/keyboard while a clip plays#77

Closed
tomaabe wants to merge 1 commit into
microsoft:mainfrom
tomaabe:fix/haptics-ui-input-lock
Closed

Prevent restarting haptic playback from gamepad/keyboard while a clip plays#77
tomaabe wants to merge 1 commit into
microsoft:mainfrom
tomaabe:fix/haptics-ui-input-lock

Conversation

@tomaabe

@tomaabe tomaabe commented Jun 8, 2026

Copy link
Copy Markdown

Summary

While a clip is playing, the Play WASAPI (L1) and Play XAudio2 (R1) buttons could still be retriggered via the controller or the keyboard, restarting playback from the beginning or starting the other engine. Only mouse clicks were correctly blocked. This change gates both play actions on !IsPlaying() for every input path.

Repro steps

  1. Build and run the Advanced Haptics sample.
  2. Connect a controller and select a multi-second clip.
  3. Start playback, then while it is still playing:
    • Press the controller L1/R1 again → playback restarts from the beginning (bug).
    • With R1 activated by keyboard Space, the button keeps focus; pressing Space again retriggers it (bug).
    • Start L1 while R1 is playing (or vice versa) → both play (bug).
    • Mouse clicks on the buttons are correctly ignored (expected).

Root cause

The play buttons were wrapped in ImGui::BeginDisabled(IsPlaying()), but BeginDisabled only suppresses mouse interaction. The gamepad shortcut (|| IsButtonPressed(...)) bypassed the disabled state entirely, and ImGui still activates keyboard Space/Enter on a button that already had focus, so playback could be retriggered through those paths.

Fix

  • Always draw the buttons (ImGui requires the call every frame) but gate each play action on !isPlaying so mouse, keyboard (Space/Enter) and gamepad (L1/R1) paths are all blocked while a clip is playing, and the two engines are mutually exclusive.
  • Call ImGui::SetWindowFocus(nullptr) when playback starts so the now-disabled button does not keep showing a pressed animation when Space is held.

Testing

  • Built Debug|x64 with Visual Studio.
  • Verified L1/R1 cannot retrigger playback mid-clip from mouse, keyboard or controller; that the two engines are mutually exclusive; that the buttons re-enable after a clip finishes; and that the pressed animation no longer lingers when Space is held on a disabled button.

Notes

  • UI-only change contained to haptics.cpp; no public API changes.

… plays

The Play WASAPI (L1) and Play XAudio2 (R1) buttons were wrapped in
ImGui::BeginDisabled while a clip was playing, but that only suppresses mouse
interaction. The gamepad shortcut ("|| IsButtonPressed(...)") bypassed the
disabled state entirely, and ImGui still activates a keyboard Space/Enter on a
button that already had focus. As a result a clip could be restarted from the
start, or the other engine started, mid-playback via the controller or the
keyboard.

Gate both play actions on !IsPlaying() for every input path (mouse, keyboard
and gamepad) so playback cannot be retriggered while active, and clear the
window focus on play so the now-disabled button stops showing a pressed
animation when Space is held.
@BrianPeekMSFT

Copy link
Copy Markdown

Fixed internally, will be in the next github publish.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants