Index: remoting/webapp/base/js/window_shape.js |
diff --git a/remoting/webapp/base/js/window_shape.js b/remoting/webapp/base/js/window_shape.js |
index ee15a0f436c85c13ed0ad815cdc4cda1cebeef66..ad887bbe3c3c81b1fab4e427200116f60f8446aa 100644 |
--- a/remoting/webapp/base/js/window_shape.js |
+++ b/remoting/webapp/base/js/window_shape.js |
@@ -20,7 +20,7 @@ remoting.WindowShape = function() { |
this.desktopRects_ = []; |
/** @private {Array<remoting.WindowShape.ClientUI>} */ |
- this.clientUICallbacks_ = []; |
+ this.clientUIs_ = []; |
}; |
/** |
@@ -31,20 +31,72 @@ remoting.WindowShape.isSupported = function() { |
return base.isAppsV2() && |
typeof(chrome.app.window.current().setShape) != 'undefined' && |
!remoting.platformIsMac(); |
-} |
+}; |
/** |
- * Add a client-side UI measurement callback. |
+ * Adds a client-side UI. |
* |
* @param {remoting.WindowShape.ClientUI} callback |
*/ |
-remoting.WindowShape.prototype.addCallback = function(callback) { |
- this.clientUICallbacks_.push(callback); |
+remoting.WindowShape.prototype.registerClientUI = function(callback) { |
+ if (this.clientUIs_.indexOf(callback) === -1) { |
+ this.clientUIs_.push(callback); |
+ this.updateClientWindowShape(); |
+ } |
+}; |
+ |
+/** |
+ * Removes a client-side UI. |
+ * |
+ * @param {remoting.WindowShape.ClientUI} callback |
+ */ |
+remoting.WindowShape.prototype.unregisterClientUI = function(callback) { |
+ var index = this.clientUIs_.indexOf(callback); |
+ this.clientUIs_.splice(index, 1); |
+ this.updateClientWindowShape(); |
+}; |
+ |
+/** |
+ * Center aligns a DOM element to the desktop shape. |
+ * |
+ * @param {HTMLElement} element |
+ */ |
+remoting.WindowShape.prototype.centerToDesktop = function(element) { |
+ var desktop = { |
+ left: Number.MAX_VALUE, |
+ right: Number.MIN_VALUE, |
+ top: Number.MAX_VALUE, |
+ bottom: Number.MIN_VALUE |
+ }; |
+ |
+ // If there is no desktop window, center it to the current viewport. |
+ if (this.desktopRects_.length === 0) { |
+ desktop.left = 0; |
+ desktop.right = window.innerWidth; |
+ desktop.top = 0; |
+ desktop.bottom = window.innerHeight; |
+ } else { |
+ // Compute the union of the bounding rects of all desktop windows. |
+ this.desktopRects_.forEach(function( |
+ /**{left: number, top: number, width: number, height: number}*/ rect) { |
+ desktop.left = Math.min(rect.left, desktop.left); |
+ desktop.right = Math.max(rect.left + rect.width, desktop.right); |
+ desktop.top = Math.min(rect.top, desktop.top); |
+ desktop.bottom = Math.max(rect.top + rect.height, desktop.bottom); |
+ }); |
+ } |
+ |
+ // Center the element to the desktop window bounding rect. |
+ var rect = element.getBoundingClientRect(); |
+ var left = (desktop.right - desktop.left - rect.width) / 2 + desktop.left; |
+ var top = (desktop.bottom - desktop.top - rect.height) / 2 + desktop.top; |
+ element.style.left = left + 'px'; |
+ element.style.top = top + 'px'; |
this.updateClientWindowShape(); |
}; |
/** |
- * Set the region associated with the remote desktop windows. |
+ * Sets the region associated with the remote desktop windows. |
* |
* @param {Array<{left: number, top: number, width: number, height: number}>} |
* rects |
@@ -55,7 +107,7 @@ remoting.WindowShape.prototype.setDesktopRects = function(rects) { |
}; |
/** |
- * Update the client window shape. |
+ * Updates the client window shape. |
*/ |
remoting.WindowShape.prototype.updateClientWindowShape = function() { |
if (!remoting.WindowShape.isSupported()) { |
@@ -63,8 +115,8 @@ remoting.WindowShape.prototype.updateClientWindowShape = function() { |
} |
var rects = this.desktopRects_.slice(); |
- for (var i = 0; i < this.clientUICallbacks_.length; ++i) { |
- this.clientUICallbacks_[i].addToRegion(rects); |
+ for (var i = 0; i < this.clientUIs_.length; ++i) { |
+ this.clientUIs_[i].addToRegion(rects); |
} |
for (var i = 0; i < rects.length; ++i) { |
var rect = /** @type {ClientRect} */ (rects[i]); |
@@ -88,7 +140,7 @@ remoting.WindowShape.ClientUI = function () { |
}; |
/** |
- * Add the context menu's bounding rectangle to the specified region. |
+ * Adds the context menu's bounding rectangle to the specified region. |
* |
* @param {Array<{left: number, top: number, width: number, height: number}>} |
* rects |