肇鑫的技术博客

业精于勤,荒于嬉

Shortcuts with modify mask in macOS

For Poster 2 Mac, which has been released lately, one of the feedbacks I got, is if I could provide a method to quickly compose and share texts. For current users, the steps are:

  1. Move mouse/trackpad to click the menu bar item of Poster 2.
  2. Move mouse to click the Write button.
  3. Compose.

Also, the user may have to close the window when texts are sent.

I want to improve those experiences. The easiest idea is to bind composing with mouse click directly. But I don't want that. In my own experience, you must make your app as simple as possible, as you may not even know, that some of the users have never known of right click. If you app need to do something with right click, those functions would be seen as never worked.

A big difference from a macOS user to an iOS user is the former uses a physical keyboard. So I want to add shortcuts for composing and hiding app.

As the beginning, I was thinking adding a menu item to do the same with Write button. However, I found I could bind Write menu item with key enter, but I could not call it in my app. I got a beep sound and nothing happened. I could use modifier mask like command, but that was not what I wanted.

Responder Chain

You should know what is a responder chain. For a brief, a responder chain is something how your app responds to a user event. For example, if a user presses keyboard a. The first responder gets the a and looks for itself if it can react the event, if not, it will pass the event to the next responder, usually is the view which contains itself. Things will go on until the event is react or there is no further responder.

NSStandardKeyBindingResponding Protocol

However, there are always some other things you have to consider. Many subclasses of NSView adopt NSStandardKeyBindingResponding protocol, and some keys have been occupied already. The good thing is, if you want to use those keys, you should override the corresponding method.

Beep Sound

Some subclasses of NSView also implemented the default beep sound if the key is not register. You must exclude the key you want in NSResponder's keyDown(with:) method.

My Resolution

Press enter key for quick editing, and press esc key to hide window.

Enter Key

Subclassing NSWindow and override keyUp(with:) method to compose.

Esc Key

Override cancelOperation(_:) for esc key.

class CancelWindow: NSWindow {
    override func keyDown(with event: NSEvent) {
        if event.keyCode == 36 { // enter key

        } else {
            super.keyDown(with: event   )
        }
    }
    
    override func keyUp(with event: NSEvent) {
        if event.keyCode == 36 { // enter key
            (self.contentViewController as? NextMainViewControllerMac)?.writePost(nil)
        } else {
            super.keyUp(with: event)
        }
    }
    
    override func cancelOperation(_ sender: Any?) {
        (NSApp.delegate as? AppDelegate)?.hide()
    }
}

Enter Key for NSButton

There is also something need to mention. If you add enter to keyEquivalent of NSButton, the border become blue automatically. This is a feature which can't be changed.