OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview | 6 * @fileoverview |
7 * Class handling creation and teardown of a remoting client session. | 7 * Class handling creation and teardown of a remoting client session. |
8 * | 8 * |
9 * The ClientSession class controls lifetime of the client plugin | 9 * The ClientSession class controls lifetime of the client plugin |
10 * object and provides the plugin with the functionality it needs to | 10 * object and provides the plugin with the functionality it needs to |
11 * establish connection. Specifically it: | 11 * establish connection. Specifically it: |
12 * - Delivers incoming/outgoing signaling messages, | 12 * - Delivers incoming/outgoing signaling messages, |
13 * - Adjusts plugin size and position when destop resolution changes, | 13 * - Adjusts plugin size and position when destop resolution changes, |
14 * | 14 * |
15 * This class should not access the plugin directly, instead it should | 15 * This class should not access the plugin directly, instead it should |
16 * do it through ClientPlugin class which abstracts plugin version | 16 * do it through ClientPlugin class which abstracts plugin version |
17 * differences. | 17 * differences. |
18 */ | 18 */ |
19 | 19 |
20 'use strict'; | 20 'use strict'; |
21 | 21 |
22 /** @suppress {duplicate} */ | 22 /** @suppress {duplicate} */ |
23 var remoting = remoting || {}; | 23 var remoting = remoting || {}; |
24 | 24 |
25 /** | 25 /** |
| 26 * @param {string} hostDisplayName A human-readable name for the host. |
26 * @param {string} accessCode The IT2Me access code. Blank for Me2Me. | 27 * @param {string} accessCode The IT2Me access code. Blank for Me2Me. |
27 * @param {function(boolean, function(string): void): void} fetchPin | 28 * @param {function(boolean, function(string): void): void} fetchPin |
28 * Called by Me2Me connections when a PIN needs to be obtained | 29 * Called by Me2Me connections when a PIN needs to be obtained |
29 * interactively. | 30 * interactively. |
30 * @param {function(string, string, string, | 31 * @param {function(string, string, string, |
31 * function(string, string): void): void} | 32 * function(string, string): void): void} |
32 * fetchThirdPartyToken Called by Me2Me connections when a third party | 33 * fetchThirdPartyToken Called by Me2Me connections when a third party |
33 * authentication token must be obtained. | 34 * authentication token must be obtained. |
34 * @param {string} authenticationMethods Comma-separated list of | 35 * @param {string} authenticationMethods Comma-separated list of |
35 * authentication methods the client should attempt to use. | 36 * authentication methods the client should attempt to use. |
36 * @param {string} hostId The host identifier for Me2Me, or empty for IT2Me. | 37 * @param {string} hostId The host identifier for Me2Me, or empty for IT2Me. |
37 * Mixed into authentication hashes for some authentication methods. | 38 * Mixed into authentication hashes for some authentication methods. |
38 * @param {string} hostJid The jid of the host to connect to. | 39 * @param {string} hostJid The jid of the host to connect to. |
39 * @param {string} hostPublicKey The base64 encoded version of the host's | 40 * @param {string} hostPublicKey The base64 encoded version of the host's |
40 * public key. | 41 * public key. |
41 * @param {remoting.ClientSession.Mode} mode The mode of this connection. | 42 * @param {remoting.ClientSession.Mode} mode The mode of this connection. |
42 * @param {string} clientPairingId For paired Me2Me connections, the | 43 * @param {string} clientPairingId For paired Me2Me connections, the |
43 * pairing id for this client, as issued by the host. | 44 * pairing id for this client, as issued by the host. |
44 * @param {string} clientPairedSecret For paired Me2Me connections, the | 45 * @param {string} clientPairedSecret For paired Me2Me connections, the |
45 * paired secret for this client, as issued by the host. | 46 * paired secret for this client, as issued by the host. |
46 * @constructor | 47 * @constructor |
47 * @extends {base.EventSource} | 48 * @extends {base.EventSource} |
48 */ | 49 */ |
49 remoting.ClientSession = function(accessCode, fetchPin, fetchThirdPartyToken, | 50 remoting.ClientSession = function(hostDisplayName, accessCode, fetchPin, |
50 authenticationMethods, | 51 fetchThirdPartyToken, authenticationMethods, |
51 hostId, hostJid, hostPublicKey, mode, | 52 hostId, hostJid, hostPublicKey, mode, |
52 clientPairingId, clientPairedSecret) { | 53 clientPairingId, clientPairedSecret) { |
53 /** @private */ | 54 /** @private */ |
54 this.state_ = remoting.ClientSession.State.CREATED; | 55 this.state_ = remoting.ClientSession.State.CREATED; |
55 | 56 |
56 /** @private */ | 57 /** @private */ |
57 this.error_ = remoting.Error.NONE; | 58 this.error_ = remoting.Error.NONE; |
58 | 59 |
59 /** @private */ | 60 /** @private */ |
| 61 this.hostDisplayName_ = hostDisplayName; |
| 62 /** @private */ |
60 this.hostJid_ = hostJid; | 63 this.hostJid_ = hostJid; |
61 /** @private */ | 64 /** @private */ |
62 this.hostPublicKey_ = hostPublicKey; | 65 this.hostPublicKey_ = hostPublicKey; |
63 /** @private */ | 66 /** @private */ |
64 this.accessCode_ = accessCode; | 67 this.accessCode_ = accessCode; |
65 /** @private */ | 68 /** @private */ |
66 this.fetchPin_ = fetchPin; | 69 this.fetchPin_ = fetchPin; |
67 /** @private */ | 70 /** @private */ |
68 this.fetchThirdPartyToken_ = fetchThirdPartyToken; | 71 this.fetchThirdPartyToken_ = fetchThirdPartyToken; |
69 /** @private */ | 72 /** @private */ |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 * | 105 * |
103 * @type {boolean} @private | 106 * @type {boolean} @private |
104 */ | 107 */ |
105 this.logHostOfflineErrors_ = true; | 108 this.logHostOfflineErrors_ = true; |
106 | 109 |
107 /** @private */ | 110 /** @private */ |
108 this.callPluginLostFocus_ = this.pluginLostFocus_.bind(this); | 111 this.callPluginLostFocus_ = this.pluginLostFocus_.bind(this); |
109 /** @private */ | 112 /** @private */ |
110 this.callPluginGotFocus_ = this.pluginGotFocus_.bind(this); | 113 this.callPluginGotFocus_ = this.pluginGotFocus_.bind(this); |
111 /** @private */ | 114 /** @private */ |
112 this.callSetScreenMode_ = this.onSetScreenMode_.bind(this); | |
113 /** @private */ | |
114 this.callToggleFullScreen_ = remoting.fullscreen.toggle.bind( | 115 this.callToggleFullScreen_ = remoting.fullscreen.toggle.bind( |
115 remoting.fullscreen); | 116 remoting.fullscreen); |
116 /** @private */ | 117 /** @private */ |
117 this.callOnFullScreenChanged_ = this.onFullScreenChanged_.bind(this) | 118 this.callOnFullScreenChanged_ = this.onFullScreenChanged_.bind(this) |
118 | 119 |
119 /** @private */ | 120 /** @private */ |
120 this.screenOptionsMenu_ = new remoting.MenuButton( | 121 this.screenOptionsMenu_ = new remoting.MenuButton( |
121 document.getElementById('screen-options-menu'), | 122 document.getElementById('screen-options-menu'), |
122 this.onShowOptionsMenu_.bind(this)); | 123 this.onShowOptionsMenu_.bind(this)); |
123 /** @private */ | 124 /** @private */ |
(...skipping 13 matching lines...) Expand all Loading... |
137 this.fullScreenButton_ = document.getElementById('toggle-full-screen'); | 138 this.fullScreenButton_ = document.getElementById('toggle-full-screen'); |
138 | 139 |
139 /** @type {remoting.GnubbyAuthHandler} @private */ | 140 /** @type {remoting.GnubbyAuthHandler} @private */ |
140 this.gnubbyAuthHandler_ = null; | 141 this.gnubbyAuthHandler_ = null; |
141 | 142 |
142 if (this.mode_ == remoting.ClientSession.Mode.IT2ME) { | 143 if (this.mode_ == remoting.ClientSession.Mode.IT2ME) { |
143 // Resize-to-client is not supported for IT2Me hosts. | 144 // Resize-to-client is not supported for IT2Me hosts. |
144 this.resizeToClientButton_.hidden = true; | 145 this.resizeToClientButton_.hidden = true; |
145 } else { | 146 } else { |
146 this.resizeToClientButton_.hidden = false; | 147 this.resizeToClientButton_.hidden = false; |
147 this.resizeToClientButton_.addEventListener( | |
148 'click', this.callSetScreenMode_, false); | |
149 } | 148 } |
150 | 149 |
151 this.shrinkToFitButton_.addEventListener( | |
152 'click', this.callSetScreenMode_, false); | |
153 this.fullScreenButton_.addEventListener( | 150 this.fullScreenButton_.addEventListener( |
154 'click', this.callToggleFullScreen_, false); | 151 'click', this.callToggleFullScreen_, false); |
155 this.defineEvents(Object.keys(remoting.ClientSession.Events)); | 152 this.defineEvents(Object.keys(remoting.ClientSession.Events)); |
156 }; | 153 }; |
157 | 154 |
158 base.extend(remoting.ClientSession, base.EventSource); | 155 base.extend(remoting.ClientSession, base.EventSource); |
159 | 156 |
160 /** @enum {string} */ | 157 /** @enum {string} */ |
161 remoting.ClientSession.Events = { | 158 remoting.ClientSession.Events = { |
162 stateChanged: 'stateChanged', | 159 stateChanged: 'stateChanged', |
163 videoChannelStateChanged: 'videoChannelStateChanged' | 160 videoChannelStateChanged: 'videoChannelStateChanged' |
164 }; | 161 }; |
165 | 162 |
166 /** | 163 /** |
| 164 * Get host display name. |
| 165 * |
| 166 * @return {string} |
| 167 */ |
| 168 remoting.ClientSession.prototype.getHostDisplayName = function() { |
| 169 return this.hostDisplayName_; |
| 170 }; |
| 171 |
| 172 /** |
167 * Called when the window or desktop size or the scaling settings change, | 173 * Called when the window or desktop size or the scaling settings change, |
168 * to set the scroll-bar visibility. | 174 * to set the scroll-bar visibility. |
169 * | 175 * |
170 * TODO(jamiewalch): crbug.com/252796: Remove this once crbug.com/240772 is | 176 * TODO(jamiewalch): crbug.com/252796: Remove this once crbug.com/240772 is |
171 * fixed. | 177 * fixed. |
172 */ | 178 */ |
173 remoting.ClientSession.prototype.updateScrollbarVisibility = function() { | 179 remoting.ClientSession.prototype.updateScrollbarVisibility = function() { |
174 var needsVerticalScroll = false; | 180 var needsVerticalScroll = false; |
175 var needsHorizontalScroll = false; | 181 var needsHorizontalScroll = false; |
176 if (!this.shrinkToFit_) { | 182 if (!this.shrinkToFit_) { |
(...skipping 18 matching lines...) Expand all Loading... |
195 } else { | 201 } else { |
196 scroller.classList.add('no-horizontal-scroll'); | 202 scroller.classList.add('no-horizontal-scroll'); |
197 } | 203 } |
198 if (needsVerticalScroll) { | 204 if (needsVerticalScroll) { |
199 scroller.classList.remove('no-vertical-scroll'); | 205 scroller.classList.remove('no-vertical-scroll'); |
200 } else { | 206 } else { |
201 scroller.classList.add('no-vertical-scroll'); | 207 scroller.classList.add('no-vertical-scroll'); |
202 } | 208 } |
203 }; | 209 }; |
204 | 210 |
| 211 /** |
| 212 * @return {boolean} True if shrink-to-fit is enabled; false otherwise. |
| 213 */ |
| 214 remoting.ClientSession.prototype.getShrinkToFit = function() { |
| 215 return this.shrinkToFit_; |
| 216 }; |
| 217 |
| 218 /** |
| 219 * @return {boolean} True if resize-to-client is enabled; false otherwise. |
| 220 */ |
| 221 remoting.ClientSession.prototype.getResizeToClient = function() { |
| 222 return this.resizeToClient_; |
| 223 }; |
| 224 |
205 // Note that the positive values in both of these enums are copied directly | 225 // Note that the positive values in both of these enums are copied directly |
206 // from chromoting_scriptable_object.h and must be kept in sync. The negative | 226 // from chromoting_scriptable_object.h and must be kept in sync. The negative |
207 // values represent state transitions that occur within the web-app that have | 227 // values represent state transitions that occur within the web-app that have |
208 // no corresponding plugin state transition. | 228 // no corresponding plugin state transition. |
209 /** @enum {number} */ | 229 /** @enum {number} */ |
210 remoting.ClientSession.State = { | 230 remoting.ClientSession.State = { |
211 CONNECTION_CANCELED: -3, // Connection closed (gracefully) before connecting. | 231 CONNECTION_CANCELED: -3, // Connection closed (gracefully) before connecting. |
212 CONNECTION_DROPPED: -2, // Succeeded, but subsequently closed with an error. | 232 CONNECTION_DROPPED: -2, // Succeeded, but subsequently closed with an error. |
213 CREATED: -1, | 233 CREATED: -1, |
214 UNKNOWN: 0, | 234 UNKNOWN: 0, |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 if (this.plugin_) { | 576 if (this.plugin_) { |
557 this.plugin_.element().removeEventListener( | 577 this.plugin_.element().removeEventListener( |
558 'focus', this.callPluginGotFocus_, false); | 578 'focus', this.callPluginGotFocus_, false); |
559 this.plugin_.element().removeEventListener( | 579 this.plugin_.element().removeEventListener( |
560 'blur', this.callPluginLostFocus_, false); | 580 'blur', this.callPluginLostFocus_, false); |
561 this.plugin_.cleanup(); | 581 this.plugin_.cleanup(); |
562 this.plugin_ = null; | 582 this.plugin_ = null; |
563 } | 583 } |
564 | 584 |
565 // Delete event handlers that aren't relevent when not connected. | 585 // Delete event handlers that aren't relevent when not connected. |
566 this.resizeToClientButton_.removeEventListener( | |
567 'click', this.callSetScreenMode_, false); | |
568 this.shrinkToFitButton_.removeEventListener( | |
569 'click', this.callSetScreenMode_, false); | |
570 this.fullScreenButton_.removeEventListener( | 586 this.fullScreenButton_.removeEventListener( |
571 'click', this.callToggleFullScreen_, false); | 587 'click', this.callToggleFullScreen_, false); |
572 | 588 |
573 // Leave full-screen mode, and stop listening for related events. | 589 // Leave full-screen mode, and stop listening for related events. |
574 var listener = this.callOnFullScreenChanged_; | 590 var listener = this.callOnFullScreenChanged_; |
575 remoting.fullscreen.syncWithMaximize(false); | 591 remoting.fullscreen.syncWithMaximize(false); |
576 remoting.fullscreen.activate( | 592 remoting.fullscreen.activate( |
577 false, | 593 false, |
578 function() { | 594 function() { |
579 remoting.fullscreen.removeListener(listener); | 595 remoting.fullscreen.removeListener(listener); |
580 }); | 596 }); |
581 if (remoting.windowFrame) { | 597 if (remoting.windowFrame) { |
582 remoting.windowFrame.setConnected(false); | 598 remoting.windowFrame.setConnected(false); |
583 } | 599 } |
| 600 remoting.toolbar.setClientSession(null); |
584 | 601 |
585 // Remove mediasource-rendering class from video-contained - this will also | 602 // Remove mediasource-rendering class from video-contained - this will also |
586 // hide the <video> element. | 603 // hide the <video> element. |
587 /** @type {HTMLElement} */(document.getElementById('video-container')) | 604 /** @type {HTMLElement} */(document.getElementById('video-container')) |
588 .classList.remove('mediasource-rendering'); | 605 .classList.remove('mediasource-rendering'); |
589 }; | 606 }; |
590 | 607 |
591 /** | 608 /** |
592 * Disconnect the current session with a particular |error|. The session will | 609 * Disconnect the current session with a particular |error|. The session will |
593 * raise a |stateChanged| event in response to it. The caller should then call | 610 * raise a |stateChanged| event in response to it. The caller should then call |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 this.plugin_.injectKeyEvent(keys[i], false); | 686 this.plugin_.injectKeyEvent(keys[i], false); |
670 } | 687 } |
671 } | 688 } |
672 | 689 |
673 /** | 690 /** |
674 * Sends a Ctrl-Alt-Del sequence to the remoting client. | 691 * Sends a Ctrl-Alt-Del sequence to the remoting client. |
675 * | 692 * |
676 * @return {void} Nothing. | 693 * @return {void} Nothing. |
677 */ | 694 */ |
678 remoting.ClientSession.prototype.sendCtrlAltDel = function() { | 695 remoting.ClientSession.prototype.sendCtrlAltDel = function() { |
| 696 console.log('Sending Ctrl-Alt-Del.'); |
679 this.sendKeyCombination_([0x0700e0, 0x0700e2, 0x07004c]); | 697 this.sendKeyCombination_([0x0700e0, 0x0700e2, 0x07004c]); |
680 } | 698 } |
681 | 699 |
682 /** | 700 /** |
683 * Sends a Print Screen keypress to the remoting client. | 701 * Sends a Print Screen keypress to the remoting client. |
684 * | 702 * |
685 * @return {void} Nothing. | 703 * @return {void} Nothing. |
686 */ | 704 */ |
687 remoting.ClientSession.prototype.sendPrintScreen = function() { | 705 remoting.ClientSession.prototype.sendPrintScreen = function() { |
| 706 console.log('Sending Print Screen.'); |
688 this.sendKeyCombination_([0x070046]); | 707 this.sendKeyCombination_([0x070046]); |
689 } | 708 } |
690 | 709 |
691 /** | 710 /** |
692 * Sets and stores the key remapping setting for the current host. | 711 * Sets and stores the key remapping setting for the current host. |
693 * | 712 * |
694 * @param {string} remappings Comma separated list of key remappings. | 713 * @param {string} remappings Comma separated list of key remappings. |
695 */ | 714 */ |
696 remoting.ClientSession.prototype.setRemapKeys = function(remappings) { | 715 remoting.ClientSession.prototype.setRemapKeys = function(remappings) { |
697 // Cancel any existing remappings and apply the new ones. | 716 // Cancel any existing remappings and apply the new ones. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 '>0x' + toKey.toString(16)); | 759 '>0x' + toKey.toString(16)); |
741 this.plugin_.remapKey(fromKey, toKey); | 760 this.plugin_.remapKey(fromKey, toKey); |
742 } else { | 761 } else { |
743 console.log('cancel remapKey 0x' + fromKey.toString(16)); | 762 console.log('cancel remapKey 0x' + fromKey.toString(16)); |
744 this.plugin_.remapKey(fromKey, fromKey); | 763 this.plugin_.remapKey(fromKey, fromKey); |
745 } | 764 } |
746 } | 765 } |
747 } | 766 } |
748 | 767 |
749 /** | 768 /** |
750 * Callback for the two "screen mode" related menu items: Resize desktop to | |
751 * fit and Shrink to fit. | |
752 * | |
753 * @param {Event} event The click event indicating which mode was selected. | |
754 * @return {void} Nothing. | |
755 * @private | |
756 */ | |
757 remoting.ClientSession.prototype.onSetScreenMode_ = function(event) { | |
758 var shrinkToFit = this.shrinkToFit_; | |
759 var resizeToClient = this.resizeToClient_; | |
760 if (event.target == this.shrinkToFitButton_) { | |
761 shrinkToFit = !shrinkToFit; | |
762 } | |
763 if (event.target == this.resizeToClientButton_) { | |
764 resizeToClient = !resizeToClient; | |
765 } | |
766 this.setScreenMode_(shrinkToFit, resizeToClient); | |
767 }; | |
768 | |
769 /** | |
770 * Set the shrink-to-fit and resize-to-client flags and save them if this is | 769 * Set the shrink-to-fit and resize-to-client flags and save them if this is |
771 * a Me2Me connection. | 770 * a Me2Me connection. |
772 * | 771 * |
773 * @param {boolean} shrinkToFit True if the remote desktop should be scaled | 772 * @param {boolean} shrinkToFit True if the remote desktop should be scaled |
774 * down if it is larger than the client window; false if scroll-bars | 773 * down if it is larger than the client window; false if scroll-bars |
775 * should be added in this case. | 774 * should be added in this case. |
776 * @param {boolean} resizeToClient True if window resizes should cause the | 775 * @param {boolean} resizeToClient True if window resizes should cause the |
777 * host to attempt to resize its desktop to match the client window size; | 776 * host to attempt to resize its desktop to match the client window size; |
778 * false to disable this behaviour for subsequent window resizes--the | 777 * false to disable this behaviour for subsequent window resizes--the |
779 * current host desktop size is not restored in this case. | 778 * current host desktop size is not restored in this case. |
780 * @return {void} Nothing. | 779 * @return {void} Nothing. |
781 * @private | |
782 */ | 780 */ |
783 remoting.ClientSession.prototype.setScreenMode_ = | 781 remoting.ClientSession.prototype.setScreenMode = |
784 function(shrinkToFit, resizeToClient) { | 782 function(shrinkToFit, resizeToClient) { |
785 if (resizeToClient && !this.resizeToClient_) { | 783 if (resizeToClient && !this.resizeToClient_) { |
786 var clientArea = this.getClientArea_(); | 784 var clientArea = this.getClientArea_(); |
787 this.plugin_.notifyClientResolution(clientArea.width, | 785 this.plugin_.notifyClientResolution(clientArea.width, |
788 clientArea.height, | 786 clientArea.height, |
789 window.devicePixelRatio); | 787 window.devicePixelRatio); |
790 } | 788 } |
791 | 789 |
792 // If enabling shrink, reset bump-scroll offsets. | 790 // If enabling shrink, reset bump-scroll offsets. |
793 var needsScrollReset = shrinkToFit && !this.shrinkToFit_; | 791 var needsScrollReset = shrinkToFit && !this.shrinkToFit_; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
975 this.plugin_.notifyClientResolution(clientArea.width, | 973 this.plugin_.notifyClientResolution(clientArea.width, |
976 clientArea.height, | 974 clientArea.height, |
977 window.devicePixelRatio); | 975 window.devicePixelRatio); |
978 } | 976 } |
979 // Activate full-screen related UX. | 977 // Activate full-screen related UX. |
980 remoting.fullscreen.addListener(this.callOnFullScreenChanged_); | 978 remoting.fullscreen.addListener(this.callOnFullScreenChanged_); |
981 remoting.fullscreen.syncWithMaximize(true); | 979 remoting.fullscreen.syncWithMaximize(true); |
982 if (remoting.windowFrame) { | 980 if (remoting.windowFrame) { |
983 remoting.windowFrame.setConnected(true); | 981 remoting.windowFrame.setConnected(true); |
984 } | 982 } |
| 983 remoting.toolbar.setClientSession(this); |
985 | 984 |
986 } else if (status == remoting.ClientSession.State.FAILED) { | 985 } else if (status == remoting.ClientSession.State.FAILED) { |
987 switch (error) { | 986 switch (error) { |
988 case remoting.ClientSession.ConnectionError.HOST_IS_OFFLINE: | 987 case remoting.ClientSession.ConnectionError.HOST_IS_OFFLINE: |
989 this.error_ = remoting.Error.HOST_IS_OFFLINE; | 988 this.error_ = remoting.Error.HOST_IS_OFFLINE; |
990 break; | 989 break; |
991 case remoting.ClientSession.ConnectionError.SESSION_REJECTED: | 990 case remoting.ClientSession.ConnectionError.SESSION_REJECTED: |
992 this.error_ = remoting.Error.INVALID_ACCESS_CODE; | 991 this.error_ = remoting.Error.INVALID_ACCESS_CODE; |
993 break; | 992 break; |
994 case remoting.ClientSession.ConnectionError.INCOMPATIBLE_PROTOCOL: | 993 case remoting.ClientSession.ConnectionError.INCOMPATIBLE_PROTOCOL: |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 * @return {{width: number, height: number}} The height of the window's client | 1506 * @return {{width: number, height: number}} The height of the window's client |
1508 * area. This differs between apps v1 and apps v2 due to the custom window | 1507 * area. This differs between apps v1 and apps v2 due to the custom window |
1509 * borders used by the latter. | 1508 * borders used by the latter. |
1510 * @private | 1509 * @private |
1511 */ | 1510 */ |
1512 remoting.ClientSession.prototype.getClientArea_ = function() { | 1511 remoting.ClientSession.prototype.getClientArea_ = function() { |
1513 return remoting.windowFrame ? | 1512 return remoting.windowFrame ? |
1514 remoting.windowFrame.getClientArea() : | 1513 remoting.windowFrame.getClientArea() : |
1515 { 'width': window.innerWidth, 'height': window.innerHeight }; | 1514 { 'width': window.innerWidth, 'height': window.innerHeight }; |
1516 } | 1515 } |
OLD | NEW |