Index: remoting/webapp/crd/js/desktop_connected_view.js |
diff --git a/remoting/webapp/crd/js/desktop_connected_view.js b/remoting/webapp/crd/js/desktop_connected_view.js |
index e4ce2acb0dab98ad18634aca4358d2bf88b58172..8b7fd8b3afc14430f7e641f3a336e6bedea35e89 100644 |
--- a/remoting/webapp/crd/js/desktop_connected_view.js |
+++ b/remoting/webapp/crd/js/desktop_connected_view.js |
@@ -67,14 +67,13 @@ remoting.DesktopConnectedView = function(session, container, host, mode, |
this.callPluginLostFocus_ = this.pluginLostFocus_.bind(this); |
/** @private */ |
this.callPluginGotFocus_ = this.pluginGotFocus_.bind(this); |
- |
- /** @type {number?} @private */ |
- this.notifyClientResolutionTimer_ = null; |
- |
/** @type {Element} @private */ |
this.mouseCursorOverlay_ = |
this.container_.querySelector('.mouse-cursor-overlay'); |
+ /** @private {remoting.DesktopViewport} */ |
+ this.viewport_ = null; |
+ |
/** @type {Element} */ |
var img = this.mouseCursorOverlay_; |
/** @param {Event} event @private */ |
@@ -83,32 +82,8 @@ remoting.DesktopConnectedView = function(session, container, host, mode, |
img.style.left = event.x + 'px'; |
}; |
- /** @type {number?} @private */ |
- this.bumpScrollTimer_ = null; |
- |
- // Bump-scroll test variables. Override to use a fake value for the width |
- // and height of the client plugin so that bump-scrolling can be tested |
- // without relying on the actual size of the host desktop. |
- /** @type {number} @private */ |
- this.pluginWidthForBumpScrollTesting_ = 0; |
- /** @type {number} @private */ |
- this.pluginHeightForBumpScrollTesting_ = 0; |
- |
/** @type {remoting.VideoFrameRecorder} @private */ |
this.videoFrameRecorder_ = null; |
- |
- /** @private {base.Disposables} */ |
- this.eventHooks_ = null; |
- |
- this.defineEvents(base.values(remoting.DesktopConnectedView.Events)); |
-}; |
- |
-base.extend(remoting.DesktopConnectedView, base.EventSourceImpl); |
- |
-/** @enum {string} */ |
-remoting.DesktopConnectedView.Events = { |
- bumpScrollStarted: 'bumpScrollStarted', |
- bumpScrollStopped: 'bumpScrollStopped' |
}; |
// The mode of this session. |
@@ -145,56 +120,33 @@ remoting.DesktopConnectedView.prototype.getMode = function() { |
* @return {boolean} True if shrink-to-fit is enabled; false otherwise. |
*/ |
remoting.DesktopConnectedView.prototype.getShrinkToFit = function() { |
- return this.host_.options.shrinkToFit; |
+ if (this.viewport_) { |
+ return this.viewport_.getShrinkToFit(); |
+ } |
+ return false; |
}; |
/** |
* @return {boolean} True if resize-to-client is enabled; false otherwise. |
*/ |
remoting.DesktopConnectedView.prototype.getResizeToClient = function() { |
- return this.host_.options.resizeToClient; |
+ if (this.viewport_) { |
+ return this.viewport_.getResizeToClient(); |
+ } |
+ return false; |
}; |
/** |
* @return {Element} The element that should host the plugin. |
+ * @private |
*/ |
-remoting.DesktopConnectedView.prototype.getPluginContainer = function() { |
- return this.container_.querySelector('.client-plugin-container') |
-}; |
- |
-/** |
- * @return {{width: number, height: number}} The height of the window's client |
- * area. This differs between apps v1 and apps v2 due to the custom window |
- * borders used by the latter. |
- * TODO: make private |
- */ |
-remoting.DesktopConnectedView.prototype.getClientArea_ = function() { |
- return remoting.windowFrame ? |
- remoting.windowFrame.getClientArea() : |
- { 'width': window.innerWidth, 'height': window.innerHeight }; |
+remoting.DesktopConnectedView.prototype.getPluginContainer_ = function() { |
+ return this.container_.querySelector('.client-plugin-container'); |
}; |
-/** |
- * @param {number} width |
- * @param {number} height |
- */ |
-remoting.DesktopConnectedView.prototype.setPluginSizeForBumpScrollTesting = |
- function(width, height) { |
- this.pluginWidthForBumpScrollTesting_ = width; |
- this.pluginHeightForBumpScrollTesting_ = height; |
-} |
- |
-/** |
- * Notifies the host of the client's current dimensions and DPI. |
- * Also takes into account per-host scaling factor, if configured. |
- * TODO: private |
- */ |
-remoting.DesktopConnectedView.prototype.notifyClientResolution_ = function() { |
- var clientArea = this.getClientArea_(); |
- var desktopScale = this.host_.options.desktopScale; |
- this.plugin_.hostDesktop().resize(clientArea.width * desktopScale, |
- clientArea.height * desktopScale, |
- window.devicePixelRatio); |
+/** @return {remoting.DesktopViewport} */ |
+remoting.DesktopConnectedView.prototype.getViewportForTesting = function() { |
+ return this.viewport_; |
}; |
/** |
@@ -209,7 +161,7 @@ remoting.DesktopConnectedView.prototype.notifyClientResolution_ = function() { |
remoting.DesktopConnectedView.prototype.createPluginAndConnect = |
function(onExtensionMessage, requiredCapabilities) { |
this.plugin_ = remoting.ClientPlugin.factory.createPlugin( |
- this.getPluginContainer(), |
+ this.getPluginContainer_(), |
onExtensionMessage, requiredCapabilities); |
var that = this; |
this.host_.options.load().then(function(){ |
@@ -257,92 +209,20 @@ remoting.DesktopConnectedView.prototype.onPluginInitialized_ = function( |
this.plugin_.allowMouseLock(); |
} |
- base.dispose(this.eventHooks_); |
- var hostDesktop = this.plugin_.hostDesktop(); |
- this.eventHooks_ = new base.Disposables( |
- new base.EventHook( |
- hostDesktop, remoting.HostDesktop.Events.sizeChanged, |
- this.onDesktopSizeChanged_.bind(this)), |
- new base.EventHook( |
- hostDesktop, remoting.HostDesktop.Events.shapeChanged, |
- this.onDesktopShapeChanged_.bind(this))); |
- |
this.plugin_.setMouseCursorHandler(this.updateMouseCursorImage_.bind(this)); |
this.onInitialized_(remoting.Error.NONE, this.plugin_); |
}; |
/** |
- * This is a callback that gets called when the plugin notifies us of a change |
- * in the size of the remote desktop. |
- * |
- * @return {void} Nothing. |
- * @private |
- */ |
-remoting.DesktopConnectedView.prototype.onDesktopSizeChanged_ = function() { |
- var desktop = this.plugin_.hostDesktop().getDimensions(); |
- console.log('desktop size changed: ' + |
- desktop.width + 'x' + |
- desktop.height +' @ ' + |
- desktop.xDpi + 'x' + |
- desktop.yDpi + ' DPI'); |
- this.updateDimensions(); |
- this.updateScrollbarVisibility(); |
-}; |
- |
-/** |
- * Sets the non-click-through area of the client in response to notifications |
- * from the plugin of desktop shape changes. |
- * |
- * @param {Array<Array<number>>} rects List of rectangles comprising the |
- * desktop shape. |
- * @return {void} Nothing. |
- * @private |
- */ |
-remoting.DesktopConnectedView.prototype.onDesktopShapeChanged_ = function( |
- rects) { |
- // Build the list of rects for the input region. |
- var inputRegion = []; |
- for (var i = 0; i < rects.length; ++i) { |
- var rect = {}; |
- rect.left = rects[i][0]; |
- rect.top = rects[i][1]; |
- rect.width = rects[i][2]; |
- rect.height = rects[i][3]; |
- inputRegion.push(rect); |
- } |
- |
- remoting.windowShape.setDesktopRects(inputRegion); |
-}; |
- |
-/** |
* This is a callback that gets called when the window is resized. |
* |
* @return {void} Nothing. |
*/ |
remoting.DesktopConnectedView.prototype.onResize = function() { |
- this.updateDimensions(); |
- |
- if (this.notifyClientResolutionTimer_) { |
- window.clearTimeout(this.notifyClientResolutionTimer_); |
- this.notifyClientResolutionTimer_ = null; |
- } |
- |
- // Defer notifying the host of the change until the window stops resizing, to |
- // avoid overloading the control channel with notifications. |
- if (this.getResizeToClient()) { |
- var kResizeRateLimitMs = 250; |
- var clientArea = this.getClientArea_(); |
- this.notifyClientResolutionTimer_ = window.setTimeout( |
- this.notifyClientResolution_.bind(this), |
- kResizeRateLimitMs); |
+ if (this.viewport_) { |
+ this.viewport_.onResize(); |
} |
- |
- // If bump-scrolling is enabled, adjust the plugin margins to fully utilize |
- // the new window area. |
- this.resetScroll_(); |
- |
- this.updateScrollbarVisibility(); |
}; |
/** |
@@ -368,8 +248,6 @@ remoting.DesktopConnectedView.prototype.onConnectionReady = function(ready) { |
*/ |
remoting.DesktopConnectedView.prototype.removePlugin = function() { |
if (this.plugin_) { |
- base.dispose(this.eventHooks_); |
- this.eventHooks_ = null; |
this.plugin_.element().removeEventListener( |
'focus', this.callPluginGotFocus_, false); |
this.plugin_.element().removeEventListener( |
@@ -404,7 +282,14 @@ remoting.DesktopConnectedView.prototype.updateClientSessionUi_ = function( |
// Stop listening for full-screen events. |
remoting.fullscreen.removeListener(this.callOnFullScreenChanged_); |
+ base.dispose(this.viewport_); |
+ this.viewport_ = null; |
} else { |
+ var scrollerElement = document.getElementById('scroller'); |
+ this.viewport_ = new remoting.DesktopViewport( |
+ scrollerElement || document.body, |
+ this.plugin_.hostDesktop(), |
+ this.host_.options); |
if (remoting.windowFrame) { |
remoting.windowFrame.setDesktopConnectedView(this); |
} |
@@ -415,33 +300,16 @@ remoting.DesktopConnectedView.prototype.updateClientSessionUi_ = function( |
remoting.optionsMenu.setDesktopConnectedView(this); |
} |
- if (this.getResizeToClient()) { |
- this.notifyClientResolution_(); |
- } |
- |
document.body.classList.add('connected'); |
this.container_.addEventListener( |
'mousemove', this.updateMouseCursorPosition_, true); |
// Activate full-screen related UX. |
remoting.fullscreen.addListener(this.callOnFullScreenChanged_); |
- this.onDesktopSizeChanged_(); |
this.setFocusHandlers_(); |
} |
}; |
/** |
- * @return {{top: number, left:number}} The top-left corner of the plugin. |
- */ |
-remoting.DesktopConnectedView.prototype.getPluginPositionForTesting = function( |
- ) { |
- var style = this.container_.style; |
- return { |
- top: parseFloat(style.marginTop), |
- left: parseFloat(style.marginLeft) |
- }; |
-}; |
- |
-/** |
* Constrains the focus to the plugin element. |
* @private |
*/ |
@@ -468,41 +336,7 @@ remoting.DesktopConnectedView.prototype.setFocusHandlers_ = function() { |
*/ |
remoting.DesktopConnectedView.prototype.setScreenMode = |
function(shrinkToFit, resizeToClient) { |
- if (resizeToClient && !this.getResizeToClient()) { |
- this.notifyClientResolution_(); |
- } |
- |
- // If enabling shrink, reset bump-scroll offsets. |
- var needsScrollReset = shrinkToFit && !this.getShrinkToFit(); |
- |
- this.host_.options.shrinkToFit = shrinkToFit; |
- this.host_.options.resizeToClient = resizeToClient; |
- this.updateScrollbarVisibility(); |
- this.host_.options.save(); |
- |
- this.updateDimensions(); |
- if (needsScrollReset) { |
- this.resetScroll_(); |
- } |
-}; |
- |
-/** |
- * Sets and stores the scale factor to apply to host sizing requests. |
- * The desktopScale applies to the dimensions reported to the host, not |
- * to the client DPI reported to it. |
- * |
- * @param {number} desktopScale Scale factor to apply. |
- */ |
-remoting.DesktopConnectedView.prototype.setDesktopScale = function( |
- desktopScale) { |
- this.host_.options.desktopScale = desktopScale; |
- |
- // onResize() will update the plugin size and scrollbars for the new |
- // scaled plugin dimensions, and send a client resolution notification. |
- this.onResize(); |
- |
- // Save the new desktop scale setting. |
- this.host_.options.save(); |
+ this.viewport_.setScreenMode(shrinkToFit, resizeToClient); |
}; |
/** |
@@ -515,7 +349,9 @@ remoting.DesktopConnectedView.prototype.setDesktopScale = function( |
*/ |
remoting.DesktopConnectedView.prototype.onFullScreenChanged_ = function ( |
fullscreen) { |
- this.enableBumpScroll_(fullscreen); |
+ if (this.viewport_) { |
+ this.viewport_.enableBumpScroll(Boolean(fullscreen)); |
+ } |
}; |
/** |
@@ -558,343 +394,6 @@ remoting.DesktopConnectedView.prototype.updateMouseCursorImage_ = |
}; |
/** |
- * Enable or disable bump-scrolling. When disabling bump scrolling, also reset |
- * the scroll offsets to (0, 0). |
- * @param {boolean=} enable True to enable bump-scrolling, false to disable it. |
- * @private |
- */ |
-remoting.DesktopConnectedView.prototype.enableBumpScroll_ = function(enable) { |
- var element = /** @type{HTMLElement} */ (document.documentElement); |
- if (enable) { |
- /** @type {null|function(Event):void} */ |
- this.onMouseMoveRef_ = this.onMouseMove_.bind(this); |
- element.addEventListener('mousemove', this.onMouseMoveRef_, false); |
- } else { |
- element.removeEventListener('mousemove', this.onMouseMoveRef_, false); |
- this.onMouseMoveRef_ = null; |
- this.resetScroll_(); |
- } |
-}; |
- |
-remoting.DesktopConnectedView.prototype.resetScroll_ = function() { |
- this.container_.style.marginTop = '0px'; |
- this.container_.style.marginLeft = '0px'; |
-}; |
- |
-/** |
- * @param {Event} event The mouse event. |
- * @private |
- */ |
-remoting.DesktopConnectedView.prototype.onMouseMove_ = function(event) { |
- if (this.bumpScrollTimer_) { |
- window.clearTimeout(this.bumpScrollTimer_); |
- this.bumpScrollTimer_ = null; |
- } |
- |
- /** |
- * Compute the scroll speed based on how close the mouse is to the edge. |
- * @param {number} mousePos The mouse x- or y-coordinate |
- * @param {number} size The width or height of the content area. |
- * @return {number} The scroll delta, in pixels. |
- */ |
- var computeDelta = function(mousePos, size) { |
- var threshold = 10; |
- if (mousePos >= size - threshold) { |
- return 1 + 5 * (mousePos - (size - threshold)) / threshold; |
- } else if (mousePos <= threshold) { |
- return -1 - 5 * (threshold - mousePos) / threshold; |
- } |
- return 0; |
- }; |
- |
- var clientArea = this.getClientArea_(); |
- var dx = computeDelta(event.x, clientArea.width); |
- var dy = computeDelta(event.y, clientArea.height); |
- |
- if (dx != 0 || dy != 0) { |
- this.raiseEvent(remoting.DesktopConnectedView.Events.bumpScrollStarted); |
- /** @type {remoting.DesktopConnectedView} */ |
- var that = this; |
- /** |
- * Scroll the view, and schedule a timer to do so again unless we've hit |
- * the edges of the screen. This timer is cancelled when the mouse moves. |
- * @param {number} expected The time at which we expect to be called. |
- */ |
- var repeatScroll = function(expected) { |
- /** @type {number} */ |
- var now = new Date().getTime(); |
- /** @type {number} */ |
- var timeout = 10; |
- var lateAdjustment = 1 + (now - expected) / timeout; |
- if (that.scroll_(lateAdjustment * dx, lateAdjustment * dy)) { |
- that.raiseEvent(remoting.DesktopConnectedView.Events.bumpScrollStopped); |
- } else { |
- that.bumpScrollTimer_ = window.setTimeout( |
- function() { repeatScroll(now + timeout); }, |
- timeout); |
- } |
- }; |
- repeatScroll(new Date().getTime()); |
- } |
-}; |
- |
-/** |
- * Scroll the client plugin by the specified amount, keeping it visible. |
- * Note that this is only used in content full-screen mode (not windowed or |
- * browser full-screen modes), where window.scrollBy and the scrollTop and |
- * scrollLeft properties don't work. |
- * @param {number} dx The amount by which to scroll horizontally. Positive to |
- * scroll right; negative to scroll left. |
- * @param {number} dy The amount by which to scroll vertically. Positive to |
- * scroll down; negative to scroll up. |
- * @return {boolean} True if the requested scroll had no effect because both |
- * vertical and horizontal edges of the screen have been reached. |
- * @private |
- */ |
-remoting.DesktopConnectedView.prototype.scroll_ = function(dx, dy) { |
- /** |
- * Helper function for x- and y-scrolling |
- * @param {number|string} curr The current margin, eg. "10px". |
- * @param {number} delta The requested scroll amount. |
- * @param {number} windowBound The size of the window, in pixels. |
- * @param {number} pluginBound The size of the plugin, in pixels. |
- * @param {{stop: boolean}} stop Reference parameter used to indicate when |
- * the scroll has reached one of the edges and can be stopped in that |
- * direction. |
- * @return {string} The new margin value. |
- */ |
- var adjustMargin = function(curr, delta, windowBound, pluginBound, stop) { |
- var minMargin = Math.min(0, windowBound - pluginBound); |
- var result = (curr ? parseFloat(curr) : 0) - delta; |
- result = Math.min(0, Math.max(minMargin, result)); |
- stop.stop = (result == 0 || result == minMargin); |
- return result + 'px'; |
- }; |
- |
- var plugin = this.plugin_.element(); |
- var style = this.container_.style; |
- |
- var stopX = { stop: false }; |
- var clientArea = this.getClientArea_(); |
- style.marginLeft = adjustMargin(style.marginLeft, dx, clientArea.width, |
- this.pluginWidthForBumpScrollTesting_ || plugin.clientWidth, stopX); |
- |
- var stopY = { stop: false }; |
- style.marginTop = adjustMargin( |
- style.marginTop, dy, clientArea.height, |
- this.pluginHeightForBumpScrollTesting_ || plugin.clientHeight, stopY); |
- return stopX.stop && stopY.stop; |
-}; |
- |
-/** |
- * Refreshes the plugin's dimensions, taking into account the sizes of the |
- * remote desktop and client window, and the current scale-to-fit setting. |
- * |
- * @return {void} Nothing. |
- */ |
-remoting.DesktopConnectedView.prototype.updateDimensions = function() { |
- var desktopSize = this.plugin_.hostDesktop().getDimensions(); |
- |
- if (desktopSize.width === 0 || |
- desktopSize.height === 0) { |
- return; |
- } |
- |
- var desktopDpi = { x: desktopSize.xDpi, |
- y: desktopSize.yDpi }; |
- var newSize = remoting.DesktopConnectedView.choosePluginSize( |
- this.getClientArea_(), window.devicePixelRatio, |
- desktopSize, desktopDpi, this.host_.options.desktopScale, |
- remoting.fullscreen.isActive(), this.getShrinkToFit()); |
- |
- // Resize the plugin if necessary. |
- console.log('plugin dimensions:' + newSize.width + 'x' + newSize.height); |
- this.plugin_.element().style.width = newSize.width + 'px'; |
- this.plugin_.element().style.height = newSize.height + 'px'; |
- |
- // When we receive the first plugin dimensions from the host, we know that |
- // remote host has started. |
- remoting.app.onVideoStreamingStarted(); |
-} |
- |
-/** |
- * Helper function accepting client and host dimensions, and returning a chosen |
- * size for the plugin element, in DIPs. |
- * |
- * @param {{width: number, height: number}} clientSizeDips Available client |
- * dimensions, in DIPs. |
- * @param {number} clientPixelRatio Number of physical pixels per client DIP. |
- * @param {{width: number, height: number}} desktopSize Size of the host desktop |
- * in physical pixels. |
- * @param {{x: number, y: number}} desktopDpi DPI of the host desktop in both |
- * dimensions. |
- * @param {number} desktopScale The scale factor configured for the host. |
- * @param {boolean} isFullscreen True if full-screen mode is active. |
- * @param {boolean} shrinkToFit True if shrink-to-fit should be applied. |
- * @return {{width: number, height: number}} Chosen plugin dimensions, in DIPs. |
- */ |
-remoting.DesktopConnectedView.choosePluginSize = function( |
- clientSizeDips, clientPixelRatio, desktopSize, desktopDpi, desktopScale, |
- isFullscreen, shrinkToFit) { |
- base.debug.assert(clientSizeDips.width > 0); |
- base.debug.assert(clientSizeDips.height > 0); |
- base.debug.assert(clientPixelRatio >= 1.0); |
- base.debug.assert(desktopSize.width > 0); |
- base.debug.assert(desktopSize.height > 0); |
- base.debug.assert(desktopDpi.x > 0); |
- base.debug.assert(desktopDpi.y > 0); |
- base.debug.assert(desktopScale > 0); |
- |
- // We have the following goals in sizing the desktop display at the client: |
- // 1. Avoid losing detail by down-scaling beyond 1:1 host:device pixels. |
- // 2. Avoid up-scaling if that will cause the client to need scrollbars. |
- // 3. Avoid introducing blurriness with non-integer up-scaling factors. |
- // 4. Avoid having huge "letterboxes" around the desktop, if it's really |
- // small. |
- // 5. Compensate for mismatched DPIs, so that the behaviour of features like |
- // shrink-to-fit matches their "natural" rather than their pixel size. |
- // e.g. with shrink-to-fit active a 1024x768 low-DPI host on a 640x480 |
- // high-DPI client will be up-scaled to 1280x960, rather than displayed |
- // at 1:1 host:physical client pixels. |
- // |
- // To determine the ideal size we follow a four-stage process: |
- // 1. Determine the "natural" size at which to display the desktop. |
- // a. Initially assume 1:1 mapping of desktop to client device pixels. |
- // b. If host DPI is less than the client's then up-scale accordingly. |
- // c. If desktopScale is configured for the host then allow that to |
- // reduce the amount of up-scaling from (b). e.g. if the client:host |
- // DPIs are 2:1 then a desktopScale of 1.5 would reduce the up-scale |
- // to 4:3, while a desktopScale of 3.0 would result in no up-scaling. |
- // 2. If the natural size of the desktop is smaller than the client device |
- // then apply up-scaling by an integer scale factor to avoid excessive |
- // letterboxing. |
- // 3. If shrink-to-fit is configured then: |
- // a. If the natural size exceeds the client size then apply down-scaling |
- // by an arbitrary scale factor. |
- // b. If we're in full-screen mode and the client & host aspect-ratios |
- // are radically different (e.g. the host is actually multi-monitor) |
- // then shrink-to-fit to the shorter dimension, rather than leaving |
- // huge letterboxes; the user can then bump-scroll around the desktop. |
- // 4. If the overall scale factor is fractionally over an integer factor |
- // then reduce it to that integer factor, to avoid blurring. |
- |
- // All calculations are performed in device pixels. |
- var clientWidth = clientSizeDips.width * clientPixelRatio; |
- var clientHeight = clientSizeDips.height * clientPixelRatio; |
- |
- // 1. Determine a "natural" size at which to display the desktop. |
- var scale = 1.0; |
- |
- // Determine the effective host device pixel ratio. |
- // Note that we round up or down to the closest integer pixel ratio. |
- var hostPixelRatioX = Math.round(desktopDpi.x / 96); |
- var hostPixelRatioY = Math.round(desktopDpi.y / 96); |
- var hostPixelRatio = Math.min(hostPixelRatioX, hostPixelRatioY); |
- |
- // Allow up-scaling to account for DPI. |
- scale = Math.max(scale, clientPixelRatio / hostPixelRatio); |
- |
- // Allow some or all of the up-scaling to be cancelled by the desktopScale. |
- if (desktopScale > 1.0) { |
- scale = Math.max(1.0, scale / desktopScale); |
- } |
- |
- // 2. If the host is still much smaller than the client, then up-scale to |
- // avoid wasting space, but only by an integer factor, to avoid blurring. |
- if (desktopSize.width * scale <= clientWidth && |
- desktopSize.height * scale <= clientHeight) { |
- var scaleX = Math.floor(clientWidth / desktopSize.width); |
- var scaleY = Math.floor(clientHeight / desktopSize.height); |
- scale = Math.min(scaleX, scaleY); |
- base.debug.assert(scale >= 1.0); |
- } |
- |
- // 3. Apply shrink-to-fit, if configured. |
- if (shrinkToFit) { |
- var scaleFitWidth = Math.min(scale, clientWidth / desktopSize.width); |
- var scaleFitHeight = Math.min(scale, clientHeight / desktopSize.height); |
- scale = Math.min(scaleFitHeight, scaleFitWidth); |
- |
- // If we're running full-screen then try to handle common side-by-side |
- // multi-monitor combinations more intelligently. |
- if (isFullscreen) { |
- // If the host has two monitors each the same size as the client then |
- // scale-to-fit will have the desktop occupy only 50% of the client area, |
- // in which case it would be preferable to down-scale less and let the |
- // user bump-scroll around ("scale-and-pan"). |
- // Triggering scale-and-pan if less than 65% of the client area would be |
- // used adds enough fuzz to cope with e.g. 1280x800 client connecting to |
- // a (2x1280)x1024 host nicely. |
- // Note that we don't need to account for scrollbars while fullscreen. |
- if (scale <= scaleFitHeight * 0.65) { |
- scale = scaleFitHeight; |
- } |
- if (scale <= scaleFitWidth * 0.65) { |
- scale = scaleFitWidth; |
- } |
- } |
- } |
- |
- // 4. Avoid blurring for close-to-integer up-scaling factors. |
- if (scale > 1.0) { |
- var scaleBlurriness = scale / Math.floor(scale); |
- if (scaleBlurriness < 1.1) { |
- scale = Math.floor(scale); |
- } |
- } |
- |
- // Return the necessary plugin dimensions in DIPs. |
- scale = scale / clientPixelRatio; |
- var pluginWidth = Math.round(desktopSize.width * scale); |
- var pluginHeight = Math.round(desktopSize.height * scale); |
- return { width: pluginWidth, height: pluginHeight }; |
-} |
- |
-/** |
- * Called when the window or desktop size or the scaling settings change, |
- * to set the scroll-bar visibility. |
- * |
- * TODO(jamiewalch): crbug.com/252796: Remove this once crbug.com/240772 is |
- * fixed. |
- */ |
-remoting.DesktopConnectedView.prototype.updateScrollbarVisibility = function() { |
- var scroller = document.getElementById('scroller'); |
- if (!scroller) { |
- return; |
- } |
- |
- var needsVerticalScroll = false; |
- var needsHorizontalScroll = false; |
- if (!this.getShrinkToFit()) { |
- // Determine whether or not horizontal or vertical scrollbars are |
- // required, taking into account their width. |
- var clientArea = this.getClientArea_(); |
- var desktopSize = this.plugin_.hostDesktop().getDimensions(); |
- needsVerticalScroll = clientArea.height < desktopSize.height; |
- needsHorizontalScroll = clientArea.width < desktopSize.width; |
- var kScrollBarWidth = 16; |
- if (needsHorizontalScroll && !needsVerticalScroll) { |
- needsVerticalScroll = |
- clientArea.height - kScrollBarWidth < desktopSize.height; |
- } else if (!needsHorizontalScroll && needsVerticalScroll) { |
- needsHorizontalScroll = |
- clientArea.width - kScrollBarWidth < desktopSize.width; |
- } |
- } |
- |
- if (needsHorizontalScroll) { |
- scroller.classList.remove('no-horizontal-scroll'); |
- } else { |
- scroller.classList.add('no-horizontal-scroll'); |
- } |
- if (needsVerticalScroll) { |
- scroller.classList.remove('no-vertical-scroll'); |
- } else { |
- scroller.classList.add('no-vertical-scroll'); |
- } |
-}; |
- |
-/** |
* Sets and stores the key remapping setting for the current host. |
* |
* @param {string} remappings Comma separated list of key remappings. |