mirror of
https://github.com/coder/code-server.git
synced 2026-06-21 01:17:10 +02:00
chore(vscode): update to 1.54.2
This commit is contained in:
@@ -81,14 +81,14 @@ export function isFileToOpen(uriToOpen: IWindowOpenable): uriToOpen is IFileToOp
|
||||
return !!(uriToOpen as IFileToOpen).fileUri;
|
||||
}
|
||||
|
||||
export type MenuBarVisibility = 'default' | 'visible' | 'toggle' | 'hidden' | 'compact';
|
||||
export type MenuBarVisibility = 'classic' | 'visible' | 'toggle' | 'hidden' | 'compact';
|
||||
|
||||
export function getMenuBarVisibility(configurationService: IConfigurationService): MenuBarVisibility {
|
||||
const titleBarStyle = getTitleBarStyle(configurationService);
|
||||
const menuBarVisibility = configurationService.getValue<MenuBarVisibility>('window.menuBarVisibility');
|
||||
const menuBarVisibility = configurationService.getValue<MenuBarVisibility | 'default'>('window.menuBarVisibility');
|
||||
|
||||
if (titleBarStyle === 'native' && menuBarVisibility === 'compact') {
|
||||
return 'default';
|
||||
if (menuBarVisibility === 'default' || (titleBarStyle === 'native' && menuBarVisibility === 'compact')) {
|
||||
return 'classic';
|
||||
} else {
|
||||
return menuBarVisibility;
|
||||
}
|
||||
@@ -114,6 +114,7 @@ export interface IWindowSettings {
|
||||
readonly enableMenuBarMnemonics: boolean;
|
||||
readonly closeWhenEmpty: boolean;
|
||||
readonly clickThroughInactive: boolean;
|
||||
readonly enableExperimentalMainProcessWorkspaceStorage: boolean;
|
||||
}
|
||||
|
||||
export function getTitleBarStyle(configurationService: IConfigurationService): 'native' | 'custom' {
|
||||
@@ -169,7 +170,7 @@ export interface IPathData {
|
||||
readonly openOnlyIfExists?: boolean;
|
||||
|
||||
// Specifies an optional id to override the editor used to edit the resource, e.g. custom editor.
|
||||
readonly overrideId?: string;
|
||||
readonly editorOverrideId?: string;
|
||||
}
|
||||
|
||||
export interface IPathsToWaitFor extends IPathsToWaitForData {
|
||||
@@ -253,6 +254,8 @@ export interface INativeWindowConfiguration extends IWindowConfiguration, Native
|
||||
filesToWait?: IPathsToWaitFor;
|
||||
|
||||
os: IOSConfiguration;
|
||||
|
||||
enableExperimentalMainProcessWorkspaceStorage: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
1410
lib/vscode/src/vs/platform/windows/electron-main/window.ts
Normal file
1410
lib/vscode/src/vs/platform/windows/electron-main/window.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,14 @@ export interface IWindowState {
|
||||
display?: number;
|
||||
}
|
||||
|
||||
export const defaultWindowState = function (mode = WindowMode.Normal): IWindowState {
|
||||
return {
|
||||
width: 1024,
|
||||
height: 768,
|
||||
mode
|
||||
};
|
||||
};
|
||||
|
||||
export const enum WindowMode {
|
||||
Maximized,
|
||||
Normal,
|
||||
@@ -52,17 +60,21 @@ export const enum WindowMode {
|
||||
Fullscreen
|
||||
}
|
||||
|
||||
export interface ILoadEvent {
|
||||
workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined;
|
||||
}
|
||||
|
||||
export interface ICodeWindow extends IDisposable {
|
||||
|
||||
readonly onLoad: Event<void>;
|
||||
readonly onReady: Event<void>;
|
||||
readonly onClose: Event<void>;
|
||||
readonly onDestroy: Event<void>;
|
||||
readonly onWillLoad: Event<ILoadEvent>;
|
||||
readonly onDidSignalReady: Event<void>;
|
||||
readonly onDidClose: Event<void>;
|
||||
readonly onDidDestroy: Event<void>;
|
||||
|
||||
readonly whenClosedOrLoaded: Promise<void>;
|
||||
|
||||
readonly id: number;
|
||||
readonly win: BrowserWindow;
|
||||
readonly win: BrowserWindow | null; /* `null` after being disposed */
|
||||
readonly config: INativeWindowConfiguration | undefined;
|
||||
|
||||
readonly openedWorkspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier;
|
||||
@@ -113,6 +125,24 @@ export interface ICodeWindow extends IDisposable {
|
||||
serializeWindowState(): IWindowState;
|
||||
}
|
||||
|
||||
export const enum WindowError {
|
||||
|
||||
/**
|
||||
* Maps to the `unresponsive` event on a `BrowserWindow`.
|
||||
*/
|
||||
UNRESPONSIVE = 1,
|
||||
|
||||
/**
|
||||
* Maps to the `render-proces-gone` event on a `WebContents`.
|
||||
*/
|
||||
CRASHED = 2,
|
||||
|
||||
/**
|
||||
* Maps to the `did-fail-load` event on a `WebContents`.
|
||||
*/
|
||||
LOAD = 3
|
||||
}
|
||||
|
||||
export const IWindowsMainService = createDecorator<IWindowsMainService>('windowsMainService');
|
||||
|
||||
export interface IWindowsCountChangedEvent {
|
||||
@@ -124,11 +154,11 @@ export interface IWindowsMainService {
|
||||
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
readonly onWindowsCountChanged: Event<IWindowsCountChangedEvent>;
|
||||
readonly onDidChangeWindowsCount: Event<IWindowsCountChangedEvent>;
|
||||
|
||||
readonly onWindowOpened: Event<ICodeWindow>;
|
||||
readonly onWindowReady: Event<ICodeWindow>;
|
||||
readonly onWindowDestroyed: Event<ICodeWindow>;
|
||||
readonly onDidOpenWindow: Event<ICodeWindow>;
|
||||
readonly onDidSignalReadyWindow: Event<ICodeWindow>;
|
||||
readonly onDidDestroyWindow: Event<ICodeWindow>;
|
||||
|
||||
open(openConfig: IOpenConfiguration): ICodeWindow[];
|
||||
openEmptyWindow(openConfig: IOpenEmptyConfiguration, options?: IOpenEmptyWindowOptions): ICodeWindow[];
|
||||
|
||||
@@ -12,9 +12,9 @@ import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup';
|
||||
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { IStateService } from 'vs/platform/state/node/state';
|
||||
import { CodeWindow } from 'vs/code/electron-main/window';
|
||||
import { CodeWindow } from 'vs/platform/windows/electron-main/window';
|
||||
import { BrowserWindow, MessageBoxOptions, WebContents } from 'electron';
|
||||
import { ILifecycleMainService, UnloadReason, LifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { ILifecycleMainService, UnloadReason, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IWindowSettings, IPath, isFileToOpen, isWorkspaceToOpen, isFolderToOpen, IWindowOpenable, IOpenEmptyWindowOptions, IAddFoldersRequest, IPathsToWaitFor, INativeWindowConfiguration, INativeOpenFileRequest } from 'vs/platform/windows/common/windows';
|
||||
@@ -35,7 +35,7 @@ import { getSingleFolderWorkspaceIdentifier, getWorkspaceIdentifier, IWorkspaces
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { assertIsDefined, withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { isWindowsDriveLetter, toSlashes, parseLineAndColumnAware, sanitizeFilePath } from 'vs/base/common/extpath';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { getPathLabel } from 'vs/base/common/labels';
|
||||
@@ -118,17 +118,17 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
|
||||
private static readonly WINDOWS: ICodeWindow[] = [];
|
||||
|
||||
private readonly _onWindowOpened = this._register(new Emitter<ICodeWindow>());
|
||||
readonly onWindowOpened = this._onWindowOpened.event;
|
||||
private readonly _onDidOpenWindow = this._register(new Emitter<ICodeWindow>());
|
||||
readonly onDidOpenWindow = this._onDidOpenWindow.event;
|
||||
|
||||
private readonly _onWindowReady = this._register(new Emitter<ICodeWindow>());
|
||||
readonly onWindowReady = this._onWindowReady.event;
|
||||
private readonly _onDidSignalReadyWindow = this._register(new Emitter<ICodeWindow>());
|
||||
readonly onDidSignalReadyWindow = this._onDidSignalReadyWindow.event;
|
||||
|
||||
private readonly _onWindowDestroyed = this._register(new Emitter<ICodeWindow>());
|
||||
readonly onWindowDestroyed = this._onWindowDestroyed.event;
|
||||
private readonly _onDidDestroyWindow = this._register(new Emitter<ICodeWindow>());
|
||||
readonly onDidDestroyWindow = this._onDidDestroyWindow.event;
|
||||
|
||||
private readonly _onWindowsCountChanged = this._register(new Emitter<IWindowsCountChangedEvent>());
|
||||
readonly onWindowsCountChanged = this._onWindowsCountChanged.event;
|
||||
private readonly _onDidChangeWindowsCount = this._register(new Emitter<IWindowsCountChangedEvent>());
|
||||
readonly onDidChangeWindowsCount = this._onDidChangeWindowsCount.event;
|
||||
|
||||
private readonly windowsStateHandler = this._register(new WindowsStateHandler(this, this.stateService, this.lifecycleMainService, this.logService, this.configurationService));
|
||||
|
||||
@@ -137,7 +137,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
private readonly initialUserEnv: IProcessEnvironment,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IStateService private readonly stateService: IStateService,
|
||||
@IEnvironmentMainService private readonly environmentService: IEnvironmentMainService,
|
||||
@IEnvironmentMainService private readonly environmentMainService: IEnvironmentMainService,
|
||||
@ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService,
|
||||
@IBackupMainService private readonly backupMainService: IBackupMainService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@@ -155,11 +155,11 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
private registerListeners(): void {
|
||||
|
||||
// Signal a window is ready after having entered a workspace
|
||||
this._register(this.workspacesManagementMainService.onWorkspaceEntered(event => this._onWindowReady.fire(event.window)));
|
||||
this._register(this.workspacesManagementMainService.onDidEnterWorkspace(event => this._onDidSignalReadyWindow.fire(event.window)));
|
||||
}
|
||||
|
||||
openEmptyWindow(openConfig: IOpenEmptyConfiguration, options?: IOpenEmptyWindowOptions): ICodeWindow[] {
|
||||
let cli = this.environmentService.args;
|
||||
let cli = this.environmentMainService.args;
|
||||
const remote = options?.remoteAuthority;
|
||||
if (cli && (cli.remote !== remote)) {
|
||||
cli = { ...cli, remote };
|
||||
@@ -670,7 +670,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
buttons: [localize('ok', "OK")],
|
||||
message: uri.scheme === Schemas.file ? localize('pathNotExistTitle', "Path does not exist") : localize('uriInvalidTitle', "URI can not be opened"),
|
||||
detail: uri.scheme === Schemas.file ?
|
||||
localize('pathNotExistDetail', "The path '{0}' does not seem to exist anymore on disk.", getPathLabel(uri.fsPath, this.environmentService)) :
|
||||
localize('pathNotExistDetail', "The path '{0}' does not seem to exist anymore on disk.", getPathLabel(uri.fsPath, this.environmentMainService)) :
|
||||
localize('uriInvalidDetail', "The URI '{0}' is not valid and can not be opened.", uri.toString()),
|
||||
noLink: true
|
||||
};
|
||||
@@ -1135,9 +1135,9 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
|
||||
// Build `INativeWindowConfiguration` from config and options
|
||||
const configuration = { ...options.cli } as INativeWindowConfiguration;
|
||||
configuration.appRoot = this.environmentService.appRoot;
|
||||
configuration.appRoot = this.environmentMainService.appRoot;
|
||||
configuration.machineId = this.machineId;
|
||||
configuration.nodeCachedDataDir = this.environmentService.nodeCachedDataDir;
|
||||
configuration.nodeCachedDataDir = this.environmentMainService.nodeCachedDataDir;
|
||||
configuration.mainPid = process.pid;
|
||||
configuration.execPath = process.execPath;
|
||||
configuration.userEnv = { ...this.initialUserEnv, ...options.userEnv };
|
||||
@@ -1157,7 +1157,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
// For all other cases we first call into registerEmptyWindowBackupSync() to set it before
|
||||
// loading the window.
|
||||
if (options.emptyWindowBackupInfo) {
|
||||
configuration.backupPath = join(this.environmentService.backupHome, options.emptyWindowBackupInfo.backupFolder);
|
||||
configuration.backupPath = join(this.environmentMainService.backupHome, options.emptyWindowBackupInfo.backupFolder);
|
||||
}
|
||||
|
||||
let window: ICodeWindow | undefined;
|
||||
@@ -1191,20 +1191,22 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
WindowsMainService.WINDOWS.push(createdWindow);
|
||||
|
||||
// Indicate new window via event
|
||||
this._onWindowOpened.fire(createdWindow);
|
||||
this._onDidOpenWindow.fire(createdWindow);
|
||||
|
||||
// Indicate number change via event
|
||||
this._onWindowsCountChanged.fire({ oldCount: this.getWindowCount() - 1, newCount: this.getWindowCount() });
|
||||
this._onDidChangeWindowsCount.fire({ oldCount: this.getWindowCount() - 1, newCount: this.getWindowCount() });
|
||||
|
||||
// Window Events
|
||||
once(createdWindow.onReady)(() => this._onWindowReady.fire(createdWindow));
|
||||
once(createdWindow.onClose)(() => this.onWindowClosed(createdWindow));
|
||||
once(createdWindow.onDestroy)(() => this._onWindowDestroyed.fire(createdWindow));
|
||||
createdWindow.win.webContents.removeAllListeners('devtools-reload-page'); // remove built in listener so we can handle this on our own
|
||||
createdWindow.win.webContents.on('devtools-reload-page', () => this.lifecycleMainService.reload(createdWindow));
|
||||
once(createdWindow.onDidSignalReady)(() => this._onDidSignalReadyWindow.fire(createdWindow));
|
||||
once(createdWindow.onDidClose)(() => this.onWindowClosed(createdWindow));
|
||||
once(createdWindow.onDidDestroy)(() => this._onDidDestroyWindow.fire(createdWindow));
|
||||
|
||||
const webContents = assertIsDefined(createdWindow.win?.webContents);
|
||||
webContents.removeAllListeners('devtools-reload-page'); // remove built in listener so we can handle this on our own
|
||||
webContents.on('devtools-reload-page', () => this.lifecycleMainService.reload(createdWindow));
|
||||
|
||||
// Lifecycle
|
||||
(this.lifecycleMainService as LifecycleMainService).registerWindow(createdWindow);
|
||||
this.lifecycleMainService.registerWindow(createdWindow);
|
||||
}
|
||||
|
||||
// Existing window
|
||||
@@ -1264,7 +1266,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
||||
WindowsMainService.WINDOWS.splice(index, 1);
|
||||
|
||||
// Emit
|
||||
this._onWindowsCountChanged.fire({ oldCount: this.getWindowCount() + 1, newCount: this.getWindowCount() });
|
||||
this._onDidChangeWindowsCount.fire({ oldCount: this.getWindowCount() + 1, newCount: this.getWindowCount() });
|
||||
}
|
||||
|
||||
getFocusedWindow(): ICodeWindow | undefined {
|
||||
|
||||
@@ -8,13 +8,12 @@ import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { defaultWindowState } from 'vs/code/electron-main/window';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IStateService } from 'vs/platform/state/node/state';
|
||||
import { INativeWindowConfiguration, IWindowSettings } from 'vs/platform/windows/common/windows';
|
||||
import { ICodeWindow, IWindowsMainService, IWindowState as IWindowUIState, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { defaultWindowState, ICodeWindow, IWindowsMainService, IWindowState as IWindowUIState, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
|
||||
export interface IWindowState {
|
||||
@@ -84,9 +83,9 @@ export class WindowsStateHandler extends Disposable {
|
||||
});
|
||||
|
||||
// Handle various lifecycle events around windows
|
||||
this.lifecycleMainService.onBeforeWindowClose(window => this.onBeforeWindowClose(window));
|
||||
this.lifecycleMainService.onBeforeCloseWindow(window => this.onBeforeCloseWindow(window));
|
||||
this.lifecycleMainService.onBeforeShutdown(() => this.onBeforeShutdown());
|
||||
this.windowsMainService.onWindowsCountChanged(e => {
|
||||
this.windowsMainService.onDidChangeWindowsCount(e => {
|
||||
if (e.newCount - e.oldCount > 0) {
|
||||
// clear last closed window state when a new window opens. this helps on macOS where
|
||||
// otherwise closing the last window, opening a new window and then quitting would
|
||||
@@ -96,16 +95,16 @@ export class WindowsStateHandler extends Disposable {
|
||||
});
|
||||
|
||||
// try to save state before destroy because close will not fire
|
||||
this.windowsMainService.onWindowDestroyed(window => this.onBeforeWindowClose(window));
|
||||
this.windowsMainService.onDidDestroyWindow(window => this.onBeforeCloseWindow(window));
|
||||
}
|
||||
|
||||
// Note that onBeforeShutdown() and onBeforeWindowClose() are fired in different order depending on the OS:
|
||||
// Note that onBeforeShutdown() and onBeforeCloseWindow() are fired in different order depending on the OS:
|
||||
// - macOS: since the app will not quit when closing the last window, you will always first get
|
||||
// the onBeforeShutdown() event followed by N onBeforeWindowClose() events for each window
|
||||
// the onBeforeShutdown() event followed by N onBeforeCloseWindow() events for each window
|
||||
// - other: on other OS, closing the last window will quit the app so the order depends on the
|
||||
// user interaction: closing the last window will first trigger onBeforeWindowClose()
|
||||
// user interaction: closing the last window will first trigger onBeforeCloseWindow()
|
||||
// and then onBeforeShutdown(). Using the quit action however will first issue onBeforeShutdown()
|
||||
// and then onBeforeWindowClose().
|
||||
// and then onBeforeCloseWindow().
|
||||
//
|
||||
// Here is the behavior on different OS depending on action taken (Electron 1.7.x):
|
||||
//
|
||||
@@ -114,27 +113,27 @@ export class WindowsStateHandler extends Disposable {
|
||||
// - close(1): close one window via the window close button
|
||||
// - closeAll: close all windows via the taskbar command
|
||||
// - onBeforeShutdown(N): number of windows reported in this event handler
|
||||
// - onBeforeWindowClose(N, M): number of windows reported and quitRequested boolean in this event handler
|
||||
// - onBeforeCloseWindow(N, M): number of windows reported and quitRequested boolean in this event handler
|
||||
//
|
||||
// macOS
|
||||
// - quit(1): onBeforeShutdown(1), onBeforeWindowClose(1, true)
|
||||
// - quit(2): onBeforeShutdown(2), onBeforeWindowClose(2, true), onBeforeWindowClose(2, true)
|
||||
// - quit(1): onBeforeShutdown(1), onBeforeCloseWindow(1, true)
|
||||
// - quit(2): onBeforeShutdown(2), onBeforeCloseWindow(2, true), onBeforeCloseWindow(2, true)
|
||||
// - quit(0): onBeforeShutdown(0)
|
||||
// - close(1): onBeforeWindowClose(1, false)
|
||||
// - close(1): onBeforeCloseWindow(1, false)
|
||||
//
|
||||
// Windows
|
||||
// - quit(1): onBeforeShutdown(1), onBeforeWindowClose(1, true)
|
||||
// - quit(2): onBeforeShutdown(2), onBeforeWindowClose(2, true), onBeforeWindowClose(2, true)
|
||||
// - close(1): onBeforeWindowClose(2, false)[not last window]
|
||||
// - close(1): onBeforeWindowClose(1, false), onBeforeShutdown(0)[last window]
|
||||
// - closeAll(2): onBeforeWindowClose(2, false), onBeforeWindowClose(2, false), onBeforeShutdown(0)
|
||||
// - quit(1): onBeforeShutdown(1), onBeforeCloseWindow(1, true)
|
||||
// - quit(2): onBeforeShutdown(2), onBeforeCloseWindow(2, true), onBeforeCloseWindow(2, true)
|
||||
// - close(1): onBeforeCloseWindow(2, false)[not last window]
|
||||
// - close(1): onBeforeCloseWindow(1, false), onBeforeShutdown(0)[last window]
|
||||
// - closeAll(2): onBeforeCloseWindow(2, false), onBeforeCloseWindow(2, false), onBeforeShutdown(0)
|
||||
//
|
||||
// Linux
|
||||
// - quit(1): onBeforeShutdown(1), onBeforeWindowClose(1, true)
|
||||
// - quit(2): onBeforeShutdown(2), onBeforeWindowClose(2, true), onBeforeWindowClose(2, true)
|
||||
// - close(1): onBeforeWindowClose(2, false)[not last window]
|
||||
// - close(1): onBeforeWindowClose(1, false), onBeforeShutdown(0)[last window]
|
||||
// - closeAll(2): onBeforeWindowClose(2, false), onBeforeWindowClose(2, false), onBeforeShutdown(0)
|
||||
// - quit(1): onBeforeShutdown(1), onBeforeCloseWindow(1, true)
|
||||
// - quit(2): onBeforeShutdown(2), onBeforeCloseWindow(2, true), onBeforeCloseWindow(2, true)
|
||||
// - close(1): onBeforeCloseWindow(2, false)[not last window]
|
||||
// - close(1): onBeforeCloseWindow(1, false), onBeforeShutdown(0)[last window]
|
||||
// - closeAll(2): onBeforeCloseWindow(2, false), onBeforeCloseWindow(2, false), onBeforeShutdown(0)
|
||||
//
|
||||
private onBeforeShutdown(): void {
|
||||
this.shuttingDown = true;
|
||||
@@ -186,7 +185,7 @@ export class WindowsStateHandler extends Disposable {
|
||||
}
|
||||
|
||||
// See note on #onBeforeShutdown() for details how these events are flowing
|
||||
private onBeforeWindowClose(window: ICodeWindow): void {
|
||||
private onBeforeCloseWindow(window: ICodeWindow): void {
|
||||
if (this.lifecycleMainService.quitRequested) {
|
||||
return; // during quit, many windows close in parallel so let it be handled in the before-quit handler
|
||||
}
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import { findWindowOnFile } from 'vs/platform/windows/electron-main/windowsFinder';
|
||||
import { ICodeWindow, IWindowState } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWorkspaceIdentifier, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { getPathFromAmdModule } from 'vs/base/common/amd';
|
||||
import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { UriDto } from 'vs/base/common/types';
|
||||
import { ICommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { INativeWindowConfiguration } from 'vs/platform/windows/common/windows';
|
||||
|
||||
const fixturesFolder = getPathFromAmdModule(require, './fixtures');
|
||||
|
||||
const testWorkspace: IWorkspaceIdentifier = {
|
||||
id: Date.now().toString(),
|
||||
configPath: URI.file(path.join(fixturesFolder, 'workspaces.json'))
|
||||
};
|
||||
|
||||
const testWorkspaceFolders = toWorkspaceFolders([{ path: path.join(fixturesFolder, 'vscode_workspace_1_folder') }, { path: path.join(fixturesFolder, 'vscode_workspace_2_folder') }], testWorkspace.configPath, extUriBiasedIgnorePathCase);
|
||||
const localWorkspaceResolver = (workspace: any) => { return workspace === testWorkspace ? { id: testWorkspace.id, configPath: workspace.configPath, folders: testWorkspaceFolders } : null; };
|
||||
|
||||
function createTestCodeWindow(options: { lastFocusTime: number, openedFolderUri?: URI, openedWorkspace?: IWorkspaceIdentifier }): ICodeWindow {
|
||||
return new class implements ICodeWindow {
|
||||
onLoad: Event<void> = Event.None;
|
||||
onReady: Event<void> = Event.None;
|
||||
onClose: Event<void> = Event.None;
|
||||
onDestroy: Event<void> = Event.None;
|
||||
whenClosedOrLoaded: Promise<void> = Promise.resolve();
|
||||
id: number = -1;
|
||||
win: Electron.BrowserWindow = undefined!;
|
||||
config: INativeWindowConfiguration | undefined;
|
||||
openedWorkspace = options.openedFolderUri ? { id: '', uri: options.openedFolderUri } : options.openedWorkspace;
|
||||
backupPath?: string | undefined;
|
||||
remoteAuthority?: string | undefined;
|
||||
isExtensionDevelopmentHost = false;
|
||||
isExtensionTestHost = false;
|
||||
lastFocusTime = options.lastFocusTime;
|
||||
isFullScreen = false;
|
||||
isReady = true;
|
||||
hasHiddenTitleBarStyle = false;
|
||||
|
||||
ready(): Promise<ICodeWindow> { throw new Error('Method not implemented.'); }
|
||||
setReady(): void { throw new Error('Method not implemented.'); }
|
||||
addTabbedWindow(window: ICodeWindow): void { throw new Error('Method not implemented.'); }
|
||||
load(config: INativeWindowConfiguration, options: { isReload?: boolean }): void { throw new Error('Method not implemented.'); }
|
||||
reload(cli?: NativeParsedArgs): void { throw new Error('Method not implemented.'); }
|
||||
focus(options?: { force: boolean; }): void { throw new Error('Method not implemented.'); }
|
||||
close(): void { throw new Error('Method not implemented.'); }
|
||||
getBounds(): Electron.Rectangle { throw new Error('Method not implemented.'); }
|
||||
send(channel: string, ...args: any[]): void { throw new Error('Method not implemented.'); }
|
||||
sendWhenReady(channel: string, token: CancellationToken, ...args: any[]): void { throw new Error('Method not implemented.'); }
|
||||
toggleFullScreen(): void { throw new Error('Method not implemented.'); }
|
||||
isMinimized(): boolean { throw new Error('Method not implemented.'); }
|
||||
setRepresentedFilename(name: string): void { throw new Error('Method not implemented.'); }
|
||||
getRepresentedFilename(): string | undefined { throw new Error('Method not implemented.'); }
|
||||
setDocumentEdited(edited: boolean): void { throw new Error('Method not implemented.'); }
|
||||
isDocumentEdited(): boolean { throw new Error('Method not implemented.'); }
|
||||
handleTitleDoubleClick(): void { throw new Error('Method not implemented.'); }
|
||||
updateTouchBar(items: UriDto<ICommandAction>[][]): void { throw new Error('Method not implemented.'); }
|
||||
serializeWindowState(): IWindowState { throw new Error('Method not implemented'); }
|
||||
dispose(): void { }
|
||||
};
|
||||
}
|
||||
|
||||
const vscodeFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'vscode_folder')) });
|
||||
const lastActiveWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 3, openedFolderUri: undefined });
|
||||
const noVscodeFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 2, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder')) });
|
||||
const windows: ICodeWindow[] = [
|
||||
vscodeFolderWindow,
|
||||
lastActiveWindow,
|
||||
noVscodeFolderWindow,
|
||||
];
|
||||
|
||||
suite('WindowsFinder', () => {
|
||||
|
||||
test('New window without folder when no windows exist', () => {
|
||||
assert.strictEqual(findWindowOnFile([], URI.file('nonexisting'), localWorkspaceResolver), undefined);
|
||||
assert.strictEqual(findWindowOnFile([], URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')), localWorkspaceResolver), undefined);
|
||||
});
|
||||
|
||||
test('Existing window with folder', () => {
|
||||
assert.strictEqual(findWindowOnFile(windows, URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')), localWorkspaceResolver), noVscodeFolderWindow);
|
||||
|
||||
assert.strictEqual(findWindowOnFile(windows, URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')), localWorkspaceResolver), vscodeFolderWindow);
|
||||
|
||||
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'nested_folder')) });
|
||||
assert.strictEqual(findWindowOnFile([window], URI.file(path.join(fixturesFolder, 'vscode_folder', 'nested_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), window);
|
||||
});
|
||||
|
||||
test('More specific existing window wins', () => {
|
||||
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 2, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder')) });
|
||||
const nestedFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder')) });
|
||||
assert.strictEqual(findWindowOnFile([window, nestedFolderWindow], URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), nestedFolderWindow);
|
||||
});
|
||||
|
||||
test('Workspace folder wins', () => {
|
||||
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedWorkspace: testWorkspace });
|
||||
assert.strictEqual(findWindowOnFile([window], URI.file(path.join(fixturesFolder, 'vscode_workspace_2_folder', 'nested_vscode_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), window);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,109 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { findWindowOnFile } from 'vs/platform/windows/electron-main/windowsFinder';
|
||||
import { ICodeWindow, ILoadEvent, IWindowState } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWorkspaceIdentifier, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { getPathFromAmdModule } from 'vs/base/common/amd';
|
||||
import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { UriDto } from 'vs/base/common/types';
|
||||
import { ICommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { INativeWindowConfiguration } from 'vs/platform/windows/common/windows';
|
||||
|
||||
suite('WindowsFinder', () => {
|
||||
|
||||
const fixturesFolder = getPathFromAmdModule(require, './fixtures');
|
||||
|
||||
const testWorkspace: IWorkspaceIdentifier = {
|
||||
id: Date.now().toString(),
|
||||
configPath: URI.file(join(fixturesFolder, 'workspaces.json'))
|
||||
};
|
||||
|
||||
const testWorkspaceFolders = toWorkspaceFolders([{ path: join(fixturesFolder, 'vscode_workspace_1_folder') }, { path: join(fixturesFolder, 'vscode_workspace_2_folder') }], testWorkspace.configPath, extUriBiasedIgnorePathCase);
|
||||
const localWorkspaceResolver = (workspace: any) => { return workspace === testWorkspace ? { id: testWorkspace.id, configPath: workspace.configPath, folders: testWorkspaceFolders } : null; };
|
||||
|
||||
function createTestCodeWindow(options: { lastFocusTime: number, openedFolderUri?: URI, openedWorkspace?: IWorkspaceIdentifier }): ICodeWindow {
|
||||
return new class implements ICodeWindow {
|
||||
onWillLoad: Event<ILoadEvent> = Event.None;
|
||||
onDidSignalReady: Event<void> = Event.None;
|
||||
onDidClose: Event<void> = Event.None;
|
||||
onDidDestroy: Event<void> = Event.None;
|
||||
whenClosedOrLoaded: Promise<void> = Promise.resolve();
|
||||
id: number = -1;
|
||||
win: Electron.BrowserWindow = null!;
|
||||
config: INativeWindowConfiguration | undefined;
|
||||
openedWorkspace = options.openedFolderUri ? { id: '', uri: options.openedFolderUri } : options.openedWorkspace;
|
||||
backupPath?: string | undefined;
|
||||
remoteAuthority?: string | undefined;
|
||||
isExtensionDevelopmentHost = false;
|
||||
isExtensionTestHost = false;
|
||||
lastFocusTime = options.lastFocusTime;
|
||||
isFullScreen = false;
|
||||
isReady = true;
|
||||
hasHiddenTitleBarStyle = false;
|
||||
|
||||
ready(): Promise<ICodeWindow> { throw new Error('Method not implemented.'); }
|
||||
setReady(): void { throw new Error('Method not implemented.'); }
|
||||
addTabbedWindow(window: ICodeWindow): void { throw new Error('Method not implemented.'); }
|
||||
load(config: INativeWindowConfiguration, options: { isReload?: boolean }): void { throw new Error('Method not implemented.'); }
|
||||
reload(cli?: NativeParsedArgs): void { throw new Error('Method not implemented.'); }
|
||||
focus(options?: { force: boolean; }): void { throw new Error('Method not implemented.'); }
|
||||
close(): void { throw new Error('Method not implemented.'); }
|
||||
getBounds(): Electron.Rectangle { throw new Error('Method not implemented.'); }
|
||||
send(channel: string, ...args: any[]): void { throw new Error('Method not implemented.'); }
|
||||
sendWhenReady(channel: string, token: CancellationToken, ...args: any[]): void { throw new Error('Method not implemented.'); }
|
||||
toggleFullScreen(): void { throw new Error('Method not implemented.'); }
|
||||
isMinimized(): boolean { throw new Error('Method not implemented.'); }
|
||||
setRepresentedFilename(name: string): void { throw new Error('Method not implemented.'); }
|
||||
getRepresentedFilename(): string | undefined { throw new Error('Method not implemented.'); }
|
||||
setDocumentEdited(edited: boolean): void { throw new Error('Method not implemented.'); }
|
||||
isDocumentEdited(): boolean { throw new Error('Method not implemented.'); }
|
||||
handleTitleDoubleClick(): void { throw new Error('Method not implemented.'); }
|
||||
updateTouchBar(items: UriDto<ICommandAction>[][]): void { throw new Error('Method not implemented.'); }
|
||||
serializeWindowState(): IWindowState { throw new Error('Method not implemented'); }
|
||||
dispose(): void { }
|
||||
};
|
||||
}
|
||||
|
||||
const vscodeFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(join(fixturesFolder, 'vscode_folder')) });
|
||||
const lastActiveWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 3, openedFolderUri: undefined });
|
||||
const noVscodeFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 2, openedFolderUri: URI.file(join(fixturesFolder, 'no_vscode_folder')) });
|
||||
const windows: ICodeWindow[] = [
|
||||
vscodeFolderWindow,
|
||||
lastActiveWindow,
|
||||
noVscodeFolderWindow,
|
||||
];
|
||||
|
||||
test('New window without folder when no windows exist', () => {
|
||||
assert.strictEqual(findWindowOnFile([], URI.file('nonexisting'), localWorkspaceResolver), undefined);
|
||||
assert.strictEqual(findWindowOnFile([], URI.file(join(fixturesFolder, 'no_vscode_folder', 'file.txt')), localWorkspaceResolver), undefined);
|
||||
});
|
||||
|
||||
test('Existing window with folder', () => {
|
||||
assert.strictEqual(findWindowOnFile(windows, URI.file(join(fixturesFolder, 'no_vscode_folder', 'file.txt')), localWorkspaceResolver), noVscodeFolderWindow);
|
||||
|
||||
assert.strictEqual(findWindowOnFile(windows, URI.file(join(fixturesFolder, 'vscode_folder', 'file.txt')), localWorkspaceResolver), vscodeFolderWindow);
|
||||
|
||||
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(join(fixturesFolder, 'vscode_folder', 'nested_folder')) });
|
||||
assert.strictEqual(findWindowOnFile([window], URI.file(join(fixturesFolder, 'vscode_folder', 'nested_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), window);
|
||||
});
|
||||
|
||||
test('More specific existing window wins', () => {
|
||||
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 2, openedFolderUri: URI.file(join(fixturesFolder, 'no_vscode_folder')) });
|
||||
const nestedFolderWindow: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedFolderUri: URI.file(join(fixturesFolder, 'no_vscode_folder', 'nested_folder')) });
|
||||
assert.strictEqual(findWindowOnFile([window, nestedFolderWindow], URI.file(join(fixturesFolder, 'no_vscode_folder', 'nested_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), nestedFolderWindow);
|
||||
});
|
||||
|
||||
test('Workspace folder wins', () => {
|
||||
const window: ICodeWindow = createTestCodeWindow({ lastFocusTime: 1, openedWorkspace: testWorkspace });
|
||||
assert.strictEqual(findWindowOnFile([window], URI.file(join(fixturesFolder, 'vscode_workspace_2_folder', 'nested_vscode_folder', 'subfolder', 'file.txt')), localWorkspaceResolver), window);
|
||||
});
|
||||
});
|
||||
@@ -4,78 +4,79 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as os from 'os';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import { tmpdir } from 'os';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { restoreWindowsState, getWindowsStateStoreData, IWindowsState, IWindowState } from 'vs/platform/windows/electron-main/windowsStateHandler';
|
||||
import { IWindowState as IWindowUIState, WindowMode } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
function getUIState(): IWindowUIState {
|
||||
return {
|
||||
x: 0,
|
||||
y: 10,
|
||||
width: 100,
|
||||
height: 200,
|
||||
mode: 0
|
||||
};
|
||||
}
|
||||
|
||||
function toWorkspace(uri: URI): IWorkspaceIdentifier {
|
||||
return {
|
||||
id: '1234',
|
||||
configPath: uri
|
||||
};
|
||||
}
|
||||
function assertEqualURI(u1: URI | undefined, u2: URI | undefined, message?: string): void {
|
||||
assert.strictEqual(u1 && u1.toString(), u2 && u2.toString(), message);
|
||||
}
|
||||
|
||||
function assertEqualWorkspace(w1: IWorkspaceIdentifier | undefined, w2: IWorkspaceIdentifier | undefined, message?: string): void {
|
||||
if (!w1 || !w2) {
|
||||
assert.strictEqual(w1, w2, message);
|
||||
return;
|
||||
}
|
||||
assert.strictEqual(w1.id, w2.id, message);
|
||||
assertEqualURI(w1.configPath, w2.configPath, message);
|
||||
}
|
||||
|
||||
function assertEqualWindowState(expected: IWindowState | undefined, actual: IWindowState | undefined, message?: string) {
|
||||
if (!expected || !actual) {
|
||||
assert.deepEqual(expected, actual, message);
|
||||
return;
|
||||
}
|
||||
assert.strictEqual(expected.backupPath, actual.backupPath, message);
|
||||
assertEqualURI(expected.folderUri, actual.folderUri, message);
|
||||
assert.strictEqual(expected.remoteAuthority, actual.remoteAuthority, message);
|
||||
assertEqualWorkspace(expected.workspace, actual.workspace, message);
|
||||
assert.deepEqual(expected.uiState, actual.uiState, message);
|
||||
}
|
||||
|
||||
function assertEqualWindowsState(expected: IWindowsState, actual: IWindowsState, message?: string) {
|
||||
assertEqualWindowState(expected.lastPluginDevelopmentHostWindow, actual.lastPluginDevelopmentHostWindow, message);
|
||||
assertEqualWindowState(expected.lastActiveWindow, actual.lastActiveWindow, message);
|
||||
assert.strictEqual(expected.openedWindows.length, actual.openedWindows.length, message);
|
||||
for (let i = 0; i < expected.openedWindows.length; i++) {
|
||||
assertEqualWindowState(expected.openedWindows[i], actual.openedWindows[i], message);
|
||||
}
|
||||
}
|
||||
|
||||
function assertRestoring(state: IWindowsState, message?: string) {
|
||||
const stored = getWindowsStateStoreData(state);
|
||||
const restored = restoreWindowsState(stored);
|
||||
assertEqualWindowsState(state, restored, message);
|
||||
}
|
||||
|
||||
const testBackupPath1 = path.join(os.tmpdir(), 'windowStateTest', 'backupFolder1');
|
||||
const testBackupPath2 = path.join(os.tmpdir(), 'windowStateTest', 'backupFolder2');
|
||||
|
||||
const testWSPath = URI.file(path.join(os.tmpdir(), 'windowStateTest', 'test.code-workspace'));
|
||||
const testFolderURI = URI.file(path.join(os.tmpdir(), 'windowStateTest', 'testFolder'));
|
||||
|
||||
const testRemoteFolderURI = URI.parse('foo://bar/c/d');
|
||||
|
||||
suite('Windows State Storing', () => {
|
||||
|
||||
function getUIState(): IWindowUIState {
|
||||
return {
|
||||
x: 0,
|
||||
y: 10,
|
||||
width: 100,
|
||||
height: 200,
|
||||
mode: 0
|
||||
};
|
||||
}
|
||||
|
||||
function toWorkspace(uri: URI): IWorkspaceIdentifier {
|
||||
return {
|
||||
id: '1234',
|
||||
configPath: uri
|
||||
};
|
||||
}
|
||||
function assertEqualURI(u1: URI | undefined, u2: URI | undefined, message?: string): void {
|
||||
assert.strictEqual(u1 && u1.toString(), u2 && u2.toString(), message);
|
||||
}
|
||||
|
||||
function assertEqualWorkspace(w1: IWorkspaceIdentifier | undefined, w2: IWorkspaceIdentifier | undefined, message?: string): void {
|
||||
if (!w1 || !w2) {
|
||||
assert.strictEqual(w1, w2, message);
|
||||
return;
|
||||
}
|
||||
assert.strictEqual(w1.id, w2.id, message);
|
||||
assertEqualURI(w1.configPath, w2.configPath, message);
|
||||
}
|
||||
|
||||
function assertEqualWindowState(expected: IWindowState | undefined, actual: IWindowState | undefined, message?: string) {
|
||||
if (!expected || !actual) {
|
||||
assert.deepStrictEqual(expected, actual, message);
|
||||
return;
|
||||
}
|
||||
assert.strictEqual(expected.backupPath, actual.backupPath, message);
|
||||
assertEqualURI(expected.folderUri, actual.folderUri, message);
|
||||
assert.strictEqual(expected.remoteAuthority, actual.remoteAuthority, message);
|
||||
assertEqualWorkspace(expected.workspace, actual.workspace, message);
|
||||
assert.deepStrictEqual(expected.uiState, actual.uiState, message);
|
||||
}
|
||||
|
||||
function assertEqualWindowsState(expected: IWindowsState, actual: IWindowsState, message?: string) {
|
||||
assertEqualWindowState(expected.lastPluginDevelopmentHostWindow, actual.lastPluginDevelopmentHostWindow, message);
|
||||
assertEqualWindowState(expected.lastActiveWindow, actual.lastActiveWindow, message);
|
||||
assert.strictEqual(expected.openedWindows.length, actual.openedWindows.length, message);
|
||||
for (let i = 0; i < expected.openedWindows.length; i++) {
|
||||
assertEqualWindowState(expected.openedWindows[i], actual.openedWindows[i], message);
|
||||
}
|
||||
}
|
||||
|
||||
function assertRestoring(state: IWindowsState, message?: string) {
|
||||
const stored = getWindowsStateStoreData(state);
|
||||
const restored = restoreWindowsState(stored);
|
||||
assertEqualWindowsState(state, restored, message);
|
||||
}
|
||||
|
||||
const testBackupPath1 = join(tmpdir(), 'windowStateTest', 'backupFolder1');
|
||||
const testBackupPath2 = join(tmpdir(), 'windowStateTest', 'backupFolder2');
|
||||
|
||||
const testWSPath = URI.file(join(tmpdir(), 'windowStateTest', 'test.code-workspace'));
|
||||
const testFolderURI = URI.file(join(tmpdir(), 'windowStateTest', 'testFolder'));
|
||||
|
||||
const testRemoteFolderURI = URI.parse('foo://bar/c/d');
|
||||
|
||||
test('storing and restoring', () => {
|
||||
let windowState: IWindowsState;
|
||||
windowState = {
|
||||
|
||||
Reference in New Issue
Block a user