summaryrefslogtreecommitdiffstats
path: root/remoting/webapp
diff options
context:
space:
mode:
authorjamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-30 21:07:27 +0000
committerjamiewalch@chromium.org <jamiewalch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-30 21:07:27 +0000
commit3febebe90d62a419d49ccc80eaf7228ac632c2fa (patch)
tree8120e36bd5e8743791f786afedbe5195ce4b036b /remoting/webapp
parent2547c91ed6fd014a7eac9a5a764f87f54b9bc714 (diff)
downloadchromium_src-3febebe90d62a419d49ccc80eaf7228ac632c2fa.zip
chromium_src-3febebe90d62a419d49ccc80eaf7228ac632c2fa.tar.gz
chromium_src-3febebe90d62a419d49ccc80eaf7228ac632c2fa.tar.bz2
Use chrome.app.window full-screen API for apps v2.
This allows us to hook onMaximized to enter full-screen which is a cleaner UX. In the future, we will also have on-screen auto-hide close/minimize/restore controls in full-screen mode, which will eliminate the need for the tool-bar menu entry completely. See https://developer.chrome.com/apps/app_window#type-AppWindow for details of the API, and http://code.google.com/p/chromium/issues/detail?id=364942 for a discussion of why this behaviour is not going to be supported by requestFullscreen. BUG=134213,252927 NOTRY=true Review URL: https://codereview.chromium.org/252783003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267329 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/webapp')
-rw-r--r--remoting/webapp/client_session.js47
-rw-r--r--remoting/webapp/fullscreen.js65
-rw-r--r--remoting/webapp/fullscreen_v1.js86
-rw-r--r--remoting/webapp/fullscreen_v2.js121
-rw-r--r--remoting/webapp/js_proto/chrome_proto.js10
-rw-r--r--remoting/webapp/remoting.js2
6 files changed, 309 insertions, 22 deletions
diff --git a/remoting/webapp/client_session.js b/remoting/webapp/client_session.js
index 22f67b9..92ded18 100644
--- a/remoting/webapp/client_session.js
+++ b/remoting/webapp/client_session.js
@@ -113,7 +113,10 @@ remoting.ClientSession = function(accessCode, fetchPin, fetchThirdPartyToken,
/** @private */
this.callSetScreenMode_ = this.onSetScreenMode_.bind(this);
/** @private */
- this.callToggleFullScreen_ = this.toggleFullScreen_.bind(this);
+ this.callToggleFullScreen_ = remoting.fullscreen.toggle.bind(
+ remoting.fullscreen);
+ /** @private */
+ this.callOnFullScreenChanged_ = this.onFullScreenChanged_.bind(this);
/** @private */
this.screenOptionsMenu_ = new remoting.MenuButton(
@@ -151,8 +154,6 @@ remoting.ClientSession = function(accessCode, fetchPin, fetchThirdPartyToken,
'click', this.callSetScreenMode_, false);
this.fullScreenButton_.addEventListener(
'click', this.callToggleFullScreen_, false);
- document.addEventListener(
- 'webkitfullscreenchange', this.onFullScreenChanged_.bind(this), false);
};
/**
@@ -544,8 +545,14 @@ remoting.ClientSession.prototype.removePlugin = function() {
this.fullScreenButton_.removeEventListener(
'click', this.callToggleFullScreen_, false);
- // In case the user had selected full-screen mode, cancel it now.
- document.webkitCancelFullScreen();
+ // Leave full-screen mode, and stop listening for related events.
+ var listener = this.callOnFullScreenChanged_;
+ remoting.fullscreen.syncWithMaximize(false);
+ remoting.fullscreen.activate(
+ false,
+ function() {
+ remoting.fullscreen.removeListener(listener);
+ });
// Remove mediasource-rendering class from video-contained - this will also
// hide the <video> element.
@@ -922,6 +929,9 @@ remoting.ClientSession.prototype.onConnectionStatusUpdate_ =
window.innerHeight,
window.devicePixelRatio);
}
+ // Start listening for full-screen related events.
+ remoting.fullscreen.addListener(this.callOnFullScreenChanged_);
+ remoting.fullscreen.syncWithMaximize(true);
} else if (status == remoting.ClientSession.State.FAILED) {
switch (error) {
case remoting.ClientSession.ConnectionError.HOST_IS_OFFLINE:
@@ -1138,7 +1148,7 @@ remoting.ClientSession.prototype.updateDimensions = function() {
// If we're running full-screen then try to handle common side-by-side
// multi-monitor combinations more intelligently.
- if (document.webkitIsFullScreen) {
+ if (remoting.fullscreen.isActive()) {
// 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
@@ -1225,30 +1235,23 @@ remoting.ClientSession.prototype.requestPairing = function(clientName, onDone) {
};
/**
- * Toggles between full-screen and windowed mode.
- * @return {void} Nothing.
+ * Called when the full-screen status has changed, either via the
+ * remoting.Fullscreen class, or via a system event such as the Escape key
+ *
+ * @param {boolean} fullscreen True if the app is entering full-screen mode;
+ * false if it is leaving it.
* @private
*/
-remoting.ClientSession.prototype.toggleFullScreen_ = function() {
- if (document.webkitIsFullScreen) {
- document.webkitCancelFullScreen();
- } else {
- document.body.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
- }
-};
-
-remoting.ClientSession.prototype.onFullScreenChanged_ = function () {
+remoting.ClientSession.prototype.onFullScreenChanged_ = function (fullscreen) {
var htmlNode = /** @type {HTMLElement} */ (document.documentElement);
- var isFullScreen = document.webkitIsFullScreen;
- this.enableBumpScroll_(isFullScreen);
- if (isFullScreen) {
+ this.enableBumpScroll_(fullscreen);
+ if (fullscreen) {
htmlNode.classList.add('full-screen');
} else {
htmlNode.classList.remove('full-screen');
}
};
-
/**
* Updates the options menu to reflect the current scale-to-fit and full-screen
* settings.
@@ -1259,7 +1262,7 @@ remoting.ClientSession.prototype.onShowOptionsMenu_ = function() {
remoting.MenuButton.select(this.resizeToClientButton_, this.resizeToClient_);
remoting.MenuButton.select(this.shrinkToFitButton_, this.shrinkToFit_);
remoting.MenuButton.select(this.fullScreenButton_,
- document.webkitIsFullScreen);
+ remoting.fullscreen.isActive());
};
/**
diff --git a/remoting/webapp/fullscreen.js b/remoting/webapp/fullscreen.js
new file mode 100644
index 0000000..d510828
--- /dev/null
+++ b/remoting/webapp/fullscreen.js
@@ -0,0 +1,65 @@
+// Copyright 2014 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
+ * Controller interface for full-screen mode.
+ */
+
+'use strict';
+
+/** @suppress {duplicate} */
+var remoting = remoting || {};
+
+/** @interface */
+remoting.Fullscreen = function() { };
+
+/**
+ * Enter or leave full-screen mode.
+ *
+ * @param {boolean} fullscreen True to enter full-screen mode; false to leave.
+ * @param {function():void=} opt_onDone Optional completion callback.
+ */
+remoting.Fullscreen.prototype.activate = function(fullscreen, opt_onDone) { };
+
+/**
+ * @return {boolean} True if full-screen mode is active.
+ */
+remoting.Fullscreen.prototype.isActive = function() { };
+
+/**
+ * Toggle full-screen mode.
+ */
+remoting.Fullscreen.prototype.toggle = function() { };
+
+/**
+ * Add a listener for the full-screen-changed event.
+ *
+ * @param {function(boolean):void} callback
+ */
+remoting.Fullscreen.prototype.addListener = function(callback) { };
+
+/**
+ * Remove a listener for the full-screen-changed event.
+ *
+ * @param {function(boolean):void} callback
+ */
+remoting.Fullscreen.prototype.removeListener = function(callback) { };
+
+/**
+ * Enable or disable automatic synchronization of full-screen and maximized
+ * states. This allows the application to enter full-screen mode whenever its
+ * window is maximized, regardless of how the user initiates this (clicking
+ * the maximize control, double-clicking the title bar or using the tray menu,
+ * for example). If the window is already maximized when this synchronization
+ * is enabled, it is full-screened.
+ *
+ * This method is a no-op for apps v1.
+ *
+ * @param {boolean} sync True to enable synchronization; false to disable.
+ */
+remoting.Fullscreen.prototype.syncWithMaximize = function(sync) { };
+
+/** @type {remoting.Fullscreen} */
+remoting.fullscreen = null;
diff --git a/remoting/webapp/fullscreen_v1.js b/remoting/webapp/fullscreen_v1.js
new file mode 100644
index 0000000..052732d
--- /dev/null
+++ b/remoting/webapp/fullscreen_v1.js
@@ -0,0 +1,86 @@
+// Copyright 2014 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
+ * Full-screen implementation for apps v1, using webkitRequestFullscreen.
+ */
+
+'use strict';
+
+/** @suppress {duplicate} */
+var remoting = remoting || {};
+
+/**
+ * @constructor
+ * @implements {remoting.Fullscreen}
+ */
+remoting.FullscreenAppsV1 = function() {
+ /**
+ * @type {string} Internal 'full-screen changed' event name
+ * @private
+ */
+ this.kEventName_ = '_fullscreenchanged';
+
+ /**
+ * @type {base.EventSource}
+ * @private
+ */
+ this.eventSource_ = new base.EventSource();
+ this.eventSource_.defineEvents([this.kEventName_]);
+
+ document.addEventListener(
+ 'webkitfullscreenchange',
+ this.onFullscreenChanged_.bind(this),
+ false);
+};
+
+remoting.FullscreenAppsV1.prototype.activate = function(
+ fullscreen, opt_onDone) {
+ if (opt_onDone) {
+ if (this.isActive() == fullscreen) {
+ opt_onDone();
+ } else {
+ /** @type {remoting.Fullscreen} */
+ var that = this;
+ var callbackAndRemoveListener = function() {
+ that.removeListener(callbackAndRemoveListener);
+ opt_onDone();
+ };
+ this.addListener(callbackAndRemoveListener);
+ }
+ }
+
+ if (fullscreen) {
+ document.body.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
+ } else {
+ document.webkitCancelFullScreen();
+ }
+};
+
+remoting.FullscreenAppsV1.prototype.toggle = function() {
+ this.activate(!this.isActive());
+};
+
+remoting.FullscreenAppsV1.prototype.isActive = function() {
+ return document.webkitIsFullScreen;
+};
+
+remoting.FullscreenAppsV1.prototype.addListener = function(callback) {
+ this.eventSource_.addEventListener(this.kEventName_, callback);
+};
+
+remoting.FullscreenAppsV1.prototype.removeListener = function(callback) {
+ this.eventSource_.removeEventListener(this.kEventName_, callback);
+};
+
+remoting.FullscreenAppsV1.prototype.syncWithMaximize = function(sync) {
+};
+
+/**
+ * @private
+ */
+remoting.FullscreenAppsV1.prototype.onFullscreenChanged_ = function() {
+ this.eventSource_.raiseEvent(this.kEventName_, this.isActive());
+};
diff --git a/remoting/webapp/fullscreen_v2.js b/remoting/webapp/fullscreen_v2.js
new file mode 100644
index 0000000..4e19f34
--- /dev/null
+++ b/remoting/webapp/fullscreen_v2.js
@@ -0,0 +1,121 @@
+// Copyright 2014 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
+ * Full-screen implementation for apps v2, using chrome.AppWindow.
+ */
+
+'use strict';
+
+/** @suppress {duplicate} */
+var remoting = remoting || {};
+
+/**
+ * @constructor
+ * @implements {remoting.Fullscreen}
+ */
+remoting.FullscreenAppsV2 = function() {
+ /**
+ * @type {boolean} True if maximize/restore events are being hooked.
+ * @private
+ */
+ this.hookingWindowEvents_ = false;
+
+ /**
+ * @type {boolean} True if the next onRestored event should cause callbacks
+ * to be notified of a full-screen changed event. onRestored fires when
+ * full-screen mode is exited and also when the window is restored from
+ * being minimized; callbacks should not be notified of the latter.
+ * @private
+ */
+ this.notifyCallbacksOnRestore_ = this.isActive();
+
+ /**
+ * @type {string} Internal 'full-screen changed' event name
+ * @private
+ */
+ this.kEventName_ = '_fullscreenchanged';
+
+ /**
+ * @type {base.EventSource}
+ * @private
+ */
+ this.eventSource_ = new base.EventSource();
+ this.eventSource_.defineEvents([this.kEventName_]);
+
+ chrome.app.window.current().onFullscreened.addListener(
+ this.onFullscreened_.bind(this));
+ chrome.app.window.current().onMaximized.addListener(
+ this.onMaximized_.bind(this));
+ chrome.app.window.current().onRestored.addListener(
+ this.onRestored_.bind(this));
+};
+
+remoting.FullscreenAppsV2.prototype.activate = function(
+ fullscreen, opt_onDone) {
+ if (opt_onDone) {
+ if (this.isActive() == fullscreen) {
+ opt_onDone();
+ } else {
+ /** @type {remoting.Fullscreen} */
+ var that = this;
+ var callbackAndRemoveListener = function() {
+ that.removeListener(callbackAndRemoveListener);
+ opt_onDone();
+ };
+ this.addListener(callbackAndRemoveListener);
+ }
+ }
+
+ if (fullscreen) {
+ chrome.app.window.current().fullscreen();
+ } else if (this.isActive()) {
+ chrome.app.window.current().restore();
+ }
+};
+
+remoting.FullscreenAppsV2.prototype.toggle = function() {
+ this.activate(!this.isActive());
+};
+
+remoting.FullscreenAppsV2.prototype.isActive = function() {
+ return chrome.app.window.current().isFullscreen();
+};
+
+remoting.FullscreenAppsV2.prototype.addListener = function(callback) {
+ this.eventSource_.addEventListener(this.kEventName_, callback);
+};
+
+remoting.FullscreenAppsV2.prototype.removeListener = function(callback) {
+ this.eventSource_.removeEventListener(this.kEventName_, callback);
+};
+
+remoting.FullscreenAppsV2.prototype.syncWithMaximize = function(sync) {
+ if (sync && chrome.app.window.current().isMaximized()) {
+ this.activate(true);
+ }
+ this.hookingWindowEvents_ = sync;
+};
+
+remoting.FullscreenAppsV2.prototype.onFullscreened_ = function() {
+ this.notifyCallbacksOnRestore_ = true;
+ this.eventSource_.raiseEvent(this.kEventName_, true);
+};
+
+remoting.FullscreenAppsV2.prototype.onMaximized_ = function() {
+ if (this.hookingWindowEvents_) {
+ this.activate(true);
+ }
+};
+
+remoting.FullscreenAppsV2.prototype.onRestored_ = function() {
+ if (this.hookingWindowEvents_) {
+ this.activate(false);
+ }
+ if (this.notifyCallbacksOnRestore_) {
+ this.notifyCallbacksOnRestore_ = false;
+ this.eventSource_.raiseEvent(this.kEventName_, false);
+ }
+};
diff --git a/remoting/webapp/js_proto/chrome_proto.js b/remoting/webapp/js_proto/chrome_proto.js
index 0e41606..273910e 100644
--- a/remoting/webapp/js_proto/chrome_proto.js
+++ b/remoting/webapp/js_proto/chrome_proto.js
@@ -279,11 +279,21 @@ var AppWindow = function() {
this.contentWindow = null;
/** @type {chrome.Event} */
this.onRestored = null;
+ /** @type {chrome.Event} */
+ this.onMaximized = null;
+ /** @type {chrome.Event} */
+ this.onFullscreened = null;
};
AppWindow.prototype.close = function() {};
AppWindow.prototype.drawAttention = function() {};
AppWindow.prototype.minimize = function() {};
+AppWindow.prototype.restore = function() {};
+AppWindow.prototype.fullscreen = function() {};
+/** @return {boolean} */
+AppWindow.prototype.isFullscreen = function() {};
+/** @return {boolean} */
+AppWindow.prototype.isMaximized = function() {};
/**
* @param {{rects: Array.<ClientRect>}} rects
diff --git a/remoting/webapp/remoting.js b/remoting/webapp/remoting.js
index d015832..07bd828 100644
--- a/remoting/webapp/remoting.js
+++ b/remoting/webapp/remoting.js
@@ -60,12 +60,14 @@ remoting.init = function() {
remoting.settings = new remoting.Settings();
if (remoting.isAppsV2) {
remoting.identity = new remoting.Identity(consentRequired_);
+ remoting.fullscreen = new remoting.FullscreenAppsV2();
} else {
remoting.oauth2 = new remoting.OAuth2();
if (!remoting.oauth2.isAuthenticated()) {
document.getElementById('auth-dialog').hidden = false;
}
remoting.identity = remoting.oauth2;
+ remoting.fullscreen = new remoting.FullscreenAppsV1();
}
remoting.stats = new remoting.ConnectionStats(
document.getElementById('statistics'));