Search code examples
macoscocoanspasteboard

List all NSPasteBoard names on macOS


Is there a way to get a list of all the NSPasteBoards and their names on the current system?

I'm wondering if there's some function available (even if private API) to achieve this. Thank you!


Solution

  • No, there's no function to do this, even with private API.

    The pboard program (/usr/libexec/pboard) runs as a daemon and manages all shared pasteboards. The NSPasteboard class talks to the pboard daemon using XPC, so to get a list of all pasteboards, pboard would need to handle some XPC message by responding with a list of pasteboard names.

    The pboard program is very simple: it initializes various things (logs, sandbox, dispatch queue, mach service) and then calls __CFPasteboardStartServicingConnection, which is actually defined in the CoreFoundation framework. This function ultimately handles each incoming XPC request by calling _CFHandlePasteboardXPCEvent.

    Looking at _CFHandlePasteboardXPCEvent in a disassembler (I used Hopper), we can see the complete list of requests supported by pboard:

    com.apple.pboard.create
    com.apple.pboard.get-counts
    com.apple.pboard.barrier
    com.apple.pboard.begin-generation
    com.apple.pboard.has-entries
    com.apple.pboard.register-entries
    com.apple.pboard.request-data
    com.apple.pboard.refresh-cache
    com.apple.pboard.release
    com.apple.pboard.unique-promise-file
    com.apple.pboard.resolve-all-promises
    com.apple.pboard.resolve-pboard-promises
    com.apple.pboard.set-data-flags
    com.apple.pboard.make-generation-local
    

    None of these has an obvious name like com.apple.pboard.get-pboard-names. Looking at how they're handled, the first thing done by almost all of them is to get a pasteboard name from the event and look up or create the pasteboard with that name.

    The only request that I found that doesn't immediately involve looking up a pasteboard by name is com.apple.pboard.resolve-all-promises, which in fact sends the intriguing message +[_CFPasteboardStore copyAllPasteboards]. However, it doesn't send the result, or in fact any result, back to the client, as far as I can tell. And that is the only use of the copyAllPasteboards selector in CoreFoundation.

    So, unless you attach to the pboard daemon with a debugger and poke around, you won't find a list of all existing pasteboards. (Attaching to pboard with a debugger requires first disabling SIP, which requires booting your recovery partition.)