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 * True to enable mouse lock. |
| 19 * This is currently disabled because the current client plugin does not |
| 20 * properly handle mouse lock and delegated large cursors at the same time. |
| 21 * This should be re-enabled (by removing this flag) once a version of |
| 22 * the plugin that supports both has reached Chrome Stable channel. |
| 23 * (crbug.com/429322). |
| 24 * |
| 25 * @type {boolean} |
| 26 */ |
| 27 remoting.enableMouseLock = false; |
| 28 |
| 29 /** |
| 30 * @param {remoting.ClientPlugin} plugin |
| 31 * @param {HTMLElement} viewportElement |
| 32 * @param {HTMLElement} cursorElement |
| 33 * |
| 34 * @constructor |
| 35 * @implements {base.Disposable} |
| 36 */ |
| 37 remoting.ConnectedView = function(plugin, viewportElement, cursorElement) { |
| 38 /** @private */ |
| 39 this.viewportElement_ = viewportElement; |
| 40 |
| 41 /** @private */ |
| 42 this.plugin_ = plugin; |
| 43 |
| 44 /** private */ |
| 45 this.cursor_ = new remoting.ConnectedView.Cursor( |
| 46 plugin, viewportElement, cursorElement); |
| 47 |
| 48 var pluginElement = plugin.element(); |
| 49 |
| 50 /** private */ |
| 51 this.disposables_ = new base.Disposables( |
| 52 this.cursor_, |
| 53 new base.DomEventHook(pluginElement, 'focus', |
| 54 this.onPluginGotFocus_.bind(this), false), |
| 55 new base.DomEventHook(pluginElement, 'blur', |
| 56 this.onPluginLostFocus_.bind(this), false), |
| 57 new base.DomEventHook(document, 'visibilitychange', |
| 58 this.onVisibilityChanged_.bind(this), false) |
| 59 ); |
| 60 |
| 61 // TODO(wez): Only allow mouse lock if the app has the pointerLock permission. |
| 62 // Enable automatic mouse-lock. |
| 63 if (remoting.enableMouseLock && |
| 64 this.plugin_.hasFeature(remoting.ClientPlugin.Feature.ALLOW_MOUSE_LOCK)) { |
| 65 this.plugin_.allowMouseLock(); |
| 66 } |
| 67 |
| 68 pluginElement.focus(); |
| 69 }; |
| 70 |
| 71 /** |
| 72 * @return {void} Nothing. |
| 73 */ |
| 74 remoting.ConnectedView.prototype.dispose = function() { |
| 75 base.dispose(this.disposables_); |
| 76 this.disposables_ = null; |
| 77 this.cursorRender_ = null; |
| 78 this.plugin_ = null; |
| 79 }; |
| 80 |
| 81 /** |
| 82 * Called when the app window is hidden. |
| 83 * @return {void} Nothing. |
| 84 * @private |
| 85 */ |
| 86 remoting.ConnectedView.prototype.onVisibilityChanged_ = function() { |
| 87 var pause = document.hidden; |
| 88 this.plugin_.pauseVideo(pause); |
| 89 this.plugin_.pauseAudio(pause); |
| 90 }; |
| 91 |
| 92 /** |
| 93 * Callback that the plugin invokes to indicate when the connection is |
| 94 * ready. |
| 95 * |
| 96 * @param {boolean} ready True if the connection is ready. |
| 97 */ |
| 98 remoting.ConnectedView.prototype.onConnectionReady = function(ready) { |
| 99 this.viewportElement_.classList.toggle('session-client-inactive', !ready); |
| 100 }; |
| 101 |
| 102 /** |
| 103 * Callback function called when the plugin element gets focus. |
| 104 * @private |
| 105 */ |
| 106 remoting.ConnectedView.prototype.onPluginGotFocus_ = function() { |
| 107 remoting.clipboard.initiateToHost(); |
| 108 }; |
| 109 |
| 110 /** |
| 111 * Callback function called when the plugin element loses focus. |
| 112 * @private |
| 113 */ |
| 114 remoting.ConnectedView.prototype.onPluginLostFocus_ = function() { |
| 115 // Release all keys to prevent them becoming 'stuck down' on the host. |
| 116 this.plugin_.releaseAllKeys(); |
| 117 |
| 118 // Focus should stay on the element, not (for example) the toolbar. |
| 119 // Due to crbug.com/246335, we can't restore the focus immediately, |
| 120 // otherwise the plugin gets confused about whether or not it has focus. |
| 121 window.setTimeout( |
| 122 this.plugin_.element().focus.bind(this.plugin_.element()), 0); |
| 123 }; |
| 124 |
| 125 /** |
| 126 * @param {remoting.ClientPlugin} plugin |
| 127 * @param {HTMLElement} viewportElement |
| 128 * @param {HTMLElement} cursorElement |
| 129 * |
| 130 * @constructor |
| 131 * @implements {base.Disposable} |
| 132 */ |
| 133 remoting.ConnectedView.Cursor = function( |
| 134 plugin, viewportElement, cursorElement) { |
| 135 /** @private */ |
| 136 this.plugin_ = plugin; |
| 137 /** @private */ |
| 138 this.cursorElement_ = cursorElement; |
| 139 /** @private */ |
| 140 this.eventHook_ = new base.DomEventHook( |
| 141 viewportElement, 'mousemove', this.onMouseMoved_.bind(this), true); |
| 142 |
| 143 this.plugin_.setMouseCursorHandler(this.onCursorChanged_.bind(this)); |
| 144 }; |
| 145 |
| 146 remoting.ConnectedView.Cursor.prototype.dispose = function() { |
| 147 base.dispose(this.eventHook_); |
| 148 this.eventHook_ = null; |
| 149 this.plugin_.setMouseCursorHandler( |
| 150 /** function(string, string, number) */ base.doNothing); |
| 151 this.plugin_ = null; |
| 152 }; |
| 153 |
| 154 /** |
| 155 * @param {string} url |
| 156 * @param {number} hotspotX |
| 157 * @param {number} hotspotY |
| 158 * @private |
| 159 */ |
| 160 remoting.ConnectedView.Cursor.prototype.onCursorChanged_ = function( |
| 161 url, hotspotX, hotspotY) { |
| 162 this.cursorElement_.hidden = !url; |
| 163 if (url) { |
| 164 this.cursorElement_.style.marginLeft = '-' + hotspotX + 'px'; |
| 165 this.cursorElement_.style.marginTop = '-' + hotspotY + 'px'; |
| 166 this.cursorElement_.src = url; |
| 167 } |
| 168 }; |
| 169 |
| 170 /** |
| 171 * @param {Event} event |
| 172 * @private |
| 173 */ |
| 174 remoting.ConnectedView.Cursor.prototype.onMouseMoved_ = function(event) { |
| 175 this.cursorElement_.style.top = event.offsetY + 'px'; |
| 176 this.cursorElement_.style.left = event.offsetX + 'px'; |
| 177 }; |
| 178 |
| 179 })(); |
OLD | NEW |