Skip to content

feat: GPUI native app on in-process Rust backend (patchops-core) - #53

Open
boggedbrush wants to merge 17 commits into
mainfrom
feat/gpui-rust-backend
Open

boggedbrush wants to merge 17 commits into
mainfrom
feat/gpui-rust-backend

Conversation

@boggedbrush

Copy link
Copy Markdown
Owner

Summary

Makes the native GPUI app the primary PatchOpsIII desktop client, running on an in-process Rust backend (patchops-core, extracted from the Tauri migration in #40). The result is one Rust process: no Chromium, no WebView, no Python, no HTTP. Electron and the Python backend are left untouched for now as the legacy fallback.

Supersedes #52 (this branch includes its commit).

Changes

Rust backend (native/core)

Parity tests

  • scripts/gen_parity_fixtures.py records what the Python backend on main does on 31 hermetic fixture game directories. native/core/tests/parity.rs checks that the Rust core produces the same responses and resulting files. All 31 pass. The reference files were not edited to accept Rust behaviour, apart from a narrow allowlist for the DXVK adoption files (documented in native/core/tests/parity/RESULTS.md).

GPUI frontend (native/gpui)

  • Restyled to closely match the Electron UI: theme tokens, nav with Lucide icons, header, game-directory bar, status overview, cards and activity log.
  • Custom titlebar with Electron's caption buttons. On Linux the app draws its own window decorations, with drag, double-click to maximise, the window menu, rounded corners and resize edges, and falls back to the compositor's frame if refused. On Windows it uses OS hit-testing so snap layouts work.
  • Runs natively on Wayland (and X11). The window is fully opaque; transparency and blur were explored and deliberately dropped for now.
  • Live progress strips and Activity Log streaming fed by the core's events, layout fixes at 800×600 and the default size, and the status-refresh interval in a single constant.

Packaging and CI

  • Native Linux and Windows ZIPs are now a single Rust executable plus resources, with no Python or PyInstaller.
  • gpui-build.yml checks formatting, runs clippy with -D warnings, runs the core, parity and GPUI tests, builds release archives, and runs smoke tests on an X11 display (Xvfb) and on Wayland (headless Weston).
  • Stable and beta release workflows attach the native ZIPs, and the VirusTotal scan covers them.
  • New gpui:build, gpui:build:release and gpui:run scripts in package.json. README and docs present GPUI as primary.

Testing

Run locally on Linux (KDE Plasma 6, Wayland):

  • cargo fmt --all --check: passes
  • cargo clippy --locked --workspace --all-targets -- -D warnings: clean
  • cargo test --locked --workspace: 100 core, 31 parity and 3 GPUI tests pass
  • python3 -m unittest scripts/test_gpui.py: 8 pass
  • python3 scripts/gen_parity_fixtures.py --check: the reference files are reproducible and current
  • Launched on native Wayland and under XWayland. Status loads from the in-process backend with no Python running.

Not yet verified / follow-ups

  • Windows: not built or run locally; CI is the first Windows build.
  • Clicking through: buttons, the titlebar, resizing and real install operations have not been exercised. Only startup, status loading and rendering were checked.
  • Enhanced: migrating the old install record permanently, so it doesn't have to be re-checked each session.
  • Later work: removing Electron and the Python backend once GPUI is accepted; signing, installers and auto-update for the native app; real KWin blur would need GPUI to support ext_background_effect_v1.

CJ Lees and others added 10 commits October 2, 2026 04:08
Restyle the GPUI client after the Electron renderer (theme tokens, nav,
header, game directory bar, cards, activity log, Lucide icons), and have
the native binary supervise a bundled PyInstaller backend. Package
self-contained Linux/Windows archives and attach them to releases.
Extract PR #40's operations into a toolkit-independent patchops-core
crate in a native/ workspace, replace the Python/HTTP supervisor with an
in-process dispatcher that keeps the existing request/response shapes,
port the September 2026 EXE build and T7 release-asset fixes from main,
and ship native archives without Python.
Compositor blur is unavailable on current KWin and GNOME, so remove the
backdrop model and its env hooks. Rounded client-side corners on X11 still
use a transparent surface for the cut-outs.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-04T00:25:43.700265Z 51d74f1 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 51d74f1bf7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/package_gpui.py
ROOT / "presets.json",
ROOT / "PatchOpsIII.ico",
ROOT / "website" / "assets" / "img" / "icon-512.png",
ROOT / "native" / "gpui" / "assets" / "icons" / "LICENSE-lucide.txt",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the required Lucide license file

This required path is not present anywhere in the repository, so every call to archive_manifest raises FileNotFoundError. Running python3 -m unittest scripts/test_gpui.py fails in PackagingTests.test_archive_contains_one_rust_executable_and_no_python_backend, and the new build workflow runs that test before building or uploading either native archive, blocking both CI and release jobs.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 88377be: the root .gitignore *.txt rule was excluding the file; it's now explicitly un-ignored and committed. Verified packaging from a clean git archive export.

Comment thread native/gpui/src/ui/graphics.rs Outdated
))
.child(quick_row(
"Refresh Rate",
self.number_control(cx, "refresh", "RefreshRate", 1, 1000),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Align the refresh-rate input with backend validation

For refresh rates from 241 through 1000, this control accepts the value and stages the operation, but config_input rejects RefreshRate above 240. This makes legitimate interaction with the newly advertised range end in a backend failure; use the same maximum in both layers or extend the core validation.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 77d57ab: the control now uses 1–240, matching patchops-core, the Python backend and the Electron UI.

Comment on lines +155 to +157
.on_click(cx.listener(|view, _: &ClickEvent, window, cx| {
view.choose_directory("dump", window, cx)
})),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow the Enhanced browser to select DUMP.zip

When a user clicks Browse intending to select the advertised DUMP.zip source, this calls choose_directory, whose PathPromptOptions explicitly permits directories only. ZIP sources therefore cannot be selected through the browse workflow and require manual entry or drag-and-drop despite being presented as a supported browse source; use a file-capable picker for this action.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 77d57ab: added a separate "Browse DUMP.zip" file picker next to "Browse Folder" (platform pickers can't offer files and folders in one dialog). Validate Source moved to its own row so the buttons fit at 800px.

Match the core/Python/Electron RefreshRate range (1-240) so the control no
longer stages values the backend rejects, and add a file picker for the
Enhanced dump source alongside the folder picker.
GPUI 0.2.2 requires a wl_seat, which weston's headless backend does not
advertise; wlroots/sway always creates one. Detect the compositor's
auto-named socket instead of assuming a fixed name.
The managed manifest stored a canonical game path but compared it with the
caller's path verbatim, so Windows 8.3 short names, the \\?\ prefix, or a
case difference made PatchOpsIII refuse its own DXVK install.

This branch has not been deployed

No deployments
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.

1 participant