@@ -27,11 +27,13 @@ import { UtilsService } from '@shared/services/utils.service';
2727import { WebClientService } from '@shared/services/web-client.service' ;
2828import { WebSessionService } from '@shared/services/web-session.service' ;
2929import { MessageService } from 'primeng/api' ;
30- import { EMPTY , from , Observable , of , Subject , throwError } from 'rxjs' ;
30+ import { debounceTime , EMPTY , from , Observable , of , Subject , Subscription , throwError } from 'rxjs' ;
3131import { catchError , map , switchMap , takeUntil } from 'rxjs/operators' ;
3232import '@devolutions/iron-remote-desktop/iron-remote-desktop.js' ;
3333import { DVL_RDP_ICON , DVL_WARNING_ICON , JET_RDP_URL } from '@gateway/app.constants' ;
3434import { AnalyticService , ProtocolString } from '@gateway/shared/services/analytic.service' ;
35+ import { WebSession } from '@shared/models/web-session.model' ;
36+ import { ComponentResizeObserverService } from '@shared/services/component-resize-observer.service' ;
3537
3638enum UserIronRdpErrorKind {
3739 General = 0 ,
@@ -49,6 +51,7 @@ enum UserIronRdpErrorKind {
4951} )
5052export class WebClientRdpComponent extends WebClientBaseComponent implements OnInit , AfterViewInit , OnDestroy {
5153 @Input ( ) webSessionId : string ;
54+ @Input ( ) sessionsContainerElement : ElementRef ;
5255 @Output ( ) componentStatus : EventEmitter < ComponentStatus > = new EventEmitter < ComponentStatus > ( ) ;
5356 @Output ( ) sizeChange : EventEmitter < void > = new EventEmitter < void > ( ) ;
5457
@@ -61,10 +64,12 @@ export class WebClientRdpComponent extends WebClientBaseComponent implements OnI
6164 formData : RdpFormDataInput ;
6265 rdpError : { kind : string ; backtrace : string } ;
6366 isFullScreenMode = false ;
64- showToolbarDiv = true ;
6567 useUnicodeKeyboard = false ;
6668 cursorOverrideActive = false ;
6769
70+ dynamicResizeSupported = false ;
71+ dynamicResizeEnabled = false ;
72+
6873 leftToolbarButtons = [
6974 {
7075 label : 'Start' ,
@@ -79,6 +84,11 @@ export class WebClientRdpComponent extends WebClientBaseComponent implements OnI
7984 ] ;
8085
8186 middleToolbarButtons = [
87+ {
88+ label : 'Full Screen' ,
89+ icon : 'dvl-icon dvl-icon-fullscreen' ,
90+ action : ( ) => this . toggleFullscreen ( ) ,
91+ } ,
8292 {
8393 label : 'Fit to Screen' ,
8494 icon : 'dvl-icon dvl-icon-minimize' ,
@@ -111,34 +121,40 @@ export class WebClientRdpComponent extends WebClientBaseComponent implements OnI
111121 checkboxes = [
112122 {
113123 label : 'Unicode Keyboard Mode' ,
114- default : this . useUnicodeKeyboard ,
124+ value : this . useUnicodeKeyboard ,
115125 onChange : ( ) => {
116126 this . useUnicodeKeyboard = ! this . useUnicodeKeyboard ;
117127 this . setKeyboardUnicodeMode ( this . useUnicodeKeyboard ) ;
118128 } ,
129+ enabled : ( ) => true ,
130+ } ,
131+ {
132+ label : 'Dynamic Resize' ,
133+ value : this . dynamicResizeEnabled ,
134+ onChange : ( ) => this . toggleDynamicResize ( ) ,
135+ enabled : ( ) => this . dynamicResizeSupported ,
119136 } ,
120137 ] ;
121138
122139 protected removeElement = new Subject ( ) ;
123140 private remoteClientEventListener : ( event : Event ) => void ;
124141 private remoteClient : UserInteraction ;
125142
143+ private componentResizeObserverDisconnect ?: ( ) => void ;
144+ private dynamicComponentResizeSubscription ?: Subscription ;
145+
126146 constructor (
127147 private renderer : Renderer2 ,
128148 protected utils : UtilsService ,
129149 protected gatewayAlertMessageService : GatewayAlertMessageService ,
130150 private webSessionService : WebSessionService ,
131151 private webClientService : WebClientService ,
152+ private componentResizeService : ComponentResizeObserverService ,
132153 protected analyticService : AnalyticService ,
133154 ) {
134155 super ( gatewayAlertMessageService , analyticService ) ;
135156 }
136157
137- @HostListener ( 'document:mousemove' , [ '$event' ] )
138- onMouseMove ( event : MouseEvent ) : void {
139- this . handleSessionToolbarDisplay ( event ) ;
140- }
141-
142158 @HostListener ( 'document:fullscreenchange' )
143159 onFullScreenChange ( ) : void {
144160 this . handleOnFullScreenEvent ( ) ;
@@ -155,6 +171,10 @@ export class WebClientRdpComponent extends WebClientBaseComponent implements OnI
155171 ngOnDestroy ( ) : void {
156172 this . removeRemoteClientListener ( ) ;
157173 this . removeWebClientGuiElement ( ) ;
174+
175+ this . dynamicComponentResizeSubscription ?. unsubscribe ( ) ;
176+ this . componentResizeObserverDisconnect ?.( ) ;
177+
158178 super . ngOnDestroy ( ) ;
159179 }
160180
@@ -182,11 +202,7 @@ export class WebClientRdpComponent extends WebClientBaseComponent implements OnI
182202 }
183203
184204 scaleTo ( scale : ScreenScale ) : void {
185- if ( scale === ScreenScale . Full ) {
186- this . toggleFullscreen ( ) ;
187- } else {
188- this . remoteClient . setScale ( scale . valueOf ( ) ) ;
189- }
205+ this . remoteClient . setScale ( scale . valueOf ( ) ) ;
190206 }
191207
192208 setKeyboardUnicodeMode ( useUnicode : boolean ) : void {
@@ -203,6 +219,30 @@ export class WebClientRdpComponent extends WebClientBaseComponent implements OnI
203219 this . cursorOverrideActive = ! this . cursorOverrideActive ;
204220 }
205221
222+ toggleDynamicResize ( ) : void {
223+ const RESIZE_DEBOUNCE_TIME = 100 ;
224+
225+ this . dynamicResizeEnabled = ! this . dynamicResizeEnabled ;
226+
227+ if ( this . dynamicResizeEnabled ) {
228+ this . componentResizeObserverDisconnect = this . componentResizeService . observe (
229+ this . sessionsContainerElement . nativeElement ,
230+ ) ;
231+
232+ this . dynamicComponentResizeSubscription = this . componentResizeService . resize$
233+ . pipe ( debounceTime ( RESIZE_DEBOUNCE_TIME ) )
234+ . subscribe ( ( { width, height } ) => {
235+ if ( ! this . isFullScreenMode ) {
236+ height -= WebSession . TOOLBAR_SIZE ;
237+ }
238+ this . remoteClient . resize ( width , height ) ;
239+ } ) ;
240+ } else {
241+ this . dynamicComponentResizeSubscription ?. unsubscribe ( ) ;
242+ this . componentResizeObserverDisconnect ?.( ) ;
243+ }
244+ }
245+
206246 removeWebClientGuiElement ( ) : void {
207247 this . removeElement . pipe ( takeUntil ( this . destroyed$ ) ) . subscribe ( {
208248 next : ( ) : void => {
@@ -236,21 +276,11 @@ export class WebClientRdpComponent extends WebClientBaseComponent implements OnI
236276 }
237277 }
238278
239- private handleSessionToolbarDisplay ( event : MouseEvent ) : void {
240- if ( ! document . fullscreenElement ) {
241- return ;
242- }
243-
244- if ( event . clientY === 0 ) {
245- this . showToolbarDiv = true ;
246- } else if ( event . clientY > 44 ) {
247- this . showToolbarDiv = false ;
248- }
249- }
250-
251279 private toggleFullscreen ( ) : void {
252280 this . isFullScreenMode = ! this . isFullScreenMode ;
253281 ! document . fullscreenElement ? this . enterFullScreen ( ) : this . exitFullScreen ( ) ;
282+
283+ this . scaleTo ( ScreenScale . Full ) ;
254284 }
255285
256286 private async enterFullScreen ( ) : Promise < void > {
@@ -259,8 +289,7 @@ export class WebClientRdpComponent extends WebClientBaseComponent implements OnI
259289 }
260290
261291 try {
262- const sessionContainerElement = this . sessionContainerElement . nativeElement ;
263- await sessionContainerElement . requestFullscreen ( ) ;
292+ await this . sessionsContainerElement . nativeElement . requestFullscreen ( ) ;
264293 } catch ( err ) {
265294 this . isFullScreenMode = false ;
266295 console . error ( `Error attempting to enable fullscreen mode: ${ err . message } (${ err . name } )` ) ;
@@ -277,7 +306,6 @@ export class WebClientRdpComponent extends WebClientBaseComponent implements OnI
277306
278307 private handleExitFullScreenEvent ( ) : void {
279308 this . isFullScreenMode = false ;
280- this . showToolbarDiv = true ;
281309
282310 const sessionContainerElement = this . sessionContainerElement . nativeElement ;
283311 const sessionToolbarElement = sessionContainerElement . querySelector ( '#sessionToolbar' ) ;
@@ -394,6 +422,7 @@ export class WebClientRdpComponent extends WebClientBaseComponent implements OnI
394422
395423 if ( connectionParameters . enableDisplayControl ) {
396424 configBuilder . withExtension ( displayControl ( true ) ) ;
425+ this . dynamicResizeSupported = true ;
397426 }
398427
399428 if ( connectionParameters . preConnectionBlob != null ) {
0 commit comments