diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index a843f9f0144..89c196bd81e 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -830,7 +830,7 @@ export function isGlobalStylesheet(node: Node): boolean { return globalStylesheets.has(node as HTMLStyleElement); } -export function cloneGlobalStylesheets(targetWindow: Window & typeof globalThis): IDisposable { +export function cloneGlobalStylesheets(targetWindow: Window): IDisposable { const disposables = new DisposableStore(); for (const [globalStylesheet] of globalStylesheets) { @@ -840,7 +840,7 @@ export function cloneGlobalStylesheets(targetWindow: Window & typeof globalThis) return disposables; } -function cloneGlobalStyleSheet(globalStylesheet: HTMLStyleElement, targetWindow: Window & typeof globalThis): IDisposable { +function cloneGlobalStyleSheet(globalStylesheet: HTMLStyleElement, targetWindow: Window): IDisposable { const clone = globalStylesheet.cloneNode(true) as HTMLStyleElement; targetWindow.document.head.appendChild(clone); diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index 5a9796b18db..3a7ba7f708d 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -96,14 +96,14 @@ export class ResourcesDropHandler { ) { } - async handleDrop(event: DragEvent, resolveTargetGroup?: () => IEditorGroup | undefined, afterDrop?: (targetGroup: IEditorGroup | undefined) => void, options?: IEditorOptions): Promise { + async handleDrop(event: DragEvent, targetWindow: Window, resolveTargetGroup?: () => IEditorGroup | undefined, afterDrop?: (targetGroup: IEditorGroup | undefined) => void, options?: IEditorOptions): Promise { const editors = await this.instantiationService.invokeFunction(accessor => extractEditorsAndFilesDropData(accessor, event)); if (!editors.length) { return; } // Make the window active to handle the drop properly within - await this.hostService.focus(); + await this.hostService.focus(targetWindow); // Check for workspace file / folder being dropped if we are allowed to do so if (this.options.allowWorkspaceOpen) { @@ -168,9 +168,6 @@ export class ResourcesDropHandler { return false; } - // Pass focus to window - this.hostService.focus(); - // Open in separate windows if we drop workspaces or just one folder if (toOpen.length > folderURIs.length || folderURIs.length === 1) { await this.hostService.openWindow(toOpen); diff --git a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts index 64221b9382d..646f5869387 100644 --- a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts +++ b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts @@ -373,7 +373,7 @@ class DropOverlay extends Themable { // Check for URI transfer else { const dropHandler = this.instantiationService.createInstance(ResourcesDropHandler, { allowWorkspaceOpen: !isWeb || isTemporaryWorkspace(this.contextService.getWorkspace()) }); - dropHandler.handleDrop(event, () => ensureTargetGroup(), targetGroup => targetGroup?.focus()); + dropHandler.handleDrop(event, getWindow(this.groupView.element), () => ensureTargetGroup(), targetGroup => targetGroup?.focus()); } } diff --git a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts index a9ed03f97c2..834e2d66644 100644 --- a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts @@ -32,7 +32,7 @@ import { ResourcesDropHandler, DraggedEditorIdentifier, DraggedEditorGroupIdenti import { Color } from 'vs/base/common/color'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { MergeGroupMode, IMergeGroupOptions, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { addDisposableListener, EventType, EventHelper, Dimension, scheduleAtNextAnimationFrame, findParentWithClass, clearNode, DragAndDropObserver, isMouseEvent } from 'vs/base/browser/dom'; +import { addDisposableListener, EventType, EventHelper, Dimension, scheduleAtNextAnimationFrame, findParentWithClass, clearNode, DragAndDropObserver, isMouseEvent, getWindow } from 'vs/base/browser/dom'; import { localize } from 'vs/nls'; import { IEditorGroupsView, EditorServiceImpl, IEditorGroupView, IInternalEditorOpenOptions, IEditorPartsView } from 'vs/workbench/browser/parts/editor/editor'; import { CloseOneEditorAction, UnpinEditorAction } from 'vs/workbench/browser/parts/editor/editorActions'; @@ -2069,7 +2069,7 @@ export class MultiEditorTabsControl extends EditorTabsControl { // Check for URI transfer else { const dropHandler = this.instantiationService.createInstance(ResourcesDropHandler, { allowWorkspaceOpen: false }); - dropHandler.handleDrop(e, () => this.groupView, () => this.groupView.focus(), options); + dropHandler.handleDrop(e, getWindow(this.titleContainer), () => this.groupView, () => this.groupView.focus(), options); } } diff --git a/src/vs/workbench/browser/parts/titlebar/windowTitle.ts b/src/vs/workbench/browser/parts/titlebar/windowTitle.ts index 5e97cbebd85..48b791514f2 100644 --- a/src/vs/workbench/browser/parts/titlebar/windowTitle.ts +++ b/src/vs/workbench/browser/parts/titlebar/windowTitle.ts @@ -54,7 +54,7 @@ export class WindowTitle extends Disposable { private readonly editorService: IEditorService; constructor( - private readonly targetWindow: Window & typeof globalThis, + private readonly targetWindow: Window, editorGroupsContainer: IEditorGroupsContainer | 'main', @IConfigurationService protected readonly configurationService: IConfigurationService, @IEditorService editorService: IEditorService, diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index 8dbd2c26bfc..48edae1a29a 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -1012,7 +1012,7 @@ export class DebugSession implements IDebugSession, IDisposable { } if (this.configurationService.getValue('debug').focusWindowOnBreak && !this.workbenchEnvironmentService.extensionTestsLocationURI) { - await this.hostService.focus({ force: true /* Application may not be active */ }); + await this.hostService.focus(window, { force: true /* Application may not be active */ }); } } } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 3bb04e433a2..55c422a9310 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -1928,7 +1928,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension [extension] = await this.getExtensions([{ id: extensionId }], { source: 'uri' }, CancellationToken.None); } if (extension) { - await this.hostService.focus(); + await this.hostService.focus(window); await this.open(extension); } }).then(undefined, error => this.onError(error)); diff --git a/src/vs/workbench/contrib/files/browser/fileImportExport.ts b/src/vs/workbench/contrib/files/browser/fileImportExport.ts index 0ad3bfa636a..10a1453fd05 100644 --- a/src/vs/workbench/contrib/files/browser/fileImportExport.ts +++ b/src/vs/workbench/contrib/files/browser/fileImportExport.ts @@ -402,7 +402,7 @@ export class ExternalFileImport { ) { } - async import(target: ExplorerItem, source: DragEvent): Promise { + async import(target: ExplorerItem, source: DragEvent, targetWindow: Window): Promise { const cts = new CancellationTokenSource(); // Indicate progress globally @@ -413,7 +413,7 @@ export class ExternalFileImport { cancellable: true, title: localize('copyingFiles', "Copying...") }, - async () => await this.doImport(target, source, cts.token), + async () => await this.doImport(target, source, targetWindow, cts.token), () => cts.dispose(true) ); @@ -423,7 +423,7 @@ export class ExternalFileImport { return importPromise; } - private async doImport(target: ExplorerItem, source: DragEvent, token: CancellationToken): Promise { + private async doImport(target: ExplorerItem, source: DragEvent, targetWindow: Window, token: CancellationToken): Promise { // Activate all providers for the resources dropped const candidateFiles = coalesce((await this.instantiationService.invokeFunction(accessor => extractEditorsAndFilesDropData(accessor, source))).map(editor => editor.resource)); @@ -438,7 +438,7 @@ export class ExternalFileImport { } // Pass focus to window - this.hostService.focus(); + this.hostService.focus(targetWindow); // Handle folders by adding to workspace if we are in workspace context and if dropped on top const folders = resolvedFiles.filter(resolvedFile => resolvedFile.success && resolvedFile.stat?.isDirectory).map(resolvedFile => ({ uri: resolvedFile.stat!.resource })); diff --git a/src/vs/workbench/contrib/files/browser/views/emptyView.ts b/src/vs/workbench/contrib/files/browser/views/emptyView.ts index 4f450ff50e0..aba7df4c942 100644 --- a/src/vs/workbench/contrib/files/browser/views/emptyView.ts +++ b/src/vs/workbench/contrib/files/browser/views/emptyView.ts @@ -20,7 +20,7 @@ import { IViewDescriptorService } from 'vs/workbench/common/views'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { isWeb } from 'vs/base/common/platform'; -import { DragAndDropObserver } from 'vs/base/browser/dom'; +import { DragAndDropObserver, getWindow } from 'vs/base/browser/dom'; import { ILocalizedString } from 'vs/platform/action/common/action'; export class EmptyView extends ViewPane { @@ -60,7 +60,7 @@ export class EmptyView extends ViewPane { onDrop: e => { container.style.backgroundColor = ''; const dropHandler = this.instantiationService.createInstance(ResourcesDropHandler, { allowWorkspaceOpen: !isWeb || isTemporaryWorkspace(this.contextService.getWorkspace()) }); - dropHandler.handleDrop(e); + dropHandler.handleDrop(e, getWindow(container)); }, onDragEnter: () => { const color = this.themeService.getColorTheme().getColor(listDropBackground); diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index d567ec80916..ab9459d78a8 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -1260,7 +1260,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { // Use local file import when supported if (!isWeb || (isTemporaryWorkspace(this.contextService.getWorkspace()) && WebFileSystemAccess.supported(window))) { const fileImport = this.instantiationService.createInstance(ExternalFileImport); - await fileImport.import(resolvedTarget, originalEvent); + await fileImport.import(resolvedTarget, originalEvent, window); } // Otherwise fallback to browser based file upload else { diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index 5a881944d4f..96edb1c4abe 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -718,7 +718,7 @@ class OpenEditorsDragAndDrop implements IListDragAndDrop group, () => group.focus(), { index }); + this.dropHandler.handleDrop(originalEvent, window, () => group, () => group.focus(), { index }); } } diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts index 0c606c68a2c..0f5e52f5342 100644 --- a/src/vs/workbench/electron-sandbox/window.ts +++ b/src/vs/workbench/electron-sandbox/window.ts @@ -683,7 +683,7 @@ export class NativeWindow extends Disposable { originalWindowFocus(); if (getActiveWindow() !== window) { - that.nativeHostService.focusWindow(); + that.nativeHostService.focusWindow({ targetWindowId: that.nativeHostService.windowId }); } }; } diff --git a/src/vs/workbench/services/host/browser/browserHostService.ts b/src/vs/workbench/services/host/browser/browserHostService.ts index 4f56301f2f9..40f79b6a74c 100644 --- a/src/vs/workbench/services/host/browser/browserHostService.ts +++ b/src/vs/workbench/services/host/browser/browserHostService.ts @@ -14,7 +14,7 @@ import { isResourceEditorInput, pathsToEditors } from 'vs/workbench/common/edito import { whenEditorClosed } from 'vs/workbench/browser/editor'; import { IFileService } from 'vs/platform/files/common/files'; import { ILabelService, Verbosity } from 'vs/platform/label/common/label'; -import { ModifierKeyEmitter, getActiveDocument, getActiveWindow, onDidRegisterWindow, trackFocus } from 'vs/base/browser/dom'; +import { ModifierKeyEmitter, getActiveDocument, onDidRegisterWindow, trackFocus } from 'vs/base/browser/dom'; import { Disposable } from 'vs/base/common/lifecycle'; import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; import { memoize } from 'vs/base/common/decorators'; @@ -201,8 +201,8 @@ export class BrowserHostService extends Disposable implements IHostService { return true; } - async focus(): Promise { - getActiveWindow().focus(); + async focus(window: Window): Promise { + window.focus(); } //#endregion @@ -505,7 +505,7 @@ export class BrowserHostService extends Disposable implements IHostService { } } - async moveTop(window: Window & typeof globalThis): Promise { + async moveTop(window: Window): Promise { // There seems to be no API to bring a window to front in browsers } diff --git a/src/vs/workbench/services/host/browser/host.ts b/src/vs/workbench/services/host/browser/host.ts index 569f40e6c60..fb2eb102556 100644 --- a/src/vs/workbench/services/host/browser/host.ts +++ b/src/vs/workbench/services/host/browser/host.ts @@ -46,7 +46,7 @@ export interface IHostService { * focused application which may not be VSCode. It may not be supported * in all environments. */ - focus(options?: { force: boolean }): Promise; + focus(window: Window, options?: { force: boolean }): Promise; //#endregion @@ -72,7 +72,7 @@ export interface IHostService { /** * Bring a window to the front and restore it if needed. */ - moveTop(window: Window & typeof globalThis): Promise; + moveTop(window: Window): Promise; //#endregion diff --git a/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts b/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts index 430d0c6c649..d33a776105a 100644 --- a/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts +++ b/src/vs/workbench/services/host/electron-sandbox/nativeHostService.ts @@ -133,7 +133,7 @@ class WorkbenchHostService extends Disposable implements IHostService { return this.nativeHostService.toggleFullScreen(); } - async moveTop(window: Window & typeof globalThis): Promise { + async moveTop(window: Window): Promise { if (getWindowsCount() <= 1) { return; // does not apply when only one window is opened } @@ -146,8 +146,11 @@ class WorkbenchHostService extends Disposable implements IHostService { //#region Lifecycle - focus(options?: { force: boolean }): Promise { - return this.nativeHostService.focusWindow(options); + focus(window: Window, options?: { force: boolean }): Promise { + return this.nativeHostService.focusWindow({ + force: options?.force, + targetWindowId: isAuxiliaryWindow(window) ? window.vscodeWindowId : this.nativeHostService.windowId + }); } restart(): Promise { diff --git a/src/vs/workbench/services/url/electron-sandbox/urlService.ts b/src/vs/workbench/services/url/electron-sandbox/urlService.ts index 3b3000abce6..6e3662033e6 100644 --- a/src/vs/workbench/services/url/electron-sandbox/urlService.ts +++ b/src/vs/workbench/services/url/electron-sandbox/urlService.ts @@ -70,7 +70,7 @@ export class RelayURLService extends NativeURLService implements IURLHandler, IO if (result) { this.logService.trace('URLService#handleURL(): handled', uri.toString(true)); - await this.nativeHostService.focusWindow({ force: true /* Application may not be active */ }); + await this.nativeHostService.focusWindow({ force: true /* Application may not be active */, targetWindowId: this.nativeHostService.windowId }); } else { this.logService.trace('URLService#handleURL(): not handled', uri.toString(true)); } diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index c2253938025..bbbe0bdd5fc 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -1485,7 +1485,7 @@ export class TestHostService implements IHostService { return await expectedShutdownTask(); } - async focus(options?: { force: boolean }): Promise { } + async focus(): Promise { } async moveTop(): Promise { } async openWindow(arg1?: IOpenEmptyWindowOptions | IWindowOpenable[], arg2?: IOpenWindowOptions): Promise { }