Repository navigation
Refactor for 3.0 - #248
Refactor for 3.0#248NightHammer1000 wants to merge 56 commits into
Conversation
Game Tools resolves a game's real runtime executable (Unreal, Unity and launcher-aware scoring, with a candidate list and Browse when ambiguous), detects shipped upscaler and anti-cheat files, and installs data-driven tools into it through a journaled transaction with a per-game ownership manifest, backups of replaced game files and refusal of unknown collisions. OptiScaler is the first tool: downloaded from its upstream GitHub release with digest verification, x64 only, proxy name and four ini settings, update/repair/remove and takeover of a manual install. Big Picture opens it from the game cog menu as /wsgm/game-tools/:appid; the Overlay offers the same service under Steam > Game Tools. Refs #218
Core/Downloads now owns the HTTPS client, GitHub/Forgejo release lookup, verified downloads and traversal-safe archive extraction. Emulators and Game Tools both call it, so other features can download releases without going through emulator types. Game Tools cleanup: status policy moves to Core (GameToolStatus), the service composes state outside its lock and reuses the folder walk for configure, remove and program choice, package hashes are recorded once at extraction, failed release lookups back off for ten minutes, and the service publishes display labels and one anti-cheat text so the Overlay and Steam page no longer keep their own tables. The Overlay depends on IGameToolsSource, shares the searchable game list with the artwork changer, and the preview uses a fake source instead of reflection. Redrawn Overlay rows also keep a disabled row's dimming. Refs #218
Overlay progress now updates in place: OverlayProgress is one shared phase line, bar and Cancel row, and ServiceSubView redraws a page only when the state it shows changes. Game Tools, emulators, the game library pages and the shared busy status use it; the emulator view reads the service's own progress channel instead of guessing. The Steam frontend shares one meter (toolkit renderSteamUiMeter) and one byte formatter that rounds like the Overlay; Game Tools, the card manager, library import and emulators use them. The Overlay card manager gets the same capacity bar inside each row. Game Tools transaction recovery, admission rules and the running check live in Core with the process probe injected; the Shell service only wires and publishes. Recovery reports an undone interrupted change once. Headless previews cover the artwork home list, the card manager and live progress ticks through explicit fakes. Also adds Core/Downloads/ VerifiedDownload.cs, which the previous commit left out. Refs #218
…and Shell Review of all of src/WSGM Core and Shell in 11 slices, then one fixer per slice for findings that stay inside the slice. Each finding was confirmed against the code first; ones that would change behaviour were skipped. - Remove dead code: DeviceProfileApplier, the obsolete ImportStateStore Forget overload, unused Steam surface command lists, single-implementation interfaces and pass-through wrappers. - Collapse duplicated lookups and helpers: fan view lookups, transition gate leases, uncertain-write admission, unit suffixes, image sniffing, marker reads, wrapper command parsing and repeated shutdown steps. - Stop per-sample allocation on capability telemetry, rereading Steam's libraryfolders.vdf per eject row, duplicate RTSS discovery and the quadratic import-state dedup. - Split multi-type files into one file per significant type in place, including AppConfig, ApplicationShutdown, NativeQamSemanticServices, RtssOsd, DeviceCapabilityRouter, NotesService, the Steam theme/animation/sound surfaces and the library import state. The Release build of WSGM.slnx is warning-free. Tests are deferred until the maintainer's manual pass.
…pass One row projection now serves the Overlay, Steam settings, Quick Access, graphics and widgets (CapabilityRowProjection, SteamCapabilityRows, DeviceHostRows, IntegerRangeProjection). CPU boost moves out of the application reconciler into CpuBoostService, AC power reading goes through one PowerSource helper, and performance status text and the frame limit ceiling come from one PerformanceProjection. Also applies the remaining cross-slice simplifications in library and storage, themes and artwork, the Steam host and session, and the smaller independent groups, and updates the docs that named moved types.
Moves every Core and Shell source file, and its tests, into a folder per feature (Device, Steam, Library, Storage, Performance, Session and so on). Namespaces stay WSGM.Core and WSGM.Shell, as in the existing Core subfolders, so no code changes. Docs and comments that named a moved file now point at its new path.
… and lighting owners DeviceCoordinator keeps lifecycle, transitions and composition. The power lane, manual TDP, presets and assignments, per-application limits and AutoTDP move to DevicePowerPolicy; the command route, user-value persistence and desired-value restore move to DeviceCapabilityCommands. The FanCurves and LightingProfiles partials become DeviceFanCurves and DeviceLightingProfiles, which own the software fan loop and the lighting restore budget. DeviceCapabilityRouter hands desired-layer resolution to CapabilityDesiredLayers, per-capability command bookkeeping to CapabilityCommandLedger and state freshness to CapabilityFreshness. The processor reset and GPU clock capability ids become CapabilityIds constants.
The Atlas fan preset table and smoothing come from its LibHandheld definition. DeviceCoordinator resolves the table once at detection and the software curve, Overlay, Steam settings and Quick Access read that value; the row projection now requires it. The definition id lookup and the built-in Atlas table are gone. Action rows show the description their publisher supplies, replacing the processor reset branch. The makers' manager apps come from LibHandheld's static catalog while WSGM keeps Handheld Companion and the takeover policy. The fan preset and manager record files now hold one type each.
…SessionModes ShellSession no longer holds every owner across eleven partials. It builds focused parts that own their services, event wiring and slice of the ordered shutdown: IntegrationServices (plugins, GPU, device), DevicePowerQueue, SessionPowerEvents, PerformanceServices, SteamUiServices, StorageServices, LibraryServices, OverlayTools, SystemServices, GameModeSurfaces, SessionBoot, DesktopLifecycleActions, SessionCommands and GameModeEntryBackend, over one SessionState. ShutdownSteps runs the ordered cleanup. Startup order, thread affinity and the shutdown sequence are unchanged. SessionModes keeps the transition gate and its events. SteamLifecycle owns Steam start, focus, close, relaunch and the debugging restart, GameModeEntry the entry attempts and DesktopReturn the desktop return.
…ed owners GameLibraryService keeps the command surface, the review and the scan/apply lifecycle. GameLibraryScanner owns the sources, detection and scans; GameLibraryApplier owns the per-entry remove, write and decorate steps and the collections; GameLibraryProjection builds the published state; GameLibraryCardStorage and GameLibraryEmulators take the storage and emulator concerns of the old partials. The review entry is now GameLibraryEntryState. LibraryTabManager is an instance owned by LibraryManagerService, so the manager's stop and completion cover every tab sync, order write and push; the static lifetime and the static Changed event are gone. The card model moved to SdCardLibraryCatalog, and the manager's records, section, order writer and picker reads each have their own file.
…k session SdFormatManager keeps format orchestration, target re-verification and the pre-erase library removal and restore. Diskpart owns the scripts, the diskpart run, the volume and letter waits and the retrim. SteamLibraryProvisioner creates and registers libraries, including Add Library, and StorageRunProgress serializes format and add runs and publishes their busy state, stage and outcome. SteamUiModuleCatalog builds the surface adapters from SteamUiBackends, declares the host's modules and pages and composes plugin modules. SteamUiPatchSwitches derives every patch switch. The host keeps lifetime, subscriptions, Apply, generation handling and readiness reconciliation. The artwork session keeps one page's state and loading. Tabs and default filters, Steam writes and current-art previews move to their own types, and the shared ArtworkBrowser owns the writer and the official lookup.
…covery AutoTDP is one type per file. The controller keeps the phase machine and hands window classification, step sizing, the present clock, raise-chain evidence and probe evidence to their own types. The service hands renderer and sensor reads to AutoTdpTelemetry, limit lookup and admission to AutoTdpPowerCapability, and the restore state to AutoTdpRestoreObligation. The trace schema, row, writer and Windows context sit in their own files. PerformanceService keeps the adapter, its gate and the write and drift-repair rules. PerformanceStateStore owns the shared state and command records, and PerformanceRefreshLoop runs the coalesced refresh and the poll. RTSS discovery now follows the reference rule: the registry names the folder (InstallDir, else InstallLocation), RTSS.exe and RTSSHooks64.dll must exist, the product version must be at least 7.3, and the running process is matched by path. The PE export reader, signature check, cached file identity and multi-registration refusal are gone.
… parts RadioManager composes WifiController (Wi-Fi state, network list, watch and join/disconnect/forget) and BluetoothPairing (the pairing attempt and its questions); PairingPrompt moves to its own file. The radio safety-net poll runs every 10 s (SafetyPollInterval) instead of every 2 s; the live feeds still carry changes while the panel or Steam scans. AudioManager gets one type per file and hands Core Audio notifications to AudioChangeWatch, snapshot reads to AudioSnapshot and default-endpoint writes to AudioEndpointSelection. ControllerManager keeps the target lifecycle and status; ControllerForwarding owns the sample drain, UI pad, UI capture, forwarding state, synthetic presses and the route gate. The rumble wrappers give way to the output router itself. Tests and docs follow the new owners.
…Explorer owners Each owner hands a self-contained job to a focused type that holds its own state: ScreensaverCatalog and ScreensaverPlayerProcess, NotesGameResolver and NotesExtensionsSection, AnimationRepoCatalog, ThemeUpdateCheck, EmulatorInstallFolders, EmulatorExternalInstall and EmulatorDataBinding, and ExplorerShellExit. Behaviour is unchanged apart from one intended fix: the one-click startup suggestions no longer offer a competing device manager or RTSS, which WSGM turns off or starts itself.
Split the 199 multi-type files under Core and Shell so each top-level type lives in a file named after it, in its feature folder. Nested types that were part of an owner's API move out to top-level files; the generic names become specific (SplashAssetTransaction, ConfigMutexLease, RegistryValueState, LibraryFilterCategories, SfoMetadata, SteamInputShimMarker, TrayIconRecord, DeviceTransitionLease, DeviceResumeAction, SteamHelperRole, SteamWsgmSettingsSetRequest, SdFormatOperations, FormatTargetIdentity). Shared test helpers move to Fakes and Builders, multi-class test files are split, and docs name the new files. No behaviour change.
The source map gains a section listing every Core and Shell feature folder and the owners in it, and its layer table names the folders. Architecture explains the layout and how ShellSession composes its session parts and runs the ordered shutdown through ShutdownSteps. The Core, Shell, main application and test guides and the wsgm and wsgm-core skills describe where a new file and its tests go. Docs, skills and one interop comment that named moved, split or removed files, types and members now point at their current owners, including the config reload watcher, the RTSS OSD parts, the running-application monitor, the keep-awake power requests and the Steam UI switch policy.
Every Intel handheld now offers its power-limit path in the Overlay and Steam Quick Access: firmware (Atlas EC, Claw WMI), PawnIO MSR 0x610, or KX, which also writes the MCHBAR mirror. The choice is stored globally and applied before PL1/PL2. On the Atlas the firmware path lagged in games and Intel's IPF service kept lowering MCHBAR PL1 to 35 W, so the direct paths disable and stop IPF while selected and restore it afterwards. KX ships again under Resources\Intel\KX, pinned by SHA-256 and checked by assert-pawnio-pin, with its Defender process exclusion and deferred extraction restored. A model that declares DeviceHardwareAccess.IntelKx makes setup turn Memory Integrity and the driver blocklist off, shown locked on the compatibility page and enforced for quiet installs. Memory Integrity off is now also written as Device Guard policy, because Windows had turned it back on. Advances libhandheld and windows-device-control. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Remove the never-shown Enable Device Integration banner action, the leftover toggle and cycle members of the overlay device source, unused runtime and router members, the OEM action generation counter, the optional reconcile read fallback and other pass-through wrappers. Give Overlay and Steam Quick Access one controller-target table, so the overlay dropdown now reads Steam Deck, Xbox 360 and DualShock 4 like Steam. Read AutoTDP from the coordinator instead of a second parameter, spell application identities once in ProfileResolver, stop republishing the software charge limit on unrelated telemetry, and take one window pass per programs refresh. Move UiCaptureState to Controller, ExceptionList to Infrastructure and ApplicationProfileSyncBuilder to Graphics, with their tests and docs.
Advance the toolkit pin, regenerate the embedded Steam asset from it, and give the overlay browser check the route-table tokens its fragment now reads from the shared gate helpers.
The Overlay input-mode picker uses the shared mode labels and offers the Steam overlay only where a validated route exists, as the Steam page does. Shortcut ownership, card portability, host and PE architecture, checksum parsing, tab copies and the RetroArch bundle list each have one home. Collections read emulator systems directly instead of a warmed cache. Removed unread counters, constant branches, default interface bodies, duplicate admission checks and a second BIOS hash pass.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Recovery owns its temporary audio service, the plugin loader and host drop single-instantiation generics, category policy and dead caps, the shutdown coordinator has one deadline model, the write-only power scheme reference is gone, Overlay and Steam share one plugin CanInvoke rule, and misplaced types move to the folders that own them.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The Overlay now draws what Steam draws. The Windows power profile and processor core rows render the NativeQam services' ChoiceRowState through one ChoiceRowSelection and ChoiceRowView. The device preset assignments render PowerPresetRows, moved out of the Steam settings service. Glyph selection is a host selection. Shell publishes the fan temperature the loop follows, the slider unit, the scenario row title, the emulator launch modes and the screensaver kind and summary. DescriptorRow and its types and PerformanceOverlaySnapshot move to Shell. Shared editors replace the hand-built ones: ComboCommit, DeviceSliderRow for brightness, DeviceSettingRow for the Windows policies and power editors, one press-to-edit button and keyboard lookup, one persisted fold, one command strip and one Load more row, which also replaces the two page-by-page pickers.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…types OverlayWindow keeps the shell, rail and navigation. The parts that only lived in it as partial files are now their own types in Overlay/: GlyphInputPreview (holds the Controller page's sample lease), OverlaySurfaceStack, QuickAccessPins, HeaderProfileScope, OverlayPowerEditors, PowerActionConfirms, StorageFormatView, OverlayPlacement and WindowsPolicyRows. Callers and tests use the parts directly. Pin ids, focus keys, Back handling and live-refresh coalescing are unchanged.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The headless render timer is a wall-clock dispatcher timer, so frames are also rendered while a window is still being built. The first window of a run is slow to JIT and gets more of those frames, and an incremental frame kept earlier anti-aliased pixels outside its dirty region. A capture then depended on the tests that ran before it: overlay-widgets-1280 and overlay-sections-1280 failed in the full run and passed alone. Verify now invalidates every visual before capturing, so the image depends only on the final tree. The six baselines that held stale edge pixels (the tab strip's wrench and Steam icons, a slider thumb edge) are promoted from the deterministic render; tolerance is unchanged.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The Claw captures were written as unreviewed artifacts. Each viewport and full-page render is now a compared baseline, so the Device renderer rewrite has to reproduce them. New cases cover the Overview at 980, its pin chooser, the GPU page entered from the Overview, without a graphics package and before one publishes, Power groups pinned to Quick Access, the prerequisite banner, the colour editor, the WSGM-owned OEM, Lighting and Diagnostics pages, the WSGM Controller page and its pin, and a pinned group that is gone. The images record current behaviour, known defects included.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
… in Shell The router now publishes the shared Power, RGB, Controller and Info pages before a descriptor set arrives and after a detach, and Shell gives every row its page where it projects it: unplaced capabilities by role, the graphics package's variable refresh row on Power, host rows through DescriptorRow.SectionId and performance rows through their snapshot. With integration off the bridge publishes no AutoTDP, profile or recovery rows. The Overlay draws and counts only that publication. The WSGM-owned fallback pages, their OverlayPage values, the DeviceOverlaySection enum and the rules folding them into declared sections are gone, so the duplicate Overview disappears and the variable refresh row is drawn on Power. Rail badges count the rows a page draws, including the Windows power controls, instead of seeding Power with one. NeedsDeviceRoot follows the published sections. Pins saved under the old fallback ids are read as the matching shared page's configuration group. The recovery row's button now reads Retry, and the GPU page's empty state uses the caption style. Device captures are promoted for the corrected badges, the variable refresh row, the removed fallback rail entries, the pinned controller group and the two labels.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The split of each published page into its pinnable groups moves from the Overlay into DeviceOverlayGroups: the Power page's leading limits, the fan group first and on its own fold, the Power titles, and the Controller page leading with its configuration. The performance snapshot owns the per-application toggle's id and splits it from the page rows, and the toggle's write goes through the same profile scope command as the header switch.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…derer Every Device page, the GPU page, Tools performance and every Quick Access group is now a DevicePage description built once per refresh: ordered groups with their pin id, titles, fold policy, rows and nested groups. The Overview is the per-application toggle above the Power page's groups. DeviceGroupRenderer draws a description and keys what it drew by group id, so an unchanged group only refreshes its rows and a changed one is rebuilt alone; turning AutoTDP on no longer rebuilds the page or drops a draft. Pinned copies take their pin: scope as they are created. DeviceCapabilityControl is the one row control, for capabilities, host rows and performance rows; host rows pass through unchanged, so their game override survives. The composite views (power assignments, Windows plan, manual power, processor cores, display) are factory-backed rows. DevicePageView owns the Device and GPU panes, and Device sections and the GPU page are sub-views of it, so they share the route, Back and leave paths of every other page; the Controller page still holds the glyph input lease. The XAML hosts, the reparenting of the power and performance controls, the header injection, the per-host value walks and the layout snapshots are gone. Intended visual changes: the Controller page shows one Configuration group (the pin list's), the GPU page entered from the Overview folds its groups, the GPU unavailable caption sits where the empty caption does, the pin chooser lists groups in page order, and Processor cores and Quick Access pins are persisted folds.
The Overlay guide, UI and overlay docs and the source map name the page descriptions, the keyed renderer, the Shell group layout and the one row control, and record the folds and the Controller configuration group.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The pages that were static XAML in OverlayWindow are page views in Overlay/, one per file, each owning its controls, handlers and requests: SteamLibraryPage, LaunchFixesPage, SystemToolsPage, PerformancePage, StoragePage, DisplayPage, AboutPage, PluginsPage, KeyboardPage, PowerSessionPage, PowerWakePage, PowerTimeoutsPage and PowerActionsPage. The launch fix flow, the library folder picker, the Display fold, the Plugins availability and the power menu's ordering live with their page; the controller subscribes to the page that raises a request. BrowserView owns its window key, text and lifetime handling and the BrowserButtons filter; NotesView drops its screenshot starter on detach. The window keeps navigation between the pages.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…hat owns it QuickAccessPins resolves action rows and pinnable Tools sections, ProgramsView resolves program pins and DevicePins resolves Device, performance, graphics and composite view groups, each to a title, availability and control. RenderPins and the pin toggle use the one resolution instead of testing id prefixes in three places; a pin is offered to toggle while its source offers it or while it is pinned. The never-displayed Steam, Tools and Power tile grids are gone. Their pinnable cards (system.notes, system.themes and the others) come from the section registry, which declares each pin id and description, and the sections have no parent page. ProgramsView owns its activation, the editor fallback and its change subscription. Behaviour change: a pinned Tools section card, and a pinned row that opens a nested page (Library Tabs, Card Manager, wake locks, a launch fix's game picker), now opens it from Quick access; before, the cross-destination push was refused and the press did nothing.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The controller keeps the sheet's lifetime and summon, navigation, the input lease and UI claims and the session actions its pages request. The rest moves to focused owners: - OverlayActivation: the hotkey, controller chord and edge swipes, and the controller polling they share with navigation. - QuickAccessPinStore: the shown pin list and its saves in press order. - OverlayPowerState: Keep awake and its wake-lock indicator, the idle timeouts and the UAC and sign-in policies, read behind each other on a worker and published only to the sheet they were read for. - OverlayOpenApps: the Open apps chips, their icons and the tray icons. - OverlaySheetServices: the borrowed services and how each sheet is connected to the brightness, manual power, energy plan, processor cores and power assignments, and which features it offers. The open, reopen, close and dispose sequences and the lease handling are unchanged.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
DeviceRowFactory creates every described row with the commands of its source, the composite views and the Controller page's glyph preview; the window passes it its borrowed sources. DevicePageView reads the missing-prerequisites banner itself and follows the integration switch and device from each Device snapshot. The graphics and performance partials fold into the window's source attachment and live refresh.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…ners The overlay code map names the destination page views, the Quick Access pin sources, DeviceRowFactory and the controller's owner types, and says the window is the shell. Navigation notes that Steam, Tools and Power have no root page and that a pinned copy opens its page's section first; the pins section says how each source resolves its ids.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…imports The Game Tools row named its folders with an unescaped backslash, so one path held a backspace byte and the other lost its separator. Prettier reformatted the Game Tools catalogue and dotnet format sorted five using blocks.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
WSGM.UiTests is self-contained and references WSGM.Setup, which is self-contained only in Release. The Debug evaluation that jb cleanupcode analyses failed with NETSDK1150 before any reference resolved, so the cleanup saw no framework or package types in that project and removed usings there and in the tests/Shared files linked into it. The tests use Setup's types and never run its executable, so the check is off there. Rider places Windows.* with System.* when it sorts usings; Roslyn's import formatter rejects that, and dotnet format only runs it while the sort options are written in .editorconfig. Both tools default to the same two values, so the options are left unwritten and Rider decides the order.
Output of jb cleanupcode with the built-in Full Cleanup profile and the solution settings layer: member order, argument style, continuation alignment and redundant usings. A rerun now changes no file. It depends on the previous commit: once WSGM.UiTests evaluates in Debug, the cleanup keeps the Avalonia, Shell and System usings that it had dropped from the UiTests files and the linked tests/Shared files.
The Big Clean.