| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 /** | |
| 6 * @fileoverview | |
| 7 * Implements a basic UX control for a connected remoting session. | |
| 8 */ | |
| 9 | |
| 10 /** @suppress {duplicate} */ | |
| 11 var remoting = remoting || {}; | |
| 12 | |
| 13 (function() { | |
| 14 | |
| 15 'use strict'; | |
| 16 | |
| 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; | |
| 28 | |
| 29 /** @private */ | |
| 30 this.plugin_ = plugin; | |
| 31 | |
| 32 /** private */ | |
| 33 this.cursor_ = new remoting.ConnectedView.Cursor( | |
| 34 plugin, viewportElement, cursorElement); | |
| 35 | |
| 36 /** @private {Element} */ | |
| 37 this.debugRegionContainer_ = | |
| 38 viewportElement.querySelector('.debug-region-container'); | |
| 39 | |
| 40 var pluginElement = plugin.element(); | |
| 41 | |
| 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 ); | |
| 51 | |
| 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 } | |
| 57 | |
| 58 pluginElement.focus(); | |
| 59 }; | |
| 60 | |
| 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; | |
| 69 }; | |
| 70 | |
| 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); | |
| 80 }; | |
| 81 | |
| 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); | |
| 90 }; | |
| 91 | |
| 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(); | |
| 99 | |
| 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); | |
| 105 }; | |
| 106 | |
| 107 /** | |
| 108 * Handles dirty region debug messages. | |
| 109 * | |
| 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 } | |
| 130 }; | |
| 131 | |
| 132 /** | |
| 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 } | |
| 142 }; | |
| 143 | |
| 144 /** | |
| 145 * @param {remoting.ClientPlugin} plugin | |
| 146 * @param {HTMLElement} viewportElement | |
| 147 * @param {HTMLElement} cursorElement | |
| 148 * | |
| 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); | |
| 161 | |
| 162 this.plugin_.setMouseCursorHandler(this.onCursorChanged_.bind(this)); | |
| 163 }; | |
| 164 | |
| 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; | |
| 171 }; | |
| 172 | |
| 173 /** | |
| 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 } | |
| 187 }; | |
| 188 | |
| 189 /** | |
| 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'; | |
| 196 }; | |
| 197 | |
| 198 })(); | |
| OLD | NEW |