Skip to content

Fix Escape handling in the clipping bezel - #16

Open
MiMoHo wants to merge 2 commits into
haad:masterfrom
MiMoHo:escape-closes-bezel
Open

Fix Escape handling in the clipping bezel#16
MiMoHo wants to merge 2 commits into
haad:masterfrom
MiMoHo:escape-closes-bezel

Conversation

@MiMoHo

@MiMoHo MiMoHo commented Aug 31, 2026

Copy link
Copy Markdown

Problem

The clipping bezel had two Escape failures:

  1. It recognized Escape only through the first character in charactersIgnoringModifiers. Some macOS key events report the physical Escape key as key code 53 with an empty character string, so the bezel did not close and indexing the empty string could raise an exception.
  2. Hiding the bezel was not treated as cancellation. metaKeysReleased pasted whenever the bezel was unpinned, even after Escape had hidden it. If the user had switched to Favorites, Escape also left the main store stashed instead of restoring it.

These paths match:

Change

  • recognize the layout-independent macOS Escape key code before character processing
  • return safely for key events without characters
  • route both hardware-keycode and character Escape through one cancellation path
  • restore a temporarily selected Favorites store before hiding
  • paste on modifier release only while the bezel is still visible and unpinned
  • preserve the existing character-based Escape fallback and normal visible-bezel paste behavior

Verification

Initial Escape event fix:

  • regression test was red before the production change
  • native AppKit fixture confirms that a key-down event can carry key code 53 with an empty character string
  • focused suite: 3/3 passed
  • native arm64 link comparison: both base and candidate linked the same 20 PBX sources with 0 errors and 40 identical existing warning signatures
  • Clang analyzer comparison: both base and candidate reported 13 identical existing diagnostics and 0 errors
  • independent review of diff SHA-256 f9bdcb32068d0064de94d6b400d4547d0759982e60bed4b5b74b7d1b89c34896: PASS, no findings

Cancellation completion:

  • RED exit 23: hidden bezel still triggered a modifier-release paste
  • RED exit 31: Escape did not restore the store before hiding
  • native fixture subclasses the real AppController and checks visible/unpinned, visible/pinned, hidden/unpinned, key-code Escape, and character Escape paths
  • final focused suite: 4/4 passed
  • native arm64 link comparison against the first PR commit: both candidates linked the same 20 PBX sources with 0 errors and 35 identical classified warning signatures
  • Clang analyzer comparison: 13 identical existing diagnostics and 0 errors
  • independent review of diff SHA-256 1e6071a6f270504e19063767ffe8717608dd37a3ce3461ef8e4e4f2970ba2060: PASS, no findings

Limitation

A full signed Xcode release build and visible physical-key end-to-end test were not available in this Command Line Tools environment. The regression uses native AppKit NSEvent fixtures, executes the real controller paths, and links the complete app target sources.

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.

1 participant