summaryrefslogtreecommitdiff
path: root/src/macos
diff options
context:
space:
mode:
Diffstat (limited to 'src/macos')
-rw-r--r--src/macos/Sources/AppDelegate.swift22
-rw-r--r--src/macos/pardes.h7
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