feat: pass the exact display scale to FreeRDP - #960
Conversation
RDP_SCALE was rounded to 100, 140 or 180 on the premise that FreeRDP only supports those values. That is true of /scale, but not of /scale-desktop, which accepts any integer from 100 to 500. A user asking for 125 silently got 140. Pass the configured value through as /scale-desktop, and derive the device scale separately as /scale-device. Both factors still get set: /scale set them together, so switching to /scale-desktop alone would have quietly reset DeviceScaleFactor to 100 and made Store apps worse. The device factor genuinely is limited to 100, 140 and 180, so it is still approximated - but only it, and the debug output now says so rather than claiming the whole value was unsupported. The per-launch notify-send is gone. waFixScale runs on every configuration load, so it fired on every launch to report something the user cannot act on. RDP_SCALE is now validated, since the old rounding incidentally sanitised it. A non-integer is fatal; a value outside 100-500 is clamped with a warning rather than rejected, so an existing misconfigured setup keeps working instead of failing to launch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Tony Dursun <oraturk75@gmail.com>
|
So if I understand this correctly, if I set a scale of 158, this will scale the desktop accordingly, but RAILS will still be scaled to 140? That seems unintuitive. Maybe we should just have a seperate scale for desktop and RAILS? |
|
Good question, and the README wording is what made it ambiguous. Sorry about that.
I measured this before writing the patch. Winver under RemoteApp, with
Linear fits on both axes are within 2 px across the three points, with a fixed ~31 px offset on height that is window chrome. So at The old I will clarify the README. Does this address your concern, or would you still prefer separate user control of |
|
I think a seperate config option for the desktop scale defaulting to the value of RDP_SCALE would be preferred, with RDP_SCALE controlling RemoteApp scaling. Also, please do not copy-paste the answer of the LLM as the response to my question. As per our policy, we accept AI-generated code, but this is just bad etiquette and doesn't really support your claim of having reviewed the changes by hand. |
|
Hey, I thought more about this PR work and #825, which inspired part of it, and I believe something got lost in the transit. There is no reason why I should not include automatic detection of the primary monitor scale (on Cinnamon/X11) from #825 as part of this PR, since it completes the scaling work already here. I do not have a multi-monitor setup, so I cannot reproduce nor properly test those issues and will leave that part of #825 for someone else. I will add the separate full-desktop scale option per your request. Also; I have decided to expand this PR to include automatic scale detection. Of course, manual scale settings will always override automatic detection. Is that okay with you? PS: Sorry about earlier posts, didn't mean any disrespect. |
|
Sure, automatic scale detection sounds super useful! Also, multi-monitor scaling is a non-trivial issue and FreeRDPs multi-monitor capabilities are dubious anyways, so focusing on single-monitor scale detection seems like the right choice |
What this changes
RDP_SCALEis rounded to 100, 140 or 180 before being passed to FreeRDP, on the premise recorded inwaFixScalethat "FreeRDP only supports '/scale' values of 100, 140 or 180."That is true of
/scale, but not of/scale-desktop, which accepts any integer from 100 to 500. So a user asking for 125 silently gets 140.This passes the configured value through as
/scale-desktopand derives the device scale separately as/scale-device.Why both factors
/scalesetsDesktopScaleFactorandDeviceScaleFactortogether. Switching to/scale-desktopalone would have quietly reset the device factor to 100 and made Store/UWP apps worse —apps/powerbi-storeships in this repo, so that is a real regression rather than a hypothetical one.The device factor really is limited: FreeRDP's
/scale-deviceaccepts only 100, 140 or 180, and that mirrors the constraint ondeviceScaleFactorin the client core data. So it still has to be sent, and it still has to be approximated — the existing rounding logic is reused for that rather than deleted. AtRDP_SCALE=125the result is desktop 125, device 140: deliberately mismatched, and better than rounding both to 140.The removed notification
#148 added a
notify-sendwarning that the value was unsupported. That warning is now wrong: the desktop value is honoured exactly, and only the device value is approximated. SincewaFixScaleruns fromwaLoadConfig, it also fired on every launch to report something the user could not act on. Replaced with a debug message that says only the device value was approximated.Validation
The old rounding incidentally sanitised
RDP_SCALE. Passing the value through raw means a non-integer or an out-of-range number reaches/scale-desktop, which rejects the command — surfacing as a launch that silently does nothing.So the value is now validated: a non-integer is fatal, and a value outside 100–500 is clamped with a warning rather than rejected, so an existing misconfigured setup keeps working instead of breaking.
Related to #825, which asks for automatic per-monitor detection. This does not implement that, but it removes the rounding that would have discarded a detected fractional value.
Testing
Against Windows 11 Pro, FreeRDP 3.30.0, X11.
Windows honours non-standard
desktopScaleFactor. Measured with a fixed-size dialog (winver) as a RemoteApp,/scale-deviceheld at 100, reading the server-reported window geometry:/scale-desktopWidth scales exactly (460 → 575 → 691). Height carries a constant ~31px of window chrome; once that is accounted for, both axes predict the 150% point within 2px.
Full-desktop mode confirmed separately via a DPI-aware probe in the guest: 96 / 120 / 144 DPI at 100 / 125 / 150.
Also exercised: 125 → desktop 125, device 140; 600 → clamped to 500, device 180; 250 → desktop 250, device 180; a non-integer → fatal in both
bin/winappsandsetup.sh. A Store app was launched at mismatched factors. All four call sites inbin/winappsand both insetup.shwere run.pre-commit runpasses on all changed files.Not tested: the Wayland path.
bin/winappsselectssdl-freerdp3for the full desktop session on Wayland, and this was tested on X11 only.AI Assistance Disclosure
This change was mostly written by Claude Opus 5 under my supervision. Every change was reviewed before it was committed, and the test results are real runs against my own Windows 11 VM.