From d4279bd62bc1a331107250db33026eb9ad2d7b50 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Mon, 8 Jun 2026 10:15:39 -0700 Subject: [PATCH] menuband: fix stuck notes when releasing a key with Ctrl/Option held MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit playKeyEvent's `if hasModifier { return false }` bailed on BOTH key-down and key-up. On key-up with Ctrl (or Option) still held it returned before the note-release path, stranding the sounding note/chord — Cmd was unaffected only because Cmd isn't in `hasModifier`. Gate the passthrough on `isDown` so key-ups always reach release, matching the method's own "release is checked on EVERY key-up, not gated by Ctrl" contract. Co-Authored-By: Claude Opus 4.8 (1M context) --- slab/menuband/Sources/MenuBand/MenuBandController.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/slab/menuband/Sources/MenuBand/MenuBandController.swift b/slab/menuband/Sources/MenuBand/MenuBandController.swift index fa876de8fc..686cca1154 100644 --- a/slab/menuband/Sources/MenuBand/MenuBandController.swift +++ b/slab/menuband/Sources/MenuBand/MenuBandController.swift @@ -2471,8 +2471,13 @@ final class MenuBandController { // through to the system. } - // Modifier combos pass through so cmd-c, cmd-tab etc. work as usual. - if hasModifier { return false } + // Modifier combos pass through so cmd-c, cmd-tab etc. work as usual — + // but ONLY gate this on key-DOWN. A key-up must ALWAYS reach the + // release path below, even while Ctrl/Option is still held; otherwise + // letting go of a note with Ctrl down strands the sounding note/chord + // (the bug: Cmd released fine because Cmd isn't in `hasModifier`, but + // Ctrl bailed here and never sent the note-off). + if hasModifier && isDown { return false } // Spacebar (keyCode 49) = reverse-replay (notepat-native parity). // Plain space rewinds the most-recent audio; we intercept it BEFORE -- 2.54.0