diff options
Diffstat (limited to 'src/macos')
| -rw-r--r-- | src/macos/Sources/AppDelegate.swift | 22 | ||||
| -rw-r--r-- | src/macos/pardes.h | 7 |
2 files changed, 25 insertions, 4 deletions
diff --git a/src/macos/Sources/AppDelegate.swift b/src/macos/Sources/AppDelegate.swift index cda35ff0..077367a4 100644 --- a/src/macos/Sources/AppDelegate.swift +++ b/src/macos/Sources/AppDelegate.swift @@ -162,6 +162,15 @@ final class AppDelegate: NSObject, NSApplicationDelegate, PardesViewDelegate { let pasteboard = NSPasteboard.general pasteboard.clearContents() _ = pasteboard.setString(yank, forType: .string) + }, + read_clipboard: { _ in + // Also the main thread, also inside pardes_tick — but this one + // answers immediately: NSPasteboard reads are synchronous, so + // the paste lands back in the core before this call returns. + // No pump, deliberately: the tick that emitted the effect is + // still draining and picks up whatever the paste queued. + guard let text = NSPasteboard.general.string(forType: .string) else { return } + AppDelegate.paste(text) }) // The real grid, never a placeholder: the core holds each shell's @@ -590,12 +599,19 @@ final class AppDelegate: NSObject, NSApplicationDelegate, PardesViewDelegate { func pardesViewRequestsPaste(_ view: PardesView) { guard let text = NSPasteboard.general.string(forType: .string) else { return } - // Swift lends a temporary NUL-terminated UTF-8 buffer for the duration - // of the call, which is exactly as long as the core borrows it. - pardes_paste(text, text.utf8.count) + AppDelegate.paste(text) pump() } + // Swift lends a temporary NUL-terminated UTF-8 buffer for the duration of + // the call, which is exactly as long as the core borrows it. Static, and + // pumping is the caller's business: the read_clipboard callback is a C + // function pointer that can capture nothing and is already inside a tick, + // where the gesture path is not. + private static func paste(_ text: String) { + pardes_paste(text, text.utf8.count) + } + // ponytail: one window, no tabs — the core has no multi-window notion, so // the last window closing really is the end of the process. func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { diff --git a/src/macos/pardes.h b/src/macos/pardes.h index 1591130e..9a64501a 100644 --- a/src/macos/pardes.h +++ b/src/macos/pardes.h @@ -129,7 +129,7 @@ typedef enum { // ---------------------------------------------------------------- runtime -// What the host lends the core. Two callbacks, because everything else the +// What the host lends the core. Three callbacks, because everything else the // core wants done it already does itself: it owns the ptys, and it opens URLs // through /usr/bin/open. Copied by value during pardes_init, so the struct // need only outlive that call. @@ -145,6 +145,11 @@ typedef struct { // The yank register changed. `text` is borrowed for the duration of the // call only. Main thread, inside pardes_tick. void (*set_clipboard)(void *userdata, const char *text, size_t len); + + // Ask the host for the system clipboard. The host answers by calling + // pardes_paste, which may be synchronous inside this call. Main thread, + // inside pardes_tick. + void (*read_clipboard)(void *userdata); } pardes_runtime_s; // ---------------------------------------------------------------- lifecycle |
