diff options
author | jamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-17 01:54:39 +0000 |
---|---|---|
committer | jamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-17 01:54:39 +0000 |
commit | 7caa553c7857652e2fe13b9beeed38958275c83e (patch) | |
tree | 1febf0c4dcd10c9a5f2271afa1dd0a4fb782c5b8 /remoting | |
parent | edd55cb2839886784859c5b3088b36eefb9f111e (diff) | |
download | chromium_src-7caa553c7857652e2fe13b9beeed38958275c83e.zip chromium_src-7caa553c7857652e2fe13b9beeed38958275c83e.tar.gz chromium_src-7caa553c7857652e2fe13b9beeed38958275c83e.tar.bz2 |
Allow resize-to-client to be enabled by the user.
Off by default (on all platforms) but saved between connections.
BUG=157254
Review URL: https://chromiumcodereview.appspot.com/11886007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@177306 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/host/remoting_me2me_host.cc | 5 | ||||
-rw-r--r-- | remoting/remoting.gyp | 1 | ||||
-rw-r--r-- | remoting/resources/remoting_strings.grd | 6 | ||||
-rw-r--r-- | remoting/webapp/client_plugin.js | 1 | ||||
-rw-r--r-- | remoting/webapp/client_screen.js | 9 | ||||
-rw-r--r-- | remoting/webapp/client_session.js | 192 | ||||
-rw-r--r-- | remoting/webapp/host_settings.js | 99 | ||||
-rw-r--r-- | remoting/webapp/main.html | 8 |
8 files changed, 243 insertions, 78 deletions
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index 741a1d2..67b1045 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -909,13 +909,8 @@ void HostProcess::StartHost() { new LogToServer(host_, ServerLogEntry::ME2ME, signal_strategy_.get())); host_event_logger_ = HostEventLogger::Create(host_, kApplicationName); -#if defined(OS_LINUX) - // Desktop resizing is implemented on all three platforms, but may not be - // the right thing to do for non-virtual desktops. Disable it until we can - // implement a configuration UI. resizing_host_observer_.reset( new ResizingHostObserver(desktop_resizer_.get(), host_)); -#endif // Create a host observer to enable/disable curtain mode as clients connect // and disconnect. diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 902fb72..86a68e5 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -179,6 +179,7 @@ 'webapp/host_list.js', 'webapp/host_screen.js', 'webapp/host_session.js', + 'webapp/host_settings.js', 'webapp/host_setup_dialog.js', 'webapp/host_table_entry.js', 'webapp/l10n.js', diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd index ce91dbc..d3efbba 100644 --- a/remoting/resources/remoting_strings.grd +++ b/remoting/resources/remoting_strings.grd @@ -447,9 +447,6 @@ <message desc="Modified version of the host name shown for hosts that are not currently accessible." name="IDR_OFFLINE"> <ph name="HOSTNAME">$1<ex>My Linux desktop</ex></ph> (offline) </message> - <message desc="Menu option for disabling shrink-to-fit. When clicked, the remote desktop will be displayed at 1:1 scale." name="IDR_ORIGINAL_SIZE"> - Original size - </message> <message desc="In the connection history dialog, clicking this button shows only recent connections from this computer." name="IDR_OUTGOING_CONNECTIONS"> From this computer </message> @@ -468,6 +465,9 @@ <message desc="Label for button to reconnect to the previous Me2Me host. This button appears on the 'session-finished' page." name="IDR_RECONNECT"> Reconnect </message> + <message desc="Button for enabling or disabling the 'resize-to-client' functionality, whereby the host desktop is resized to match the client size as closely as possible." name="IDR_RESIZE_TO_CLIENT"> + Resize desktop to fit + </message> <message desc="Label for button to retry connecting to a Me2Me host, after failing to connect to that host. This button appears on the 'session-finished' page." name="IDR_RETRY"> Retry </message> diff --git a/remoting/webapp/client_plugin.js b/remoting/webapp/client_plugin.js index 0d91c07..97a10da 100644 --- a/remoting/webapp/client_plugin.js +++ b/remoting/webapp/client_plugin.js @@ -53,7 +53,6 @@ remoting.ClientPlugin.prototype.isSupportedVersion = function() {}; * @enum {string} */ remoting.ClientPlugin.Feature = { - HIGH_QUALITY_SCALING: 'highQualityScaling', INJECT_KEY_EVENT: 'injectKeyEvent', NOTIFY_CLIENT_DIMENSIONS: 'notifyClientDimensions', PAUSE_VIDEO: 'pauseVideo', diff --git a/remoting/webapp/client_screen.js b/remoting/webapp/client_screen.js index 0ee39dd..a1a01b9 100644 --- a/remoting/webapp/client_screen.js +++ b/remoting/webapp/client_screen.js @@ -94,15 +94,6 @@ remoting.cancelConnect = function() { */ /** - * Toggle the scale-to-fit feature for the current client session. - * - * @return {void} Nothing. - */ -remoting.toggleScaleToFit = function() { - remoting.clientSession.setScaleToFit(!remoting.clientSession.getScaleToFit()); -}; - -/** * Update the remoting client layout in response to a resize event. * * @return {void} Nothing. diff --git a/remoting/webapp/client_session.js b/remoting/webapp/client_session.js index 5659a77..3dfaa43 100644 --- a/remoting/webapp/client_session.js +++ b/remoting/webapp/client_session.js @@ -30,8 +30,8 @@ var remoting = remoting || {}; * for Me2Me. * @param {string} authenticationMethods Comma-separated list of * authentication methods the client should attempt to use. - * @param {string} authenticationTag A host-specific tag to mix into - * authentication hashes. + * @param {string} hostId The host identifier for Me2Me, or empty for IT2Me. + * Mixed into authentication hashes for some authentication methods. * @param {remoting.ClientSession.Mode} mode The mode of this connection. * @param {function(remoting.ClientSession.State, remoting.ClientSession.State):void} onStateChange @@ -39,7 +39,7 @@ var remoting = remoting || {}; * @constructor */ remoting.ClientSession = function(hostJid, hostPublicKey, sharedSecret, - authenticationMethods, authenticationTag, + authenticationMethods, hostId, mode, onStateChange) { this.state = remoting.ClientSession.State.CREATED; @@ -47,30 +47,43 @@ remoting.ClientSession = function(hostJid, hostPublicKey, sharedSecret, this.hostPublicKey = hostPublicKey; this.sharedSecret = sharedSecret; this.authenticationMethods = authenticationMethods; - this.authenticationTag = authenticationTag; + this.hostId = hostId; this.mode = mode; this.clientJid = ''; this.sessionId = ''; /** @type {remoting.ClientPlugin} */ this.plugin = null; - this.scaleToFit = false; + /** @private */ + this.shrinkToFit_ = true; + /** @private */ + this.resizeToClient_ = false; + /** @private */ this.hasReceivedFrame_ = false; this.logToServer = new remoting.LogToServer(); this.onStateChange = onStateChange; /** @type {number?} @private */ this.notifyClientDimensionsTimer_ = null; + /** @type {number?} @private */ + this.bumpScrollTimer_ = null; + + /** + * Allow error reporting to be suppressed in situations where it would not + * be useful, for example, when the device is offline. + * + * @type {boolean} @private + */ + this.logErrors_ = true; /** @private */ this.callPluginLostFocus_ = this.pluginLostFocus_.bind(this); /** @private */ this.callPluginGotFocus_ = this.pluginGotFocus_.bind(this); /** @private */ - this.callEnableShrink_ = this.setScaleToFit.bind(this, true); - /** @private */ - this.callDisableShrink_ = this.setScaleToFit.bind(this, false); + this.callSetScreenMode_ = this.onSetScreenMode_.bind(this); /** @private */ this.callToggleFullScreen_ = this.toggleFullScreen_.bind(this); + /** @private */ this.screenOptionsMenu_ = new remoting.MenuButton( document.getElementById('screen-options-menu'), @@ -81,24 +94,26 @@ remoting.ClientSession = function(hostJid, hostPublicKey, sharedSecret, ); /** @type {HTMLElement} @private */ - this.shrinkToFit_ = document.getElementById('enable-shrink-to-fit'); + this.resizeToClientButton_ = + document.getElementById('screen-resize-to-client'); /** @type {HTMLElement} @private */ - this.originalSize_ = document.getElementById('disable-shrink-to-fit'); + this.shrinkToFitButton_ = document.getElementById('screen-shrink-to-fit'); /** @type {HTMLElement} @private */ - this.fullScreen_ = document.getElementById('toggle-full-screen'); + this.fullScreenButton_ = document.getElementById('toggle-full-screen'); - this.shrinkToFit_.addEventListener('click', this.callEnableShrink_, false); - this.originalSize_.addEventListener('click', this.callDisableShrink_, false); - this.fullScreen_.addEventListener('click', this.callToggleFullScreen_, false); - /** @type {number?} @private */ - this.bumpScrollTimer_ = null; - /** - * Allow error reporting to be suppressed in situations where it would not - * be useful, for example, when the device is offline. - * - * @type {boolean} @private - */ - this.logErrors_ = true; + if (this.mode == remoting.ClientSession.Mode.IT2ME) { + // Resize-to-client is not supported for IT2Me hosts. + this.resizeToClientButton_.parentNode.removeChild( + this.resizeToClientButton_); + } else { + this.resizeToClientButton_.addEventListener( + 'click', this.callSetScreenMode_, false); + } + + this.shrinkToFitButton_.addEventListener( + 'click', this.callSetScreenMode_, false); + this.fullScreenButton_.addEventListener( + 'click', this.callToggleFullScreen_, false); }; // Note that the positive values in both of these enums are copied directly @@ -166,6 +181,10 @@ remoting.ClientSession.STATS_KEY_DECODE_LATENCY = 'decodeLatency'; remoting.ClientSession.STATS_KEY_RENDER_LATENCY = 'renderLatency'; remoting.ClientSession.STATS_KEY_ROUNDTRIP_LATENCY = 'roundtripLatency'; +// Keys for per-host settings. +remoting.ClientSession.KEY_RESIZE_TO_CLIENT = 'resizeToClient'; +remoting.ClientSession.KEY_SHRINK_TO_FIT = 'shrinkToFit'; + /** * The current state of the session. * @type {remoting.ClientSession.State} @@ -245,6 +264,28 @@ remoting.ClientSession.prototype.pluginLostFocus_ = function() { remoting.ClientSession.prototype.createPluginAndConnect = function(container) { this.plugin = this.createClientPlugin_(container, this.PLUGIN_ID); + remoting.HostSettings.load(this.hostId, + this.onHostSettingsLoaded_.bind(this)); +}; + +/** + * @param {Object.<string>} options The current options for the host, or {} + * if this client has no saved settings for the host. + * @private + */ +remoting.ClientSession.prototype.onHostSettingsLoaded_ = function(options) { + if (remoting.ClientSession.KEY_RESIZE_TO_CLIENT in options && + typeof(options[remoting.ClientSession.KEY_RESIZE_TO_CLIENT]) == + 'boolean') { + this.resizeToClient_ = /** @type {boolean} */ + options[remoting.ClientSession.KEY_RESIZE_TO_CLIENT]; + } + if (remoting.ClientSession.KEY_SHRINK_TO_FIT in options && + typeof(options[remoting.ClientSession.KEY_SHRINK_TO_FIT]) == + 'boolean') { + this.shrinkToFit_ = /** @type {boolean} */ + options[remoting.ClientSession.KEY_SHRINK_TO_FIT]; + } this.plugin.element().focus(); @@ -292,11 +333,6 @@ remoting.ClientSession.prototype.onPluginInitialized_ = function(initialized) { this.plugin.remapKey(0x0700e4, 0x0700e7); } - // Enable scale-to-fit if and only if the plugin is new enough for - // high-quality scaling. - this.setScaleToFit(this.plugin.hasFeature( - remoting.ClientPlugin.Feature.HIGH_QUALITY_SCALING)); - /** @param {string} msg The IQ stanza to send. */ this.plugin.onOutgoingIqHandler = this.sendIq_.bind(this); /** @param {string} msg The message to log. */ @@ -330,11 +366,12 @@ remoting.ClientSession.prototype.removePlugin = function() { this.plugin.cleanup(); this.plugin = null; } - this.shrinkToFit_.removeEventListener('click', this.callEnableShrink_, false); - this.originalSize_.removeEventListener('click', this.callDisableShrink_, - false); - this.fullScreen_.removeEventListener('click', this.callToggleFullScreen_, - false); + this.resizeToClientButton_.removeEventListener( + 'click', this.callSetScreenMode_, false); + this.shrinkToFitButton_.removeEventListener( + 'click', this.callSetScreenMode_, false); + this.fullScreenButton_.removeEventListener( + 'click', this.callToggleFullScreen_, false); }; /** @@ -404,27 +441,63 @@ remoting.ClientSession.prototype.sendPrintScreen = function() { } /** - * Enables or disables the client's scale-to-fit feature. + * Callback for the two "screen mode" related menu items: Resize desktop to + * fit and Shrink to fit. * - * @param {boolean} scaleToFit True to enable scale-to-fit, false otherwise. + * @param {Event} event The click event indicating which mode was selected. * @return {void} Nothing. + * @private */ -remoting.ClientSession.prototype.setScaleToFit = function(scaleToFit) { - this.scaleToFit = scaleToFit; - this.updateDimensions(); - // If enabling scaling, reset bump-scroll offsets. - if (scaleToFit) { - this.scroll_(0, 0); +remoting.ClientSession.prototype.onSetScreenMode_ = function(event) { + var shrinkToFit = this.shrinkToFit_; + var resizeToClient = this.resizeToClient_; + if (event.target == this.shrinkToFitButton_) { + shrinkToFit = !shrinkToFit; } -} + if (event.target == this.resizeToClientButton_) { + resizeToClient = !resizeToClient; + } + this.setScreenMode_(shrinkToFit, resizeToClient); +}; /** - * Returns whether the client is currently scaling the host to fit the tab. + * Set the shrink-to-fit and resize-to-client flags and save them if this is + * a Me2Me connection. * - * @return {boolean} The current scale-to-fit setting. + * @param {boolean} shrinkToFit True if the remote desktop should be scaled + * down if it is larger than the client window; false if scroll-bars + * should be added in this case. + * @param {boolean} resizeToClient True if window resizes should cause the + * host to attempt to resize its desktop to match the client window size; + * false to disable this behaviour for subsequent window resizes--the + * current host desktop size is not restored in this case. + * @return {void} Nothing. + * @private */ -remoting.ClientSession.prototype.getScaleToFit = function() { - return this.scaleToFit; +remoting.ClientSession.prototype.setScreenMode_ = + function(shrinkToFit, resizeToClient) { + + if (resizeToClient && !this.resizeToClient_) { + this.plugin.notifyClientDimensions(window.innerWidth, window.innerHeight); + } + + // If enabling shrink, reset bump-scroll offsets. + var needsScrollReset = shrinkToFit && !this.shrinkToFit_; + + this.shrinkToFit_ = shrinkToFit; + this.resizeToClient_ = resizeToClient; + + if (this.hostId != '') { + var options = {}; + options[remoting.ClientSession.KEY_SHRINK_TO_FIT] = this.shrinkToFit_; + options[remoting.ClientSession.KEY_RESIZE_TO_CLIENT] = this.resizeToClient_; + remoting.HostSettings.save(this.hostId, options); + } + + this.updateDimensions(); + if (needsScrollReset) { + this.scroll_(0, 0); + } } /** @@ -495,7 +568,7 @@ remoting.ClientSession.prototype.connectPluginToWcs_ = function() { remoting.wcs.setOnIq(onIncomingIq); this.plugin.connect(this.hostJid, this.hostPublicKey, this.clientJid, this.sharedSecret, this.authenticationMethods, - this.authenticationTag); + this.hostId); }; /** @@ -510,7 +583,9 @@ remoting.ClientSession.prototype.onConnectionStatusUpdate_ = function(status, error) { if (status == remoting.ClientSession.State.CONNECTED) { this.onDesktopSizeChanged_(); - this.plugin.notifyClientDimensions(window.innerWidth, window.innerHeight) + if (this.resizeToClient_) { + this.plugin.notifyClientDimensions(window.innerWidth, window.innerHeight); + } } else if (status == remoting.ClientSession.State.FAILED) { this.error = /** @type {remoting.ClientSession.ConnectionError} */ (error); } @@ -573,11 +648,13 @@ remoting.ClientSession.prototype.onResize = function() { // Defer notifying the host of the change until the window stops resizing, to // avoid overloading the control channel with notifications. - this.notifyClientDimensionsTimer_ = window.setTimeout( - this.plugin.notifyClientDimensions.bind(this.plugin, - window.innerWidth, - window.innerHeight), - 1000); + if (this.resizeToClient_) { + this.notifyClientDimensionsTimer_ = window.setTimeout( + this.plugin.notifyClientDimensions.bind(this.plugin, + window.innerWidth, + window.innerHeight), + 1000); + } // If bump-scrolling is enabled, adjust the plugin margins to fully utilize // the new window area. @@ -642,7 +719,7 @@ remoting.ClientSession.prototype.updateDimensions = function() { var desktopHeight = this.plugin.desktopHeight; var scale = 1.0; - if (this.getScaleToFit()) { + if (this.shrinkToFit_) { // Scale to fit the entire desktop in the client window. var scaleFitWidth = Math.min(1.0, 1.0 * windowWidth / desktopWidth); var scaleFitHeight = Math.min(1.0, 1.0 * windowHeight / desktopHeight); @@ -754,9 +831,10 @@ remoting.ClientSession.prototype.toggleFullScreen_ = function() { * @private */ remoting.ClientSession.prototype.onShowOptionsMenu_ = function() { - remoting.MenuButton.select(this.shrinkToFit_, this.scaleToFit); - remoting.MenuButton.select(this.originalSize_, !this.scaleToFit); - remoting.MenuButton.select(this.fullScreen_, document.webkitIsFullScreen); + remoting.MenuButton.select(this.resizeToClientButton_, this.resizeToClient_); + remoting.MenuButton.select(this.shrinkToFitButton_, this.shrinkToFit_); + remoting.MenuButton.select(this.fullScreenButton_, + document.webkitIsFullScreen); }; /** diff --git a/remoting/webapp/host_settings.js b/remoting/webapp/host_settings.js new file mode 100644 index 0000000..426d8b2 --- /dev/null +++ b/remoting/webapp/host_settings.js @@ -0,0 +1,99 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview + * Class handling saving and restoring of per-host options. + */ + +'use strict'; + +/** @suppress {duplicate} */ +var remoting = remoting || {}; + +/** @type {Object} */ +remoting.HostSettings = {}; + +/** + * Load the settings for the specified host. Settings are returned as a + * dictionary of (name, value) pairs. + * + * @param {string} hostId The host identifer for which to load options. + * @param {function(Object):void} callback Callback to which the + * current settings for the host are passed. If there are no settings, + * then an empty dictionary is passed. + * @return {void} Nothing. + */ +remoting.HostSettings.load = function(hostId, callback) { + /** + * @param {Object} requestedHost + * @param {Object} allHosts + * @return {void} Nothing. + */ + var onDone = function(requestedHost, allHosts) { + callback(requestedHost); + }; + remoting.HostSettings.loadInternal_(hostId, onDone); +}; + +/** + * Save the settings for the specified hosts. Existing settings with the same + * names will be overwritten; settings not currently saved will be created. + * + * @param {string} hostId The host identifer for which to save options. + * @param {Object} options The options to save, expressed as a dictionary of + * (name, value) pairs. + * @param {function():void=} opt_callback Optional completion callback. + * @return {void} Nothing. + */ +remoting.HostSettings.save = function(hostId, options, opt_callback) { + /** + * @param {Object} requestedHost + * @param {Object} allHosts + * @return {void} Nothing. + */ + var onDone = function(requestedHost, allHosts) { + for (var option in options) { + requestedHost[option] = options[option]; + } + allHosts[hostId] = requestedHost; + var newSettings = {}; + newSettings[remoting.HostSettings.KEY_] = JSON.stringify(allHosts); + chrome.storage.local.set(newSettings, opt_callback); + }; + remoting.HostSettings.loadInternal_(hostId, onDone); +}; + +/** + * Helper function for both load and save. + * + * @param {string} hostId The host identifer for which to load options. + * @param {function(Object, Object):void} callback Callback to which the + * current settings for the specified host and for all hosts are passed. + * @return {void} Nothing. + */ +remoting.HostSettings.loadInternal_ = function(hostId, callback) { + /** + * @param {Object.<string>} allHosts The current options for all hosts. + * @return {void} Nothing. + */ + var onDone = function(allHosts) { + var result = {}; + try { + var result = jsonParseSafe(allHosts[remoting.HostSettings.KEY_]); + if (hostId in result && typeof(result[hostId] == 'Object')) { + callback(result[hostId], /** @type {Object} */(result)); + return; + } + } catch (err) { + var typedErr = /** @type {*} */ (err); + console.error('Error loading host settings:', typedErr); + } + callback({}, {}); + }; + chrome.storage.local.get(remoting.HostSettings.KEY_, onDone); +}; + +/** @type {string} @private */ +remoting.HostSettings.KEY_ = 'remoting-host-options';
\ No newline at end of file diff --git a/remoting/webapp/main.html b/remoting/webapp/main.html index 26fa487..a3cbb54 100644 --- a/remoting/webapp/main.html +++ b/remoting/webapp/main.html @@ -16,7 +16,6 @@ found in the LICENSE file. <link rel="stylesheet" href="main.css"> <link rel="stylesheet" href="menu_button.css"> <link rel="stylesheet" href="toolbar.css"> - <script src="host_setup_dialog.js"></script> <script src="client_plugin.js"></script> <script src="client_plugin_async.js"></script> <script src="client_screen.js"></script> @@ -30,6 +29,8 @@ found in the LICENSE file. <script src="host_list.js"></script> <script src="host_screen.js"></script> <script src="host_session.js"></script> + <script src="host_settings.js"></script> + <script src="host_setup_dialog.js"></script> <script src="host_table_entry.js"></script> <script src="l10n.js"></script> <script src="log_to_server.js"></script> @@ -624,8 +625,9 @@ found in the LICENSE file. class="kd-disclosureindicator"> </button> <ul> - <li id="enable-shrink-to-fit" i18n-content="SHRINK_TO_FIT"></li> - <li id="disable-shrink-to-fit" i18n-content="ORIGINAL_SIZE"></li> + <li id="screen-resize-to-client" + i18n-content="RESIZE_TO_CLIENT"></li> + <li id="screen-shrink-to-fit" i18n-content="SHRINK_TO_FIT"></li> <li class="menu-separator"></li> <li id="toggle-full-screen" i18n-content="FULL_SCREEN"></li> </ul> |