cocoabits / MASShortcut

Modern framework for managing global keyboard shortcuts compatible with Mac App Store. More details:
http://blog.shpakovski.com/2012/07/global-keyboard-shortcuts-in-cocoa.html
BSD 2-Clause "Simplified" License
1.52k stars 220 forks source link

Is there a way I can detect Key press and hold with MASShortcut? #148

Open rampatra opened 4 years ago

rampatra commented 4 years ago

I want to perform some actions when the user presses and holds Fn key. Can I detect Key press and hold with this library? If yes, a simple code snippet would be great.

Kentzo commented 4 years ago

The answer is going to be different on whether your keypress is an ansi key-code (like A or ]) or a modifier flag (like Ctrl or Cmd).

AFAIK the underlying system API used by MASShortcut does not allow you to detect keycode-less shortcuts (like Fn). You may take a look at SRShortcutRecorder and specifically its SRAXGlobalShortcutMonitor. Note that this API requires Accessibility Permission.

As of ability to detect holds: neither MASShortcut nor SRShortcutRecorder supports it. That's an interesting feature though, please create an issue and detail your use-case.

rampatra commented 4 years ago

The answer is going to be different on whether your keypress is an ansi key-code (like A or ]) or a modifier flag (like Ctrl or Cmd).

What if I say I am okay with using key having ansi key-code (like A or ])?

AFAIK the underlying system API used by MASShortcut does not allow you to detect keycode-less shortcuts (like Fn). You may take a look at SRShortcutRecorder and specifically its SRAXGlobalShortcutMonitor. Note that this API requires Accessibility Permission.

I have installed one app on my machine and one of its features works with long press Fn key and doesn't ask for accessibility permission. Not sure how are they doing it. Need to investigate more on this.

As of ability to detect holds: neither MASShortcut nor SRShortcutRecorder supports it. That's an interesting feature though, please create an issue and detail your use-case.

Can you pl tell me what more details you need? My use-case is that I want to toggle a feature of my app when a user presses and holds a key instead of just pressing once. That's all.

Kentzo commented 4 years ago

Not sure how are they doing it. Need to investigate more on this.

If you only need to know when Fn is pressed and not prevent / alter how other apps see it, I think NSEvent. addGlobalMonitorForEvents should be sufficient to get notified when modifier flags change and act accordingly.

My use-case is that I want to toggle a feature of my app when a user presses and holds a key instead of just pressing once.

  1. Whether you need to toggle a keycode+modifier or modifier-only combination
  2. Whether you need run loop (as in RunLoop) to be blocked for the duration of the hold
  3. Whether you need to prevent other apps from seeing the event

If you answers are "modifier-only", "not blocking" and "no" then I'd use the API I mentioned above to set up a Timer or DispatchSourceTimer.

EDIT

When timer fires, just check modifier flags again. Or cancel the timer if modifier flags change before it gets a chance to fire.

shpakovski commented 4 years ago

@Kentzo Thanks for help!

@rampatra Don’t forget about System Preferences which may intercept fn:

fn