diff --git a/examples/core-transparent-window/App.zig b/examples/core-transparent-window/App.zig index 04276375..e4fd7549 100644 --- a/examples/core-transparent-window/App.zig +++ b/examples/core-transparent-window/App.zig @@ -31,6 +31,7 @@ pub fn init( const window = try core.windows.new(.{ .title = "core-transparent-window", + .vsync_mode = .triple, }); // Store our render pipeline in our module's state, so we can access it later on. @@ -153,7 +154,7 @@ pub fn tick(app: *App, core: *mach.Core) void { app.title_timer.reset(); // TODO(object): window-title - // try updateWindowTitle(core); + core.windows.set(app.window, .title, std.fmt.allocPrintZ(core.allocator, "core-custom-entrypoint [ {d}fps ] [ Input {d}hz ]", .{ core.frame.rate, core.input.rate }) catch unreachable); } if (app.color_time >= 4.0 or app.color_time <= 0.0) { diff --git a/src/core/Darwin.zig b/src/core/Darwin.zig index ef58e19a..81dea09f 100644 --- a/src/core/Darwin.zig +++ b/src/core/Darwin.zig @@ -22,6 +22,7 @@ pub const Darwin = @This(); pub const Native = struct { window: *objc.app_kit.Window = undefined, + view: *objc.mach.View = undefined, }; pub const Context = struct { @@ -69,6 +70,7 @@ pub fn tick(core: *Core) !void { if (core_window.native) |native| { const native_window: *objc.app_kit.Window = native.window; + const native_view: *objc.mach.View = native.view; if (core.windows.updated(window_id, .color)) { switch (core_window.color) { @@ -81,6 +83,7 @@ pub fn tick(core: *Core) !void { ); native_window.setBackgroundColor(color); native_window.setTitlebarAppearsTransparent(true); + native_view.layer().setOpaque(false); }, .solid => |wc| { const color = objc.app_kit.Color.colorWithRed_green_blue_alpha( @@ -91,9 +94,11 @@ pub fn tick(core: *Core) !void { ); native_window.setBackgroundColor(color); native_window.setTitlebarAppearsTransparent(false); + native_view.layer().setOpaque(true); }, .system => { native_window.setTitlebarAppearsTransparent(false); + native_view.layer().setOpaque(true); }, } } @@ -130,8 +135,9 @@ fn initWindow( const layer = objc.quartz_core.MetalLayer.new(); defer layer.release(); - layer.setDisplaySyncEnabled(true); - layer.setOpaque(false); + if (core_window.color == .transparent) { + layer.setOpaque(false); + } metal_descriptor.* = .{ .layer = layer, @@ -241,7 +247,7 @@ fn initWindow( // Set core_window.native, which we use to check if a window is initialized // Then call core.initWindow to finish initializing the window - core_window.native = .{ .window = native_window }; + core_window.native = .{ .window = native_window, .view = view }; core.windows.setValueRaw(window_id, core_window); try core.initWindow(window_id); } else std.debug.panic("mach: window failed to initialize", .{}); diff --git a/src/sysgpu/metal.zig b/src/sysgpu/metal.zig index 0243b24b..d6b9576b 100644 --- a/src/sysgpu/metal.zig +++ b/src/sysgpu/metal.zig @@ -480,11 +480,14 @@ pub const SwapChain = struct { if (swapchain.current_drawable) |_| { const queue = try swapchain.device.getQueue(); - const command_buffer = queue.command_queue.commandBuffer() orelse { + const command_buffer: *mtl.CommandBuffer = queue.command_queue.commandBuffer() orelse { return error.NewCommandBufferFailed; }; + command_buffer.presentDrawable(@ptrCast(swapchain.current_drawable)); // TODO - objc casting? command_buffer.commit(); + if (swapchain.surface.layer.displaySyncEnabled()) + command_buffer.waitUntilScheduled(); } } };