⚠️ Work in ProgressThis project is currently under active development and is not yet ready for production use. APIs may change without notice, features may be incomplete, and breaking changes are expected. Use at your own risk.
A Swift package for programmatic control over screensavers and wallpapers on macOS, with special support for per-screen/space configuration introduced in macOS Sonoma.
📝 Development Status: Features marked with status indicators
- 🖥️ Screensaver Management: Set and configure screensavers programmatically ✅ Implemented
- 🎨 Wallpaper Control: Change desktop wallpapers for individual or all screens
⚠️ Partially implemented - 🚀 macOS Sonoma Support: Support for per-screen/space configuration system ✅ Implemented
- 🔄 Pre-Sonoma Compatibility: Legacy support for older macOS versions
⚠️ Not fully tested - 📦 Swift Package Manager: Easy integration into your Swift projects
⚠️ API may change - 🧪 Type-Safe API: Leverage Swift's type system for safe configuration ✅ Implemented
- 🔧 CLI Tool: Command-line interface for testing and automation
⚠️ Partially implemented
- macOS 10.15 (Catalina) or later
- Swift 6.2 or later
- Xcode 14.0 or later (for development)
⚠️ Development Version Only
This package is not yet published to a stable release. You can only install the development version.
Add PaperSaver to your Package.swift file:
dependencies: [
.package(url: "https://github.com/AerialScreensaver/PaperSaver.git", branch: "main")
]Or add it through Xcode:
- File → Add Package Dependencies...
- Enter the repository URL:
https://github.com/AerialScreensaver/PaperSaver.git - Select "Branch" and enter
main - Click "Add Package"
import PaperSaverKit
// Example: Ensure Aerial screensaver is active system-wide
func ensureAerialScreensaver() async {
let paperSaver = PaperSaver()
do {
// Check if Aerial is the only active screensaver system-wide
let activeScreensavers = paperSaver.getActiveScreensavers()
let isAerialActive = activeScreensavers == ["Aerial"]
if isAerialActive {
print("✅ Aerial screensaver is already active")
} else {
print("Setting Aerial screensaver...")
try await paperSaver.setScreensaverEverywhere(module: "Aerial")
print("✅ Successfully set Aerial screensaver")
}
} catch PaperSaverError.screensaverNotFound {
print("❌ Error: Aerial screensaver not found. Please install it first.")
} catch {
print("❌ Error setting screensaver: \(error.localizedDescription)")
}
}
// Usage in async context
await ensureAerialScreensaver()// Set screensaver to activate after 5 minutes of inactivity
try paperSaver.setIdleTime(seconds: 300)let availableScreensavers = paperSaver.listAvailableScreensavers()
for screensaver in availableScreensavers {
print("\(screensaver.name): \(screensaver.identifier)")
}PaperSaver automatically detects the macOS version and uses the appropriate method for managing screensavers and wallpapers:
- macOS Sonoma (14.0) and later: Uses the new per-screen/space configuration system via
com.apple.wallpaper - Pre-Sonoma versions: Falls back to traditional
com.apple.screensaverpreferences and NSWorkspace APIs
git clone https://github.com/AerialScreensaver/PaperSaver.git
cd PaperSaver
swift buildswift testThe project includes a command-line interface for testing and development:
# Build and run the CLI
swift run papersaver --help
# List available screensavers
swift run papersaver list
# List spaces (macOS Sonoma+)
swift run papersaver list-spaces
# Set a screensaver
swift run papersaver set-saver Aerial- Improving wallpaper management functionality
- Enhanced error handling and validation
- Comprehensive test coverage
- Documentation and examples
This project is licensed under the MIT License - see the LICENSE file for details.
⚠️ Development Project: Please keep in mind this is a work-in-progress when reporting issues.
For questions, suggestions, or feature requests, please open an issue on GitHub.