Files
ggbond268--mactools/Plugins/AutoHideDock/Sources/AutoHideDockPlugin.swift
T
wehub-resource-sync 1d1286fadb
Build / Build and test (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:18:38 +08:00

168 lines
5.6 KiB
Swift

import AppKit
import Foundation
import OSLog
import SwiftUI
import MacToolsPluginKit
protocol DockCommandRunning {
func setDockAutohide(_ isEnabled: Bool) throws
}
struct ProcessDockCommandRunner: DockCommandRunning {
private let localization: PluginLocalization
init(localization: PluginLocalization = PluginLocalization(bundle: .main)) {
self.localization = localization
}
func setDockAutohide(_ isEnabled: Bool) throws {
let script = """
tell application "System Events"
tell dock preferences
set autohide to \(isEnabled ? "true" : "false")
end tell
end tell
"""
let appleScript = NSAppleScript(source: script)
var error: NSDictionary?
appleScript?.executeAndReturnError(&error)
if let error {
let message = (error[NSAppleScript.errorMessage] as? String)?.trimmingCharacters(in: .whitespacesAndNewlines)
throw NSError(
domain: "AutoHideDockPlugin",
code: (error[NSAppleScript.errorNumber] as? Int) ?? 1,
userInfo: [
NSLocalizedDescriptionKey: message?.isEmpty == false
? message!
: localization.string(
"error.toggleFailed",
defaultValue: "切换 Dock 自动隐藏失败"
)
]
)
}
}
}
public final class AutoHideDockPluginFactory: NSObject, MacToolsPluginBundleFactory {
public static func makeProvider(context: PluginRuntimeContext) throws -> any PluginProvider {
AutoHideDockPluginProvider(context: context)
}
}
@MainActor
private struct AutoHideDockPluginProvider: PluginProvider {
let context: PluginRuntimeContext
func makePlugins() -> [any MacToolsPlugin] {
[AutoHideDockPlugin(localization: PluginLocalization(bundle: context.resourceBundle))]
}
}
@MainActor
final class AutoHideDockPlugin: MacToolsPlugin, PluginPrimaryPanel {
let metadata: PluginMetadata
let primaryPanelDescriptor = PluginPrimaryPanelDescriptor(
controlStyle: .switch,
menuActionBehavior: .keepPresented
)
var onStateChange: (() -> Void)?
var requestPermissionGuidance: ((String) -> Void)?
var shortcutBindingResolver: ((String) -> ShortcutBinding?)?
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "cc.ggbond.mactools", category: "AutoHideDockPlugin")
private let commandRunner: any DockCommandRunning
private let stateReader: () -> Bool
private let localization: PluginLocalization
private var isDockHidden: Bool
private var lastErrorMessage: String?
init(
commandRunner: (any DockCommandRunning)? = nil,
stateReader: @escaping () -> Bool = { AutoHideDockPlugin.readDockAutohideState() },
localization: PluginLocalization = PluginLocalization(bundle: .main)
) {
self.localization = localization
self.commandRunner = commandRunner ?? ProcessDockCommandRunner(localization: localization)
self.stateReader = stateReader
self.metadata = PluginMetadata(
id: "auto-hide-dock",
title: localization.string("metadata.title", defaultValue: "自动隐藏程序坞"),
iconName: "rectangle.bottomthird.inset.filled",
iconTint: Color(nsColor: .systemBlue),
order: 45,
defaultDescription: localization.string(
"metadata.description",
defaultValue: "自动隐藏程序坞,提供更干净的桌面环境"
)
)
self.isDockHidden = stateReader()
}
var primaryPanelState: PluginPanelState {
PluginPanelState(
subtitle: isDockHidden
? localization.string("panel.subtitle.enabled", defaultValue: "已开启")
: localization.string("panel.subtitle.disabled", defaultValue: "已关闭"),
isOn: isDockHidden,
isExpanded: false,
isEnabled: true,
isVisible: true,
detail: nil,
errorMessage: lastErrorMessage
)
}
var permissionRequirements: [PluginPermissionRequirement] { [] }
var settingsSections: [PluginSettingsSection] { [] }
var shortcutDefinitions: [PluginShortcutDefinition] { [] }
func refresh() {
let latestState = stateReader()
if latestState != isDockHidden {
isDockHidden = latestState
onStateChange?()
}
}
func handleAction(_ action: PluginPanelAction) {
guard case let .setSwitch(isEnabled) = action else {
return
}
setDockHidden(isEnabled)
}
func permissionState(for permissionID: String) -> PluginPermissionState {
PluginPermissionState(isGranted: true, footnote: nil)
}
func handlePermissionAction(id: String) {}
func handleSettingsAction(id: String) {}
func handleShortcutAction(id: String) {}
private func setDockHidden(_ isEnabled: Bool) {
do {
try commandRunner.setDockAutohide(isEnabled)
isDockHidden = isEnabled
lastErrorMessage = nil
onStateChange?()
} catch {
logger.error("Failed to update Dock auto-hide: \(error.localizedDescription, privacy: .public)")
lastErrorMessage = error.localizedDescription
refresh()
onStateChange?()
}
}
private nonisolated static func readDockAutohideState() -> Bool {
let defaults = UserDefaults(suiteName: "com.apple.dock")
return defaults?.object(forKey: "autohide") as? Bool ?? false
}
}