Skip to content

Fix Escape key not working in terminal panels (e.g. lazygit) - #1957

Merged
lawrencecchen merged 1 commit into
manaflow-ai:mainfrom
che-3:fix/esc-not-working-in-panels
Mar 23, 2026
Merged

lawrencecchen merged 1 commit into
manaflow-ai:mainfrom
che-3:fix/esc-not-working-in-panels

Conversation

@che-3

@che-3 che-3 commented Mar 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • shouldConsumeSuppressedEscape had an isARepeat early return that unconditionally swallowed all repeated Escape key events, with no time limit
  • This caused Escape to stop working in TUI apps (lazygit, vim, etc.) running in panels after the command palette was dismissed
  • Removed the isARepeat guard so repeated Escapes fall through to the existing 0.35s time-based check, which correctly expires

Root Cause

// Before: repeat Escapes consumed forever until keyUp
if event.isARepeat {
    return true  // BUG: no time limit
}

// After: removed — falls through to 0.35s grace period check

Test plan

  • Open lazygit in a panel, press ? to open help, press Esc → dialog closes
  • Open command palette (Cmd+K), press Esc to dismiss, then press Esc in terminal → Esc works
  • Hold Esc key → first 0.35s suppressed (prevents palette re-trigger), then passes through
  • Rapid Esc taps in vim/neovim → all register correctly

Fixes #1610

🤖 Generated with Claude Code


Summary by cubic

Fixes Escape not working in terminal panels and TUIs after dismissing the command palette. Repeated Escapes are no longer consumed indefinitely and now respect the 0.35s suppression window. Fixes #1610.

  • Bug Fixes
    • Removed isARepeat early return in shouldConsumeSuppressedEscape, letting repeats pass the 0.35s time-based check.
    • Esc works again in TUI apps in panels (e.g., lazygit, vim), including rapid taps and key repeat.

Written for commit 5de59cd. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes
    • Refined escape key suppression logic to use elapsed time-based detection instead of repeat event consumption, providing more consistent and predictable suppression behavior.

The `shouldConsumeSuppressedEscape` function had an early return that
unconditionally consumed all repeated Escape key events (`isARepeat`),
regardless of whether the suppression window had expired. This caused
Escape presses to be swallowed in TUI apps (e.g. lazygit) running in
panels, because the repeat events never reached the active responder.

Removing the `isARepeat` guard lets repeated Escapes fall through to
the existing time-based check (0.35s window), which correctly expires
and stops consuming events after the command palette is dismissed.

Fixes manaflow-ai#1610

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Mar 22, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Mar 22, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cdb74119-f348-4383-9148-d14ff396325f

📥 Commits

Reviewing files that changed from the base of the PR and between e0e0e35 and 5de59cd.

📒 Files selected for processing (1)
  • Sources/AppDelegate.swift
💤 Files with no reviewable changes (1)
  • Sources/AppDelegate.swift

📝 Walkthrough

Walkthrough

This change modifies the escape key suppression logic in AppDelegate by removing the immediate consumption of repeat key events. Escape suppression now depends solely on elapsed uptime since suppression started (≤0.35 seconds) rather than treating all repeat events as suppressible.

Changes

Cohort / File(s) Summary
Escape Suppression Logic
Sources/AppDelegate.swift
Removed early return for repeat key events; escape suppression now depends only on uptime elapsed since suppression started (≤0.35s).

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Possibly related PRs

  • PR #847 — Introduced the escape-suppression function that is directly modified by this change to fix repeat key event handling.

Poem

🐰 A bounce and a leap through panels so keen,
The Esc key now works where it's never been seen,
No more repeat traps to hold back the flight,
Just uptime and timing to set our app right! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing Escape key functionality in terminal panels like lazygit, which directly corresponds to the bug fix implemented.
Description check ✅ Passed The PR description includes summary, root cause analysis, and test plan, but the Testing section in the template is incomplete with unchecked items and no manual verification details provided.
Linked Issues check ✅ Passed The code change directly addresses issue #1610 by removing the isARepeat early return that was causing Escape to stop working in TUI applications like lazygit within panels.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the Escape key suppression logic in shouldConsumeSuppressedEscape, with no unrelated modifications present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 1 file

@greptile-apps

greptile-apps Bot commented Mar 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR removes a 3-line isARepeat early-return guard from shouldConsumeSuppressedEscape in AppDelegate.swift. The removed guard unconditionally consumed all repeated Escape keyDown events (hold-key repeats) after a command palette dismissal, with no time bound — effectively blocking Escape from reaching the terminal until the key was fully released. The fix lets repeated Escapes fall through to the existing 0.35s time-based suppression window, which correctly expires and restores normal Escape delivery to TUI apps like lazygit and vim.

  • Root cause fixed: repeated Escapes were absorbed forever by the isARepeat → return true path; the time-based check at ≤ 0.35s was never reached for held keys.
  • Post-fix behaviour: both initial and repeated Escapes are suppressed for up to 0.35s after palette dismissal (preventing accidental re-opens), then pass through normally.
  • Fallback cleanup (line 4459-4461) and clearEscapeSuppressionForKeyUp remain intact, so state hygiene is unaffected.
  • No regression test added: given the macOS keyboard-event simulation constraints noted in the test quality policy, the manual test plan is the appropriate coverage here.

Confidence Score: 5/5

  • This PR is safe to merge — the change is minimal, well-scoped, and correctly targeted at the root cause.
  • A 3-line deletion that removes an unconditional early-return, deferring to an already-correct 0.35s time-based check. The before/after behaviour is clearly understood, the surrounding keyUp cleanup paths are untouched, and the fix is consistent with how the suppression state machine was designed to work. No new logic is introduced and no regressions are apparent.
  • No files require special attention.

Important Files Changed

Filename Overview
Sources/AppDelegate.swift Removes the isARepeat early-return guard from shouldConsumeSuppressedEscape, so held Escape keyDown repeats fall through to the existing 0.35s time-based suppression window instead of being consumed indefinitely.

Sequence Diagram

sequenceDiagram
    participant User
    participant EventMonitor
    participant shouldConsumeSuppressedEscape
    participant Terminal

    User->>EventMonitor: Esc keyDown (dismiss palette)
    EventMonitor->>EventMonitor: beginCommandPaletteEscapeSuppression(startedAt=t0)
    EventMonitor->>EventMonitor: dismiss palette → return true (consumed)

    Note over User,Terminal: User continues holding Esc (repeat events)

    User->>EventMonitor: Esc keyDown (isARepeat=true, t0+0.1s)
    EventMonitor->>shouldConsumeSuppressedEscape: check suppression
    shouldConsumeSuppressedEscape-->>EventMonitor: elapsed=0.1s ≤ 0.35s → true (consumed)

    User->>EventMonitor: Esc keyDown (isARepeat=true, t0+0.4s)
    EventMonitor->>shouldConsumeSuppressedEscape: check suppression
    shouldConsumeSuppressedEscape->>shouldConsumeSuppressedEscape: elapsed=0.4s > 0.35s → endSuppression()
    shouldConsumeSuppressedEscape-->>EventMonitor: false (pass through)
    EventMonitor->>Terminal: Esc delivered ✓

    User->>EventMonitor: Esc keyUp
    EventMonitor->>EventMonitor: clearEscapeSuppressionForKeyUp() (no-op, already cleared)
Loading

Reviews (1): Last reviewed commit: "fix: stop consuming repeated Escape keys..." | Re-trigger Greptile

@lawrencecchen
lawrencecchen merged commit 5be9eda into manaflow-ai:main Mar 23, 2026
4 of 5 checks passed
@lawrencecchen

Copy link
Copy Markdown
Contributor

Thank you for the contribution!

bn-l pushed a commit to bn-l/cmux that referenced this pull request Apr 3, 2026
…-panels

Fix Escape key not working in terminal panels (e.g. lazygit)
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.

Esc does not work inside panels

2 participants