window - try to improve focus handling (#206721)

This commit is contained in:
Benjamin Pasero
2024-03-03 14:35:38 -08:00
committed by GitHub
parent 161d501000
commit c0fddb67b9
10 changed files with 81 additions and 125 deletions
-20
View File
@@ -921,26 +921,6 @@ export function getActiveWindow(): CodeWindow {
return (document.defaultView?.window ?? mainWindow) as CodeWindow;
}
export function focusWindow(element: Node, options?: { force: boolean }): void {
const window = getWindow(element);
// Force: always focus the element window
if (options?.force) {
window.focus();
}
// Not forced: only focus the element window if another
// window in the same workspace group has focus (when auxiliary
// windows are opened).
// This prevents stealing focus from another workspace window.
else {
const activeWindow = getActiveWindow();
if (activeWindow.document.hasFocus() && activeWindow !== window) {
window.focus();
}
}
}
const globalStylesheets = new Map<HTMLStyleElement /* main stylesheet */, Set<HTMLStyleElement /* aux window clones that track the main stylesheet */>>();
export function isGlobalStylesheet(node: Node): boolean {
+2 -8
View File
@@ -10,7 +10,7 @@ import { IComposite, ICompositeControl } from 'vs/workbench/common/composite';
import { Event, Emitter } from 'vs/base/common/event';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IConstructorSignature, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { trackFocus, Dimension, IDomPosition, focusWindow } from 'vs/base/browser/dom';
import { trackFocus, Dimension, IDomPosition } from 'vs/base/browser/dom';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { Disposable } from 'vs/base/common/lifecycle';
import { assertIsDefined } from 'vs/base/common/types';
@@ -149,13 +149,7 @@ export abstract class Composite extends Component implements IComposite {
* Called when this composite should receive keyboard focus.
*/
focus(): void {
const container = this.getContainer();
if (container) {
// Make sure to focus the window of the container
// because it is possible that the composite is
// opened in a auxiliary window that is not focused.
focusWindow(container);
}
// Subclasses can implement
}
/**
+1 -4
View File
@@ -5,7 +5,7 @@
import { Disposable, DisposableMap, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import { EventType, addDisposableListener, getClientArea, position, size, IDimension, isAncestorUsingFlowTo, computeScreenAwareSize, getActiveDocument, getWindows, getActiveWindow, focusWindow, isActiveDocument, getWindow, getWindowId, getActiveElement } from 'vs/base/browser/dom';
import { EventType, addDisposableListener, getClientArea, position, size, IDimension, isAncestorUsingFlowTo, computeScreenAwareSize, getActiveDocument, getWindows, getActiveWindow, isActiveDocument, getWindow, getWindowId, getActiveElement } from 'vs/base/browser/dom';
import { onDidChangeFullscreen, isFullscreen, isWCOEnabled } from 'vs/base/browser/browser';
import { IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackup';
import { isWindows, isLinux, isMacintosh, isWeb, isIOS } from 'vs/base/common/platform';
@@ -1124,9 +1124,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
focusPart(part: SINGLE_WINDOW_PARTS): void;
focusPart(part: Parts, targetWindow: Window = mainWindow): void {
const container = this.getContainer(targetWindow, part) ?? this.mainContainer;
if (container) {
focusWindow(container);
}
switch (part) {
case Parts.EDITOR_PART:
@@ -11,7 +11,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
import { Emitter, Relay } from 'vs/base/common/event';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { Dimension, trackFocus, addDisposableListener, EventType, EventHelper, findParentWithClass, isAncestor, IDomNodePagePosition, isMouseEvent, isActiveElement, focusWindow, getWindow, getActiveElement } from 'vs/base/browser/dom';
import { Dimension, trackFocus, addDisposableListener, EventType, EventHelper, findParentWithClass, isAncestor, IDomNodePagePosition, isMouseEvent, isActiveElement, getWindow, getActiveElement } from 'vs/base/browser/dom';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
@@ -976,9 +976,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
focus(): void {
// Ensure window focus
focusWindow(this.element);
// Pass focus to editor panes
if (this.activeEditorPane) {
this.activeEditorPane.focus();
@@ -8,7 +8,7 @@ import * as nls from 'vs/nls';
import { Event, Emitter } from 'vs/base/common/event';
import { asCssVariable, foreground } from 'vs/platform/theme/common/colorRegistry';
import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { after, append, $, trackFocus, EventType, addDisposableListener, createCSSRule, asCSSUrl, Dimension, reset, asCssValueWithDefault, focusWindow } from 'vs/base/browser/dom';
import { after, append, $, trackFocus, EventType, addDisposableListener, createCSSRule, asCSSUrl, Dimension, reset, asCssValueWithDefault } from 'vs/base/browser/dom';
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { Action, IAction, IActionRunner } from 'vs/base/common/actions';
import { ActionsOrientation, IActionViewItem, prepareActions } from 'vs/base/browser/ui/actionbar/actionbar';
@@ -630,8 +630,6 @@ export abstract class ViewPane extends Pane implements IView {
}
focus(): void {
focusWindow(this.element);
if (this.viewWelcomeController.enabled) {
this.viewWelcomeController.focus();
} else if (this.element) {
+42 -9
View File
@@ -4,14 +4,14 @@
*--------------------------------------------------------------------------------------------*/
import { isSafari, setFullscreen } from 'vs/base/browser/browser';
import { addDisposableListener, EventHelper, EventType, focusWindow, getWindowById, getWindows, getWindowsCount, windowOpenNoOpener, windowOpenPopup, windowOpenWithSuccess } from 'vs/base/browser/dom';
import { addDisposableListener, EventHelper, EventType, getActiveWindow, getWindow, getWindowById, getWindows, getWindowsCount, windowOpenNoOpener, windowOpenPopup, windowOpenWithSuccess } from 'vs/base/browser/dom';
import { DomEmitter } from 'vs/base/browser/event';
import { HidDeviceData, requestHidDevice, requestSerialPort, requestUsbDevice, SerialPortData, UsbDeviceData } from 'vs/base/browser/deviceAccess';
import { timeout } from 'vs/base/common/async';
import { Event } from 'vs/base/common/event';
import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { matchesScheme, Schemas } from 'vs/base/common/network';
import { isIOS, isMacintosh } from 'vs/base/common/platform';
import { isIOS, isMacintosh, isNative } from 'vs/base/common/platform';
import Severity from 'vs/base/common/severity';
import { URI } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
@@ -30,6 +30,7 @@ import { registerWindowDriver } from 'vs/workbench/services/driver/browser/drive
import { CodeWindow, isAuxiliaryWindow, mainWindow } from 'vs/base/browser/window';
import { createSingleCallFunction } from 'vs/base/common/functional';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
export abstract class BaseWindow extends Disposable {
@@ -39,11 +40,16 @@ export abstract class BaseWindow extends Disposable {
constructor(
targetWindow: CodeWindow,
dom = { getWindowsCount, getWindows }, /* for testing */
@IHostService protected readonly hostService: IHostService
@IHostService protected readonly hostService: IHostService,
@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService
) {
super();
if (isNative) {
this.enableNativeWindowFocus(targetWindow);
}
this.enableWindowFocusOnElementFocus(targetWindow);
this.enableMultiWindowAwareTimeout(targetWindow, dom);
this.registerFullScreenListeners(targetWindow.vscodeWindowId);
@@ -51,13 +57,40 @@ export abstract class BaseWindow extends Disposable {
//#region focus handling in multi-window applications
protected enableNativeWindowFocus(targetWindow: CodeWindow): void {
const originalWindowFocus = targetWindow.focus.bind(targetWindow);
const that = this;
targetWindow.focus = function () {
originalWindowFocus();
if (
!that.environmentService.extensionTestsLocationURI && // never steal focus when running tests
!targetWindow.document.hasFocus() // skip when already having focus
) {
// Enable `window.focus()` to work in Electron by
// asking the main process to focus the window.
// https://github.com/electron/electron/issues/25578
that.hostService.focus(targetWindow);
}
};
}
protected enableWindowFocusOnElementFocus(targetWindow: CodeWindow): void {
const originalFocus = HTMLElement.prototype.focus;
targetWindow.HTMLElement.prototype.focus = function (this: HTMLElement, options?: FocusOptions | undefined): void {
// Ensure elements window is focused
focusWindow(this);
// If the active focused window is not the same as the
// window of the element to focus, make sure to focus
// that window first before focusing the element.
const activeWindow = getActiveWindow();
if (activeWindow.document.hasFocus()) {
const elementWindow = getWindow(this);
if (activeWindow !== elementWindow) {
elementWindow.focus();
}
}
// Pass to original focus() method
originalFocus.apply(this, [options]);
@@ -178,12 +211,12 @@ export class BrowserWindow extends BaseWindow {
@IDialogService private readonly dialogService: IDialogService,
@ILabelService private readonly labelService: ILabelService,
@IProductService private readonly productService: IProductService,
@IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
@IBrowserWorkbenchEnvironmentService private readonly browserEnvironmentService: IBrowserWorkbenchEnvironmentService,
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IHostService hostService: IHostService
) {
super(mainWindow, undefined, hostService);
super(mainWindow, undefined, hostService, browserEnvironmentService);
this.registerListeners();
this.create();
@@ -280,8 +313,8 @@ export class BrowserWindow extends BaseWindow {
this.openerService.setDefaultExternalOpener({
openExternal: async (href: string) => {
let isAllowedOpener = false;
if (this.environmentService.options?.openerAllowedExternalUrlPrefixes) {
for (const trustedPopupPrefix of this.environmentService.options.openerAllowedExternalUrlPrefixes) {
if (this.browserEnvironmentService.options?.openerAllowedExternalUrlPrefixes) {
for (const trustedPopupPrefix of this.browserEnvironmentService.options.openerAllowedExternalUrlPrefixes) {
if (href.startsWith(trustedPopupPrefix)) {
isAllowedOpener = true;
break;
+9 -32
View File
@@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
import { URI } from 'vs/base/common/uri';
import { onUnexpectedError } from 'vs/base/common/errors';
import { equals } from 'vs/base/common/objects';
import { EventType, EventHelper, addDisposableListener, ModifierKeyEmitter, getActiveElement, hasWindow, getWindow, getWindowById, getWindowId, getWindows } from 'vs/base/browser/dom';
import { EventType, EventHelper, addDisposableListener, ModifierKeyEmitter, getActiveElement, hasWindow, getWindow, getWindowById, getWindows } from 'vs/base/browser/dom';
import { Action, Separator, WorkbenchActionExecutedClassification, WorkbenchActionExecutedEvent } from 'vs/base/common/actions';
import { IFileService } from 'vs/platform/files/common/files';
import { EditorResourceAccessor, IUntitledTextResourceEditorInput, SideBySideEditor, pathsToEditors, IResourceDiffEditorInput, IUntypedEditorInput, IEditorPane, isResourceEditorInput, IResourceMergeEditorInput } from 'vs/workbench/common/editor';
@@ -107,7 +107,7 @@ export class NativeWindow extends BaseWindow {
@IMenuService private readonly menuService: IMenuService,
@ILifecycleService private readonly lifecycleService: ILifecycleService,
@IIntegrityService private readonly integrityService: IIntegrityService,
@INativeWorkbenchEnvironmentService private readonly environmentService: INativeWorkbenchEnvironmentService,
@INativeWorkbenchEnvironmentService private readonly nativeEnvironmentService: INativeWorkbenchEnvironmentService,
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IOpenerService private readonly openerService: IOpenerService,
@@ -131,7 +131,7 @@ export class NativeWindow extends BaseWindow {
@IUtilityProcessWorkerWorkbenchService private readonly utilityProcessWorkerWorkbenchService: IUtilityProcessWorkerWorkbenchService,
@IHostService hostService: IHostService
) {
super(mainWindow, undefined, hostService);
super(mainWindow, undefined, hostService, nativeEnvironmentService);
this.mainPartEditorService = editorService.createScoped('main', this._store);
@@ -353,7 +353,7 @@ export class NativeWindow extends BaseWindow {
this._register(Event.debounce(this.editorService.onDidVisibleEditorsChange, () => undefined, 0, undefined, undefined, undefined, this._store)(() => this.maybeCloseWindow()));
// Listen to editor closing (if we run with --wait)
const filesToWait = this.environmentService.filesToWait;
const filesToWait = this.nativeEnvironmentService.filesToWait;
if (filesToWait) {
this.trackClosedWaitFiles(filesToWait.waitMarkerFileUri, coalesce(filesToWait.paths.map(path => path.fileUri)));
}
@@ -412,7 +412,7 @@ export class NativeWindow extends BaseWindow {
Event.map(Event.filter(this.nativeHostService.onDidMaximizeWindow, windowId => !!hasWindow(windowId)), windowId => ({ maximized: true, windowId })),
Event.map(Event.filter(this.nativeHostService.onDidUnmaximizeWindow, windowId => !!hasWindow(windowId)), windowId => ({ maximized: false, windowId }))
)(e => this.layoutService.updateWindowMaximizedState(getWindowById(e.windowId)!.window, e.maximized)));
this.layoutService.updateWindowMaximizedState(mainWindow, this.environmentService.window.maximized ?? false);
this.layoutService.updateWindowMaximizedState(mainWindow, this.nativeEnvironmentService.window.maximized ?? false);
// Detect panel position to determine minimum width
this._register(this.layoutService.onDidChangePanelPosition(pos => this.onDidChangePanelPosition(positionFromString(pos))));
@@ -582,7 +582,7 @@ export class NativeWindow extends BaseWindow {
}
private maybeCloseWindow(): void {
const closeWhenEmpty = this.configurationService.getValue('window.closeWhenEmpty') || this.environmentService.args.wait;
const closeWhenEmpty = this.configurationService.getValue('window.closeWhenEmpty') || this.nativeEnvironmentService.args.wait;
if (!closeWhenEmpty) {
return; // return early if configured to not close when empty
}
@@ -671,29 +671,6 @@ export class NativeWindow extends BaseWindow {
if (this.environmentService.enableSmokeTestDriver) {
this.setupDriver();
}
// Patch methods that we need to work properly
this.patchMethods();
}
private patchMethods(): void {
// Enable `window.focus()` to work in Electron by
// asking the main process to focus the window.
// https://github.com/electron/electron/issues/25578
const that = this;
const originalWindowFocus = mainWindow.focus.bind(mainWindow);
mainWindow.focus = function () {
if (that.environmentService.extensionTestsLocationURI) {
return; // no focus when we are running tests from CLI
}
originalWindowFocus();
if (!mainWindow.document.hasFocus()) {
that.nativeHostService.focusWindow({ targetWindowId: getWindowId(mainWindow) });
}
};
}
private async handleWarnings(): Promise<void> {
@@ -731,11 +708,11 @@ export class NativeWindow extends BaseWindow {
let installLocationUri: URI;
if (isMacintosh) {
// appRoot = /Applications/Visual Studio Code - Insiders.app/Contents/Resources/app
installLocationUri = dirname(dirname(dirname(URI.file(this.environmentService.appRoot))));
installLocationUri = dirname(dirname(dirname(URI.file(this.nativeEnvironmentService.appRoot))));
} else {
// appRoot = C:\Users\<name>\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app
// appRoot = /usr/share/code-insiders/resources/app
installLocationUri = dirname(dirname(URI.file(this.environmentService.appRoot)));
installLocationUri = dirname(dirname(URI.file(this.nativeEnvironmentService.appRoot)));
}
for (const folder of this.contextService.getWorkspace().folders) {
@@ -753,7 +730,7 @@ export class NativeWindow extends BaseWindow {
// macOS 10.13 and 10.14 warning
if (isMacintosh) {
const majorVersion = this.environmentService.os.release.split('.')[0];
const majorVersion = this.nativeEnvironmentService.os.release.split('.')[0];
const eolReleases = new Map<string, string>([
['17', 'macOS High Sierra'],
['18', 'macOS Mojave'],
@@ -22,6 +22,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { Barrier } from 'vs/base/common/async';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
export const IAuxiliaryWindowService = createDecorator<IAuxiliaryWindowService>('auxiliaryWindowService');
@@ -84,9 +85,10 @@ export class AuxiliaryWindow extends BaseWindow implements IAuxiliaryWindow {
readonly container: HTMLElement,
stylesHaveLoaded: Barrier,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IHostService hostService: IHostService
@IHostService hostService: IHostService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService
) {
super(window, undefined, hostService);
super(window, undefined, hostService, environmentService);
this.whenStylesHaveLoaded = stylesHaveLoaded.wait().then(() => { });
this.registerListeners();
@@ -182,7 +184,8 @@ export class BrowserAuxiliaryWindowService extends Disposable implements IAuxili
@IDialogService private readonly dialogService: IDialogService,
@IConfigurationService protected readonly configurationService: IConfigurationService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IHostService protected readonly hostService: IHostService
@IHostService protected readonly hostService: IHostService,
@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService
) {
super();
}
@@ -237,7 +240,7 @@ export class BrowserAuxiliaryWindowService extends Disposable implements IAuxili
}
protected createAuxiliaryWindow(targetWindow: CodeWindow, container: HTMLElement, stylesLoaded: Barrier): AuxiliaryWindow {
return new AuxiliaryWindow(targetWindow, container, stylesLoaded, this.configurationService, this.hostService);
return new AuxiliaryWindow(targetWindow, container, stylesLoaded, this.configurationService, this.hostService, this.environmentService);
}
private async openWindow(options?: IAuxiliaryWindowOpenOptions): Promise<Window | undefined> {
@@ -293,24 +296,20 @@ export class BrowserAuxiliaryWindowService extends Disposable implements IAuxili
}
protected createContainer(auxiliaryWindow: CodeWindow, disposables: DisposableStore, options?: IAuxiliaryWindowOpenOptions): { stylesLoaded: Barrier; container: HTMLElement } {
this.patchMethods(auxiliaryWindow);
auxiliaryWindow.document.createElement = function () {
// Disallow `createElement` because it would create
// HTML Elements in the "wrong" context and break
// code that does "instanceof HTMLElement" etc.
throw new Error('Not allowed to create elements in child window JavaScript context. Always use the main window so that "xyz instanceof HTMLElement" continues to work.');
};
this.applyMeta(auxiliaryWindow);
const { stylesLoaded } = this.applyCSS(auxiliaryWindow, disposables);
const container = this.applyHTML(auxiliaryWindow, disposables);
return { stylesLoaded, container };
}
protected patchMethods(auxiliaryWindow: CodeWindow): void {
// Disallow `createElement` because it would create
// HTML Elements in the "wrong" context and break
// code that does "instanceof HTMLElement" etc.
auxiliaryWindow.document.createElement = function () {
throw new Error('Not allowed to create elements in child window JavaScript context. Always use the main window so that "xyz instanceof HTMLElement" continues to work.');
};
}
private applyMeta(auxiliaryWindow: CodeWindow): void {
for (const metaTag of ['meta[charset="utf-8"]', 'meta[http-equiv="Content-Security-Policy"]', 'meta[name="viewport"]', 'meta[name="theme-color"]']) {
const metaElement = mainWindow.document.querySelector(metaTag);
@@ -17,11 +17,11 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { ShutdownReason } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { Barrier } from 'vs/base/common/async';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { applyZoom } from 'vs/platform/window/electron-sandbox/window';
import { getZoomLevel } from 'vs/base/browser/browser';
import { getActiveWindow } from 'vs/base/browser/dom';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
type NativeCodeWindow = CodeWindow & {
readonly vscode: ISandboxGlobals;
@@ -38,9 +38,10 @@ export class NativeAuxiliaryWindow extends AuxiliaryWindow {
@IConfigurationService configurationService: IConfigurationService,
@INativeHostService private readonly nativeHostService: INativeHostService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IHostService hostService: IHostService
@IHostService hostService: IHostService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService
) {
super(window, container, stylesHaveLoaded, configurationService, hostService);
super(window, container, stylesHaveLoaded, configurationService, hostService, environmentService);
}
protected override async confirmBeforeClose(e: BeforeUnloadEvent): Promise<void> {
@@ -68,10 +69,10 @@ export class NativeAuxiliaryWindowService extends BrowserAuxiliaryWindowService
@IDialogService dialogService: IDialogService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@ITelemetryService telemetryService: ITelemetryService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IHostService hostService: IHostService
@IHostService hostService: IHostService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService
) {
super(layoutService, dialogService, configurationService, telemetryService, hostService);
super(layoutService, dialogService, configurationService, telemetryService, hostService, environmentService);
}
protected override async resolveWindowId(auxiliaryWindow: NativeCodeWindow): Promise<number> {
@@ -97,29 +98,8 @@ export class NativeAuxiliaryWindowService extends BrowserAuxiliaryWindowService
return super.createContainer(auxiliaryWindow, disposables);
}
protected override patchMethods(auxiliaryWindow: NativeCodeWindow): void {
super.patchMethods(auxiliaryWindow);
// Enable `window.focus()` to work in Electron by
// asking the main process to focus the window.
// https://github.com/electron/electron/issues/25578
const that = this;
const originalWindowFocus = auxiliaryWindow.focus.bind(auxiliaryWindow);
auxiliaryWindow.focus = function () {
if (that.environmentService.extensionTestsLocationURI) {
return; // no focus when we are running tests from CLI
}
originalWindowFocus();
if (!auxiliaryWindow.document.hasFocus()) {
that.nativeHostService.focusWindow({ targetWindowId: auxiliaryWindow.vscodeWindowId });
}
};
}
protected override createAuxiliaryWindow(targetWindow: CodeWindow, container: HTMLElement, stylesHaveLoaded: Barrier,): AuxiliaryWindow {
return new NativeAuxiliaryWindow(targetWindow, container, stylesHaveLoaded, this.configurationService, this.nativeHostService, this.instantiationService, this.hostService);
return new NativeAuxiliaryWindow(targetWindow, container, stylesHaveLoaded, this.configurationService, this.nativeHostService, this.instantiationService, this.hostService, this.environmentService);
}
}
+3 -2
View File
@@ -10,7 +10,7 @@ import { DisposableStore } from 'vs/base/common/lifecycle';
import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler';
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
import { BaseWindow } from 'vs/workbench/browser/window';
import { TestHostService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestEnvironmentService, TestHostService } from 'vs/workbench/test/browser/workbenchTestServices';
suite('Window', () => {
@@ -19,9 +19,10 @@ suite('Window', () => {
class TestWindow extends BaseWindow {
constructor(window: CodeWindow, dom: { getWindowsCount: () => number; getWindows: () => Iterable<IRegisteredCodeWindow> }) {
super(window, dom, new TestHostService());
super(window, dom, new TestHostService(), TestEnvironmentService);
}
protected override enableNativeWindowFocus(): void { }
protected override enableWindowFocusOnElementFocus(): void { }
}