3
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
- import { Event } from 'vs/base/common/event' ;
6
+ import { Emitter , Event } from 'vs/base/common/event' ;
7
7
import { IHostService } from 'vs/workbench/services/host/browser/host' ;
8
8
import { INativeHostService } from 'vs/platform/native/common/native' ;
9
9
import { InstantiationType , registerSingleton } from 'vs/platform/instantiation/common/extensions' ;
@@ -15,7 +15,9 @@ import { NativeHostService } from 'vs/platform/native/electron-sandbox/nativeHos
15
15
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService' ;
16
16
import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService' ;
17
17
import { isAuxiliaryWindow } from 'vs/workbench/services/auxiliaryWindow/electron-sandbox/auxiliaryWindowService' ;
18
- import { getActiveWindow } from 'vs/base/browser/dom' ;
18
+ import { getActiveDocument , getActiveWindow , onDidRegisterWindow , trackFocus } from 'vs/base/browser/dom' ;
19
+ import { DomEmitter } from 'vs/base/browser/event' ;
20
+ import { memoize } from 'vs/base/common/decorators' ;
19
21
20
22
class WorkbenchNativeHostService extends NativeHostService {
21
23
@@ -41,14 +43,29 @@ class WorkbenchHostService extends Disposable implements IHostService {
41
43
42
44
//#region Focus
43
45
44
- get onDidChangeFocus ( ) : Event < boolean > { return this . _onDidChangeFocus ; }
45
- private _onDidChangeFocus : Event < boolean > = Event . latch ( Event . any (
46
- Event . map ( Event . filter ( this . nativeHostService . onDidFocusWindow , id => id === this . nativeHostService . windowId ) , ( ) => this . hasFocus ) ,
47
- Event . map ( Event . filter ( this . nativeHostService . onDidBlurWindow , id => id === this . nativeHostService . windowId ) , ( ) => this . hasFocus )
48
- ) , undefined , this . _store ) ;
46
+ @memoize
47
+ get onDidChangeFocus ( ) : Event < boolean > {
48
+ const emitter = this . _register ( new Emitter < boolean > ( ) ) ;
49
+
50
+ // Main window: track via native API
51
+ this . _register ( Event . filter ( this . nativeHostService . onDidFocusWindow , id => id === this . nativeHostService . windowId , this . _store ) ( ( ) => emitter . fire ( this . hasFocus ) ) ) ;
52
+ this . _register ( Event . filter ( this . nativeHostService . onDidBlurWindow , id => id === this . nativeHostService . windowId , this . _store ) ( ( ) => emitter . fire ( this . hasFocus ) ) ) ;
53
+
54
+ // Aux windows: track via DOM APIs
55
+ this . _register ( onDidRegisterWindow ( ( { window, disposables } ) => {
56
+ const focusTracker = disposables . add ( trackFocus ( window ) ) ;
57
+ const onVisibilityChange = disposables . add ( new DomEmitter ( window . document , 'visibilitychange' ) ) ;
58
+
59
+ disposables . add ( focusTracker . onDidFocus ( ( ) => emitter . fire ( this . hasFocus ) ) ) ;
60
+ disposables . add ( focusTracker . onDidBlur ( ( ) => emitter . fire ( this . hasFocus ) ) ) ;
61
+ disposables . add ( onVisibilityChange . event ( ( ) => emitter . fire ( this . hasFocus ) ) ) ;
62
+ } ) ) ;
63
+
64
+ return emitter . event ;
65
+ }
49
66
50
67
get hasFocus ( ) : boolean {
51
- return document . hasFocus ( ) ;
68
+ return getActiveDocument ( ) . hasFocus ( ) ;
52
69
}
53
70
54
71
async hadLastFocus ( ) : Promise < boolean > {
0 commit comments