Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aux window - less use of ILayoutService.container #196282

Merged
merged 2 commits into from Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 10 additions & 8 deletions src/vs/base/browser/dom.ts
Expand Up @@ -19,7 +19,7 @@ import { URI } from 'vs/base/common/uri';

export const { registerWindow, getWindows, onDidRegisterWindow, onWillUnregisterWindow, onDidUnregisterWindow } = (function () {
const windows = new Set([window]);
const onDidRegisterWindow = new event.Emitter<{ window: Window & typeof globalThis; disposableStore: DisposableStore }>();
const onDidRegisterWindow = new event.Emitter<{ window: Window & typeof globalThis; disposables: DisposableStore }>();
const onDidUnregisterWindow = new event.Emitter<Window & typeof globalThis>();
const onWillUnregisterWindow = new event.Emitter<Window & typeof globalThis>();
return {
Expand All @@ -33,19 +33,21 @@ export const { registerWindow, getWindows, onDidRegisterWindow, onWillUnregister

windows.add(window);

const disposableStore = new DisposableStore();
disposableStore.add(toDisposable(() => {
const disposables = new DisposableStore();
disposables.add(toDisposable(() => {
windows.delete(window);
onDidUnregisterWindow.fire(window);
}));

onDidRegisterWindow.fire({ window, disposableStore });

disposableStore.add(addDisposableListener(window, 'beforeunload', () => {
disposables.add(addDisposableListener(window, EventType.BEFORE_UNLOAD, () => {
onWillUnregisterWindow.fire(window);
}));

return disposableStore;
const eventDisposables = new DisposableStore();
disposables.add(eventDisposables);
onDidRegisterWindow.fire({ window, disposables: eventDisposables });

return disposables;
},
getWindows(): Iterable<Window & typeof globalThis> {
return windows;
Expand Down Expand Up @@ -1652,7 +1654,7 @@ export class ModifierKeyEmitter extends event.Emitter<IModifierKeyStatus> {
metaKey: false
};

this._subscriptions.add(event.Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposableStore }) => this.registerListeners(window, disposableStore), { window, disposableStore: this._subscriptions }));
this._subscriptions.add(event.Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposables }) => this.registerListeners(window, disposables), { window, disposables: this._subscriptions }));
}

private registerListeners(window: Window, disposables: DisposableStore): void {
Expand Down
10 changes: 5 additions & 5 deletions src/vs/base/browser/touch.ts
Expand Up @@ -91,11 +91,11 @@ export class Gesture extends Disposable {
this.handle = null;
this._lastSetTapCountTime = 0;

this._register(EventUtils.runAndSubscribe(DomUtils.onDidRegisterWindow, ({ window, disposableStore }) => {
disposableStore.add(DomUtils.addDisposableListener(window.document, 'touchstart', (e: TouchEvent) => this.onTouchStart(e), { passive: false }));
disposableStore.add(DomUtils.addDisposableListener(window.document, 'touchend', (e: TouchEvent) => this.onTouchEnd(e)));
disposableStore.add(DomUtils.addDisposableListener(window.document, 'touchmove', (e: TouchEvent) => this.onTouchMove(e), { passive: false }));
}, { window, disposableStore: this._store }));
this._register(EventUtils.runAndSubscribe(DomUtils.onDidRegisterWindow, ({ window, disposables }) => {
disposables.add(DomUtils.addDisposableListener(window.document, 'touchstart', (e: TouchEvent) => this.onTouchStart(e), { passive: false }));
disposables.add(DomUtils.addDisposableListener(window.document, 'touchend', (e: TouchEvent) => this.onTouchEnd(e)));
disposables.add(DomUtils.addDisposableListener(window.document, 'touchmove', (e: TouchEvent) => this.onTouchMove(e), { passive: false }));
}, { window, disposables: this._store }));
}

public static addTarget(element: HTMLElement): IDisposable {
Expand Down
2 changes: 1 addition & 1 deletion src/vs/platform/quickinput/browser/quickInputController.ts
Expand Up @@ -58,7 +58,7 @@ export class QuickInputController extends Disposable {
this.idPrefix = options.idPrefix;
this.parentElement = options.container;
this.styles = options.styles;
this._register(Event.runAndSubscribe(dom.onDidRegisterWindow, ({ window, disposableStore }) => this.registerKeyModsListeners(window, disposableStore), { window, disposableStore: this._store }));
this._register(Event.runAndSubscribe(dom.onDidRegisterWindow, ({ window, disposables }) => this.registerKeyModsListeners(window, disposables), { window, disposables: this._store }));
this._register(dom.onWillUnregisterWindow(window => {
if (this.ui && dom.getWindow(this.ui.container) === window) {
// The window this quick input is contained in is about to
Expand Down
23 changes: 14 additions & 9 deletions src/vs/workbench/browser/actions/textInputActions.ts
Expand Up @@ -8,13 +8,14 @@ import { localize } from 'vs/nls';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { Disposable } from 'vs/base/common/lifecycle';
import { EventHelper } from 'vs/base/browser/dom';
import { EventHelper, addDisposableListener, getActiveDocument } from 'vs/base/browser/dom';
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { Registry } from 'vs/platform/registry/common/platform';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { isNative } from 'vs/base/common/platform';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IAuxiliaryWindowService } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService';

export class TextInputActionsProvider extends Disposable implements IWorkbenchContribution {

Expand All @@ -23,7 +24,8 @@ export class TextInputActionsProvider extends Disposable implements IWorkbenchCo
constructor(
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
@IContextMenuService private readonly contextMenuService: IContextMenuService,
@IClipboardService private readonly clipboardService: IClipboardService
@IClipboardService private readonly clipboardService: IClipboardService,
@IAuxiliaryWindowService private readonly auxiliaryWindowService: IAuxiliaryWindowService
) {
super();

Expand All @@ -36,18 +38,18 @@ export class TextInputActionsProvider extends Disposable implements IWorkbenchCo
this.textInputActions.push(

// Undo/Redo
new Action('undo', localize('undo', "Undo"), undefined, true, async () => document.execCommand('undo')),
new Action('redo', localize('redo', "Redo"), undefined, true, async () => document.execCommand('redo')),
new Action('undo', localize('undo', "Undo"), undefined, true, async () => getActiveDocument().execCommand('undo')),
new Action('redo', localize('redo', "Redo"), undefined, true, async () => getActiveDocument().execCommand('redo')),
new Separator(),

// Cut / Copy / Paste
new Action('editor.action.clipboardCutAction', localize('cut', "Cut"), undefined, true, async () => document.execCommand('cut')),
new Action('editor.action.clipboardCopyAction', localize('copy', "Copy"), undefined, true, async () => document.execCommand('copy')),
new Action('editor.action.clipboardCutAction', localize('cut', "Cut"), undefined, true, async () => getActiveDocument().execCommand('cut')),
new Action('editor.action.clipboardCopyAction', localize('copy', "Copy"), undefined, true, async () => getActiveDocument().execCommand('copy')),
new Action('editor.action.clipboardPasteAction', localize('paste', "Paste"), undefined, true, async element => {

// Native: paste is supported
if (isNative) {
document.execCommand('paste');
getActiveDocument().execCommand('paste');
}

// Web: paste is not supported due to security reasons
Expand All @@ -69,14 +71,17 @@ export class TextInputActionsProvider extends Disposable implements IWorkbenchCo
new Separator(),

// Select All
new Action('editor.action.selectAll', localize('selectAll', "Select All"), undefined, true, async () => document.execCommand('selectAll'))
new Action('editor.action.selectAll', localize('selectAll', "Select All"), undefined, true, async () => getActiveDocument().execCommand('selectAll'))
);
}

private registerListeners(): void {

// Context menu support in input/textarea
this.layoutService.container.addEventListener('contextmenu', e => this.onContextMenu(e));
this._register(addDisposableListener(this.layoutService.container, 'contextmenu', e => this.onContextMenu(e)));
this._register(this.auxiliaryWindowService.onDidOpenAuxiliaryWindow(({ window, disposables }) => {
disposables.add(addDisposableListener(window.container, 'contextmenu', e => this.onContextMenu(e)));
}));
}

private onContextMenu(e: MouseEvent): void {
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/browser/contextkeys.ts
Expand Up @@ -239,7 +239,7 @@ export class WorkbenchContextKeysHandler extends Disposable {

this._register(this.editorGroupService.onDidChangeEditorPartOptions(() => this.updateEditorAreaContextKeys()));

this._register(Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposableStore }) => disposableStore.add(addDisposableListener(window, EventType.FOCUS_IN, () => this.updateInputContextKeys(window.document), true)), { window, disposableStore: this._store }));
this._register(Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposables }) => disposables.add(addDisposableListener(window, EventType.FOCUS_IN, () => this.updateInputContextKeys(window.document), true)), { window, disposables: this._store }));

this._register(this.contextService.onDidChangeWorkbenchState(() => this.updateWorkbenchStateContextKey()));
this._register(this.contextService.onDidChangeWorkspaceFolders(() => {
Expand Down
8 changes: 4 additions & 4 deletions src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts
Expand Up @@ -270,10 +270,10 @@ class EditorWordWrapContextKeyTracker extends Disposable implements IWorkbenchCo
@IContextKeyService private readonly _contextService: IContextKeyService,
) {
super();
this._register(Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposableStore }) => {
disposableStore.add(addDisposableListener(window, 'focus', () => this._update(), true));
disposableStore.add(addDisposableListener(window, 'blur', () => this._update(), true));
}, { window, disposableStore: this._store }));
this._register(Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposables }) => {
disposables.add(addDisposableListener(window, 'focus', () => this._update(), true));
disposables.add(addDisposableListener(window, 'blur', () => this._update(), true));
}, { window, disposables: this._store }));
this._editorService.onDidActiveEditorChange(() => this._update());
this._canToggleWordWrap = CAN_TOGGLE_WORD_WRAP.bindTo(this._contextService);
this._editorWordWrap = EDITOR_WORD_WRAP.bindTo(this._contextService);
Expand Down
Expand Up @@ -18,7 +18,7 @@ class ContextMenuContribution implements IWorkbenchContribution {
@ILayoutService layoutService: ILayoutService,
@IContextMenuService contextMenuService: IContextMenuService
) {
const update = (visible: boolean) => layoutService.container.classList.toggle('context-menu-visible', visible);
const update = (visible: boolean) => layoutService.activeContainer.classList.toggle('context-menu-visible', visible);
contextMenuService.onDidShowContextMenu(() => update(true), null, this.disposables);
contextMenuService.onDidHideContextMenu(() => update(false), null, this.disposables);
}
Expand Down
Expand Up @@ -6,7 +6,7 @@
import { localize } from 'vs/nls';
import { Emitter, Event } from 'vs/base/common/event';
import { Dimension, EventHelper, EventType, addDisposableListener, copyAttributes, getActiveWindow, getClientArea, position, registerWindow, size, trackAttributes } from 'vs/base/browser/dom';
import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
Expand All @@ -18,10 +18,17 @@ import Severity from 'vs/base/common/severity';

export const IAuxiliaryWindowService = createDecorator<IAuxiliaryWindowService>('auxiliaryWindowService');

export interface IAuxiliaryWindowOpenEvent {
readonly window: IAuxiliaryWindow;
readonly disposables: DisposableStore;
}

export interface IAuxiliaryWindowService {

readonly _serviceBrand: undefined;

readonly onDidOpenAuxiliaryWindow: Event<IAuxiliaryWindowOpenEvent>;

open(options?: { position?: IRectangle }): Promise<IAuxiliaryWindow>;
}

Expand All @@ -38,16 +45,21 @@ export interface IAuxiliaryWindow extends IDisposable {

export type AuxiliaryWindow = Window & typeof globalThis;

export class BrowserAuxiliaryWindowService implements IAuxiliaryWindowService {
export class BrowserAuxiliaryWindowService extends Disposable implements IAuxiliaryWindowService {

declare readonly _serviceBrand: undefined;

private static readonly DEFAULT_SIZE = { width: 800, height: 600 };

private readonly _onDidOpenAuxiliaryWindow = this._register(new Emitter<IAuxiliaryWindowOpenEvent>());
readonly onDidOpenAuxiliaryWindow = this._onDidOpenAuxiliaryWindow.event;

constructor(
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
@IDialogService private readonly dialogService: IDialogService
) { }
) {
super();
}

async open(options?: { position?: IRectangle }): Promise<IAuxiliaryWindow> {
const disposables = new DisposableStore();
Expand All @@ -62,14 +74,20 @@ export class BrowserAuxiliaryWindowService implements IAuxiliaryWindowService {

const { container, onWillLayout, onDidClose } = this.create(auxiliaryWindow, disposables);

return {
const result = {
window: auxiliaryWindow,
container,
onWillLayout: onWillLayout.event,
onDidClose: onDidClose.event,
layout: () => onWillLayout.fire(getClientArea(container)),
dispose: () => disposables.dispose()
};

const eventDisposables = new DisposableStore();
disposables.add(eventDisposables);
this._onDidOpenAuxiliaryWindow.fire({ window: result, disposables: eventDisposables });

return result;
}

private async doOpen(options?: { position?: IRectangle }): Promise<AuxiliaryWindow | undefined> {
Expand Down Expand Up @@ -222,6 +240,8 @@ export class BrowserAuxiliaryWindowService implements IAuxiliaryWindowService {
onWillLayout.fire(dimension);
}));

this._register(addDisposableListener(container, EventType.SCROLL, () => container.scrollTop = 0)); // // Prevent container from scrolling (#55456)

if (isWeb) {
disposables.add(addDisposableListener(container, EventType.DROP, e => EventHelper.stop(e, true))); // Prevent default navigation on drop
disposables.add(addDisposableListener(container, EventType.WHEEL, e => e.preventDefault(), { passive: false })); // Prevent the back/forward gestures in macOS
Expand Down
19 changes: 16 additions & 3 deletions src/vs/workbench/services/history/browser/historyService.ts
Expand Up @@ -34,6 +34,7 @@ import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { ILogService, LogLevel } from 'vs/platform/log/common/log';
import { IAuxiliaryWindowService } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService';

export class HistoryService extends Disposable implements IHistoryService {

Expand All @@ -57,7 +58,8 @@ export class HistoryService extends Disposable implements IHistoryService {
@IWorkspacesService private readonly workspacesService: IWorkspacesService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
@IContextKeyService private readonly contextKeyService: IContextKeyService
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IAuxiliaryWindowService private readonly auxiliaryWindowService: IAuxiliaryWindowService
) {
super();

Expand Down Expand Up @@ -111,8 +113,14 @@ export class HistoryService extends Disposable implements IHistoryService {
mouseBackForwardSupportListener.clear();

if (this.configurationService.getValue(HistoryService.MOUSE_NAVIGATION_SETTING)) {
mouseBackForwardSupportListener.add(addDisposableListener(this.layoutService.container, EventType.MOUSE_DOWN, e => this.onMouseDownOrUp(e, true)));
mouseBackForwardSupportListener.add(addDisposableListener(this.layoutService.container, EventType.MOUSE_UP, e => this.onMouseDownOrUp(e, false)));
this.doRegisterMouseNavigationListener(this.layoutService.container, mouseBackForwardSupportListener);

this._register(this.auxiliaryWindowService.onDidOpenAuxiliaryWindow(({ window, disposables }) => {
const listenerDisposables = new DisposableStore();
mouseBackForwardSupportListener.add(listenerDisposables);
disposables.add(listenerDisposables);
this.doRegisterMouseNavigationListener(window.container, listenerDisposables);
}));
}
};

Expand All @@ -125,6 +133,11 @@ export class HistoryService extends Disposable implements IHistoryService {
handleMouseBackForwardSupport();
}

private doRegisterMouseNavigationListener(container: HTMLElement, disposables: DisposableStore): void {
disposables.add(addDisposableListener(container, EventType.MOUSE_DOWN, e => this.onMouseDownOrUp(e, true)));
disposables.add(addDisposableListener(container, EventType.MOUSE_UP, e => this.onMouseDownOrUp(e, false)));
}

private onMouseDownOrUp(event: MouseEvent, isMouseDown: boolean): void {

// Support to navigate in history when mouse buttons 4/5 are pressed
Expand Down
Expand Up @@ -238,7 +238,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
this.updateKeybindingsJsonSchema();
this._register(extensionService.onDidRegisterExtensions(() => this.updateKeybindingsJsonSchema()));

this._register(Event.runAndSubscribe(dom.onDidRegisterWindow, ({ window, disposableStore }) => disposableStore.add(this._registerKeyListeners(window)), { window, disposableStore: this._store }));
this._register(Event.runAndSubscribe(dom.onDidRegisterWindow, ({ window, disposables }) => disposables.add(this._registerKeyListeners(window)), { window, disposables: this._store }));

this._register(browser.onDidChangeFullscreen(() => {
const keyboard: IKeyboard | null = (<INavigatorWithKeyboard>navigator).keyboard;
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/services/progress/browser/progressService.ts
Expand Up @@ -546,7 +546,7 @@ export class ProgressService extends Disposable implements IProgressService {
}

dialog = new Dialog(
this.layoutService.container,
this.layoutService.activeContainer,
message,
buttons,
{
Expand All @@ -556,7 +556,7 @@ export class ProgressService extends Disposable implements IProgressService {
disableCloseAction: options.sticky,
disableDefaultAction: options.sticky,
keyEventProcessor: (event: StandardKeyboardEvent) => {
const resolved = this.keybindingService.softDispatch(event, this.layoutService.container);
const resolved = this.keybindingService.softDispatch(event, this.layoutService.activeContainer);
if (resolved.kind === ResultKind.KbFound && resolved.commandId) {
if (!allowableCommands.includes(resolved.commandId)) {
EventHelper.stop(event, true);
Expand Down