From 16b1c18508657c3360fc3e41932491e1e836d545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alcibiades=20Cabral=20D=C3=ADaz?= Date: Sat, 7 Nov 2026 12:24:57 +0000 Subject: [PATCH 1/2] Add a setting to hide the toolbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Settings → Appearance → Toolbar → Show the toolbar (on by default). When off, the toolbar no longer appears when the pointer turns on or when the mouse reaches the bottom of the screen. It still shows while Accessibility permission is missing, so the permission button stays reachable. Co-Authored-By: Claude Opus 5.5 --- Sources/TinyHand/OverlayController.swift | 2 +- Sources/TinyHand/Preferences.swift | 7 +++++- Sources/TinyHand/SettingsView.swift | 32 +++++++++++++++--------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/Sources/TinyHand/OverlayController.swift b/Sources/TinyHand/OverlayController.swift index 4829a77..08bbc4f 100644 --- a/Sources/TinyHand/OverlayController.swift +++ b/Sources/TinyHand/OverlayController.swift @@ -484,7 +484,7 @@ final class OverlayController { let near = f.insetBy(dx: -80, dy: 0).union(f.offsetBy(dx: 0, dy: 90)).insetBy(dx: 0, dy: -10).contains(mouse) let needsPermission = !inputTap.isInstalled let drawing = armView.ink.isDrawing - toolbar.setRevealed(!drawing && (near || Date() < revealUntil || needsPermission)) + toolbar.setRevealed(needsPermission || (Preferences.showToolbar && !drawing && (near || Date() < revealUntil))) let menuLikely = !menuRects.isEmpty || ownMenuOpen || Date() < menuOpeningUntil || Date().timeIntervalSince(lastButtonEvent) < 2 diff --git a/Sources/TinyHand/Preferences.swift b/Sources/TinyHand/Preferences.swift index e18b2a2..6eff8f7 100644 --- a/Sources/TinyHand/Preferences.swift +++ b/Sources/TinyHand/Preferences.swift @@ -144,6 +144,11 @@ enum Preferences { set { set(newValue.rawValue, "inkChoice") } } + static var showToolbar: Bool { + get { defaults.object(forKey: "showToolbar") as? Bool ?? true } + set { set(newValue, "showToolbar") } + } + static var showInkButton: Bool { get { defaults.object(forKey: "showInkButton") as? Bool ?? true } set { set(newValue, "showInkButton") } @@ -182,7 +187,7 @@ enum Preferences { static func resetAll() { for key in ["shortcut.toggle", "shortcut.clear", "pointerSize", "showShadow", "fadeSeconds", "sound.hands", "sound.laser", "interactKey", "interactKeepsHand", "doubleShiftClickThrough", "pinnedStyles", "pointerStyle", - "inkChoice", "showInkButton", "tapSound"] { + "inkChoice", "showInkButton", "showToolbar", "tapSound"] { defaults.removeObject(forKey: key) } NotificationCenter.default.post(name: changed, object: nil) diff --git a/Sources/TinyHand/SettingsView.swift b/Sources/TinyHand/SettingsView.swift index a065a52..94b6790 100644 --- a/Sources/TinyHand/SettingsView.swift +++ b/Sources/TinyHand/SettingsView.swift @@ -938,20 +938,28 @@ private struct AppearancePage: View { @ObservedObject var model: SettingsModel var body: some View { - Card(title: "Pointer") { - Row("Size") { - HStack(spacing: 10) { - Image(systemName: "hand.point.up.left.fill").font(.system(size: 10)).foregroundColor(.secondary) - Slider(value: model.binding({ Double(Preferences.pointerSize) }, { Preferences.pointerSize = CGFloat($0) }), - in: Double(Preferences.pointerSizeRange.lowerBound)...Double(Preferences.pointerSizeRange.upperBound)) - .frame(width: 180) - .focusable(false) - Image(systemName: "hand.point.up.left.fill").font(.system(size: 16)).foregroundColor(.secondary) + VStack(alignment: .leading, spacing: 22) { + Card(title: "Pointer") { + Row("Size") { + HStack(spacing: 10) { + Image(systemName: "hand.point.up.left.fill").font(.system(size: 10)).foregroundColor(.secondary) + Slider(value: model.binding({ Double(Preferences.pointerSize) }, { Preferences.pointerSize = CGFloat($0) }), + in: Double(Preferences.pointerSizeRange.lowerBound)...Double(Preferences.pointerSizeRange.upperBound)) + .frame(width: 180) + .focusable(false) + Image(systemName: "hand.point.up.left.fill").font(.system(size: 16)).foregroundColor(.secondary) + } + } + Row("Shadow under the pointer") { + Toggle("", isOn: model.binding({ Preferences.showShadow }, { Preferences.showShadow = $0 })) + .toggleStyle(.switch).labelsHidden().focusable(false) } } - Row("Shadow under the pointer") { - Toggle("", isOn: model.binding({ Preferences.showShadow }, { Preferences.showShadow = $0 })) - .toggleStyle(.switch).labelsHidden().focusable(false) + Card(title: "Toolbar") { + Row("Show the toolbar", detail: Preferences.showToolbar ? "Appears when the pointer turns on and when you move to the bottom of the screen." : "Hidden while you present. Turn it back on to switch pointers.") { + Toggle("", isOn: model.binding({ Preferences.showToolbar }, { Preferences.showToolbar = $0 })) + .toggleStyle(.switch).labelsHidden().focusable(false) + } } } } From 75121410ec7bece5c19a91982e5d8c589370c6d4 Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Tue, 10 Nov 2026 12:25:28 +0000 Subject: [PATCH 2/2] Move toolbar settings to the Pointers page --- Sources/TinyHand/SettingsView.swift | 49 +++++++++++++++-------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/Sources/TinyHand/SettingsView.swift b/Sources/TinyHand/SettingsView.swift index 94b6790..4b62fc9 100644 --- a/Sources/TinyHand/SettingsView.swift +++ b/Sources/TinyHand/SettingsView.swift @@ -582,6 +582,7 @@ private struct PointersPage: View { RoundedRectangle(cornerRadius: 14, style: .continuous) .fill(Color.primary.opacity(0.045)) ) + .opacity(Preferences.showToolbar ? 1 : 0.45) .background(GeometryReader { g in Color.clear .onAppear { rowFrame = g.frame(in: .named("pointersPage")) } @@ -603,6 +604,18 @@ private struct PointersPage: View { Text(message).font(.system(size: 12)).foregroundColor(.red).padding(.horizontal, 4) } } + Card(title: "Toolbar") { + Row("Show the toolbar", detail: Preferences.showToolbar + ? "Pops up when the pointer turns on and near the bottom of the screen." + : "Stays hidden. Press Esc to exit, or use the menu bar.") { + Toggle("", isOn: model.binding({ Preferences.showToolbar }, { Preferences.showToolbar = $0 })) + .toggleStyle(.switch).labelsHidden().focusable(false) + } + Row("Ink button", detail: "Change the colour while you present.") { + Toggle("", isOn: model.binding({ Preferences.showInkButton }, { Preferences.showInkButton = $0 })) + .toggleStyle(.switch).labelsHidden().focusable(false) + } + } YourHands(model: model) } .coordinateSpace(name: "pointersPage") @@ -938,28 +951,20 @@ private struct AppearancePage: View { @ObservedObject var model: SettingsModel var body: some View { - VStack(alignment: .leading, spacing: 22) { - Card(title: "Pointer") { - Row("Size") { - HStack(spacing: 10) { - Image(systemName: "hand.point.up.left.fill").font(.system(size: 10)).foregroundColor(.secondary) - Slider(value: model.binding({ Double(Preferences.pointerSize) }, { Preferences.pointerSize = CGFloat($0) }), - in: Double(Preferences.pointerSizeRange.lowerBound)...Double(Preferences.pointerSizeRange.upperBound)) - .frame(width: 180) - .focusable(false) - Image(systemName: "hand.point.up.left.fill").font(.system(size: 16)).foregroundColor(.secondary) - } - } - Row("Shadow under the pointer") { - Toggle("", isOn: model.binding({ Preferences.showShadow }, { Preferences.showShadow = $0 })) - .toggleStyle(.switch).labelsHidden().focusable(false) + Card(title: "Pointer") { + Row("Size") { + HStack(spacing: 10) { + Image(systemName: "hand.point.up.left.fill").font(.system(size: 10)).foregroundColor(.secondary) + Slider(value: model.binding({ Double(Preferences.pointerSize) }, { Preferences.pointerSize = CGFloat($0) }), + in: Double(Preferences.pointerSizeRange.lowerBound)...Double(Preferences.pointerSizeRange.upperBound)) + .frame(width: 180) + .focusable(false) + Image(systemName: "hand.point.up.left.fill").font(.system(size: 16)).foregroundColor(.secondary) } } - Card(title: "Toolbar") { - Row("Show the toolbar", detail: Preferences.showToolbar ? "Appears when the pointer turns on and when you move to the bottom of the screen." : "Hidden while you present. Turn it back on to switch pointers.") { - Toggle("", isOn: model.binding({ Preferences.showToolbar }, { Preferences.showToolbar = $0 })) - .toggleStyle(.switch).labelsHidden().focusable(false) - } + Row("Shadow under the pointer") { + Toggle("", isOn: model.binding({ Preferences.showShadow }, { Preferences.showShadow = $0 })) + .toggleStyle(.switch).labelsHidden().focusable(false) } } } @@ -997,10 +1002,6 @@ private struct DrawingPage: View { .fixedSize() .focusable(false) } - Row("Ink button in the toolbar", detail: "Change the colour while you present.") { - Toggle("", isOn: model.binding({ Preferences.showInkButton }, { Preferences.showInkButton = $0 })) - .toggleStyle(.switch).labelsHidden().focusable(false) - } } } }