desktop: restore scaleViewport — disabling it doubled every pointer coordinate
Reverts the scaleViewport=false half of 69c750d. That change was wrong and it caused a worse bug than
the one it was aimed at.
noVNC maps a click as (clientX - canvasRect.left) / display._scale. autoscale(), which only runs when
scaleViewport is enabled, sets the canvas's displayed size and _scale in the same call, so the two are
consistent by construction. With scaleViewport off, _scale is pinned at 1 while the canvas continues to
be displayed at some other size and nothing reconciles them.
Measured on the owner's session against a 1109x715 desktop: pointing a quarter of the way across
registered at x=575 (51%), and pointing at the middle saturated at x=1108, the right-hand edge. A clean
factor of two in both axes. Clicks near the right and bottom edges still appeared to work, because
doubling an already-large coordinate clamps back onto the edge it was aimed at — which is why the
panel clock and the dock stayed clickable while the middle of the screen did not.
My reasoning for the original change — that resizeSession and scaleViewport are alternatives — was
simply wrong. They are complementary: resize matches the session to the container, scaling covers the
interval before the server honours it, and scaling is also what keeps the coordinate maths honest.
showDotCursor stays: the invisible pointer was a real and separate defect.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -140,14 +140,18 @@ export const DesktopView = ({ className, style }: DesktopViewProps) => {
|
||||
credentials: { password },
|
||||
});
|
||||
|
||||
// resizeSession WITHOUT scaleViewport. They are alternatives, not complements: resizeSession asks
|
||||
// the server to become the container's size, scaleViewport scales whatever the server sends to fit.
|
||||
// Xvnc implements RandR SetDesktopSize, so the session really does become the container size and
|
||||
// there is nothing left to scale. With both enabled any gap between the size requested and the size
|
||||
// granted leaves a fractional scale that pointer coordinates are mapped through — which is how the
|
||||
// cursor ended up offset from where you clicked. One strategy, 1:1 pixels, no coordinate maths.
|
||||
// BOTH. They are not alternatives — scaling is the fallback that covers the gap between resize
|
||||
// events, and more importantly it is what keeps the coordinate maths self-consistent.
|
||||
//
|
||||
// noVNC maps a click as (clientX - canvasRect.left) / display._scale. Only scaleViewport's
|
||||
// autoscale() sets the canvas's displayed size and _scale TOGETHER, so the two cannot disagree.
|
||||
// Turning it off pins _scale at 1 while the canvas keeps being displayed at some other size, and
|
||||
// nothing reconciles them: measured here, pointing a quarter of the way across the desktop landed
|
||||
// at 51%, and pointing at the middle saturated at the right-hand edge. A clean factor of two.
|
||||
// Clicks near the right and bottom edges still appeared to work, because doubling an already-large
|
||||
// coordinate clamps back onto the edge it was aimed at.
|
||||
rfb.resizeSession = true;
|
||||
rfb.scaleViewport = false;
|
||||
rfb.scaleViewport = true;
|
||||
rfb.focusOnClick = true;
|
||||
// noVNC hides the browser's own cursor over the canvas and draws the REMOTE cursor in its place.
|
||||
// Until the server sends a cursor shape its image is RFB.cursors.none — so nothing is drawn, the
|
||||
|
||||
Reference in New Issue
Block a user