Skip to content

Commit

Permalink
use zig-objc for the macOS backend
Browse files Browse the repository at this point in the history
  • Loading branch information
zenith391 committed Mar 7, 2024
1 parent add79a1 commit c92e525
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 209 deletions.
16 changes: 16 additions & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.{
.name = "capy",
.version = "0.4.0",
.minimum_zig_version = "0.12.0-dev.2063+804cee3b9",
.dependencies = .{
.@"zig-objc" = .{
.url = "https://github.com/mitchellh/zig-objc/archive/f6ed382b6db296626a9b56dadcf9d7e4fcba71d3.tar.gz",
.hash = "1220c94dbcdf5a799ce2b1571978ff3c97bab1341fe329084fcc3c06e5d6375469b9",
},
.macos_sdk = .{
.url = "https://github.com/mitchellh/zig-build-macos-sdk/archive/4186e9fd445d12041651abe59ea5f396499b0844.tar.gz",
.hash = "1220bc2612b57b0cfaaecbcac38e3144e5a9362ff668d71eb8334e895047bdbb7148",
},
},
.paths = .{ "android", "include", "src", "vendor", "LICENSE", "README.md", "build.zig", "build_capy.zig", "build.zig.zon", },
}
25 changes: 18 additions & 7 deletions build_capy.zig
Original file line number Diff line number Diff line change
Expand Up @@ -208,21 +208,32 @@ pub fn install(step: *std.Build.Step.Compile, options: CapyBuildOptions) !*std.B
},
.macos => {
if (@import("builtin").os.tag != .macos) {
const sdk_root_dir = b.pathFromRoot("macos-sdk/");
const sdk_framework_dir = std.fs.path.join(b.allocator, &.{ sdk_root_dir, "System/Library/Frameworks" }) catch unreachable;
const sdk_include_dir = std.fs.path.join(b.allocator, &.{ sdk_root_dir, "usr/include" }) catch unreachable;
const sdk_lib_dir = std.fs.path.join(b.allocator, &.{ sdk_root_dir, "usr/lib" }) catch unreachable;
module.addFrameworkPath(.{ .path = sdk_framework_dir });
module.addSystemIncludePath(.{ .path = sdk_include_dir });
module.addLibraryPath(.{ .path = sdk_lib_dir });
// const sdk_root_dir = b.pathFromRoot("macos-sdk/");
// const sdk_framework_dir = std.fs.path.join(b.allocator, &.{ sdk_root_dir, "System/Library/Frameworks" }) catch unreachable;
// const sdk_include_dir = std.fs.path.join(b.allocator, &.{ sdk_root_dir, "usr/include" }) catch unreachable;
// const sdk_lib_dir = std.fs.path.join(b.allocator, &.{ sdk_root_dir, "usr/lib" }) catch unreachable;
// module.addFrameworkPath(.{ .path = sdk_framework_dir });
// module.addSystemIncludePath(.{ .path = sdk_include_dir });
// module.addLibraryPath(.{ .path = sdk_lib_dir });
// @import("macos_sdk").addPathsModule(module);
@import("macos_sdk").addPaths(step);
}

const objc = b.dependency("zig-objc", .{ .target = step.root_module.resolved_target.?, .optimize = step.root_module.optimize.? });
module.addImport("objc", objc.module("objc"));

module.link_libc = true;
module.linkFramework("CoreData", .{});
module.linkFramework("ApplicationServices", .{});
module.linkFramework("CoreFoundation", .{});
module.linkFramework("CoreGraphics", .{});
module.linkFramework("CoreText", .{});
module.linkFramework("CoreServices", .{});
module.linkFramework("Foundation", .{});
module.linkFramework("AppKit", .{});
module.linkFramework("ColorSync", .{});
module.linkFramework("ImageIO", .{});
module.linkFramework("CFNetwork", .{});
module.linkSystemLibrary("objc", .{ .use_pkg_config = .no });
},
.linux, .freebsd => {
Expand Down
26 changes: 26 additions & 0 deletions src/backends/macos/AppKit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,29 @@ pub const NSBackingStore = enum(NSUInteger) {
/// The window renders all drawing into a display buffer and then flushes it to the screen.
Buffered,
};

pub const CGFloat = f64;

pub const CGPoint = extern struct {
x: CGFloat,
y: CGFloat,
};

pub const CGSize = extern struct {
width: CGFloat,
height: CGFloat,
};

pub const CGRect = extern struct {
origin: CGPoint,
size: CGSize,

pub fn make(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) CGRect {
return .{
.origin = .{ .x = x, .y = y },
.size = .{ .width = width, .height = height },
};
}
};

pub const NSRect = CGRect;
53 changes: 28 additions & 25 deletions src/backends/macos/backend.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const std = @import("std");
const shared = @import("../shared.zig");
const lib = @import("../../main.zig");
const objc = @import("objc.zig");
const objc = @import("objc");
const AppKit = @import("AppKit.zig");
const trait = @import("../../trait.zig");

Expand All @@ -11,7 +11,7 @@ const BackendError = shared.BackendError;
const MouseButton = shared.MouseButton;

// pub const PeerType = *opaque {};
pub const PeerType = objc.id;
pub const PeerType = objc.Object;

const atomicValue = if (@hasDecl(std.atomic, "Value")) std.atomic.Value else std.atomic.Atomic; // support zig 0.11 as well as current master
var activeWindows = atomicValue(usize).init(0);
Expand Down Expand Up @@ -104,43 +104,45 @@ pub fn Events(comptime T: type) type {
pub const Window = struct {
source_dpi: u32 = 96,
scale: f32 = 1.0,
peer: objc.id,
peer: objc.Object,

pub usingnamespace Events(Window);

pub fn create() BackendError!Window {
const NSWindow = objc.getClass("NSWindow") catch return BackendError.InitializationError;
const rect = objc.NSRect.make(100, 100, 200, 200);
const NSWindow = objc.getClass("NSWindow").?;
const rect = AppKit.NSRect.make(100, 100, 200, 200);
const style = AppKit.NSWindowStyleMask.Titled | AppKit.NSWindowStyleMask.Closable | AppKit.NSWindowStyleMask.Miniaturizable | AppKit.NSWindowStyleMask.Resizable | AppKit.NSWindowStyleMask.FullSizeContentView;

std.log.info("make new rect", .{});
const newRect = objc.msgSendByName(objc.NSRect, NSWindow, "frameRectForContentRect:styleMask:", .{ rect, style }) catch unreachable;
// const newRect = objc.msgSendByName(objc.NSRect, NSWindow, "frameRectForContentRect:styleMask:", .{ rect, style }) catch unreachable;

std.log.info("make ", .{});
std.log.info("new rect: {x}", .{@as(u64, @bitCast(newRect.origin.y))});
// std.log.info("new rect: {x}", .{@as(u64, @bitCast(newRect.origin.y))});
const flag: u8 = @intFromBool(false);

const window = objc.msgSendByName(
objc.id,
objc.alloc(NSWindow) catch return BackendError.UnknownError,
const window = NSWindow.msgSend(
objc.Object,
"initWithContentRect:styleMask:backing:defer:",
.{ rect, style, AppKit.NSBackingStore.Buffered, flag },
) catch return BackendError.UnknownError;
);

return Window{
.peer = window,
};
}

pub fn resize(self: *Window, width: c_int, height: c_int) void {
const frame = objc.NSRect.make(
100,
100,
@as(objc.CGFloat, @floatFromInt(width)),
@as(objc.CGFloat, @floatFromInt(height)),
);
// TODO: resize animation can be handled using a DataWrapper on the user-facing API
_ = objc.msgSendByName(void, self.peer, "setFrame:display:", .{ frame, true }) catch unreachable;
_ = height;
_ = width;
_ = self;
// const frame = objc.NSRect.make(
// 100,
// 100,
// @as(objc.CGFloat, @floatFromInt(width)),
// @as(objc.CGFloat, @floatFromInt(height)),
// );
// // TODO: resize animation can be handled using a DataWrapper on the user-facing API
// _ = objc.msgSendByName(void, self.peer, "setFrame:display:", .{ frame, true }) catch unreachable;
}

pub fn setTitle(self: *Window, title: [*:0]const u8) void {
Expand All @@ -161,11 +163,12 @@ pub const Window = struct {
}

pub fn show(self: *Window) void {
std.log.info("show window", .{});
objc.msgSendByName(void, self.peer, "setIsVisible:", .{ @as(objc.id, self.peer), @as(u8, @intFromBool(true)) }) catch unreachable;
objc.msgSendByName(void, self.peer, "makeKeyAndOrderFront:", .{@as(objc.id, self.peer)}) catch unreachable;
std.log.info("showed window", .{});
_ = activeWindows.fetchAdd(1, .Release);
_ = self;
// std.log.info("show window", .{});
// objc.msgSendByName(void, self.peer, "setIsVisible:", .{ @as(objc.id, self.peer), @as(u8, @intFromBool(true)) }) catch unreachable;
// objc.msgSendByName(void, self.peer, "makeKeyAndOrderFront:", .{@as(objc.id, self.peer)}) catch unreachable;
// std.log.info("showed window", .{});
// _ = activeWindows.fetchAdd(1, .Release);
}

pub fn close(self: *Window) void {
Expand All @@ -175,7 +178,7 @@ pub const Window = struct {
};

pub const Container = struct {
peer: objc.id,
peer: objc.Object,

pub usingnamespace Events(Container);

Expand Down
3 changes: 0 additions & 3 deletions src/backends/macos/c.zig

This file was deleted.

174 changes: 0 additions & 174 deletions src/backends/macos/objc.zig

This file was deleted.

Empty file removed zig.sum
Empty file.

0 comments on commit c92e525

Please sign in to comment.