From a928c050b98bed7be1a46da694c53d0c52982344 Mon Sep 17 00:00:00 2001 From: leo12025 Date: Sat, 27 Dec 2025 18:25:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(UI):=20=E6=94=B9=E8=BF=9B=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E7=95=8C=E9=9D=A2=E5=B8=83=E5=B1=80=E5=92=8C=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构菜单界面,添加应用标题和版本信息,优化按钮和状态显示样式 使用卡片式布局和阴影效果提升整体视觉体验 简化状态显示逻辑,增加更直观的状态指示图标 --- PowerBar/AppState.swift | 33 +++++++++---- PowerBar/ContentView.swift | 24 ---------- PowerBar/PowerBarApp.swift | 97 +++++++++++++++++++++++++++++--------- 3 files changed, 99 insertions(+), 55 deletions(-) delete mode 100644 PowerBar/ContentView.swift diff --git a/PowerBar/AppState.swift b/PowerBar/AppState.swift index 3b0c108..0968962 100644 --- a/PowerBar/AppState.swift +++ b/PowerBar/AppState.swift @@ -14,7 +14,7 @@ class AppState: ObservableObject { // 内部属性 private var monitorTimer: Timer? - private var caffeinateProcess: Process? + private var caffeinateProcess: Process? // 直接使用Process对象,但简化实现 // 配置参数 private let idleThreshold: TimeInterval = 300 // 5分钟无操作视为空闲 @@ -82,19 +82,18 @@ class AppState: ObservableObject { private func getSystemIdleTime() -> TimeInterval { // 这是一个更可靠、更原生的方法 var onPort: mach_port_t = 0 - var prop: Unmanaged? // 获取 IO Master Port let kr = IOMainPort(0, &onPort) guard kr == KERN_SUCCESS else { return 0 } - // 查找电源管理服务 - let powerService = IOServiceGetMatchingService(onPort, IOServiceMatching("IOPMPowerSource")) - guard powerService != 0 else { return 0 } + // 查找 HID 系统服务,这是正确的获取 HIDIdleTime 的服务 + let hidSystem = IOServiceGetMatchingService(onPort, IOServiceMatching("IOHIDSystem")) + guard hidSystem != 0 else { return 0 } // 尝试获取空闲时间属性 - let result = IORegistryEntryCreateCFProperty(powerService, "HIDIdleTime" as CFString, kCFAllocatorDefault, 0) - IOObjectRelease(powerService) + let result = IORegistryEntryCreateCFProperty(hidSystem, "HIDIdleTime" as CFString, kCFAllocatorDefault, 0) + IOObjectRelease(hidSystem) guard let data = result?.takeRetainedValue() as? Data else { return 0 } @@ -111,12 +110,21 @@ class AppState: ObservableObject { guard caffeinateProcess == nil else { return } print("用户活动,启动 caffeinate 阻止睡眠...") + + // 简化实现,直接启动 caffeinate 进程 caffeinateProcess = Process() caffeinateProcess?.executableURL = URL(fileURLWithPath: "/usr/bin/caffeinate") caffeinateProcess?.arguments = ["-d"] // -d 指示系统不要关闭显示屏 + // 配置输出,避免产生不必要的输出 + let outputPipe = Pipe() + caffeinateProcess?.standardOutput = outputPipe + caffeinateProcess?.standardError = outputPipe + caffeinateProcess?.standardInput = Pipe() + do { try caffeinateProcess?.run() + print("成功启动 caffeinate 进程") } catch { print("启动 caffeinate 失败: \(error)") caffeinateProcess = nil @@ -124,11 +132,16 @@ class AppState: ObservableObject { } private func stopCaffeinate() { - guard caffeinateProcess != nil else { return } + guard let process = caffeinateProcess else { return } - print("用户空闲或功能关闭,停止 caffeinate.") - caffeinateProcess?.terminate() + print("用户空闲或功能关闭,停止 caffeinate 进程") + + // 简化实现,直接终止进程 + process.terminate() + + // 不等待进程退出,避免阻塞 caffeinateProcess = nil + print("已重置 caffeinate 进程引用") } // MARK: - UI State Update diff --git a/PowerBar/ContentView.swift b/PowerBar/ContentView.swift deleted file mode 100644 index 44ce956..0000000 --- a/PowerBar/ContentView.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// ContentView.swift -// PowerBar -// -// Created by Leo on 2025/12/27. -// - -import SwiftUI - -struct ContentView: View { - var body: some View { - VStack { - Image(systemName: "globe") - .imageScale(.large) - .foregroundStyle(.tint) - Text("Hello, world!") - } - .padding() - } -} - -#Preview { - ContentView() -} diff --git a/PowerBar/PowerBarApp.swift b/PowerBar/PowerBarApp.swift index 8839be6..7393c40 100644 --- a/PowerBar/PowerBarApp.swift +++ b/PowerBar/PowerBarApp.swift @@ -32,42 +32,88 @@ struct MenuContent: View { @EnvironmentObject var appState: AppState var body: some View { - VStack(alignment: .leading, spacing: 10) { + VStack(alignment: .leading, spacing: 8) { + // 应用标题和版本 + HStack { + Image(systemName: "power") + .foregroundColor(.blue) + VStack(alignment: .leading, spacing: 2) { + Text("PowerBar") + .font(.headline) + .fontWeight(.semibold) + Text("v1.0.0") + .font(.caption2) + .foregroundColor(.secondary) + } + } + .padding(.bottom, 4) + // 主要操作按钮:切换功能 Button(action: { // 点击按钮,切换功能的开关状态 appState.toggleFunction() }) { - HStack { + HStack(spacing: 12) { Image(systemName: appState.isFunctionEnabled ? "stop.circle.fill" : "play.circle.fill") .foregroundColor(appState.isFunctionEnabled ? .red : .green) - .frame(width: 20) - Text(appState.isFunctionEnabled ? "关闭常亮" : "开启常亮") + .font(.title2) + VStack(alignment: .leading, spacing: 2) { + Text(appState.isFunctionEnabled ? "关闭常亮" : "开启常亮") + .font(.body) + Text(appState.isFunctionEnabled ? "系统将恢复自动睡眠" : "防止系统进入睡眠状态") + .font(.caption2) + .foregroundColor(.secondary) + } } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(8) + .background( + RoundedRectangle(cornerRadius: 8) + .fill(appState.isFunctionEnabled ? Color.red.opacity(0.1) : Color.green.opacity(0.1)) + ) } + .buttonStyle(.plain) Divider() // 状态显示 - HStack { - Text("当前状态:") + VStack(alignment: .leading, spacing: 4) { + Text("当前状态") + .font(.caption) .foregroundColor(.secondary) - Spacer() - if appState.isFunctionEnabled { - Text(appState.isUserIdle ? "空闲" : "活动中") - .foregroundColor(appState.isUserIdle ? .orange : .green) - - // 附加显示 caffeinate 状态 - if !appState.isUserIdle { - Text(" (保护中)") - .foregroundColor(.green) + HStack { + if appState.isFunctionEnabled { + HStack(spacing: 6) { + Circle() + .fill(appState.isUserIdle ? Color.orange : Color.green) + .frame(width: 8, height: 8) + Text(appState.isUserIdle ? "空闲" : "活动中") + .font(.body) + + // 附加显示 caffeinate 状态 + if !appState.isUserIdle { + Text("(保护中)") + .font(.caption2) + .foregroundColor(.secondary) + } + } + } else { + HStack(spacing: 6) { + Circle() + .fill(Color.gray) + .frame(width: 8, height: 8) + Text("已关闭") + .font(.body) + } } - } else { - Text("已关闭") - .foregroundColor(.gray) + Spacer() } } - .font(.caption) + .padding(8) + .background( + RoundedRectangle(cornerRadius: 8) + .fill(Color.secondary.opacity(0.05)) + ) Divider() @@ -75,8 +121,17 @@ struct MenuContent: View { Button("退出 PowerBar") { NSApp.terminate(nil) } + .buttonStyle(.plain) + .font(.caption) + .foregroundColor(.secondary) + .padding(4) } - .padding(8) - .frame(minWidth: 220) + .padding(12) + .frame(minWidth: 280) + .background( + RoundedRectangle(cornerRadius: 12) + .fill(Color.white) + .shadow(radius: 4) + ) } }