aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrace Yoder <grace_yoder@outlook.com>2026-06-29 09:45:37 -0600
committerGrace Yoder <grace_yoder@outlook.com>2026-06-30 16:33:26 -0600
commit565174c4b8c73e9e28524709060335a0b17ee3fb (patch)
tree4e642c58ef4f4c227b29537be56183c73d9b5179
parent2f75723e16974bd21762fb64d5f6ce53984b115d (diff)
feat(NSPasteboard): added objective c bridge and build changes
-rw-r--r--build.zig15
-rw-r--r--src/Clip.zig3
-rw-r--r--src/Clip/NSPBBridge.m12
-rw-r--r--src/Clip/NSPasteboard.zig18
4 files changed, 48 insertions, 0 deletions
diff --git a/build.zig b/build.zig
index 242a70c..cb43d76 100644
--- a/build.zig
+++ b/build.zig
@@ -23,6 +23,21 @@ pub fn build(b: *std.Build) void {
}),
});
+ if (target.result.os.tag == .macos) {
+ exe.root_module.addCSourceFiles(.{
+ .files = &.{"src/Clip/NSPBBridge.m"},
+ .language = .objective_c,
+ .flags = &.{"-fobjc-arc"},
+ });
+ exe.root_module.linkFramework("Cocoa", .{});
+ tests.root_module.addCSourceFiles(.{
+ .files = &.{"src/Clip/NSPBBridge.m"},
+ .language = .objective_c,
+ .flags = &.{"-fobjc-arc"},
+ });
+ tests.root_module.linkFramework("Cocoa", .{});
+ }
+
const test_step = b.step("test", "Run tests");
const run_tests = b.addRunArtifact(tests);
test_step.dependOn(&run_tests.step);
diff --git a/src/Clip.zig b/src/Clip.zig
index 8d264c8..1adeeb0 100644
--- a/src/Clip.zig
+++ b/src/Clip.zig
@@ -1,4 +1,5 @@
pub const OSC52 = @import("Clip/OSC52.zig");
+// pub const PBCopy = if (@import("builtin").os.tag == .macos) @import("Clip/OSC52.zig") else null;
// I am not sure if this is super idiomatic Zig or if this is bad practice, but
// by ensuring that all Clip backends implement the same methods, we are able
@@ -15,6 +16,8 @@ fn assertFn(comptime T: type, comptime name: []const u8, comptime Sig: type) voi
}
test {
+ _ = @import("Clip/NSPasteBoard.zig");
+
inline for (@typeInfo(@This()).@"struct".decls) |decl| {
// Only grab types of structs
const T = @field(@This(), decl.name);
diff --git a/src/Clip/NSPBBridge.m b/src/Clip/NSPBBridge.m
new file mode 100644
index 0000000..e736c3f
--- /dev/null
+++ b/src/Clip/NSPBBridge.m
@@ -0,0 +1,12 @@
+// Simple bridge to objective_c code
+// https://nathancraddock.com/blog/writing-to-the-clipboard-the-hard-way/
+#import <Cocoa/Cocoa.h>
+NSPasteboard *pboard;
+
+void initPB() { pboard = [NSPasteboard generalPasteboard]; }
+
+void sendPB(const char *text) {
+ [pboard clearContents];
+ [pboard setString:[NSString stringWithUTF8String:text]
+ forType:NSPasteboardTypeString];
+}
diff --git a/src/Clip/NSPasteboard.zig b/src/Clip/NSPasteboard.zig
new file mode 100644
index 0000000..92c3403
--- /dev/null
+++ b/src/Clip/NSPasteboard.zig
@@ -0,0 +1,18 @@
+const std = @import("std");
+
+extern fn sendPB(text: [*:0]const u8) void;
+extern fn initPB() void;
+
+test "objc bridge" {
+ initPB();
+ sendPB("test_string");
+
+ const result = try std.process.run(std.testing.allocator, std.testing.io, .{
+ .argv = &.{"pbpaste"},
+ });
+ defer std.testing.allocator.free(result.stdout);
+ defer std.testing.allocator.free(result.stderr);
+
+ try std.testing.expectEqualStrings("test_string", std.mem.trim(u8, result.stdout, "\n"));
+}
+