Implement the screen saver - #2
Merged
Merged
Conversation
Ports Neco's cat to a .saver bundle, following the layout of winebarrel/Macstify: a `Sources/` target that builds NecoSaver.saver and a `Preview/` host app for development, plus the Makefile and CI that go with them. Sprites.swift, the sprite expansion, the cat's brain and the litter marks are carried over from Neco. Two changes make them work under ScreenSaver.framework: - Neko reads an injected `field` rect instead of NSScreen. A saver gets one view per display and may only draw inside its own bounds. - There is no cursor to chase behind the shield window, so the cat always runs Neco's wander mode. Cursor tracking is gone rather than switchable. The two overlay NSPanels collapse into one ScreenSaverView that paints the background, the mess and the cats in order, and the 60fps Timer becomes animateOneFrame(). Settings live in ScreenSaverDefaults, not UserDefaults.standard, and are edited through a configure sheet built in code: cats, size, speed, background, paw prints, scratch marks. Marks and cat sprites scale together, and the litter ink flips to the opposite end of the greyscale from the background so it stays visible either way.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports Neco's cat to a
.saverbundle, following the layout ofwinebarrel/Macstify: a
Sources/target that builds
NecoSaver.saverand aPreview/host app for development,plus the Makefile and CI that go with them.
What is carried over from Neco
Sprites.swift, the sprite expansion, the cat's brain and the litter marks comefrom Neco — copied, not shared, since the
sprite data never changes and
Neko.swiftis settled. Two changes make them workunder ScreenSaver.framework:
Nekoreads an injectedfieldrect instead ofNSScreen. A saver gets oneview per display and may only draw inside its own bounds.
Neco's wander mode. Cursor tracking is removed rather than made switchable.
The two overlay
NSPanels collapse into oneScreenSaverViewthat paints thebackground, the mess and the cats in that order, and the 60fps
TimerbecomesanimateOneFrame(). Settings live inScreenSaverDefaults, notUserDefaults.standard, which would otherwise resolve to a different domaindepending on which host loaded the bundle.
SpriteCachenow vendsCGImageinstead ofNSImage, so the engine draws intothe
CGContextit is handed with no dependency on the currentNSGraphicsContext— which is what lets the preview app render offscreen.Options
Edited through a configure sheet built in code (no nib to locate at runtime):
The litter ink takes the opposite end of the greyscale from the background: the
marks are a fixed dark colour in Neco, which would leave them invisible on the
black default here.
Not done
"Show the real desktop behind the cat" is not possible in a
.saver— the saveris a
CGShieldingWindowLevel()window covering the screen, and a snapshotapproach would need screen-recording TCC granted to
legacyScreenSaverratherthan to us. The background is a plain grey instead.
Verified
xcodebuild build analyzepasses for both schemesswiftlint --strict,swiftlint analyze --strictandswiftformat --lintare cleanprincipalClassresolves, i.e.@objc(NecoSaverView)matches
NSPrincipalClassand the Options sheet layout
.savercontains onlyInfo.plistand the executable — no entitlementscopied over from the app, no resources
Not verified: behaviour in System Settings on a real machine (
make install,then
killall legacyScreenSaver), multi-display, and the live thumbnail preview.