diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index e71e7431e..c07fdfdce 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -737,6 +737,25 @@ pub fn setFocus(self: *Metal, focus: bool) !void { } } +/// Callback when the window is visible or occluded. +/// +/// Must be called on the render thread. +pub fn setVisible(self: *Metal, visible: bool) void { + // If we're not visible, then we want to stop the display link + // because it is a waste of resources and we can move to pure + // change-driven updates. + if (comptime DisplayLink != void) link: { + const display_link = self.display_link orelse break :link; + if (visible and self.focused) { + log.warn("starting display link because window is visible", .{}); + display_link.start() catch {}; + } else { + log.warn("stopping display link because window is not visible", .{}); + display_link.stop() catch {}; + } + } +} + /// Set the new font size. /// /// Must be called on the render thread. diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 2a845d602..8fbf4654c 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -579,6 +579,14 @@ pub fn setFocus(self: *OpenGL, focus: bool) !void { self.focused = focus; } +/// Callback when the window is visible or occluded. +/// +/// Must be called on the render thread. +pub fn setVisible(self: *OpenGL, visible: bool) void { + _ = self; + _ = visible; +} + /// Set the new font size. /// /// Must be called on the render thread. diff --git a/src/renderer/Thread.zig b/src/renderer/Thread.zig index ce7fc4d7c..3ed9385da 100644 --- a/src/renderer/Thread.zig +++ b/src/renderer/Thread.zig @@ -272,6 +272,9 @@ fn drainMailbox(self: *Thread) !void { // still be happening. if (v) self.drawFrame(); + // Notify the renderer so it can update any state. + self.renderer.setVisible(v); + // Note that we're explicitly today not stopping any // cursor timers, draw timers, etc. These things have very // little resource cost and properly maintaining their active