diff --git a/AppDelegate.swift b/AppDelegate.swift index af61d7c..ea8d622 100644 --- a/AppDelegate.swift +++ b/AppDelegate.swift @@ -14,10 +14,12 @@ class AppDelegate: NSObject, NSApplicationDelegate { var statusItem: NSStatusItem? var popover: NSPopover? var playerManager: PlayerManager! + var sleepManager: SleepManager! var menu: NSMenu! func applicationDidFinishLaunching(_ notification: Notification) { playerManager = PlayerManager() + sleepManager = SleepManager() statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) @@ -51,24 +53,28 @@ class AppDelegate: NSObject, NSApplicationDelegate { menu.addItem(NSMenuItem.separator()) // Play/Pause - let playPauseItem = NSMenuItem(title: "Play", action: #selector(togglePlayPause), keyEquivalent: "") + let playPauseItem = NSMenuItem(title: "播放", action: #selector(togglePlayPause), keyEquivalent: "") menu.addItem(playPauseItem) // Previous - menu.addItem(NSMenuItem(title: "Previous", action: #selector(playPrevious), keyEquivalent: "")) + menu.addItem(NSMenuItem(title: "上一首", action: #selector(playPrevious), keyEquivalent: "")) // Next - menu.addItem(NSMenuItem(title: "Next", action: #selector(playNext), keyEquivalent: "")) - + menu.addItem(NSMenuItem(title: "下一首", action: #selector(playNext), keyEquivalent: "")) menu.addItem(NSMenuItem.separator()) // Reconfigure folder - menu.addItem(NSMenuItem(title: "Sources", action: #selector(reconfigureFolder), keyEquivalent: "s")) + menu.addItem(NSMenuItem(title: "设置音乐源", action: #selector(reconfigureFolder), keyEquivalent: "s")) + + // 防止休眠开关 + let preventSleepItem = NSMenuItem(title: "防止 Mac 休眠", action: #selector(togglePreventSleep), keyEquivalent: "") + preventSleepItem.state = sleepManager.preventSleep ? .on : .off + menu.addItem(preventSleepItem) menu.addItem(NSMenuItem.separator()) // Quit - menu.addItem(NSMenuItem(title: "Exit", action: #selector(quit), keyEquivalent: "")) + menu.addItem(NSMenuItem(title: "退出", action: #selector(quit), keyEquivalent: "")) // Set up observers for player state changes NotificationCenter.default.addObserver(self, selector: #selector(updateMenuItems), name: NSNotification.Name("TrackChanged"), object: nil) @@ -108,11 +114,11 @@ class AppDelegate: NSObject, NSApplicationDelegate { @objc func updateMenuItems() { if let trackInfoItem = menu.item(at: 0), let trackLabel = trackInfoItem.view?.subviews.first as? NSTextField { - trackLabel.stringValue = playerManager.currentTrack?.title ?? "No track selected" + trackLabel.stringValue = playerManager.currentTrack?.title ?? "未选择音乐源" } if let playPauseItem = menu.item(at: 2) { - playPauseItem.title = playerManager.isPlaying ? "Pause" : "Play" + playPauseItem.title = playerManager.isPlaying ? "暂停" : "播放" } } @@ -139,4 +145,15 @@ class AppDelegate: NSObject, NSApplicationDelegate { @objc func quit() { NSApplication.shared.terminate(self) } + @objc func togglePreventSleep() { + sleepManager.preventSleep.toggle() + if let preventSleepItem = menu.item(withTitle: "防止 Mac 休眠") { + preventSleepItem.state = sleepManager.preventSleep ? .on : .off + } + } + + // 添加这个方法来确保应用保持活跃状态 + func applicationWillTerminate(_ aNotification: Notification) { + sleepManager.preventSleep = false + } } diff --git a/MacMusicPlayer.xcodeproj/project.pbxproj b/MacMusicPlayer.xcodeproj/project.pbxproj index 44176d6..0ed460c 100644 --- a/MacMusicPlayer.xcodeproj/project.pbxproj +++ b/MacMusicPlayer.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 991C44522C9A9E1600F2BB76 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 991C44512C9A9E1600F2BB76 /* ContentView.swift */; }; 991C44542C9A9E2A00F2BB76 /* ControlOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 991C44532C9A9E2A00F2BB76 /* ControlOverlay.swift */; }; 991C445D2C9AB7FA00F2BB76 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 991C445C2C9AB7FA00F2BB76 /* AppDelegate.swift */; }; + 99C304BA2CABDEAB00D7B495 /* SleepManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99C304B92CABDEAB00D7B495 /* SleepManager.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -23,6 +24,7 @@ 991C44512C9A9E1600F2BB76 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 991C44532C9A9E2A00F2BB76 /* ControlOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlOverlay.swift; sourceTree = ""; }; 991C445C2C9AB7FA00F2BB76 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 99C304B92CABDEAB00D7B495 /* SleepManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SleepManager.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ @@ -83,6 +85,7 @@ isa = PBXGroup; children = ( 991C444D2C9A9DEE00F2BB76 /* PlayerManager.swift */, + 99C304B92CABDEAB00D7B495 /* SleepManager.swift */, ); path = Managers; sourceTree = ""; @@ -191,6 +194,7 @@ 991C44522C9A9E1600F2BB76 /* ContentView.swift in Sources */, 991C44542C9A9E2A00F2BB76 /* ControlOverlay.swift in Sources */, 991C443B2C9A9C6E00F2BB76 /* MacMusicPlayerApp.swift in Sources */, + 99C304BA2CABDEAB00D7B495 /* SleepManager.swift in Sources */, 991C444E2C9A9DEE00F2BB76 /* PlayerManager.swift in Sources */, 991C44502C9A9E0400F2BB76 /* Track.swift in Sources */, ); diff --git a/MacMusicPlayer/Info.plist b/MacMusicPlayer/Info.plist index db9c907..185ada3 100644 --- a/MacMusicPlayer/Info.plist +++ b/MacMusicPlayer/Info.plist @@ -23,5 +23,7 @@ audio + NSPowerManagementUsageDescription + MacMusicPlayer 需要权限来防止系统休眠,以确保音乐播放不被中断。 diff --git a/Managers/SleepManager.swift b/Managers/SleepManager.swift new file mode 100644 index 0000000..7e28862 --- /dev/null +++ b/Managers/SleepManager.swift @@ -0,0 +1,42 @@ +// +// SleepManager.swift +// MacMusicPlayer +// +// Created by X on 10/1/24. +// + +import Foundation +import IOKit.pwr_mgt + +class SleepManager: ObservableObject { + @Published var preventSleep = false { + didSet { + updateSleepAssertion() + } + } + + private var assertionID: IOPMAssertionID = 0 + + func updateSleepAssertion() { + if preventSleep { + createAssertion() + } else { + releaseAssertion() + } + } + + private func createAssertion() { + let reason = "MacMusicPlayer is preventing display sleep" + IOPMAssertionCreateWithName(kIOPMAssertionTypePreventUserIdleDisplaySleep as CFString, + IOPMAssertionLevel(kIOPMAssertionLevelOn), + reason as CFString, + &assertionID) + } + + private func releaseAssertion() { + if assertionID != 0 { + IOPMAssertionRelease(assertionID) + assertionID = 0 + } + } +} diff --git a/README.md b/README.md index fcdc226..42197c1 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ MacMusicPlayer 是一个简洁、轻量级的 macOS 音乐播放器,设计为 - 📂 随时重新配置音乐文件夹 - 🎨 简洁的用户界面,最小化干扰 +- 😴 支持防止 Mac 休眠(一键开启) + ## 安装 1. 下载最新的 MacMusicPlayer.dmg 文件。