Open tesths opened 5 years ago
You can't because your app misses an app menu.
As a workaround, you could use a library to bind cmd+w to closing the preferences window.
@Mortennn Thanks for your advise. But I already try your solution. It has some problem. MASShortcut is global binding. If I bind cmd+w to my app, other app can not use cmd+w to close windows. I have to stop my app, so that other apps will be normal to use cmd+w to close it's window.
I think it's my fault. As apple document says
All of an application’s menus in the menu bar are owned by one NSMenu instance that’s created by the application when it starts up. You can retrieve this main menu with the NSApplication method mainMenu.
So I add custom menu programmatically. And now I can close it by cmd+w. I just reference Working without a nib, Part 10: Mac Main Menu. All things done.
I think we could add something to make this just work.
NSApp.activate(ignoringOtherApps: true)
in PreferencesWindowController.show()
.final class WindowForMenuBarApp: NSWindow {
override var canBecomeMain: Bool { true }
override var canBecomeKey: Bool { true }
override var acceptsFirstResponder: Bool { true }
override func cancelOperation(_ sender: Any?) {
performClose(self)
}
override func keyDown(with event: NSEvent) {
if event.modifiers == .command {
if event.charactersIgnoringModifiers == "w" {
performClose(self)
return
}
if event.charactersIgnoringModifiers == "m" {
performMiniaturize(self)
return
}
}
super.keyDown(with: event)
}
}
@DivineDominion @SamusAranX Thoughts?
I don't understand the use case, yet. Even menu bar apps can have an (invisible) main menu that handles the shortcuts. (I maintain 2 that work nicely.)
I think this is workaround the app developers need to implement, not the Preferences library. Since preferences are so central to apps, there's no harm in showing a workaround as a code snippet or as another example app target. (I would prefer the latter.)
Even menu bar apps can have an (invisible) main menu that handles the shortcuts. (I maintain 2 that work nicely.)
Without also showing the Dock icon when the window is shown? That's news to me.
I think this is workaround the app developers need to implement, not the Preferences library.
I'm arguing this for egoistic reasons, as I plan to use Preferences in one of my menu bar apps, and it would be nice if it just worked. After all, the point of this package is to make it easier to add a Preferences window, and many apps are menu bar apps, so it's not like this is a niche problem. I think most menu bar apps either don't care about fixing this or don't even know it's an issue. So the ultimate gain of us adding this here is generally better UX in many apps for the user, which is a big win.
I don't have a computer with Xcode for 2 weeks, but can have a look at this later!
If you want to try, create a new Cocoa app from scratch, add the LSUIElement Info.plist key, and add a text view to the main window. Copy and paste should just work. Now disable or remove the "Edit" main menu (that is not even visible during the app runtime) and try again.
If you want to try, create a new Cocoa app from scratch, add the LSUIElement Info.plist key, and add a text view to the main window. Copy and paste should just work. Now disable or remove the "Edit" main menu (that is not even visible during the app runtime) and try again.
Wow. Interesting. I could have sworn that did not use to work, but I have not had a MainMenu.xib in my menu bar app for years.
Tidbit: When using SwiftUI, that (Command+C, etc) works even with a main menu.
I just reference Working without a nib, Part 10: Mac Main Menu. All things done.
Here is code for my menu bar app with SwiftUI. Since main menu are invisible on menu bar app, I removed File/Edit submenu rules and removed localized string.
import Cocoa
@objc protocol EditMenuActions {
func redo(_ sender: AnyObject)
func undo(_ sender: AnyObject)
}
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationWillFinishLaunching(_ notification: Notification) {
let mainMenu = NSMenu(title: "MainMenu")
let menuItem = mainMenu.addItem(withTitle: "", action: nil, keyEquivalent: "")
let submenu = NSMenu()
submenu.addItem(withTitle: "Close Window", action: #selector(NSWindow.performClose(_:)), keyEquivalent: "w")
submenu.addItem(withTitle: "Undo", action: #selector(EditMenuActions.undo(_:)), keyEquivalent: "z")
submenu.addItem(withTitle: "Redo", action: #selector(EditMenuActions.redo(_:)), keyEquivalent: "Z")
submenu.addItem(withTitle: "Cut", action: #selector(NSText.cut(_:)), keyEquivalent: "x")
submenu.addItem(withTitle: "Copy", action: #selector(NSText.copy(_:)), keyEquivalent: "c")
submenu.addItem(withTitle: "Paste", action: #selector(NSText.paste(_:)), keyEquivalent: "v")
submenu.addItem(withTitle: "Select All", action: #selector(NSText.selectAll(_:)), keyEquivalent: "a")
mainMenu.setSubmenu(submenu, for: menuItem)
NSApp.mainMenu = mainMenu
}
}
@iolate 👍 Keep in mind that if users set custom keyboard shortcuts, though, and using a non-English language for macOS, their rebound keys might be broken if you do not localize the titles. https://support.apple.com/en-sa/guide/mac-help/mchlp2271/mac
I make an app, just with statusbar and menu item. And I add preferences in the menu item. But when the Preferences open, I can't use cmd+w close it. Only has to click red close button in the left up corner.