system wide shortcut for Mac OS X

前端 未结 3 453
滥情空心
滥情空心 2020-12-10 09:27

So I was asked to port some internal helper applications to Mac OS X 10.7.

Works all quite welll as the platform dependent code is minimal anyhow, but one applicati

相关标签:
3条回答
  • 2020-12-10 09:35

    I recently coded up an extension to quodlibet capturing multimedia keys (since absorbed into quodlibet itself); for your setup the same process applies.

    I used the Quartz CGEventTapCreate hook and event loop, and the Cocoa AppKit framework to decipher key codes to achieve this.

    The following code registers a python callback which is passed global key presses, and starts the event loop:

    import Quartz
    from AppKit import NSKeyUp, NSSystemDefined, NSEvent
    
    # Set up a tap, with type of tap, location, options and event mask
    tap = Quartz.CGEventTapCreate(
        Quartz.kCGSessionEventTap, # Session level is enough for our needs
        Quartz.kCGHeadInsertEventTap, # Insert wherever, we do not filter
        Quartz.kCGEventTapOptionListenOnly, # Listening is enough
        Quartz.CGEventMaskBit(NSSystemDefined), # NSSystemDefined for media keys
        keyboardTapCallback,
        None
    )
    
    runLoopSource = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
    Quartz.CFRunLoopAddSource(
        Quartz.CFRunLoopGetCurrent(),
        runLoopSource,
        Quartz.kCFRunLoopDefaultMode
    )
    # Enable the tap
    Quartz.CGEventTapEnable(tap, True)
    # and run! This won't return until we exit or are terminated.
    Quartz.CFRunLoopRun()
    

    I defined a tap for system defined keys only (media keys); you'll have to specify a different event mask (CGEventMaskBit with one or more Event Types); e.g. Quartz.CGEventMaskBit(Quartz.kCGEventKeyUp) for key up events.

    The callback should have the following signature (it implements the CGEventTapCallBack method from the Quartz API:

    def keyboardTapCallback(proxy, type_, event, refcon):
        # Convert the Quartz CGEvent into something more useful
        keyEvent = NSEvent.eventWithCGEvent_(event)
    

    I converted the Quartz event into a NSEvent, because all the information I could find on Mac multimedia keys was referring to that class.

    In principle you can achieve the same thing with the AppKit APIs too, but then your Python application is treated as a Mac Application (visible in the Dock with an icon and everything), while I wanted this to be kept in the background altogether.

    0 讨论(0)
  • 2020-12-10 09:43

    Why has nobody ever mentioned the hammerspoon, which supports custom global system shortcuts, which can invoke shell command or launch UI application like Safari, PHOTOSHOP.

    The following is an example written by me demonstrating how to invoke shell function with global hotkeys. https://gist.github.com/BigSully/0e59ab97f148bc167ea19dbd42ebef4b

    Use hs.execute to execute shell command, either non-interactive or interactive.

    hs.hotkey.bind({"cmd", "alt", "ctrl"}, "P", function()
      local output = hs.execute("toggleProxy", true)
      hs.alert.show(output)
    end)
    

    or Use hs.application.launchOrFocus to launch application hs.application.launchOrFocus("Safari")

    0 讨论(0)
  • 2020-12-10 09:53

    Using the power of google, I found this snippet of code, which allows the registration of global hotkeys for Mac OS X

    You'll need to add the Carbon framework, and probably a bridged cast for ARC when passing the Objective-C self pointer to the C function.

    At a minimum, you'll also need to:

    #import <Carbon/Carbon.h>
    

    The keycodes can be seen on this page explaining the virtual key codes.

    0 讨论(0)
提交回复
热议问题