Skip to content

feat: polish library and settings with window size presets - #746

Closed
MohamedElGhandour wants to merge 806 commits into
metalsharp:mainfrom
MohamedElGhandour:codex/ui-polish
Closed

MohamedElGhandour wants to merge 806 commits into
metalsharp:mainfrom
MohamedElGhandour:codex/ui-polish

Conversation

@MohamedElGhandour

@MohamedElGhandour MohamedElGhandour commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Latest tested fixes: 12ee4bc8. The branch push succeeded, but GitHub currently shows “Processing updates” and still reports the old PR head; new CI has not started. The fork is now in a different repository network from metalsharp/MetalSharp, which may explain the stalled update. Local verification below covers the new commit.

Summary

Library controls become cramped or disproportionately small on large displays, and Settings mixes unrelated options in a long grid. This gives the library a shared responsive layout, groups Settings into focused categories, and adds saved window-size presets that keep desktop space visible.

Changes

  • Replace tiny text/Unicode control glyphs with bundled SVG icons for search, play, edit, dropdowns, carousel navigation, downloads, Settings gears, and close buttons, with consistent sizing and alignment.
  • Stack the hero and carousel with explicit height budgets; scale controls, SVG icons, typography, and collection columns for Full HD, 2K, and 4K displays.
  • Organize Settings into General, Integrations, Storage, Updates, and Advanced, with compact tabs, larger controls, and preserved actions and confirmations.
  • Add Automatic, Compact, Full HD, 2K, and Large (4K) window presets. Apply changes immediately, fit smaller displays, and store the selection with existing UI preferences.
  • Add explicit offline preview dimensions and regression coverage for layout bounds, preset sizing/serialization, category mapping, and language-menu placement.

PR Readiness (MANDATORY)

  • Real-game launch test: N/A for this presentation/window-preference change; game launch callbacks, runtime routing, and compatibility rules are unchanged.
  • No hardcoded paths, secrets, or absolute user-home paths introduced.
  • Config/rules TOML validation: N/A; unchanged.
  • Version metadata: N/A; no version bump.
  • Bottle/runtime migration and launch behavior preserved; no migration changes.
  • User-facing behavior documented in docs/development.md.
  • Regression tests added for the new geometry and state decisions.

Local toolchain

  • GPUI formatting, build, and tests: 119 passed, 3 tests ignored.
  • Regular and FEX C backend suites: both make test commands passed.
  • Packaged native preview: binary hash recorded and deep/strict ad-hoc signature verification passed.
  • Diff/pre-commit checks passed; no new dependencies or repository-root files.
  • C++/Obj-C compilation, clang-format, CTest, shell/rule/release-workflow checks: N/A; those sources and tooling are unchanged.

Test notes

Native macOS GPUI preview on a 3840 × 2160 logical display:

Check Observed
Automatic / Large 2800 × 1700 content, normal window with desktop margins
Compact / Full HD / 2K 1360 × 860 / 1920 × 1080 / 2560 × 1440 content in the same window
Settings navigation All categories reachable; category switches close the language picker and preserve independent scrolling
Minimum 720 × 540 viewport Compact tabs and scrolling work; language picker opens upward near the bottom edge

These previews use sample artwork and do not access production credentials or write preferences. Serialization and fallback are covered by tests; production preference persistence was not exercised against the user's profile. No real-game run is claimed for this UI commit.

The C suites skipped archive-based runtime simulation and Wine facade integration because the worktree lacks the runtime archives / MetalSharp Wine app. Existing fullscreen-to-windowed transition handling was not manually exercised.

Risk

Changes are confined to the native UI and its existing preferences file. Window sizes use logical points and fit within display bounds, with a 720 × 540 minimum. Invalid or missing stored presets fall back to Automatic. Reverting this commit restores the previous UI; no game data or runtime rollback is needed.

Review follow-up — 4 November 2026

The hero title and action group now stay vertically centered on the left of the artwork using flex alignment instead of a fixed top offset. The generated backend-route inventory was refreshed, fixing the stale-inventory failure in GPUI CI without changing any route.

Merged current main while preserving the published branch history. Upstream data relocation, quit cleanup and MetalFX changes are retained; Data Location appears under Storage. The old and rewritten 1.0 release commits have identical trees and provided the common content base for reconciliation.

Flow Action Expected Observed Result
Hero Switch Compact, Full HD, 2K and Large presets Left-aligned content stays vertically centered on the hero Correct at 1360×860, 1920×1080, 2560×1440 and 2800×1700 logical points Pass
Uninstalled collection Open three sample owned games through the real C backend in an isolated validation profile Artwork, titles and Install buttons remain visible Correct at Compact and Large sizes, including a deliberately long title Pass
Search Filter for Portal, then clear One matching card, then all three cards Correct Pass
Settings Open Storage after merging upstream Data Location remains available Visible beneath MetalSharp Data Folder Pass

Added a regression for parsing and merging a sync response containing both installed and uninstalled games. The owned entries and their artwork remain available to the uninstalled collection while the Play library stays restricted to installed games.

cargo fmt --check, cargo test --locked --offline (119 passed, 3 ignored), regular/FEX C suites, route-inventory verification, DMG workflow verification and diff checks passed. A separate locally assembled QA app used the compiled frontend/backend, unchanged icon/runtime resources from the installed app, current UI assets/configs, and verified deep/strict ad-hoc code signing; binary hashes were recorded.

The card check used synthetic cached ownership data with no API key, as agreed with Mohamed. A live Steam API sync, Steam sign-in, actual installation and game launching were not performed. Standard full-Xcode packaging remains untested locally because actool is unavailable; the native QA app was assembled separately and the installed app was not changed.

UI previews

Native offline previews with sample games. Large (4K) uses a 2800 × 1700 content window and leaves desktop space visible. The first preview below predates the review alignment fix; the following screenshots show the current result.

Library and carousel — before review alignment fix

New library hero, carousel, larger controls, and SVG icons

After review — centered hero, Full HD

Full HD: hero content centered vertically on the left of the artwork

After review — centered hero, Large (4K)

Large preset: hero content remains centered vertically on the left

Uninstalled collection — sample ownership data

Real backend and native UI in an isolated validation profile, using cached sample ownership data and no API key. Artwork, Install buttons and a deliberately long title remain visible. This is a presentation check, not a live Steam API sync.

Three uninstalled sample game cards with artwork, titles and Install actions

Collection

Responsive game collection grid

Settings and window-size presets

Settings category sidebar and window-size presets

SVG icons — close-up

Text glyphs were replaced by scalable vector assets; this native-size crop shows Play, edit, dropdown, and Settings controls.

Close-up of the new SVG Play, edit, dropdown, and Settings icons

aaf2tbz added 30 commits October 4, 2026 10:49
Replace the connected-workbench modules with a live controller that drives
the real C backend on :9274 exactly as the Electron renderer did: setup
wizard (runtime/Steam installs into ~/.metalsharp, API key saves), library
sync for Steam and Ubisoft, Play/Stop with external-exit detection, hero
game settings, bottle route changes, launcher buttons, Settings actions,
updater download/install/restart, post-update migration, streaming, and the
GOG/Epic/GameJolt/emulator Sharp library.

The backend now removes the previous route's DLLs before staging a new
bottle route so switching e.g. DXMT -> D3DMetal leaves no stale DLLs.

Add package-app.sh to build MetalSharp.app with the com.metalsharp.app
identity expected by update.sh.
- First-launch intro video: MetalSharp-Startup.mp4 plays over the window
  with "Skip intro" (WKWebView overlay), remembered once seen.
- Cmd+P Process Manager HUD with helper sampling, MetalFX toggle/factor,
  non-Steam Wine force kill, and the --process-manager-overlay mode.
- LibraryView's one-time vkd3d default-rules repair.
- Sharp installer tooling reachable from SharpView: Launch Doctor and
  diagnostics drawer, D3DMetal launch path with track-running, bottle
  badges and launch log, app/GameJolt rename, cover position.
- GameJolt store embedded in the Sharp page with the draggable split,
  hidden under app overlays; toasts stay visible above it.
- Steam: the library hero button only starts Steam (it toggled, so it
  stopped a starting client). Skip redundant Wine registry imports, poll
  readiness every 100 ms, restart stale sessions instead of reporting a
  false success, stop via wineserver -k plus a kill sweep, show pending
  Starting/Stopping states, verify Wine is gone after setup's Steam
  install, and bring the Steam installer window to the front once.
- Settings: draw the confirm dialog and language menu without nesting a
  deferred layer inside the deferred overlay (GPUI aborted the app); same
  for Sharp's resolution menu. Uninstall stops Wine sessions and the
  backend, deletes data off the UI thread and shows the result dialog on
  the main thread.
- Shutdown: children spawned from GCD worker threads inherited a blocked
  signal mask, so the backend never received SIGTERM; clear the mask for
  spawned processes and in the backend's main(). Quit no longer blocks:
  SIGTERM plus a detached 3 s SIGKILL watchdog. Run the startup update
  check after the first library load, as Electron does.
- Browser: per-provider persistent WebKit stores keep Steam, GOG, Epic and
  TheGamesDB sign-ins; GOG disconnect and Epic logout clear theirs.
- Packaging: fail when the graphics bundle lacks the vkd3d-proton, DXVK or
  DXMT lanes; stop forcing MACOSX_DEPLOYMENT_TARGET for cargo, which made
  the macOS 27 linker emit proc-macro dylibs dyld rejects.
- Bottles: a saved "dxmt" route is honoured when saving, launching,
  checking readiness and diagnosing instead of falling back to the game's
  default route. Route DLLs are staged when an installed game is first
  detected (marker bottles/steam_<id>/.route-staged), not only on first
  launch or Bottle save.
- Executables: Skyrim SE launches SkyrimSE.exe, and a "<Name>Launcher.exe"
  next to "<Name>.exe" no longer wins on directory order.
- Steam: a cold start whose UI never initialized gets one automatic
  restart if htmlcache/"First Run" is not written within 10 s. The Steam
  client is launched through "MetalSharp Steam.app" (built by packaging
  from assets/metalsharp-steam.icon) so its first window carries the
  MetalSharp Steam icon instead of MetalSharp's; without the helper the
  launch is unchanged.
- Audio: FAudio's Windows build ships in metalsharp-assets
  (assets/faudio), unpacks to runtime/faudio and is installed into the
  Steam prefix with a SkyrimSE.exe-only native override so xWMA NPC
  dialogue plays. Older installs extract it from the bundle on demand.
  Third-party notices in LICENSES/FAUDIO-*.
- Updated the MetalSharp app icon.
Settings -> Graphics runtime logs now keeps each direct game launch's
Wine stderr (errors, DLL loads, exceptions) in
logs/<route>/<appid>/launch.stderr.log instead of discarding it; before,
only Rain World and EVE wrote launch logs.
The GPUI app in app-gpui/ is now the application. Remove the Electron main
process, Vue renderer, shared types, npm/Vite/TypeScript/Biome/Prettier
tooling, electron-builder hooks and the Vue/Electron source tests.
app/src-c, app/native, app/tools, app/bundles, app/updater and the two
backend source-contract tests stay.

Release: release.yml builds the GPUI app with package-app.sh, signs it
inside-out with hardened runtime and tools/dmg/entitlements.mac.plist
(Developer ID when signing is prepared, ad hoc otherwise), builds
MetalSharp-<version>-arm64.dmg with tools/dmg/package-gpui-dmg.sh and
reuses the notarize/verify scripts. The DMG name, bundle id and signing
team stay as update.sh's recovery path requires.

The app version comes from CMakeLists.txt; set-version.sh no longer needs
Node. The intro video moves to app-gpui/assets/intro. CI drops the Vue,
Electron and JS/Vue CodeQL jobs and runs the backend contract tests in the
native job; the pre-commit hook checks rustfmt instead of TypeScript.
Docs, install.sh, CODEOWNERS and third-party notices are updated.
GOG's sign-in now redirects to login.gog.com, and its Steam, Xbox, Google
and Discord buttons open a popup that posts the login back to the opener.
Allow *.gog.com for GOG sign-in, open window.open popups with the
WebKit-provided configuration, and check popup navigations and redirects
against the provider hosts. Epic's allowlist gains the hosts its
PlayStation, Nintendo, Steam, Xbox, Apple, Facebook and LEGO logins
redirect through, and captcha frames may load over HTTPS in both windows.
The column count ignored the workspace panel's 1px border, so a full row
overflowed by 2px and its last card wrapped, leaving an empty column.
… Sharp

- Sharp apps, GOG, Epic and GameJolt now stage the selected route's DLLs
  next to the game exe when the route is saved and before launch, using
  the Steam staging (previous route DLLs removed by byte comparison).
  GOG gains /sharp-library/gog/set-engine; installer exes are skipped.
- When a Sharp app exits, programs it installed (new uninstall entries,
  Start Menu/Desktop shortcuts, and for launchers new game folders beside
  them, in Program Files or on mapped drives) are added to the library
  with the same route. Installers run before this are scanned once.
- External volumes get drive letters (Y: down) in the Sharp prefix so
  launcher folder pickers can reach them.
- The Sharp card's Open Folder button becomes Add Asset: pick files from
  the unpacked MetalSharp assets and copy them beside the app's exe,
  keeping a .metalsharp-backup of any replaced file.
- gamejolt.c is clang-formatted so the pre-commit check passes.
The API key rows now end with clickable links that open the key pages in
the mini browser, reusing the setup screen's help opener.
Collection gains Installed / Uninstalled tabs. Uninstalled lists owned
Steam games that aren't installed and installs them with Valve's macOS
steamcmd (Windows depots), downloaded once to ~/.metalsharp/tools.

- Backend (steamcmd.c): stdin-driven sign-in with Steam Guard code and
  mobile-approval states (only the account name is saved), Steam library
  listing with free space, a sequential install queue with progress and
  cancel, staging into the chosen library then moving the game into
  steamapps/common with its appmanifest. steamcmd is stopped when the
  backend exits.
- UI: sign-in sheet, internal/external library picker, per-card progress
  and cancel, library refresh when an install finishes.
- Cards show compatibility badges from the repo's sources: Playable
  (GAMES-SUPPORTED.md), May Run (mtsp-rules.toml), or kernel anti-cheat.
AMID EVIL intermittently exits during startup when its shipping exe is
launched directly, but starts reliably through Steam with the same staged
route DLLs. Route DLLs are still staged; the launch is then handed to
steam://rungameid like Baldur's Gate 3.
Nothing imports the hook, so it was never loaded; DXMT staging, the DXMT
readiness check (which looked for it in lib/dxmt) and Launch Doctor's
expected files no longer include it. Copies already in game folders are
still removed by route cleanup.
metalsharp-runtime.tar.zst on the bundles release now ships an ntdll.so
built from the MetalSharp Wine 11.17 tree with DXMT-only GSBASE/TEB
switching (fixes Unity/Mono titles such as Rain World and Besiege), pipe2
gated to macOS 27+, the msync client matching wineserver (WINEMSYNC), and
the MetalSharp 1.0 version string.
The description and its link sat in a wrapping row, so the text stopped
wrapping and ran under the key inputs and status badges. Stack the link
under the wrapped description instead.
The release check and CI bundle downloads still used the pre-transfer
aaf2tbz/metalsharp path and only worked through GitHub's redirect. The
update check's error responses also hard-coded current_version 0.76.0,
which set-version.sh does not bump; use MS_BACKEND_VERSION.
set-version.sh no longer rewrites a hardcoded version in updater.c, whose
fallback responses now use MS_BACKEND_VERSION; it checks for that instead.
With the repository variable METALSHARP_RELEASE_RUNNER set to local, the
release jobs run on the runner labelled metalsharp-release instead of
macos-14. The build job deletes its temporary signing keychain afterwards,
since a self-hosted runner keeps the user's keychain search list.
Picks up the steamcmd and GOG set-engine routes added to the C backend.
Replace Electron desktop with native GPUI application
package-local-preview.sh bundles libmetalsharp_host_runtime.dylib from the
CMake build directory, which the GPUI Preview workflow never produced.
The previous rebuild dropped tools/bundles/wine/0001-x87sidecar-cooperative.patch,
so release bundle verification rejected the runtime.
prepare-apple-signing.sh kept the indentation from `security list-keychains`,
so it re-added the login keychain as a path relative to ~/Library/Keychains.
On a self-hosted runner that hid the Developer ID intermediate, leaving no
valid signing identity, and left the user's search list broken. The release
cleanup step now deletes the temporary keychain whenever signing was attempted.
aaf2tbz and others added 22 commits October 28, 2026 00:50
…tion, every prefix included, without the updater's marker
…s before clearing Metal's cache that every Mullion game shares
…er builds left in a game's folders, once, at its next launch
…unning migration, and an install lock keeps both from replacing the app at once
…s-fex.toml is the regular rules on MetalSharp Wine's lanes plus the games verified there
… and updates, and a changelog entry crediting Deadlock's fixes
…Wine and everything it carries are covered with their license texts
…eds METALSHARP_WINE_APP instead of a maintainer's path
…11 and D3D10 (welcome guide, changelog, architecture)
…o longer migrates at its second launch, and a Steam prefix MetalSharp Wine built reads as FEX
…nloaded regular DMG instead of recovering, and so reinstalling, FEX
…, swapped in safely and then consumed, and a failed restore leaves the build unrecorded to retry
…-recover for the regular build updating itself, the downloaded DMG with its variant otherwise
MetalSharp 1.0.0: the Arm64 FEX build on MetalSharp Wine
@aaf2tbz

aaf2tbz commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator

I like this! Thanks! I can review all your work tonight, thanks for your contributions.

@aaf2tbz

aaf2tbz commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

If youre okay with fixing the one failing Ci, and applying the suggested edit, I will merge this!

| play | art editor | graphics selection | settings, on the hero art, should stay centered per desktop size / resolution.

(Left centered, on the hero image surface)

And verify behavior is unchanged in the uninstalled portion by syncing a steam api key and ensuring that uninstalled game cards are also correctly presented.

-- If you want me to cover these final changes let me know!

@MohamedElGhandour

Copy link
Copy Markdown
Contributor Author

@aaf2tbz could you clarify why #745 and #746 were closed? I pushed the review fixes and conflict resolutions, with local checks and screenshots. GitHub was still showing the older commits under “Processing updates,” so I’m unsure whether the closure was related to that.

@aaf2tbz

aaf2tbz commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

I'm opening them again. I completely botched my repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants