Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / remoting / webapp / base / js / connected_view.js
blobf92656c243ef35f09b6a57829c575c73918b848e
1 // Copyright 2015 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.
5 /**
6  * @fileoverview
7  * Implements a basic UX control for a connected remoting session.
8  */
10 /** @suppress {duplicate} */
11 var remoting = remoting || {};
13 (function() {
15 'use strict';
17 /**
18  * @param {remoting.ClientPlugin} plugin
19  * @param {HTMLElement} viewportElement
20  * @param {HTMLElement} cursorElement
21  *
22  * @constructor
23  * @implements {base.Disposable}
24  */
25 remoting.ConnectedView = function(plugin, viewportElement, cursorElement) {
26   /** @private */
27   this.viewportElement_ = viewportElement;
29   /** @private */
30   this.plugin_ = plugin;
32   /** private */
33   this.cursor_ = new remoting.ConnectedView.Cursor(
34       plugin, viewportElement, cursorElement);
36   /** @private {Element} */
37   this.debugRegionContainer_ =
38       viewportElement.querySelector('.debug-region-container');
40   var pluginElement = plugin.element();
42   /** private */
43   this.disposables_ = new base.Disposables(
44     this.cursor_,
45     new base.DomEventHook(pluginElement, 'blur',
46                           this.onPluginLostFocus_.bind(this), false),
47     new base.DomEventHook(document, 'visibilitychange',
48                           this.onVisibilityChanged_.bind(this), false),
49     new remoting.Clipboard(plugin)
50   );
52   // TODO(wez): Only allow mouse lock if the app has the pointerLock permission.
53   // Enable automatic mouse-lock.
54   if (this.plugin_.hasFeature(remoting.ClientPlugin.Feature.ALLOW_MOUSE_LOCK)) {
55     this.plugin_.allowMouseLock();
56   }
58   pluginElement.focus();
61 /**
62  * @return {void} Nothing.
63  */
64 remoting.ConnectedView.prototype.dispose = function() {
65   base.dispose(this.disposables_);
66   this.disposables_ = null;
67   this.cursorRender_ = null;
68   this.plugin_ = null;
71 /**
72  * Called when the app window is hidden.
73  * @return {void} Nothing.
74  * @private
75  */
76 remoting.ConnectedView.prototype.onVisibilityChanged_ = function() {
77   var pause = document.hidden;
78   this.plugin_.pauseVideo(pause);
79   this.plugin_.pauseAudio(pause);
82 /**
83  * Callback that the plugin invokes to indicate when the connection is
84  * ready.
85  *
86  * @param {boolean} ready True if the connection is ready.
87  */
88 remoting.ConnectedView.prototype.onConnectionReady = function(ready) {
89   this.viewportElement_.classList.toggle('session-client-inactive', !ready);
92 /**
93  * Callback function called when the plugin element loses focus.
94  * @private
95  */
96 remoting.ConnectedView.prototype.onPluginLostFocus_ = function() {
97   // Release all keys to prevent them becoming 'stuck down' on the host.
98   this.plugin_.releaseAllKeys();
100   // Focus should stay on the element, not (for example) the toolbar.
101   // Due to crbug.com/246335, we can't restore the focus immediately,
102   // otherwise the plugin gets confused about whether or not it has focus.
103   window.setTimeout(
104       this.plugin_.element().focus.bind(this.plugin_.element()), 0);
108  * Handles dirty region debug messages.
110  * @param {{rects:Array<Array<number>>}} region Dirty region of the latest
111  *     frame.
112  */
113 remoting.ConnectedView.prototype.handleDebugRegion = function(region) {
114   while (this.debugRegionContainer_.firstChild) {
115     this.debugRegionContainer_.removeChild(
116         this.debugRegionContainer_.firstChild);
117   }
118   if (region.rects) {
119     var rects = region.rects;
120     for (var i = 0; i < rects.length; ++i) {
121       var rect = document.createElement('div');
122       rect.classList.add('debug-region-rect');
123       rect.style.left = rects[i][0] + 'px';
124       rect.style.top = rects[i][1] +'px';
125       rect.style.width = rects[i][2] +'px';
126       rect.style.height = rects[i][3] + 'px';
127       this.debugRegionContainer_.appendChild(rect);
128     }
129   }
133  * Enables or disables rendering of dirty regions for debugging.
134  * @param {boolean} enable True to enable rendering.
135  */
136 remoting.ConnectedView.prototype.enableDebugRegion = function(enable) {
137   if (enable) {
138     this.plugin_.setDebugDirtyRegionHandler(this.handleDebugRegion.bind(this));
139   } else {
140     this.plugin_.setDebugDirtyRegionHandler(null);
141   }
145  * @param {remoting.ClientPlugin} plugin
146  * @param {HTMLElement} viewportElement
147  * @param {HTMLElement} cursorElement
149  * @constructor
150  * @implements {base.Disposable}
151  */
152 remoting.ConnectedView.Cursor = function(
153     plugin, viewportElement, cursorElement) {
154   /** @private */
155   this.plugin_ = plugin;
156   /** @private */
157   this.cursorElement_ = cursorElement;
158   /** @private */
159   this.eventHook_ = new base.DomEventHook(
160       viewportElement, 'mousemove', this.onMouseMoved_.bind(this), true);
162   this.plugin_.setMouseCursorHandler(this.onCursorChanged_.bind(this));
165 remoting.ConnectedView.Cursor.prototype.dispose = function() {
166   base.dispose(this.eventHook_);
167   this.eventHook_ = null;
168   this.plugin_.setMouseCursorHandler(
169       /** function(string, string, number) */ base.doNothing);
170   this.plugin_ = null;
174  * @param {string} url
175  * @param {number} hotspotX
176  * @param {number} hotspotY
177  * @private
178  */
179 remoting.ConnectedView.Cursor.prototype.onCursorChanged_ = function(
180     url, hotspotX, hotspotY) {
181   this.cursorElement_.hidden = !url;
182   if (url) {
183     this.cursorElement_.style.marginLeft = '-' + hotspotX + 'px';
184     this.cursorElement_.style.marginTop = '-' + hotspotY + 'px';
185     this.cursorElement_.src = url;
186   }
190  * @param {Event} event
191  * @private
192  */
193 remoting.ConnectedView.Cursor.prototype.onMouseMoved_ = function(event) {
194   this.cursorElement_.style.top = event.offsetY + 'px';
195   this.cursorElement_.style.left = event.offsetX + 'px';
198 })();