Repository navigation
Conversation
…tation) Catalog repository and migration, Dev profile, Steam discovery, visibility and metadata, and the first half of the shared game experience plan (common models, GameLogoArea, GamePrimaryActions). Rebased on the published 0.1.4.3 (nxnative 8a5c5e7e). Known gap: SteamArtworkRequest is referenced by its test but not implemented yet, so the test target does not compile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SteamArtworkRequest picks the layout role's local art: the player's pick first, then for squares the bundle's CFBundleIconFile (kept inside Contents/Resources). Spotlight, search and the Steam details square ask for the square role; Collection keeps the portrait cover. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Spotlight and Collection show a Steam game with the same logo area, action positions, stats line, genre chips and arrival motion as an nxnative game. Until Steam Play and Options exist, the first two positions open Details and hide the game. The Steam hero now loads through SeleneHeroArt, so it crossfades like nxnative art. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Spotlight recorded a Steam selection as a non-game, so moving between Steam and nxnative games dropped the art to the wallpaper until the next hero loaded. Collection cleared it the same way. Both now keep the art until the next game's hero crossfades in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Spotlight page now takes a source's presentation and actions: Steam games get the same screenshot strip and viewer, About this game, activity column and action grid as nxnative games, with an Installation panel instead of Build & Sources. GameDetailPresentation gains a Steam initializer that claims nothing nxnative. Steam facts are shared by the head, the page and the input counts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Steam's library hero is a ~3:1 banner, so filling the screen enlarged and cropped it. SteamBackdropChoice now picks the first screen-shaped image: the stores' clean heroes found by name (Xbox, GOG Galaxy, TheGamesDB fan art), then the game's first Steam screenshot, the banner last. The player's own pick still comes first, and the choice is kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Play hands steam://run/<AppID> to the verified Steam client only. A session starts when the installation's own app is seen running and ends when it exits; Steam staying open never counts. The Steam head shows Play, Resume, Cancel while waiting and Try again after a failure, with a one-line note; Spotlight and Collection A and hints follow it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Steam game's Options pill, Y in Spotlight and Y in Collection open Options in Game options' look and input: Play, Edit details (Change artwork, Change metadata, Store page), Move on Spotlight, Favorite, Hidden and Show in Finder. The shared artwork and metadata pickers now work on a Steam game: Steam's own art for its AppID, online finds and SteamGridDB browsing, saved in the Steam personal store, never touching the installed app's icon. The separate Steam details page and its sheet editor are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Steam game already running when NX Library starts now gets its session: the coordinator reads no processes before it has the session store. Stopping it forgets old states, Play reads the processes before resuming, and an empty store answer is asked again after a minute. Architecture notes describe the shared Steam experience. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change artwork lists a Steam game's own art (labelled Steam library) before the slower online search finishes, and shows wide banners whole. Browse online on LaunchBox looks for a Steam game's Mac or Windows entry, never a console one. Play hands the request to Steam without bringing Steam to the front. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Valve has no way to keep an open Steam out of sight when it gets steam://run, so Play now starts a closed Steam with the documented -silent -nofriendsui options and hides an open one while the game is on its way. After 15 s without the game Steam is shown again and the head says to check it; once Play is over Steam comes back only if it was in view before. The setting lives in Game sources and is on by default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sidebar now lists sections under General, Switch, Steam and
System. Game sources becomes Steam's Library page, with Keep Steam in
the background under Play, and Switch's Library no longer links to it.
Search, Changed and the page title name a platform section with its
platform ("Steam · Library"), and section order, sidebar navigation and
the settings catalog follow the groups. Section identities are
unchanged. Settings subheadings are now translated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the group headings the sections are taller than the window, and the sidebar never scrolled to the selection, so About stayed out of view. The sidebar now scrolls the selected section into view when it appears and whenever the selection changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The animated scroll started in the same frame as the new section's content and stuttered, most visibly when the selection wraps from About back to Search. The sidebar now brings the selection into view without animation, as macOS sidebars do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Selecting Search in the sidebar focused its field at once, so the keys went to the field instead of the sidebar. The field now opens only on A, Return or Right from the sidebar (or a click); Down from the field still goes to its results. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Esc (or B) while typing in Search resigned the field and then also went back, leaving Settings. Back now only closes the field when typing, and the player stays on Search in the sidebar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The moonlight was paced by a CVDisplayLink, which tells the system nothing about its frame rate. After about ten seconds without input a variable-refresh display slowed down, nextDrawable waited up to 80 ms and the motes fell from 60 to ~30 fps; typing or any other on-screen change hid it. Measured with a temporary frame log: Settings Search stuttered after 12 s idle, Start-up too. On macOS 14 and later the moonlight now runs from a CAMetalDisplayLink asking for 60 fps, on a render thread of its own: the display keeps its rate and each drawable comes when the screen can take it, and the motes advance by presentation time. The same log then read 57-61 fps idle with no stalls. macOS 13 keeps the CVDisplayLink. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In Spotlight a Steam head slid as one block, while a Switch head slides only its logo and fades the pills and stats in after it; in Collection its fade eased instead of running linear. The Steam head now uses the Switch heads' own motions, shared as constants. Steam logos are kept decoded like Switch ones, so a game seen before shows its logo from the first frame instead of its title, and a logo that lands later fades in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The automatic Steam background now tries LaunchBox's fan art for the game's Mac or Windows entry after Xbox, GOG and TheGamesDB and before screenshots: the full file, and only one whose stated size suits a screen. Steam's 3:1 library banner stays the last resort, shown cropped. With no banner, the first image that loads is shown instead of the last URL tried. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A running Steam session was checked against the installation as the catalog has it now. With the installation gone (a refresh) any process with the same pid kept it open, and with the app named at a new path the session ended while the game was still playing. The session now lasts while the process it saw start, same pid and same bundle, is alive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Check engine at launch and Setup move to Switch · Engine; Refresh library at launch and Box covers to Switch · Library. Readiness and Environment go: Engine's Compatibility already shows and re-checks the same environment. The caches stay only in Storage. Rumble, App icon and Storage keep their places, with the reasons in architecture.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SteamBackdrop had no callers; its UI-less check goes with it and CI runs the shared game header check instead. Twelve strings with no use left in the sources are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
appendingPathComponent asked the disk, so a missing folder had no trailing slash and no longer equalled file.deletingLastPathComponent(). CI, on a fresh Mac, failed testSharedAndScopedDefaultPathsAreConsistent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Steam's hero, logo and tiles used NSImage(contentsOf:), which decodes on first draw on the main thread. Measured on a cached 1920x1080 Steam hero: 56-75 ms for that first draw against 14-16 ms predecoded, the hitch seen going from a Switch game to a Steam one. They now use GameArtLoader.decode at the nxnative sizes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The column keeps its quicker 0.12 s delay and 0.3 s length; its fade now eases out like Spotlight's logo instead of running linear. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
steamBundleID is a constant read from NSWorkspace observers, so it is nonisolated; SteamMetadataService's default transport is a @sendable closure. steamPersonalizationChanged was never posted or observed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- refresh no longer asks LaunchServices isTerminated for every running app, and launches/quits arrive once (runningApplications KVO), not also through the workspace notifications. - A pid's paths are resolved once while it lives and an installation's once per check, instead of every process x game x refresh. - Steam tiles read the app icon once per bundle instead of in body. - supportedOperations/requireSupported/CatalogGameOperation and CatalogGameOptions.specificRows were never used by the app; the real guard is the record payload (wrongIntegration), now what tests check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Status: awaiting human validation. Nothing here is approved for release until the maintainer has tried it in NX Library Dev.
What this adds
NX Library can now show native Mac Steam games next to Switch ports. Settings are grouped so each platform's settings are separate.
Steam games
-silent, stays hidden while the game starts and comes back if it needs the player.Settings
Fixes
CAMetalDisplayLinkon macOS 14+; CVDisplayLink was dropping it to about 30 fps after about 10 s without input.Cleanup
SteamBackdropview and its UI-less check are removed. CI now runs the shared game header check instead.Checks run
swift test: 1386 tests pass.check_localizations.py,check_publication.py,run_notices.pyandrun_game_header.pypass.scripts/build_app.sh, andcodesign --verify --deep --strictpasses.Awaiting manual validation by the maintainer
Do not merge before the maintainer confirms.
🤖 Generated with Claude Code