feat: navigate launcher results with control-j and control-k

This commit is contained in:
2026-10-11 19:28:20 +02:00
parent eb75f652a7
commit d02fdadd94
2 changed files with 20 additions and 1 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ Open `Package.swift` in Xcode to edit the project. Use the bundled app above to
## Controls
- Type to filter applications; the first match is selected automatically.
- Up/Down changes the selection without leaving search.
- Up/Down or Control-K/Control-J changes the selection without leaving search or modifying its text.
- Return, keypad Enter, the Open Application button, or a double-click opens the selection.
- Escape, Command-W, or switching focus away dismisses the launcher.
- Reopen from Finder or the Dock to show it again with an empty search. Dismissal leaves the process running; Command-Q quits it.
@@ -32,6 +32,7 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
super.init(window: window)
configureContent(in: window)
window.delegate = self
window.navigateSelection = { [weak self] offset in self?.moveSelection(by: offset) }
}
required init?(coder: NSCoder) {
@@ -390,6 +391,24 @@ private final class ApplicationTableView: NSTableView {
private final class LauncherPanel: NSPanel {
override var canBecomeKey: Bool { true }
override var canBecomeMain: Bool { true }
var navigateSelection: ((Int) -> Void)?
override func sendEvent(_ event: NSEvent) {
if event.type == .keyDown, attachedSheet == nil,
event.modifierFlags.intersection([.control, .command, .option, .shift]) == .control {
switch event.charactersIgnoringModifiers?.lowercased() {
case "j":
navigateSelection?(1)
return
case "k":
navigateSelection?(-1)
return
default:
break
}
}
super.sendEvent(event)
}
override func performClose(_ sender: Any?) {
close()