Match UI size on the client to the host by measuring the client's image area (EDID, not percentages) #453
Replies: 1 comment
|
Update: both drafts picked up a second commit, Question 2 above was whether millimetres of image width are too unfriendly to ask for. Rather than trade precision for a diagonal, this keeps the millimetre as the input and removes the part that was actually unfriendly — having to find the number. export const clientImageWidthPresets: ClientImageWidthPreset[] = [
// Dell's manual gives a 344.68 x 215.42 mm active area at 2560x1600, so 188.65 PPI.
{ label: 'Alienware m16 R2', mode: '2560x1600', widthMm: 345 },
// Samsung's 8.0-inch inner panel at 2504x2256 works out to 150.97 x 136.01 mm, so 421.3 PPI.
{ label: 'Galaxy Z Fold8 Ultra (inner panel)', mode: '2504x2256', widthMm: 151 },
];The settings schema hangs it off the field as a generic Questions 1 and 3 are the ones I still can't answer myself, and the hardware check the PRs ask for is still unrun. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
The gap
The stream protocol carries pixels, never physical dimensions. I went looking for a place to read a
client's screen size or DPI — nvhttp
/launch, the SDP attributes insrc/rtsp.cpp, moonlight-common-c— and there isn't one. The host cannot tell a 2504-pixel-wide phone panel from a 2504-pixel-wide desktop
monitor.
effective_virtual_display_scale_percent()bridges that with a guess from the short edge alone:Resolution is a weak proxy for density, and the existing tests already show the seam: 3440x1440 and
1440x2560 are very different displays and both land on 175%.
The consequence is that buttons, text, and the cursor come out at a different physical size on the
client than they have on the host's own monitor. #386 is the same thing seen from the user's side —
someone picked 175% in Vibepollo, Windows recommended 150% "on two different phones", and the two
disagreed until they set Windows by hand.
The direction I'd argue for
Not another picked percentage. ClassicOldSong#290 (which ClassicOldSong#1013 was closed as
a duplicate of) already went around this loop. Asked about specifying scaling as a percentage from the
client, the Apollo maintainer answered:
and then:
He also said auto-detecting the client's physical size isn't feasible and it has to be entered manually,
which matches what the protocol survey above found.
Vibepollo already synthesises an EDID physical size — but derives the millimetres from the scale
(
dpi = 96 * scale / 100, thenmm = px * 25.4 / dpi). The proposal is to let that run in the honestdirection: measure the client's image area once, put the real millimetres in the EDID, and let Windows
derive DPI from them the way it does for any real monitor. The percentage becomes a derived value rather
than the input.
What it looks like in practice
One setting: the width, in millimetres, of the image area the client actually displays. Deliberately the
image area, not the device — on a letterboxed panel those differ, and a device diagonal bakes in the
error. Height follows from the width and the mode's pixel aspect, so it stays one number.
Both from vendor figures (Dell's manual gives 188.65 PPI, Samsung's 8.0-inch inner panel gives 421.3 PPI
— the arithmetic reproduces both). The phone is the case that shows the stakes: the resolution heuristic
is off by 200 percentage points there.
Draft PR
I've put a working version up as a draft on both sides — #452 here and Nonary/vibeshine#266 on
Vibeshine, since that's where features originate. They're the same change; whichever one you'd
rather take, I'll close the other. It reuses
effective_virtual_display_scale_percent()and the existing
config_overridesallowlists rather than adding a parallel path, so it's alreadyper-client and per-app overridable, and it adds no protocol changes, no client auto-detection, and no
new UI component.
Two things worth saying plainly. First, I could not run the project's test suite — Vibepollo builds
under MSYS2 UCRT64 and I don't have that toolchain, and the full build also needs the virtual display
driver SDK. I verified the new logic in isolation (34 assertions, including the pre-existing scale cases
as regression) and the web typecheck, but nobody has confirmed on real hardware that a client ends up
with correctly-sized UI. That check needs someone with the driver and a device. Second, the PR was
written with AI assistance; I've reviewed it and the limits above are stated there too.
What I'm actually asking
Less "please merge this" than "is this the right shape?". Specifically:
Apollo maintainer raised for percentages applying to physical size too?
plus aspect, even though letterboxing makes that lossier?
overrides already cause flexibility problems on handhelds. Does that concern carry over to Vibepollo?
If you'd rather implement this yourself, that's a fine outcome — the reasoning and the measured numbers
above should be enough to work from, and the draft can just be closed.
All reactions