Skip to content

fix(voice): abort voice recording on Ctrl key chords; skip insert on empty transcription#12268

Open
kyledross wants to merge 1 commit into
warpdotdev:masterfrom
kyledross:fix/voice-input-ctrl-chord-conflict
Open

fix(voice): abort voice recording on Ctrl key chords; skip insert on empty transcription#12268
kyledross wants to merge 1 commit into
warpdotdev:masterfrom
kyledross:fix/voice-input-ctrl-chord-conflict

Conversation

@kyledross
Copy link
Copy Markdown

Fixes #11415

Description

Two bugs in the voice input code path when a modifier key is configured as the voice toggle.

Ctrl-chord conflict: Pressing a chord with the voice-toggle modifier while recording is active (e.g. Ctrl+Shift+V to paste) dispatched the keybinding while the editor was still locked in Selectable state, causing the action to silently fail.

Root cause: WarpUI matches keybindings before running element event handlers for KeyDown events. So the Paste binding fired while the editor was non-editable, and the element-level handler that was meant to abort voice was never reached.

Empty transcription clears selection: Starting and stopping voice without speaking returned an empty transcription string. apply_transcribed_voice_input called user_insert("") unconditionally, replacing any active selection with nothing.

Linked Issue

Fixes #11415

  • The linked issue is labeled ready-to-spec or ready-to-implement.
  • Where appropriate, screenshots or a short video of the implementation are included below.

Changes

element.rsmodifier_key_change: When any modifier key other than the voice toggle key is pressed while voice is active, dispatch AbortVoiceInput immediately. Modifier-key events bypass the keybinding system entirely, so this handler always fires. For Ctrl+Shift+V, voice is aborted on the Shift press, so the editor is already Editable by the time V triggers Paste.

mod.rspaste(): Abort voice at the start of the Paste action as a safety net for chords with no intermediate modifier press (e.g. a direct Ctrl+V).

apply_transcribed_voice_input: Skip user_insert when transcription returns an empty string.

New AbortVoiceInput EditorAction variant: Encapsulates the abort call so it can be dispatched from the element-level modifier handler and any future action handlers without exposing stop_voice_input beyond its current pub(super) scope.

Testing

  • I have manually tested my changes locally with ./script/run

Tests added:

  • test_empty_transcription_does_not_modify_buffer
  • test_non_empty_transcription_inserts_text
  • test_transcription_error_does_not_modify_buffer
  • test_unhandled_modifier_key_is_noop_when_voice_inactive

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

Co-Authored-By: Oz oz-agent@warp.dev

When a modifier key other than the configured voice toggle key is pressed
while voice recording is active (e.g. Shift pressed while Ctrl is the
voice toggle key), voice is now aborted immediately. This ensures the
editor is back in Editable state before the subsequent non-modifier key
press (e.g. V) triggers its keybinding.

Root cause: the WarpUI event system matches keybindings *before* running
element event handlers for KeyDown events. This meant that when the user
held Ctrl (starting voice, locking the editor to Selectable) and pressed
Ctrl+Shift+V to paste, the Paste keybinding fired while the editor was
still Selectable, silently failing. The element-level key handler that
was intended to abort voice was never reached because the keybinding was
already matched and consumed the event.

Two complementary fixes:

1. modifier_key_change (element.rs): When any modifier key other than
   the voice toggle key is pressed while voice is active, dispatch
   AbortVoiceInput immediately. Because modifier-key events bypass
   the keybinding system entirely, this handler always fires. For
   Ctrl+Shift+V this aborts voice on the Shift press, so by the time
   V is pressed the editor is already Editable and the Paste keybinding
   succeeds.

2. paste() (mod.rs): Abort voice at the start of the Paste action as
   a safety net for chords with no intermediate modifier press (e.g.
   Ctrl+V). Restores Editable state before the clipboard insert runs.

Additionally, apply_transcribed_voice_input no longer inserts into the
editor when transcription returns an empty string, preventing a silent
buffer mutation when the user presses and releases the voice toggle key
without speaking anything.

New AbortVoiceInput EditorAction variant encapsulates the abort call
so it can be dispatched from both the element-level modifier handler
and any future action handlers without exposing stop_voice_input
beyond its current pub(super) scope.

Tests added:
- test_empty_transcription_does_not_modify_buffer
- test_non_empty_transcription_inserts_text
- test_transcription_error_does_not_modify_buffer
- test_unhandled_modifier_key_is_noop_when_voice_inactive

Co-Authored-By: Oz <oz-agent@warp.dev>
@cla-bot cla-bot Bot added the cla-signed label Jun 5, 2026
@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label Jun 5, 2026
@kyledross kyledross marked this pull request as ready for review June 7, 2026 11:57
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented Jun 7, 2026

@kyledross

Every PR must be linked to a same-repo issue before Oz can review it.

This PR is linked to #11415, but no linked issue is marked ready-to-implement yet. Only repository maintainers apply that label, so please wait for a maintainer to mark the issue. Once it is marked, push a new commit or comment /oz-review to re-trigger review.

See the contribution guidelines for the full readiness model.

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kyledross

Every PR must be linked to a same-repo issue before Oz can review it.

This PR is linked to #11415, but no linked issue is marked ready-to-implement yet. Only repository maintainers apply that label, so please wait for a maintainer to mark the issue. Once it is marked, push a new commit or comment /oz-review to re-trigger review.

See the contribution guidelines for the full readiness model.

Powered by Oz

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

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Voice input active state blocks Ctrl key chords (e.g. Ctrl+V paste does nothing while voice is recording)

1 participant