Skip to content

Wide-screen layout, and one executable with a tray icon - #8

Merged
peans99 merged 4 commits into
mainfrom
wide-screen-and-tray
Aug 21, 2026
Merged

Wide-screen layout, and one executable with a tray icon#8
peans99 merged 4 commits into
mainfrom
wide-screen-and-tray

Conversation

@peans99

@peans99 peans99 commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Two things: the dashboard now uses a wide screen, and the whole application ships as one file with a tray icon.

Use the whole screen

An ultrawide showed the problem — the content column was capped at 1440px, so on a 3440px display two thirds of the glass was dead black with the header stranded a screen away from the table beneath it.

  • The column is one variable now, min(2040px, 94vw), shared by the page, the footer and the header's inner padding. 2040 is where these tables stop being readable.
  • What the column still cannot use goes to the brand rather than staying blank: the emblem stripped to its geometry sits in the right margin at 6% and runs off the edge, a vertical wordmark labels the left margin, and hairline rails mark where the column begins and ends.
  • A faint overhead glow behind everything — at that size flat black read as an unfinished page rather than a dark one.

All decorative pieces appear only past 1600px and never in the overlay.

One executable, and somewhere to click

The release defeated a non-technical user four times over: install the .NET Desktop Runtime, pick the right file out of a fifty-file zip, get past SmartScreen, then find no way to stop it short of Task Manager.

  • The server runs inside the overlay process. Program.cs is a three-line entry point over a new ServerHost.Build, which the WPF app calls at startup and the standalone server still calls for itself. No more hunting for Quantumwake.Server.exe to spawn, and no orphaned server outliving a crashed overlay.
  • The dashboard is embedded in the assembly. web/ still copies beside the binary and that copy still wins, so a stylesheet edit needs no rebuild; EmbeddedWeb serves the compiled-in copy when no directory exists next to the executable.
  • Result: a self-contained 87 MB single file, no runtime required. Measured before committing to the approach.
  • A tray icon: open dashboard, show/hide overlay, quit. Hiding the overlay leaves the dashboard running, and the choice persists in settings.json, kept apart from overlay.json because geometry is rewritten on every drag.

Deliberately not built: an installer (a single exe does not need one) and code signing (a few hundred a year that a free fan tool cannot justify — the SmartScreen prompt is documented in the release notes instead).

Verification

154 tests pass. The published single file was run and checked: it serves index.html, app.css and the SVG marks out of embedded resources with correct content types, and with ShowOverlay=false it starts no WebView2 child at all while the dashboard still answers.

Note on the release

release.yml here builds the single file. The v0.1.0 tag has not been pushed yet — pushing it before this merges would cut a release from the old workflow and ship the three-executable, runtime-dependent zip this change exists to replace. Merge first, then move the tag onto the merged commit.

peans99 and others added 3 commits August 21, 2026 11:23
nekron's ultrawide showed the problem: the content column was capped at 1440px,
so on a 3440px display two thirds of the glass was dead black, with the header
stranded a screen away from the table beneath it.

The column is one variable now - min(2040px, 94vw) - shared by the page, the
footer and the header's inner padding, so the brand lines up with the content
instead of hugging a distant edge. 2040 is where these tables stop being
readable; beyond that the eye loses the row.

What the column still cannot use is given to the brand rather than left blank:
the emblem stripped to its geometry sits in the right margin at six per cent and
runs off the edge, a vertical wordmark labels the left margin the way a HUD
labels a panel, and hairline rails mark where the column begins and ends so the
margin reads as framing. All three appear only past 1600px and never in the
overlay, which has no space to spare.

Also a faint overhead glow behind everything. At this size the flat black read
as an unfinished page rather than a dark one.

The watermark needed two attempts: anchored to the viewport edge it computed to
-660px on an ultrawide and sat entirely off-screen. It is positioned from the
column's right rail outwards instead, which holds at any width.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Answering "how do we simplify this for people who are not technical?" The
release defeated them four times over: install the .NET Desktop Runtime first,
pick the right file out of a fifty-file zip, get past SmartScreen, and then find
no way to stop the thing short of Task Manager.

The server now runs inside the overlay process. Program.cs became a three-line
entry point over a new ServerHost.Build, which the WPF app calls at startup and
the standalone server still calls for itself. The overlay no longer hunts for
Quantumwake.Server.exe and starts it as a child, which also removes a failure
mode: an orphaned server outliving a crashed overlay.

The dashboard is compiled into the assembly. web/ still copies next to the
binary and that copy still wins - editing a stylesheet should not need a rebuild
- but the same files are embedded as resources and EmbeddedWeb serves those when
no directory exists beside the executable. A middleware rather than an
IFileProvider: twenty lines against a class that would have to lie about
directory listings, range requests and change tokens.

The result is a self-contained single file of 87 MB needing no runtime at all. I
measured before committing to the approach, expecting a self-contained WPF build
to be far worse; against "install .NET first" the trade is not close.

A tray icon, because there was nowhere to click: open dashboard, show or hide
the overlay, quit. Hiding the overlay leaves the dashboard running, which is what
a second-monitor user wants, and the choice persists in settings.json - kept
apart from overlay.json deliberately, since geometry is rewritten on every drag
and a preference someone chose should not share a file with that. Shutdown is
explicit, so closing the overlay no longer kills the app.

Deliberately not built: an installer, because a single exe does not need one,
and code signing, which costs a few hundred a year a free fan tool cannot
justify. The SmartScreen prompt is documented in the release notes instead.

Verified by publishing and running the single file: it serves index.html, app.css
and the SVG marks out of embedded resources with correct content types, and with
ShowOverlay=false it starts no WebView2 child at all while the dashboard still
answers. 154 tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Dependabot filed six pull requests within minutes of the workflows landing, all
of them fair - the action pins were already a major version or three behind what
GitHub ships. Folded into this branch rather than merged separately, so main
takes one review instead of seven, and they close themselves when it lands.

  actions/checkout          4 -> 7
  actions/setup-dotnet      4 -> 6
  actions/upload-artifact   4 -> 7
  Microsoft.NET.Test.Sdk    17.14.1 -> 18.9.0
  xunit.runner.visualstudio 3.1.4 -> 4.0.0
  coverlet.collector        6.0.4 -> 10.0.1

Three of those are major bumps of the test runner. Verified rather than assumed:
restore is clean and all 154 tests pass on the new versions.

Also parks nekron's question - which commodities can be sold where - in
docs/commodity-catalogue.md while the detail is fresh. The short of it: the
community's account of p4k encryption is accurate, but on this install the
DataCore is not the wall. Game2.dcb is 330 MB and unencrypted and P4kArchive can
already pull it out; what has never been done is parse it, since every search so
far was a raw byte scan that finds strings and misses structure.

The doc records four routes and what each costs: write a DataForge reader
(recommended - offline, no redistribution, and it settles the question either
way), ship pre-extracted scunpacked JSON (contradicts our own NOTICE), fetch UEX
at runtime (breaks the no-network promise, so opt-in only), or decrypt the shop
inventory tables (not planned - reading what CIG left open is one thing,
circumventing what they deliberately encrypted is another).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nekron merged four of the dependabot pull requests while this branch was folding
all six in, so both sides raised checkout, setup-dotnet, upload-artifact and
coverlet to the same versions. Git handled three files; the test project
conflicted on Microsoft.NET.Test.Sdk, where this branch has 18.9.0 and main
still had 17.14.1 because that pull request is open.

Kept 18.9.0, which with xunit.runner.visualstudio 4.0.0 makes this branch a
superset of main: merging it closes the two remaining dependabot requests as
well. 154 tests pass on the merged tree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@peans99
peans99 merged commit bc326c9 into main Aug 21, 2026
1 check passed
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