From 4463c11a90de625226318bdc4eba8f1eff176627 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Tue, 11 Aug 2026 22:13:53 -0700 Subject: [PATCH] =?UTF-8?q?macpal:=20camera-shy=20=E2=80=94=20the=20badge?= =?UTF-8?q?=20steps=20out=20while=20a=20reel=20is=20filming?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While SlabMenubar's reel records the screen (a Captutor Stage take films everything), the pal orders itself off at 20Hz so it never lands in the footage, and steps back in the moment the take ends. Co-Authored-By: Claude Fable 5 --- macpal/Sources/PalCore.swift | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/macpal/Sources/PalCore.swift b/macpal/Sources/PalCore.swift index 7ee7f81af5..4a654db003 100644 --- a/macpal/Sources/PalCore.swift +++ b/macpal/Sources/PalCore.swift @@ -326,6 +326,11 @@ final class PalController: NSObject { let agentChip = GhostImageView() var agentName = "" private var agentTicks = 0 + // Camera-shy: while SlabMenubar's reel is recording (a Captutor Stage take + // films the whole screen), the badge orders itself off so it never lands in + // the footage. Watched at 20Hz so it's gone before the first frame. + private let reelStateFile = NSString(string: "~/.local/share/slab/state/reel.state").expandingTildeInPath + private var hiddenForRecording = false var draggingBadge = false var hovering = false // Menu Band "sing" easter egg state. @@ -492,6 +497,7 @@ final class PalController: NSObject { Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { [weak self] _ in self?.updateClickability() self?.tickNotes() + self?.checkRecordingHide() } // Plugins poll on their own cadence off a 1s tick (cheap; each gates itself). Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in @@ -525,6 +531,28 @@ final class PalController: NSObject { agentChip.layer?.borderColor = accent.cgColor } + // ── camera-shy hide ───────────────────────────────────────────────────── + // Order the whole pal off while a screen recording is live, restore after. + // The reel writes {"recording":true} into its state file the instant it + // starts, so a Captutor Stage take never films the badge in the corner. + private func checkRecordingHide() { + let recording: Bool + if let data = FileManager.default.contents(atPath: reelStateFile), + let obj = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] { + recording = (obj["recording"] as? Bool) ?? false + } else { + recording = false + } + if recording && !hiddenForRecording { + hiddenForRecording = true + window.orderOut(nil) + } else if !recording && hiddenForRecording { + hiddenForRecording = false + window.orderFrontRegardless() + layout() + } + } + // ── agent contact ───────────────────────────────────────────────────── // Same file contract as the rest of the badge: /agent names the // machine's resident agent; artwork resolves wire-first, then the bundle. -- 2.51.2