Skip to content

Fix stale resize-handle first responder swallowing every Paste Bar key - #113

Open
maximdx wants to merge 1 commit into
momenbasel:mainfrom
maximdx:fix/resize-handle-stale-first-responder
Open

maximdx wants to merge 1 commit into
momenbasel:mainfrom
maximdx:fix/resize-handle-stale-first-responder

Conversation

@maximdx

@maximdx maximdx commented Nov 7, 2026

Copy link
Copy Markdown

Fixes #112.

Problem

When the Paste Bar's resize handle holds first responder outside an active drag, the bar's local key monitor handed every key to the handle, and the handle handled none of them. The bar was visible and focused-looking, but:

  • arrow keys did not move the selection,
  • Escape did not close the bar,
  • typing did not open the search field,
  • every key just played the system alert sound.

The bad state survived hiding/reopening the bar (the panel keeps its first responder across orderOut) and only an app relaunch cleared it. It could also be entered without an interrupted drag by moving keyboard focus onto the handle.

Root cause

Four things combined:

  1. AppController.handleKey stepped aside whenever the first responder was a BarResizeHandleResponder — the condition added in Add a live-resize handle for the Paste Bar #87 was missing the "while dragging" part.
  2. BarResizeHandleView.acceptsFirstResponder was always true, so the handle could hold focus any time.
  3. finishTracking() restored previousFirstResponder; if the handle already owned focus before the drag, that "restore" handed focus back to the handle itself.
  4. BarWindowController.show() never cleared a stale handle first responder, so a stuck state persisted across presentations.

Changes

  • AppController.swift — only yield the bar's keys to the handle while it is actively dragging (handle.isTrackingDrag).
  • BarResizeHandle.swift — the handle is focusable only for the duration of a drag (acceptsFirstResponder gated on isTrackingDrag, which mouseDown sets before asking the window for first responder), and finishTracking() never restores focus to the handle itself.
  • BarWindowController.swift — opening the bar clears a stale handle first responder, so an already-stuck state heals on the next presentation.

Verification

  • Environment: Pesty 1.3.0 (Build 9), macOS 27.2 (26B123), Apple Silicon; Swift 6.4 (Xcode 27.1). The patch uses no new APIs, so CI's Xcode 26.3 should behave the same.
  • swift build succeeds; the patch adds no warnings (the only build warnings are pre-existing Combine-import warnings in SettingsView.swift, unrelated to this change).
  • swift test: 7/7 tests pass.
  • VERSION=0.0.0 BUILD=ci ./scripts/build_app.sh (CI's bundle step) succeeds; universal arm64 + x86_64 binary.
  • Reproduced the stuck state deterministically (handle made first responder outside a drag) and compared behavior: before the patch the arrows were swallowed; after the patch the selection moved from the 1st to the 4th card using real hardware-level key events (not synthetic NSEvents), with Esc closing the bar and typing opening search.

Visual change

None — no visual delta. The strip, the handle and its drag behavior look and behave exactly as before; the only difference is where keyboard focus goes when a drag is not in progress.

Behavior note: while not dragging, the handle no longer takes first responder, so it is not reachable through Full Keyboard Access / key-view traversal. That never gave a working keyboard-adjust path (keys were swallowed) and VoiceOver increment/decrement actions still work; the handle's purpose is mouse dragging.

The resize handle could hold first responder outside a drag. The bar's
key monitor then handed every key to the handle, which handled none of
them, so arrows, Escape, Return and typing all just beeped while the
bar looked focused. Hiding the bar did not help because the panel keeps
its first responder across orderOut; only relaunching the app cleared it.

Gate the key monitor's early return on isTrackingDrag, make the handle
focusable only while a drag is in progress, never restore focus to the
handle itself in finishTracking, and clear a stale handle first
responder when the bar is shown.

Fixes momenbasel#112.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-08T01:33:48.548003Z c8d9783 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@maximdx

maximdx commented Nov 8, 2026

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: c8d9783b1b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@maximdx

maximdx commented Nov 8, 2026

Copy link
Copy Markdown
Author

@momenbasel Friendly ping — the fix for #112 is ready for review (Codex review passed); could you take a look when you have a moment, thanks!

This branch has not been deployed

No deployments
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.

[Bug] A stale resize-handle first responder swallows every Paste Bar key (arrows/Esc/typing only beep)

1 participant