diff --git a/static/client.html b/static/client.html
index d5f7166..37f2924 100644
--- a/static/client.html
+++ b/static/client.html
@@ -1859,12 +1859,46 @@
if (document.hidden) keyboard.reset();
});
- // Mouse input
+ // Mouse input. Pointer positions come in screen pixels of the
+ // display element; sendMouseState divides out the uniform display
+ // scale, and the fill factors from scaleDisplay() are divided out
+ // here, since they are a transform the display knows nothing about.
+ var fillX = 1, fillY = 1;
var mouse = new Guacamole.Mouse(client.getDisplay().getElement());
mouse.onEach(['mousedown', 'mousemove', 'mouseup'], function(e) {
- client.sendMouseState(e.state, true);
+ var state = e.state;
+ if (fillX !== 1 || fillY !== 1) {
+ state = new Guacamole.Mouse.State(state);
+ state.x /= fillX;
+ state.y /= fillY;
+ }
+ client.sendMouseState(state, true);
});
+ // Absorb a small shortfall between the framebuffer and the
+ // viewport. The uniform fit in scaleDisplay() makes one axis match
+ // exactly and leaves the other short when the server could not
+ // honour the requested size: Windows RDP without GFX rounds the
+ // width down to a multiple of 16, so a 1710-wide window gets a
+ // 1696-wide desktop and a 14px strip of bare page down the right
+ // edge (#251). A stretch of that last percent or two is invisible;
+ // the strip is not. A larger gap is a real aspect mismatch (fixed
+ // resolution, no resize support) and keeps the letterbox.
+ var FILL_MAX = 1.025;
+ function applyFill(el, w, h, availW, availH) {
+ fillX = 1;
+ fillY = 1;
+ if (w > 0 && w < availW && availW / w <= FILL_MAX) fillX = availW / w;
+ if (h > 0 && h < availH && availH / h <= FILL_MAX) fillY = availH / h;
+ if (fillX !== 1 || fillY !== 1) {
+ el.style.transformOrigin = '0 0';
+ el.style.transform = 'scale(' + fillX + ', ' + fillY + ')';
+ } else {
+ el.style.transformOrigin = '';
+ el.style.transform = '';
+ }
+ }
+
// Show the remote pointer image as the browser's own pointer, and
// only fall back to the display's software cursor layer where CSS
// cursors are unsupported. Guacamole.Display puts that layer in
@@ -1942,10 +1976,12 @@
// Monitor 0 is at combined (0,0); no negative offset needed.
el.style.marginLeft = '0';
el.style.marginTop = '0';
+ applyFill(el, 0, 0, 0, 0);
}
else {
// Single display: scale the whole framebuffer to fit.
display.scale(Math.min(availW / dw, availH / dh));
+ applyFill(el, dw * display.getScale(), dh * display.getScale(), availW, availH);
displayEl.style.overflow = '';
displayEl.style.position = '';
displayEl.style.width = '';