1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * Class handling setting of the local app window shape to account for windows
8 * on the remote desktop, as well as any client-side UI.
13 /** @suppress {duplicate} */
14 var remoting = remoting || {};
17 remoting.WindowShape = function() {
18 /** @private {Array<{left: number, top: number,
19 width: number, height: number}>} */
20 this.desktopRects_ = [];
22 /** @private {Array<remoting.WindowShape.ClientUI>} */
27 * @return {boolean} True if setShape is available and implemented for the
30 remoting.WindowShape.isSupported = function() {
31 return base.isAppsV2() &&
32 typeof(chrome.app.window.current().setShape) != 'undefined' &&
33 !remoting.platformIsMac();
37 * Adds a client-side UI.
39 * @param {remoting.WindowShape.ClientUI} callback
41 remoting.WindowShape.prototype.registerClientUI = function(callback) {
42 if (this.clientUIs_.indexOf(callback) === -1) {
43 this.clientUIs_.push(callback);
44 this.updateClientWindowShape();
49 * Removes a client-side UI.
51 * @param {remoting.WindowShape.ClientUI} callback
53 remoting.WindowShape.prototype.unregisterClientUI = function(callback) {
54 var index = this.clientUIs_.indexOf(callback);
55 this.clientUIs_.splice(index, 1);
56 this.updateClientWindowShape();
60 * Center aligns a DOM element to the desktop shape.
62 * @param {HTMLElement} element
64 remoting.WindowShape.prototype.centerToDesktop = function(element) {
66 left: Number.MAX_VALUE,
67 right: Number.MIN_VALUE,
68 top: Number.MAX_VALUE,
69 bottom: Number.MIN_VALUE
72 // If there is no desktop window, center it to the current viewport.
73 if (this.desktopRects_.length === 0) {
75 desktop.right = window.innerWidth;
77 desktop.bottom = window.innerHeight;
79 // Compute the union of the bounding rects of all desktop windows.
80 this.desktopRects_.forEach(function(
81 /**{left: number, top: number, width: number, height: number}*/ rect) {
82 desktop.left = Math.min(rect.left, desktop.left);
83 desktop.right = Math.max(rect.left + rect.width, desktop.right);
84 desktop.top = Math.min(rect.top, desktop.top);
85 desktop.bottom = Math.max(rect.top + rect.height, desktop.bottom);
89 // Center the element to the desktop window bounding rect.
90 var rect = element.getBoundingClientRect();
91 var left = (desktop.right - desktop.left - rect.width) / 2 + desktop.left;
92 var top = (desktop.bottom - desktop.top - rect.height) / 2 + desktop.top;
93 element.style.left = Math.round(left) + 'px';
94 element.style.top = Math.round(top) + 'px';
95 this.updateClientWindowShape();
99 * Sets the region associated with the remote desktop windows.
101 * @param {Array<{left: number, top: number, width: number, height: number}>}
104 remoting.WindowShape.prototype.setDesktopRects = function(rects) {
105 this.desktopRects_ = rects;
106 this.updateClientWindowShape();
110 * Updates the client window shape.
112 remoting.WindowShape.prototype.updateClientWindowShape = function() {
113 if (!remoting.WindowShape.isSupported()) {
117 var rects = this.desktopRects_.slice();
118 for (var i = 0; i < this.clientUIs_.length; ++i) {
119 this.clientUIs_[i].addToRegion(rects);
121 for (var i = 0; i < rects.length; ++i) {
122 var rect = /** @type {ClientRect} */ (rects[i]);
123 var left = Math.floor(rect.left);
124 var right = Math.ceil(rect.left + rect.width);
125 var top = Math.floor(rect.top);
126 var bottom = Math.ceil(rect.top + rect.height);
127 rects[i] = { left: left,
130 height: bottom - top };
132 chrome.app.window.current().setShape({rects: rects});
139 remoting.WindowShape.ClientUI = function () {
143 * Adds the context menu's bounding rectangle to the specified region.
145 * @param {Array<{left: number, top: number, width: number, height: number}>}
148 remoting.WindowShape.ClientUI.prototype.addToRegion = function(rects) {};