Make pasting reliable and turn items into checkboxes
Pasting still failed because the panel is a nonactivating panel: it can be key while the app is not active, and menu key equivalents are not delivered reliably in that state. Cmd+V is now dispatched to the responder chain directly, and the app no longer replaces SwiftUI's main menu — it only adds Hide Panel to it, so the Edit items that AppKit routes text shortcuts through stay intact. Rows also gained a checkbox so a workspace works as a checklist without turning the row into a button, which would swallow the checkbox's clicks.
This commit is contained in:
+18
-36
@@ -32,7 +32,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
// which locks the user out once the panel is hidden.
|
||||
if CommandLine.arguments.contains("--diag") {
|
||||
setupStatusItem()
|
||||
setupMainMenu()
|
||||
installMenuItems()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
||||
self.writeDiagnostics()
|
||||
NSApp.terminate(nil)
|
||||
@@ -60,9 +60,11 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
HotkeyManager.shared.start()
|
||||
|
||||
setupStatusItem()
|
||||
setupMainMenu()
|
||||
promptForAccessibilityIfNeeded()
|
||||
|
||||
// Let SwiftUI finish installing its main menu, then augment it.
|
||||
DispatchQueue.main.async { self.installMenuItems() }
|
||||
|
||||
// Show the panel on launch so the app is discoverable (it has no Dock
|
||||
// icon and the menu bar icon can be hard to spot on a full bar).
|
||||
Task { @MainActor in
|
||||
@@ -111,44 +113,24 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
return .terminateNow
|
||||
}
|
||||
|
||||
/// Accessory apps have no visible menu bar, but the main menu still
|
||||
/// services key equivalents — this is what makes Cmd+Q and Cmd+W work
|
||||
/// while the panel has focus.
|
||||
///
|
||||
/// The Edit menu is not decoration: AppKit routes Cmd+C/V/X/A/Z through
|
||||
/// these items, so a minimal main menu silently breaks pasting and
|
||||
/// selecting in the composer.
|
||||
private func setupMainMenu() {
|
||||
let mainMenu = NSMenu()
|
||||
/// Adds "Hide Panel" to the menu SwiftUI already installed. Do NOT replace
|
||||
/// `NSApp.mainMenu`: SwiftUI's menu carries the Edit items that AppKit
|
||||
/// routes Cmd+C/V/X/A/Z through, so replacing it breaks text editing in the
|
||||
/// composer. This only inserts one item and drops SwiftUI's Settings item,
|
||||
/// whose empty scene would otherwise shadow the in-panel Cmd+, sync panel.
|
||||
private func installMenuItems() {
|
||||
guard let appMenu = NSApp.mainMenu?.items.first?.submenu else { return }
|
||||
|
||||
let appMenuItem = NSMenuItem()
|
||||
mainMenu.addItem(appMenuItem)
|
||||
let appMenu = NSMenu(title: "Prompt")
|
||||
appMenuItem.submenu = appMenu
|
||||
if let settings = appMenu.items.firstIndex(where: { $0.keyEquivalent == "," && $0.keyEquivalentModifierMask == [.command] }) {
|
||||
appMenu.removeItem(at: settings)
|
||||
}
|
||||
guard !appMenu.items.contains(where: { $0.action == #selector(hidePanel) }) else { return }
|
||||
|
||||
let hide = NSMenuItem(title: "Hide Panel", action: #selector(hidePanel), keyEquivalent: "w")
|
||||
hide.target = self
|
||||
appMenu.addItem(hide)
|
||||
appMenu.addItem(.separator())
|
||||
let quit = NSMenuItem(title: "Quit Prompt", action: #selector(quit), keyEquivalent: "q")
|
||||
quit.target = self
|
||||
appMenu.addItem(quit)
|
||||
|
||||
let editMenuItem = NSMenuItem()
|
||||
mainMenu.addItem(editMenuItem)
|
||||
let editMenu = NSMenu(title: "Edit")
|
||||
editMenuItem.submenu = editMenu
|
||||
|
||||
editMenu.addItem(withTitle: "Undo", action: Selector(("undo:")), keyEquivalent: "z")
|
||||
let redo = editMenu.addItem(withTitle: "Redo", action: Selector(("redo:")), keyEquivalent: "z")
|
||||
redo.keyEquivalentModifierMask = [.command, .shift]
|
||||
editMenu.addItem(.separator())
|
||||
editMenu.addItem(withTitle: "Cut", action: #selector(NSText.cut(_:)), keyEquivalent: "x")
|
||||
editMenu.addItem(withTitle: "Copy", action: #selector(NSText.copy(_:)), keyEquivalent: "c")
|
||||
editMenu.addItem(withTitle: "Paste", action: #selector(NSText.paste(_:)), keyEquivalent: "v")
|
||||
editMenu.addItem(withTitle: "Select All", action: #selector(NSText.selectAll(_:)), keyEquivalent: "a")
|
||||
|
||||
NSApp.mainMenu = mainMenu
|
||||
let quitIndex = appMenu.items.firstIndex { $0.action == #selector(NSApplication.terminate(_:)) } ?? appMenu.items.count
|
||||
appMenu.insertItem(.separator(), at: quitIndex)
|
||||
appMenu.insertItem(hide, at: quitIndex + 1)
|
||||
}
|
||||
|
||||
@MainActor @objc private func hidePanel() {
|
||||
|
||||
Reference in New Issue
Block a user