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 140607eebf2fd4c44e703e90707f772e52e4ad94..cae7f5fd7766661f4413aa0fb3cc6a1a85a86924 100644 |
--- a/remoting/webapp/crd/js/desktop_connected_view.js |
+++ b/remoting/webapp/crd/js/desktop_connected_view.js |
@@ -27,9 +27,7 @@ remoting.enableMouseLock = false; |
/** |
* @param {remoting.ClientSession} session |
* @param {HTMLElement} container |
- * @param {string} hostDisplayName A human-readable name for the host. |
- * @param {string} hostId The host identifier for Me2Me, or empty for IT2Me. |
- * Mixed into authentication hashes for some authentication methods. |
+ * @param {remoting.Host} host |
* @param {remoting.DesktopConnectedView.Mode} mode The mode of this connection. |
* @param {string} defaultRemapKeys The default set of remap keys, to use |
* when the client doesn't define any. |
@@ -37,9 +35,8 @@ remoting.enableMouseLock = false; |
* @constructor |
* @extends {base.EventSourceImpl} |
*/ |
-remoting.DesktopConnectedView = function(session, container, hostDisplayName, |
- hostId, mode, defaultRemapKeys, |
- onInitialized) { |
+remoting.DesktopConnectedView = function(session, container, host, mode, |
+ defaultRemapKeys, onInitialized) { |
this.session_ = session; |
/** @type {HTMLElement} @private */ |
@@ -49,23 +46,11 @@ remoting.DesktopConnectedView = function(session, container, hostDisplayName, |
this.plugin_ = null; |
/** @private */ |
- this.hostDisplayName_ = hostDisplayName; |
- |
- /** @private */ |
- this.hostId_ = hostId; |
+ this.host_ = host; |
/** @private */ |
this.mode_ = mode; |
- /** @type {boolean} @private */ |
- this.shrinkToFit_ = true; |
- |
- /** @type {boolean} @private */ |
- this.resizeToClient_ = true; |
- |
- /** @type {number} @private */ |
- this.desktopScale_ = 1.0; |
- |
/** @type {string} @private */ |
this.defaultRemapKeys_ = defaultRemapKeys; |
@@ -86,13 +71,13 @@ remoting.DesktopConnectedView = function(session, container, hostDisplayName, |
/** @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 */ |
@@ -101,29 +86,12 @@ remoting.DesktopConnectedView = function(session, container, hostDisplayName, |
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; |
}; |
base.extend(remoting.DesktopConnectedView, base.EventSourceImpl); |
-/** @enum {string} */ |
-remoting.DesktopConnectedView.Events = { |
- bumpScrollStarted: 'bumpScrollStarted', |
- bumpScrollStopped: 'bumpScrollStopped' |
-}; |
- |
// The mode of this session. |
/** @enum {number} */ |
remoting.DesktopConnectedView.Mode = { |
@@ -144,7 +112,7 @@ remoting.DesktopConnectedView.KEY_DESKTOP_SCALE = 'desktopScale'; |
* @return {string} |
*/ |
remoting.DesktopConnectedView.prototype.getHostDisplayName = function() { |
- return this.hostDisplayName_; |
+ return this.host_.hostName; |
}; |
/** |
@@ -158,33 +126,26 @@ remoting.DesktopConnectedView.prototype.getMode = function() { |
* @return {boolean} True if shrink-to-fit is enabled; false otherwise. |
*/ |
remoting.DesktopConnectedView.prototype.getShrinkToFit = function() { |
- return this.shrinkToFit_; |
+ if (this.viewport_) { |
+ return this.viewport_.getShrinkToFit(); |
+ } |
}; |
/** |
* @return {boolean} True if resize-to-client is enabled; false otherwise. |
*/ |
remoting.DesktopConnectedView.prototype.getResizeToClient = function() { |
- return this.resizeToClient_; |
+ if (this.viewport_) { |
+ return this.viewport_.getResizeToClient(); |
+ } |
}; |
/** |
* @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'); |
}; |
/** |
@@ -193,10 +154,14 @@ remoting.DesktopConnectedView.prototype.getClientArea_ = function() { |
* TODO: private |
*/ |
remoting.DesktopConnectedView.prototype.notifyClientResolution_ = function() { |
- var clientArea = this.getClientArea_(); |
- this.plugin_.notifyClientResolution(clientArea.width * this.desktopScale_, |
- clientArea.height * this.desktopScale_, |
- window.devicePixelRatio); |
+ if (this.viewport_) { |
+ this.viewport_.resizeHostDesktop(); |
+ } |
+}; |
+ |
+/** @return {remoting.DesktopViewport} */ |
+remoting.DesktopConnectedView.prototype.getViewportForTesting = function() { |
+ return this.viewport_; |
}; |
/** |
@@ -205,52 +170,18 @@ remoting.DesktopConnectedView.prototype.notifyClientResolution_ = function() { |
* @param {function(string, string):boolean} onExtensionMessage The handler for |
* protocol extension messages. Returns true if a message is recognized; |
* false otherwise. |
- * @param {Array<string>} requiredCapabilities A list of capabilities |
+ * @param {Array.<string>} requiredCapabilities A list of capabilities |
* required by this application. |
*/ |
remoting.DesktopConnectedView.prototype.createPluginAndConnect = |
function(onExtensionMessage, requiredCapabilities) { |
this.plugin_ = remoting.ClientPlugin.factory.createPlugin( |
- this.getPluginContainer(), |
+ this.getPluginContainer_(), |
onExtensionMessage, requiredCapabilities); |
- remoting.HostSettings.load(this.hostId_, |
- this.onHostSettingsLoaded_.bind(this)); |
-}; |
- |
-/** |
- * @param {Object<string|boolean|number>} options The current options for the |
- * host, or {} if this client has no saved settings for the host. |
- * @private |
- */ |
-remoting.DesktopConnectedView.prototype.onHostSettingsLoaded_ = function( |
- options) { |
- if (remoting.DesktopConnectedView.KEY_REMAP_KEYS in options && |
- typeof(options[remoting.DesktopConnectedView.KEY_REMAP_KEYS]) == |
- 'string') { |
- this.remapKeys_ = /** @type {string} */ |
- (options[remoting.DesktopConnectedView.KEY_REMAP_KEYS]); |
- } |
- if (remoting.DesktopConnectedView.KEY_RESIZE_TO_CLIENT in options && |
- typeof(options[remoting.DesktopConnectedView.KEY_RESIZE_TO_CLIENT]) == |
- 'boolean') { |
- this.resizeToClient_ = /** @type {boolean} */ |
- (options[remoting.DesktopConnectedView.KEY_RESIZE_TO_CLIENT]); |
- } |
- if (remoting.DesktopConnectedView.KEY_SHRINK_TO_FIT in options && |
- typeof(options[remoting.DesktopConnectedView.KEY_SHRINK_TO_FIT]) == |
- 'boolean') { |
- this.shrinkToFit_ = /** @type {boolean} */ |
- (options[remoting.DesktopConnectedView.KEY_SHRINK_TO_FIT]); |
- } |
- if (remoting.DesktopConnectedView.KEY_DESKTOP_SCALE in options && |
- typeof(options[remoting.DesktopConnectedView.KEY_DESKTOP_SCALE]) == |
- 'number') { |
- this.desktopScale_ = /** @type {number} */ |
- (options[remoting.DesktopConnectedView.KEY_DESKTOP_SCALE]); |
- } |
- |
- /** @param {boolean} result */ |
- this.plugin_.initialize(this.onPluginInitialized_.bind(this)); |
+ var that = this; |
+ this.host_.options().load().then(function(){ |
+ that.plugin_.initialize(that.onPluginInitialized_.bind(that)); |
+ }); |
}; |
/** |
@@ -293,89 +224,20 @@ remoting.DesktopConnectedView.prototype.onPluginInitialized_ = function( |
this.plugin_.allowMouseLock(); |
} |
- this.plugin_.setDesktopShapeUpdateHandler( |
- this.onDesktopShapeChanged_.bind(this)); |
- this.plugin_.setDesktopSizeUpdateHandler( |
- this.onDesktopSizeChanged_.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() { |
- console.log('desktop size changed: ' + |
- this.plugin_.getDesktopWidth() + 'x' + |
- this.plugin_.getDesktopHeight() +' @ ' + |
- this.plugin_.getDesktopXDpi() + 'x' + |
- this.plugin_.getDesktopYDpi() + ' 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; |
+ if (this.viewport_) { |
+ this.viewport_.onResize(); |
} |
- |
- // Defer notifying the host of the change until the window stops resizing, to |
- // avoid overloading the control channel with notifications. |
- if (this.resizeToClient_) { |
- var kResizeRateLimitMs = 1000; |
- if (this.session_.hasCapability( |
- remoting.ClientSession.Capability.RATE_LIMIT_RESIZE_REQUESTS)) { |
- kResizeRateLimitMs = 250; |
- } |
- var clientArea = this.getClientArea_(); |
- this.notifyClientResolutionTimer_ = window.setTimeout( |
- this.notifyClientResolution_.bind(this), |
- kResizeRateLimitMs); |
- } |
- |
- // If bump-scrolling is enabled, adjust the plugin margins to fully utilize |
- // the new window area. |
- this.resetScroll_(); |
- |
- this.updateScrollbarVisibility(); |
}; |
/** |
@@ -435,7 +297,13 @@ remoting.DesktopConnectedView.prototype.updateClientSessionUi_ = function( |
// Stop listening for full-screen events. |
remoting.fullscreen.removeListener(this.callOnFullScreenChanged_); |
+ base.dispose(this.viewport_); |
+ this.viewport_ = null; |
} else { |
+ this.viewport_ = new remoting.DesktopViewport( |
+ document.getElementById('scroller'), |
+ this.plugin_.hostDesktop(), |
+ this.host_.options()); |
if (remoting.windowFrame) { |
remoting.windowFrame.setDesktopConnectedView(this); |
} |
@@ -446,33 +314,16 @@ remoting.DesktopConnectedView.prototype.updateClientSessionUi_ = function( |
remoting.optionsMenu.setDesktopConnectedView(this); |
} |
- if (this.resizeToClient_) { |
- 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 |
*/ |
@@ -499,51 +350,7 @@ remoting.DesktopConnectedView.prototype.setFocusHandlers_ = function() { |
*/ |
remoting.DesktopConnectedView.prototype.setScreenMode = |
function(shrinkToFit, resizeToClient) { |
- if (resizeToClient && !this.resizeToClient_) { |
- this.notifyClientResolution_(); |
- } |
- |
- // If enabling shrink, reset bump-scroll offsets. |
- var needsScrollReset = shrinkToFit && !this.shrinkToFit_; |
- |
- this.shrinkToFit_ = shrinkToFit; |
- this.resizeToClient_ = resizeToClient; |
- this.updateScrollbarVisibility(); |
- |
- if (this.hostId_ != '') { |
- var options = {}; |
- options[remoting.DesktopConnectedView.KEY_SHRINK_TO_FIT] = |
- this.shrinkToFit_; |
- options[remoting.DesktopConnectedView.KEY_RESIZE_TO_CLIENT] = |
- this.resizeToClient_; |
- remoting.HostSettings.save(this.hostId_, options); |
- } |
- |
- 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.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. |
- var options = {}; |
- options[remoting.DesktopConnectedView.KEY_DESKTOP_SCALE] = this.desktopScale_; |
- remoting.HostSettings.save(this.hostId_, options); |
+ this.viewport_.setScreenMode(shrinkToFit, resizeToClient); |
}; |
/** |
@@ -556,7 +363,9 @@ remoting.DesktopConnectedView.prototype.setDesktopScale = function( |
*/ |
remoting.DesktopConnectedView.prototype.onFullScreenChanged_ = function ( |
fullscreen) { |
- this.enableBumpScroll_(fullscreen); |
+ if (this.viewport_) { |
+ this.viewport_.enableBumpScroll(fullscreen); |
+ } |
}; |
/** |
@@ -599,342 +408,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() { |
- if (this.plugin_.getDesktopWidth() == 0 || |
- this.plugin_.getDesktopHeight() == 0) { |
- return; |
- } |
- |
- var desktopSize = { width: this.plugin_.getDesktopWidth(), |
- height: this.plugin_.getDesktopHeight() }; |
- var desktopDpi = { x: this.plugin_.getDesktopXDpi(), |
- y: this.plugin_.getDesktopYDpi() }; |
- var newSize = remoting.DesktopConnectedView.choosePluginSize( |
- this.getClientArea_(), window.devicePixelRatio, |
- desktopSize, desktopDpi, this.desktopScale_, |
- remoting.fullscreen.isActive(), this.shrinkToFit_); |
- |
- // 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.shrinkToFit_) { |
- // Determine whether or not horizontal or vertical scrollbars are |
- // required, taking into account their width. |
- var clientArea = this.getClientArea_(); |
- needsVerticalScroll = clientArea.height < this.plugin_.getDesktopHeight(); |
- needsHorizontalScroll = clientArea.width < this.plugin_.getDesktopWidth(); |
- var kScrollBarWidth = 16; |
- if (needsHorizontalScroll && !needsVerticalScroll) { |
- needsVerticalScroll = |
- clientArea.height - kScrollBarWidth < this.plugin_.getDesktopHeight(); |
- } else if (!needsHorizontalScroll && needsVerticalScroll) { |
- needsHorizontalScroll = |
- clientArea.width - kScrollBarWidth < this.plugin_.getDesktopWidth(); |
- } |
- } |
- |
- 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. |
@@ -946,9 +419,8 @@ remoting.DesktopConnectedView.prototype.setRemapKeys = function(remappings) { |
this.applyRemapKeys_(true); |
// Save the new remapping setting. |
- var options = {}; |
- options[remoting.DesktopConnectedView.KEY_REMAP_KEYS] = this.remapKeys_; |
- remoting.HostSettings.save(this.hostId_, options); |
+ this.host_.options().remapKeys = this.remapKeys_; |
+ this.host_.options().save(); |
}; |
/** |