WIP: add Dock visibility setting

This commit is contained in:
Akshay Kolli
2026-06-30 02:25:52 -07:00
parent 3c4e4741d6
commit 3b6af36d18
6 changed files with 152 additions and 5 deletions

View File

@@ -1,6 +1,17 @@
import AppKit
final class AppDelegate: NSObject, NSApplicationDelegate {
enum PresentationSurface: Equatable {
case menuBar
case dock
}
struct PresentationPlan: Equatable {
let showMenuBarIcon: Bool
let showDockIcon: Bool
let activationPolicy: NSApplication.ActivationPolicy
}
struct StatusMenuPresentation: Equatable {
let summary: String
let detail: String?
@@ -61,6 +72,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
settingsShortcut: settings.settingsShortcut
)
bindSettings()
applyPresentation(changedSurface: nil)
monitor.setPaused(settings.pauseCapture)
monitor.start()
shortcutManager.start()
@@ -415,7 +427,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
case .launchAtLogin:
applyLaunchAtLoginSetting(settings.launchAtLogin)
case .showMenuBarIcon:
refreshStatusItem()
applyPresentation(changedSurface: .menuBar)
case .showDockIcon:
applyPresentation(changedSurface: .dock)
case .pauseCapture:
monitor.setPaused(settings.pauseCapture)
if settings.showMenuBarIcon {
@@ -430,6 +444,48 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
}
}
static func presentationPlan(
showMenuBarIcon: Bool,
showDockIcon: Bool,
changedSurface: PresentationSurface?
) -> PresentationPlan {
var plannedMenuBarIcon = showMenuBarIcon
var plannedDockIcon = showDockIcon
if !plannedMenuBarIcon && !plannedDockIcon {
if changedSurface == .menuBar {
plannedDockIcon = true
} else {
plannedMenuBarIcon = true
}
}
return PresentationPlan(
showMenuBarIcon: plannedMenuBarIcon,
showDockIcon: plannedDockIcon,
activationPolicy: plannedDockIcon ? .regular : .accessory
)
}
private func applyPresentation(changedSurface: PresentationSurface?) {
let plan = Self.presentationPlan(
showMenuBarIcon: settings.showMenuBarIcon,
showDockIcon: settings.showDockIcon,
changedSurface: changedSurface
)
if settings.showMenuBarIcon != plan.showMenuBarIcon {
settings.showMenuBarIcon = plan.showMenuBarIcon
}
if settings.showDockIcon != plan.showDockIcon {
settings.showDockIcon = plan.showDockIcon
}
NSApp.setActivationPolicy(plan.activationPolicy)
configureMainMenu()
refreshStatusItem()
}
private func applyLaunchAtLoginSetting(_ shouldLaunch: Bool) {
let result = lifecycleService.applyLaunchAtLogin(shouldLaunch)
switch result {

View File

@@ -8,6 +8,7 @@ final class SettingsModel {
case settingsShortcut
case launchAtLogin
case showMenuBarIcon
case showDockIcon
case pauseCapture
case pollProfile
case captureStatus
@@ -23,6 +24,7 @@ final class SettingsModel {
static let pruneDuplicates = "pruneDuplicates"
static let launchAtLogin = "launchAtLogin"
static let showMenuBarIcon = "showMenuBarIcon"
static let showDockIcon = "showDockIcon"
static let openShortcut = "openShortcut"
static let settingsShortcut = "settingsShortcut"
static let ignoredApps = "ignoredApps"
@@ -56,6 +58,9 @@ final class SettingsModel {
var showMenuBarIcon: Bool {
didSet { if oldValue != showMenuBarIcon { storeAndNotify(.showMenuBarIcon) } }
}
var showDockIcon: Bool {
didSet { if oldValue != showDockIcon { storeAndNotify(.showDockIcon) } }
}
var openShortcut: ShortcutBinding {
didSet { if oldValue != openShortcut { storeAndNotify(.openShortcut) } }
}
@@ -107,6 +112,7 @@ final class SettingsModel {
pruneDuplicates = defaults.object(forKey: Keys.pruneDuplicates) as? Bool ?? true
launchAtLogin = defaults.object(forKey: Keys.launchAtLogin) as? Bool ?? false
showMenuBarIcon = defaults.object(forKey: Keys.showMenuBarIcon) as? Bool ?? true
showDockIcon = defaults.object(forKey: Keys.showDockIcon) as? Bool ?? false
openShortcut = Self.readShortcut(from: defaults.string(forKey: Keys.openShortcut)) ?? AppConfiguration.defaultOpenShortcut
settingsShortcut = Self.readShortcut(from: defaults.string(forKey: Keys.settingsShortcut)) ?? AppConfiguration.defaultSettingsShortcut
ignoredApps = defaults.stringArray(forKey: Keys.ignoredApps) ?? AppConfiguration.defaultIgnoredApps
@@ -135,6 +141,7 @@ final class SettingsModel {
defaults.set(pruneDuplicates, forKey: Keys.pruneDuplicates)
defaults.set(launchAtLogin, forKey: Keys.launchAtLogin)
defaults.set(showMenuBarIcon, forKey: Keys.showMenuBarIcon)
defaults.set(showDockIcon, forKey: Keys.showDockIcon)
defaults.set(openShortcut.encoded(), forKey: Keys.openShortcut)
defaults.set(settingsShortcut.encoded(), forKey: Keys.settingsShortcut)
defaults.set(ignoredApps, forKey: Keys.ignoredApps)

View File

@@ -13,6 +13,7 @@ final class SettingsWindowController: NSObject, NSTextFieldDelegate, NSTextViewD
private let defaultSortPopup = NSPopUpButton()
private let launchAtLoginButton = NSButton()
private let showMenuBarIconButton = NSButton()
private let showDockIconButton = NSButton()
private let launchStatusLabel = NSTextField(labelWithString: "")
private var openShortcutControls: ShortcutControlSet?
@@ -124,6 +125,7 @@ final class SettingsWindowController: NSObject, NSTextFieldDelegate, NSTextViewD
}
configureCheckbox(launchAtLoginButton, title: "Launch at login", action: #selector(launchAtLoginChanged))
configureCheckbox(showMenuBarIconButton, title: "Show ClipBored in the menu bar", action: #selector(showMenuBarIconChanged))
configureCheckbox(showDockIconButton, title: "Show ClipBored in the Dock", action: #selector(showDockIconChanged))
configureStatusLabel(launchStatusLabel)
return page([
@@ -138,6 +140,7 @@ final class SettingsWindowController: NSObject, NSTextFieldDelegate, NSTextViewD
section("Lifecycle", [
launchAtLoginButton,
showMenuBarIconButton,
showDockIconButton,
launchStatusLabel
])
])
@@ -392,6 +395,7 @@ final class SettingsWindowController: NSObject, NSTextFieldDelegate, NSTextViewD
select(defaultSortPopup, rawValue: settings.defaultSortMode.rawValue)
launchAtLoginButton.state = settings.launchAtLogin ? .on : .off
showMenuBarIconButton.state = settings.showMenuBarIcon ? .on : .off
showDockIconButton.state = settings.showDockIcon ? .on : .off
launchStatusLabel.stringValue = settings.launchAtLoginErrorMessage
refreshShortcutControls(openShortcutControls, binding: settings.openShortcut)
@@ -468,7 +472,19 @@ final class SettingsWindowController: NSObject, NSTextFieldDelegate, NSTextViewD
}
@objc private func showMenuBarIconChanged() {
settings.showMenuBarIcon = showMenuBarIconButton.state == .on
let shouldShowMenuBarIcon = showMenuBarIconButton.state == .on
settings.showMenuBarIcon = shouldShowMenuBarIcon
if !shouldShowMenuBarIcon && !settings.showDockIcon {
settings.showDockIcon = true
}
}
@objc private func showDockIconChanged() {
let shouldShowDockIcon = showDockIconButton.state == .on
settings.showDockIcon = shouldShowDockIcon
if !shouldShowDockIcon && !settings.showMenuBarIcon {
settings.showMenuBarIcon = true
}
}
@objc private func shortcutChanged(_ sender: NSControl) {