diff --git a/mac/Sources/Byre/Dialogs.swift b/mac/Sources/Byre/Dialogs.swift index de916e1..376550c 100644 --- a/mac/Sources/Byre/Dialogs.swift +++ b/mac/Sources/Byre/Dialogs.swift @@ -143,7 +143,7 @@ final class Overlays { guard let self, let window = self.window, win == ObjectIdentifier(window) else { return false } - return self.key(code, flags, chars, ctrl) + return self.key(event, code, flags, chars, ctrl) } return taken ? nil : event } @@ -158,7 +158,7 @@ final class Overlays { } } - private func key(_ code: UInt16, _ flags: NSEvent.ModifierFlags, _ chars: String, _ ctrl: @MainActor (String) -> Bool) -> Bool { + private func key(_ event: NSEvent, _ code: UInt16, _ flags: NSEvent.ModifierFlags, _ chars: String, _ ctrl: @MainActor (String) -> Bool) -> Bool { if !dialogOpen && flags.contains(.control) && !flags.contains(.command) && goKeys.contains(chars) { return ctrl(chars) } @@ -203,6 +203,11 @@ final class Overlays { switcher.pick() return true } + if switcher.inList && (flags.isDisjoint(with: [.command, .control, .function]) || (flags.subtracting(.capsLock) == .command && chars.lowercased() == "v")) { + switcher.pending = event + switcher.inList = false + return true + } } return false } diff --git a/mac/Sources/Byre/Switcher.swift b/mac/Sources/Byre/Switcher.swift index 5adf868..24dcb23 100644 --- a/mac/Sources/Byre/Switcher.swift +++ b/mac/Sources/Byre/Switcher.swift @@ -79,6 +79,7 @@ private let shortcuts: [(String, [(String, String)])] = [ ("Task switcher", [ ("Tab", "Switch between the text and the list"), ("↑ ↓", "Move the highlight, in the list"), + ("Typing, ⌘V", "Jump from the list to the text"), ("Enter", "Pick the highlighted row"), ("Shift+Enter", "New line in the first message"), ("name: message", "Start the task in the project whose name starts with name"), @@ -154,7 +155,8 @@ final class SwitcherModel { let imageKey = "switcher:\(UUID().uuidString)" var text = "" var selected = 0 - var inList = false + var inList = true + @ObservationIgnored var pending: NSEvent? var workflows: [WorkflowSummary] = [] init(store: Store, overlays: Overlays, anchor: CGRect) { @@ -317,6 +319,7 @@ final class SwitcherModel { } catch { overlays.openSwitcher(store) if let s = overlays.switcher { + s.inList = false s.setText(typed) store.images.restore(s.imageKey, imgs) } @@ -418,7 +421,11 @@ private struct SwitcherBox: View { .onAppear { DispatchQueue.main.async { logFocus("switcher before focus") - focused = true + if model.inList { + overlays.window?.makeFirstResponder(nil) + } else { + focused = true + } DispatchQueue.main.async { logFocus("switcher after focus focused=\(focused)") } @@ -430,6 +437,10 @@ private struct SwitcherBox: View { .onChange(of: focused) { if focused { model.inList = false + if let event = model.pending { + model.pending = nil + NSApp.postEvent(event, atStart: true) + } } } }