mirror of https://github.com/microsoft/vscode.git
This commit is contained in:
parent
b6fe5a8f41
commit
129f975fd4
|
@ -55,24 +55,7 @@ const TS_CONFIG_PATH = path.join(__dirname, '../../', 'src', 'tsconfig.json');
|
|||
//
|
||||
const ignored = new Set([
|
||||
'vs/base/common/arrays.ts',
|
||||
'vs/platform/workspace/common/workspace.ts',
|
||||
'vs/platform/files/node/watcher/nodejs/nodejsWatcherLib.ts',
|
||||
'vs/platform/storage/common/storage.ts',
|
||||
'vs/platform/state/node/stateService.ts',
|
||||
'vs/platform/workspaces/electron-main/workspacesManagementMainService.ts',
|
||||
'vs/platform/windows/electron-main/windowImpl.ts',
|
||||
'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow.ts',
|
||||
'vs/base/parts/storage/node/storage.ts',
|
||||
'vs/platform/storage/electron-main/storageMainService.ts',
|
||||
'vs/platform/backup/electron-main/backupMainService.ts',
|
||||
'vs/platform/files/node/diskFileSystemProviderServer.ts',
|
||||
'vs/platform/native/electron-main/nativeHostMainService.ts',
|
||||
'vs/platform/menubar/electron-main/menubarMainService.ts',
|
||||
'vs/platform/windows/electron-main/windowsStateHandler.ts',
|
||||
'vs/platform/windows/electron-main/windowsMainService.ts',
|
||||
'vs/platform/workspaces/electron-main/workspacesMainService.ts',
|
||||
'vs/platform/extensionManagement/common/extensionsScannerService.ts',
|
||||
'vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService.ts',
|
||||
'vs/platform/configuration/common/configurations.ts',
|
||||
'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.ts',
|
||||
'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts',
|
||||
|
@ -158,7 +141,6 @@ const ignored = new Set([
|
|||
'vs/workbench/browser/parts/editor/editorStatus.ts',
|
||||
'vs/workbench/browser/parts/editor/editorPart.ts',
|
||||
'vs/workbench/browser/parts/editor/editorParts.ts',
|
||||
'vs/workbench/browser/parts/auxiliarybar/auxiliaryBarPart.ts',
|
||||
'vs/workbench/services/textfile/common/textFileEditorModel.ts',
|
||||
'vs/workbench/services/history/browser/historyService.ts',
|
||||
'vs/workbench/services/notification/common/notificationService.ts',
|
||||
|
@ -204,31 +186,23 @@ const ignored = new Set([
|
|||
'vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts',
|
||||
'vs/workbench/contrib/accessibilitySignals/browser/editorTextPropertySignalsContribution.ts',
|
||||
'vs/workbench/contrib/inlineCompletions/browser/inlineCompletionLanguageStatusBarContribution.ts',
|
||||
'vs/workbench/browser/parts/dialogs/dialogHandler.ts',
|
||||
'vs/workbench/browser/parts/notifications/notificationsCenter.ts',
|
||||
'vs/workbench/browser/parts/notifications/notificationsToasts.ts',
|
||||
'vs/workbench/services/storage/browser/storageService.ts',
|
||||
'vs/workbench/services/textfile/common/textFileEditorModelManager.ts',
|
||||
'vs/workbench/services/textfile/browser/textFileService.ts',
|
||||
'vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts',
|
||||
'vs/workbench/services/workingCopy/common/workingCopyBackupTracker.ts',
|
||||
'vs/workbench/contrib/welcomeDialog/browser/welcomeWidget.ts',
|
||||
'vs/code/browser/workbench/workbench.ts',
|
||||
'vs/workbench/electron-sandbox/window.ts',
|
||||
'vs/platform/storage/common/storageService.ts',
|
||||
'vs/workbench/services/files/electron-sandbox/diskFileSystemProvider.ts',
|
||||
'vs/code/electron-utility/sharedProcess/contrib/codeCacheCleaner.ts',
|
||||
'vs/code/electron-utility/sharedProcess/contrib/languagePackCachedDataCleaner.ts',
|
||||
'vs/editor/standalone/browser/quickInput/standaloneQuickInputService.ts',
|
||||
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordInsertView.ts',
|
||||
'vs/platform/files/node/watcher/parcel/parcelWatcher.ts',
|
||||
'vs/platform/terminal/node/ptyService.ts',
|
||||
'vs/workbench/services/host/electron-sandbox/nativeHostService.ts',
|
||||
'vs/workbench/services/integrity/electron-sandbox/integrityService.ts',
|
||||
'vs/workbench/api/common/extHostLanguageFeatures.ts',
|
||||
'vs/workbench/api/common/extHostFileSystemEventService.ts',
|
||||
'vs/workbench/api/common/extHostSearch.ts',
|
||||
'vs/workbench/api/node/extHostDiskFileSystemProvider.ts',
|
||||
'vs/workbench/test/common/workbenchTestServices.ts',
|
||||
'vs/workbench/test/browser/workbenchTestServices.ts',
|
||||
'vs/workbench/contrib/testing/test/common/testStubs.ts',
|
||||
|
|
|
@ -24,24 +24,7 @@ const TS_CONFIG_PATH = path.join(__dirname, '../../', 'src', 'tsconfig.json');
|
|||
|
||||
const ignored = new Set([
|
||||
'vs/base/common/arrays.ts',
|
||||
'vs/platform/workspace/common/workspace.ts',
|
||||
'vs/platform/files/node/watcher/nodejs/nodejsWatcherLib.ts',
|
||||
'vs/platform/storage/common/storage.ts',
|
||||
'vs/platform/state/node/stateService.ts',
|
||||
'vs/platform/workspaces/electron-main/workspacesManagementMainService.ts',
|
||||
'vs/platform/windows/electron-main/windowImpl.ts',
|
||||
'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow.ts',
|
||||
'vs/base/parts/storage/node/storage.ts',
|
||||
'vs/platform/storage/electron-main/storageMainService.ts',
|
||||
'vs/platform/backup/electron-main/backupMainService.ts',
|
||||
'vs/platform/files/node/diskFileSystemProviderServer.ts',
|
||||
'vs/platform/native/electron-main/nativeHostMainService.ts',
|
||||
'vs/platform/menubar/electron-main/menubarMainService.ts',
|
||||
'vs/platform/windows/electron-main/windowsStateHandler.ts',
|
||||
'vs/platform/windows/electron-main/windowsMainService.ts',
|
||||
'vs/platform/workspaces/electron-main/workspacesMainService.ts',
|
||||
'vs/platform/extensionManagement/common/extensionsScannerService.ts',
|
||||
'vs/platform/utilityProcess/electron-main/utilityProcessWorkerMainService.ts',
|
||||
'vs/platform/configuration/common/configurations.ts',
|
||||
'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/tokenizer.ts',
|
||||
'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/bracketPairsTree.ts',
|
||||
|
@ -127,7 +110,6 @@ const ignored = new Set([
|
|||
'vs/workbench/browser/parts/editor/editorStatus.ts',
|
||||
'vs/workbench/browser/parts/editor/editorPart.ts',
|
||||
'vs/workbench/browser/parts/editor/editorParts.ts',
|
||||
'vs/workbench/browser/parts/auxiliarybar/auxiliaryBarPart.ts',
|
||||
'vs/workbench/services/textfile/common/textFileEditorModel.ts',
|
||||
'vs/workbench/services/history/browser/historyService.ts',
|
||||
'vs/workbench/services/notification/common/notificationService.ts',
|
||||
|
@ -173,31 +155,23 @@ const ignored = new Set([
|
|||
'vs/workbench/contrib/editSessions/browser/editSessionsStorageService.ts',
|
||||
'vs/workbench/contrib/accessibilitySignals/browser/editorTextPropertySignalsContribution.ts',
|
||||
'vs/workbench/contrib/inlineCompletions/browser/inlineCompletionLanguageStatusBarContribution.ts',
|
||||
'vs/workbench/browser/parts/dialogs/dialogHandler.ts',
|
||||
'vs/workbench/browser/parts/notifications/notificationsCenter.ts',
|
||||
'vs/workbench/browser/parts/notifications/notificationsToasts.ts',
|
||||
'vs/workbench/services/storage/browser/storageService.ts',
|
||||
'vs/workbench/services/textfile/common/textFileEditorModelManager.ts',
|
||||
'vs/workbench/services/textfile/browser/textFileService.ts',
|
||||
'vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts',
|
||||
'vs/workbench/services/workingCopy/common/workingCopyBackupTracker.ts',
|
||||
'vs/workbench/contrib/welcomeDialog/browser/welcomeWidget.ts',
|
||||
'vs/code/browser/workbench/workbench.ts',
|
||||
'vs/workbench/electron-sandbox/window.ts',
|
||||
'vs/platform/storage/common/storageService.ts',
|
||||
'vs/workbench/services/files/electron-sandbox/diskFileSystemProvider.ts',
|
||||
'vs/code/electron-utility/sharedProcess/contrib/codeCacheCleaner.ts',
|
||||
'vs/code/electron-utility/sharedProcess/contrib/languagePackCachedDataCleaner.ts',
|
||||
'vs/editor/standalone/browser/quickInput/standaloneQuickInputService.ts',
|
||||
'vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsWordInsertView.ts',
|
||||
'vs/platform/files/node/watcher/parcel/parcelWatcher.ts',
|
||||
'vs/platform/terminal/node/ptyService.ts',
|
||||
'vs/workbench/services/host/electron-sandbox/nativeHostService.ts',
|
||||
'vs/workbench/services/integrity/electron-sandbox/integrityService.ts',
|
||||
'vs/workbench/api/common/extHostLanguageFeatures.ts',
|
||||
'vs/workbench/api/common/extHostFileSystemEventService.ts',
|
||||
'vs/workbench/api/common/extHostSearch.ts',
|
||||
'vs/workbench/api/node/extHostDiskFileSystemProvider.ts',
|
||||
'vs/workbench/test/common/workbenchTestServices.ts',
|
||||
'vs/workbench/test/browser/workbenchTestServices.ts',
|
||||
'vs/workbench/contrib/testing/test/common/testStubs.ts',
|
||||
|
|
|
@ -38,13 +38,20 @@ export class SQLiteStorageDatabase implements IStorageDatabase {
|
|||
private static readonly BUSY_OPEN_TIMEOUT = 2000; // timeout in ms to retry when opening DB fails with SQLITE_BUSY
|
||||
private static readonly MAX_HOST_PARAMETERS = 256; // maximum number of parameters within a statement
|
||||
|
||||
private readonly name = basename(this.path);
|
||||
private readonly name: string;
|
||||
|
||||
private readonly logger = new SQLiteStorageDatabaseLogger(this.options.logging);
|
||||
private readonly logger: SQLiteStorageDatabaseLogger;
|
||||
|
||||
private readonly whenConnected = this.connect(this.path);
|
||||
private readonly whenConnected: Promise<IDatabaseConnection>;
|
||||
|
||||
constructor(private readonly path: string, private readonly options: ISQLiteStorageDatabaseOptions = Object.create(null)) { }
|
||||
constructor(
|
||||
private readonly path: string,
|
||||
options: ISQLiteStorageDatabaseOptions = Object.create(null)
|
||||
) {
|
||||
this.name = basename(this.path);
|
||||
this.logger = new SQLiteStorageDatabaseLogger(options.logging);
|
||||
this.whenConnected = this.connect(this.path);
|
||||
}
|
||||
|
||||
async getItems(): Promise<Map<string, string>> {
|
||||
const connection = await this.whenConnected;
|
||||
|
|
|
@ -28,6 +28,7 @@ interface ISecretStorageCrypto {
|
|||
}
|
||||
|
||||
class TransparentCrypto implements ISecretStorageCrypto {
|
||||
|
||||
async seal(data: string): Promise<string> {
|
||||
return data;
|
||||
}
|
||||
|
@ -44,6 +45,7 @@ const enum AESConstants {
|
|||
}
|
||||
|
||||
class NetworkError extends Error {
|
||||
|
||||
constructor(inner: Error) {
|
||||
super(inner.message);
|
||||
this.name = inner.name;
|
||||
|
@ -52,10 +54,13 @@ class NetworkError extends Error {
|
|||
}
|
||||
|
||||
class ServerKeyedAESCrypto implements ISecretStorageCrypto {
|
||||
private _serverKey: Uint8Array | undefined;
|
||||
|
||||
/** Gets whether the algorithm is supported; requires a secure context */
|
||||
public static supported() {
|
||||
private serverKey: Uint8Array | undefined;
|
||||
|
||||
/**
|
||||
* Gets whether the algorithm is supported; requires a secure context
|
||||
*/
|
||||
static supported() {
|
||||
return !!crypto.subtle;
|
||||
}
|
||||
|
||||
|
@ -141,8 +146,8 @@ class ServerKeyedAESCrypto implements ISecretStorageCrypto {
|
|||
}
|
||||
|
||||
private async getServerKeyPart(): Promise<Uint8Array> {
|
||||
if (this._serverKey) {
|
||||
return this._serverKey;
|
||||
if (this.serverKey) {
|
||||
return this.serverKey;
|
||||
}
|
||||
|
||||
let attempt = 0;
|
||||
|
@ -154,12 +159,15 @@ class ServerKeyedAESCrypto implements ISecretStorageCrypto {
|
|||
if (!res.ok) {
|
||||
throw new Error(res.statusText);
|
||||
}
|
||||
|
||||
const serverKey = new Uint8Array(await res.arrayBuffer());
|
||||
if (serverKey.byteLength !== AESConstants.KEY_LENGTH / 8) {
|
||||
throw Error(`The key retrieved by the server is not ${AESConstants.KEY_LENGTH} bit long.`);
|
||||
}
|
||||
this._serverKey = serverKey;
|
||||
return this._serverKey;
|
||||
|
||||
this.serverKey = serverKey;
|
||||
|
||||
return this.serverKey;
|
||||
} catch (e) {
|
||||
lastError = e instanceof Error ? e : new Error(String(e));
|
||||
attempt++;
|
||||
|
@ -172,34 +180,39 @@ class ServerKeyedAESCrypto implements ISecretStorageCrypto {
|
|||
if (lastError) {
|
||||
throw new NetworkError(lastError);
|
||||
}
|
||||
|
||||
throw new Error('Unknown error');
|
||||
}
|
||||
}
|
||||
|
||||
export class LocalStorageSecretStorageProvider implements ISecretStorageProvider {
|
||||
private readonly _storageKey = 'secrets.provider';
|
||||
|
||||
private _secretsPromise: Promise<Record<string, string>> = this.load();
|
||||
private readonly storageKey = 'secrets.provider';
|
||||
|
||||
private secretsPromise: Promise<Record<string, string>>;
|
||||
|
||||
type: 'in-memory' | 'persisted' | 'unknown' = 'persisted';
|
||||
|
||||
constructor(
|
||||
private readonly crypto: ISecretStorageCrypto,
|
||||
) { }
|
||||
) {
|
||||
this.secretsPromise = this.load();
|
||||
}
|
||||
|
||||
private async load(): Promise<Record<string, string>> {
|
||||
const record = this.loadAuthSessionFromElement();
|
||||
// Get the secrets from localStorage
|
||||
const encrypted = localStorage.getItem(this._storageKey);
|
||||
|
||||
const encrypted = localStorage.getItem(this.storageKey);
|
||||
if (encrypted) {
|
||||
try {
|
||||
const decrypted = JSON.parse(await this.crypto.unseal(encrypted));
|
||||
|
||||
return { ...record, ...decrypted };
|
||||
} catch (err) {
|
||||
// TODO: send telemetry
|
||||
console.error('Failed to decrypt secrets from localStorage', err);
|
||||
if (!(err instanceof NetworkError)) {
|
||||
localStorage.removeItem(this._storageKey);
|
||||
localStorage.removeItem(this.storageKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,33 +256,35 @@ export class LocalStorageSecretStorageProvider implements ISecretStorageProvider
|
|||
}
|
||||
|
||||
async get(key: string): Promise<string | undefined> {
|
||||
const secrets = await this._secretsPromise;
|
||||
const secrets = await this.secretsPromise;
|
||||
|
||||
return secrets[key];
|
||||
}
|
||||
|
||||
async set(key: string, value: string): Promise<void> {
|
||||
const secrets = await this._secretsPromise;
|
||||
const secrets = await this.secretsPromise;
|
||||
secrets[key] = value;
|
||||
this._secretsPromise = Promise.resolve(secrets);
|
||||
this.secretsPromise = Promise.resolve(secrets);
|
||||
this.save();
|
||||
}
|
||||
|
||||
async delete(key: string): Promise<void> {
|
||||
const secrets = await this._secretsPromise;
|
||||
const secrets = await this.secretsPromise;
|
||||
delete secrets[key];
|
||||
this._secretsPromise = Promise.resolve(secrets);
|
||||
this.secretsPromise = Promise.resolve(secrets);
|
||||
this.save();
|
||||
}
|
||||
|
||||
private async save(): Promise<void> {
|
||||
try {
|
||||
const encrypted = await this.crypto.seal(JSON.stringify(await this._secretsPromise));
|
||||
localStorage.setItem(this._storageKey, encrypted);
|
||||
const encrypted = await this.crypto.seal(JSON.stringify(await this.secretsPromise));
|
||||
localStorage.setItem(this.storageKey, encrypted);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class LocalStorageURLCallbackProvider extends Disposable implements IURLCallbackProvider {
|
||||
|
||||
private static REQUEST_ID = 0;
|
||||
|
@ -485,6 +500,7 @@ class WorkspaceProvider implements IWorkspaceProvider {
|
|||
return !!result;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import { promises } from 'fs';
|
||||
import { RunOnceScheduler } from '../../../../base/common/async.js';
|
||||
import { onUnexpectedError } from '../../../../base/common/errors.js';
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
|
@ -14,17 +14,19 @@ import { IProductService } from '../../../../platform/product/common/productServ
|
|||
|
||||
export class CodeCacheCleaner extends Disposable {
|
||||
|
||||
private readonly _DataMaxAge = this.productService.quality !== 'stable'
|
||||
? 1000 * 60 * 60 * 24 * 7 // roughly 1 week (insiders)
|
||||
: 1000 * 60 * 60 * 24 * 30 * 3; // roughly 3 months (stable)
|
||||
private readonly dataMaxAge: number;
|
||||
|
||||
constructor(
|
||||
currentCodeCachePath: string | undefined,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IProductService productService: IProductService,
|
||||
@ILogService private readonly logService: ILogService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.dataMaxAge = productService.quality !== 'stable'
|
||||
? 1000 * 60 * 60 * 24 * 7 // roughly 1 week (insiders)
|
||||
: 1000 * 60 * 60 * 24 * 30 * 3; // roughly 3 months (stable)
|
||||
|
||||
// Cached data is stored as user data and we run a cleanup task every time
|
||||
// the editor starts. The strategy is to delete all files that are older than
|
||||
// 3 months (1 week respectively)
|
||||
|
@ -55,8 +57,8 @@ export class CodeCacheCleaner extends Disposable {
|
|||
|
||||
// Delete cache folder if old enough
|
||||
const codeCacheEntryPath = join(codeCacheRootPath, codeCache);
|
||||
const codeCacheEntryStat = await fs.promises.stat(codeCacheEntryPath);
|
||||
if (codeCacheEntryStat.isDirectory() && (now - codeCacheEntryStat.mtime.getTime()) > this._DataMaxAge) {
|
||||
const codeCacheEntryStat = await promises.stat(codeCacheEntryPath);
|
||||
if (codeCacheEntryStat.isDirectory() && (now - codeCacheEntryStat.mtime.getTime()) > this.dataMaxAge) {
|
||||
this.logService.trace(`[code cache cleanup]: Removing code cache folder ${codeCache}.`);
|
||||
|
||||
return Promises.rm(codeCacheEntryPath);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import { promises } from 'fs';
|
||||
import { RunOnceScheduler } from '../../../../base/common/async.js';
|
||||
import { IStringDictionary } from '../../../../base/common/collections.js';
|
||||
import { onUnexpectedError } from '../../../../base/common/errors.js';
|
||||
|
@ -33,17 +33,19 @@ interface ILanguagePackFile {
|
|||
|
||||
export class LanguagePackCachedDataCleaner extends Disposable {
|
||||
|
||||
private readonly _DataMaxAge = this.productService.quality !== 'stable'
|
||||
? 1000 * 60 * 60 * 24 * 7 // roughly 1 week (insiders)
|
||||
: 1000 * 60 * 60 * 24 * 30 * 3; // roughly 3 months (stable)
|
||||
private readonly dataMaxAge: number;
|
||||
|
||||
constructor(
|
||||
@INativeEnvironmentService private readonly environmentService: INativeEnvironmentService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IProductService private readonly productService: IProductService
|
||||
@IProductService productService: IProductService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.dataMaxAge = productService.quality !== 'stable'
|
||||
? 1000 * 60 * 60 * 24 * 7 // roughly 1 week (insiders)
|
||||
: 1000 * 60 * 60 * 24 * 30 * 3; // roughly 3 months (stable)
|
||||
|
||||
// We have no Language pack support for dev version (run from source)
|
||||
// So only cleanup when we have a build version.
|
||||
if (this.environmentService.isBuilt) {
|
||||
|
@ -59,7 +61,7 @@ export class LanguagePackCachedDataCleaner extends Disposable {
|
|||
|
||||
try {
|
||||
const installed: IStringDictionary<boolean> = Object.create(null);
|
||||
const metaData: ILanguagePackFile = JSON.parse(await fs.promises.readFile(join(this.environmentService.userDataPath, 'languagepacks.json'), 'utf8'));
|
||||
const metaData: ILanguagePackFile = JSON.parse(await promises.readFile(join(this.environmentService.userDataPath, 'languagepacks.json'), 'utf8'));
|
||||
for (const locale of Object.keys(metaData)) {
|
||||
const entry = metaData[locale];
|
||||
installed[`${entry.hash}.${locale}`] = true;
|
||||
|
@ -94,8 +96,8 @@ export class LanguagePackCachedDataCleaner extends Disposable {
|
|||
}
|
||||
|
||||
const candidate = join(folder, entry);
|
||||
const stat = await fs.promises.stat(candidate);
|
||||
if (stat.isDirectory() && (now - stat.mtime.getTime()) > this._DataMaxAge) {
|
||||
const stat = await promises.stat(candidate);
|
||||
if (stat.isDirectory() && (now - stat.mtime.getTime()) > this.dataMaxAge) {
|
||||
this.logService.trace(`[language pack cache cleanup]: Removing language pack cache folder: ${join(packEntry, entry)}`);
|
||||
|
||||
await Promises.rm(candidate);
|
||||
|
|
|
@ -20,7 +20,7 @@ export interface IAuxiliaryWindow extends IBaseWindow {
|
|||
|
||||
export class AuxiliaryWindow extends BaseWindow implements IAuxiliaryWindow {
|
||||
|
||||
readonly id = this.webContents.id;
|
||||
readonly id: number;
|
||||
parentId = -1;
|
||||
|
||||
override get win() {
|
||||
|
@ -43,6 +43,8 @@ export class AuxiliaryWindow extends BaseWindow implements IAuxiliaryWindow {
|
|||
) {
|
||||
super(configurationService, stateService, environmentMainService, logService);
|
||||
|
||||
this.id = this.webContents.id;
|
||||
|
||||
// Try to claim window
|
||||
this.tryClaimWindow();
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ export class BackupMainService implements IBackupMainService {
|
|||
|
||||
private static readonly backupWorkspacesMetadataStorageKey = 'backupWorkspaces';
|
||||
|
||||
protected backupHome = this.environmentMainService.backupHome;
|
||||
protected backupHome: string;
|
||||
|
||||
private workspaces: IWorkspaceBackupInfo[] = [];
|
||||
private folders: IFolderBackupInfo[] = [];
|
||||
|
@ -40,11 +40,12 @@ export class BackupMainService implements IBackupMainService {
|
|||
private readonly backupPathComparer = { isEqual: (pathA: string, pathB: string) => isEqual(pathA, pathB, !isLinux) };
|
||||
|
||||
constructor(
|
||||
@IEnvironmentMainService private readonly environmentMainService: IEnvironmentMainService,
|
||||
@IEnvironmentMainService environmentMainService: IEnvironmentMainService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IStateService private readonly stateService: IStateService
|
||||
) {
|
||||
this.backupHome = environmentMainService.backupHome;
|
||||
}
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
|
|
|
@ -272,16 +272,18 @@ export abstract class AbstractSessionFileWatcher extends Disposable implements I
|
|||
// This is important because we want to ensure that we only
|
||||
// forward events from the watched paths for this session and
|
||||
// not other clients that asked to watch other paths.
|
||||
private readonly fileWatcher = this._register(new DiskFileSystemProvider(this.logService));
|
||||
private readonly fileWatcher: DiskFileSystemProvider;
|
||||
|
||||
constructor(
|
||||
private readonly uriTransformer: IURITransformer,
|
||||
sessionEmitter: Emitter<IFileChange[] | string>,
|
||||
private readonly logService: ILogService,
|
||||
logService: ILogService,
|
||||
private readonly environmentService: IEnvironmentService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.fileWatcher = this._register(new DiskFileSystemProvider(logService));
|
||||
|
||||
this.registerListeners(sessionEmitter);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,10 @@ import { joinPath } from '../../../../../base/common/resources.js';
|
|||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { realpath } from '../../../../../base/node/extpath.js';
|
||||
import { Promises } from '../../../../../base/node/pfs.js';
|
||||
import { FileChangeType, IFileChange } from '../../../common/files.js';
|
||||
import { FileChangeFilter, FileChangeType, IFileChange } from '../../../common/files.js';
|
||||
import { ILogMessage, coalesceEvents, INonRecursiveWatchRequest, parseWatcherPatterns, IRecursiveWatcherWithSubscribe, isFiltered, isWatchRequestWithCorrelation } from '../../../common/watcher.js';
|
||||
import { Lazy } from '../../../../../base/common/lazy.js';
|
||||
import { ParsedPattern } from '../../../../../base/common/glob.js';
|
||||
|
||||
export class NodeJSFileWatcherLibrary extends Disposable {
|
||||
|
||||
|
@ -50,9 +51,9 @@ export class NodeJSFileWatcherLibrary extends Disposable {
|
|||
// to coalesce events and reduce spam.
|
||||
private readonly fileChangesAggregator = this._register(new RunOnceWorker<IFileChange>(events => this.handleFileChanges(events), NodeJSFileWatcherLibrary.FILE_CHANGES_HANDLER_DELAY));
|
||||
|
||||
private readonly excludes = parseWatcherPatterns(this.request.path, this.request.excludes);
|
||||
private readonly includes = this.request.includes ? parseWatcherPatterns(this.request.path, this.request.includes) : undefined;
|
||||
private readonly filter = isWatchRequestWithCorrelation(this.request) ? this.request.filter : undefined; // filtering is only enabled when correlating because watchers are otherwise potentially reused
|
||||
private readonly excludes: ParsedPattern[];
|
||||
private readonly includes: ParsedPattern[] | undefined;
|
||||
private readonly filter: FileChangeFilter | undefined;
|
||||
|
||||
private readonly cts = new CancellationTokenSource();
|
||||
|
||||
|
@ -78,7 +79,7 @@ export class NodeJSFileWatcherLibrary extends Disposable {
|
|||
return result;
|
||||
});
|
||||
|
||||
readonly ready = this.watch();
|
||||
readonly ready: Promise<void>;
|
||||
|
||||
private _isReusingRecursiveWatcher = false;
|
||||
get isReusingRecursiveWatcher(): boolean { return this._isReusingRecursiveWatcher; }
|
||||
|
@ -95,6 +96,12 @@ export class NodeJSFileWatcherLibrary extends Disposable {
|
|||
private verboseLogging?: boolean
|
||||
) {
|
||||
super();
|
||||
|
||||
this.excludes = parseWatcherPatterns(this.request.path, this.request.excludes);
|
||||
this.includes = this.request.includes ? parseWatcherPatterns(this.request.path, this.request.includes) : undefined;
|
||||
this.filter = isWatchRequestWithCorrelation(this.request) ? this.request.filter : undefined; // filtering is only enabled when correlating because watchers are otherwise potentially reused
|
||||
|
||||
this.ready = this.watch();
|
||||
}
|
||||
|
||||
private async watch(): Promise<void> {
|
||||
|
|
|
@ -12,7 +12,7 @@ import { CancellationToken, CancellationTokenSource } from '../../../../../base/
|
|||
import { toErrorMessage } from '../../../../../base/common/errorMessage.js';
|
||||
import { Emitter, Event } from '../../../../../base/common/event.js';
|
||||
import { randomPath, isEqual, isEqualOrParent } from '../../../../../base/common/extpath.js';
|
||||
import { GLOBSTAR, patternsEquals } from '../../../../../base/common/glob.js';
|
||||
import { GLOBSTAR, ParsedPattern, patternsEquals } from '../../../../../base/common/glob.js';
|
||||
import { BaseWatcher } from '../baseWatcher.js';
|
||||
import { TernarySearchTree } from '../../../../../base/common/ternarySearchTree.js';
|
||||
import { normalizeNFC } from '../../../../../base/common/normalization.js';
|
||||
|
@ -37,8 +37,8 @@ export class ParcelWatcherInstance extends Disposable {
|
|||
private didStop = false;
|
||||
get stopped(): boolean { return this.didStop; }
|
||||
|
||||
private readonly includes = this.request.includes ? parseWatcherPatterns(this.request.path, this.request.includes) : undefined;
|
||||
private readonly excludes = this.request.excludes ? parseWatcherPatterns(this.request.path, this.request.excludes) : undefined;
|
||||
private readonly includes: ParsedPattern[] | undefined;
|
||||
private readonly excludes: ParsedPattern[] | undefined;
|
||||
|
||||
private readonly subscriptions = new Map<string, Set<(change: IFileChange) => void>>();
|
||||
|
||||
|
@ -65,6 +65,9 @@ export class ParcelWatcherInstance extends Disposable {
|
|||
) {
|
||||
super();
|
||||
|
||||
this.includes = this.request.includes ? parseWatcherPatterns(this.request.path, this.request.includes) : undefined;
|
||||
this.excludes = this.request.excludes ? parseWatcherPatterns(this.request.path, this.request.excludes) : undefined;
|
||||
|
||||
this._register(toDisposable(() => this.subscriptions.clear()));
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ export class MenubarMainService extends Disposable implements IMenubarMainServic
|
|||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private readonly menubar = this.installMenuBarAfterWindowOpen();
|
||||
private readonly menubar: Promise<Menubar>;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
|
@ -28,6 +28,8 @@ export class MenubarMainService extends Disposable implements IMenubarMainServic
|
|||
@ILogService private readonly logService: ILogService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.menubar = this.installMenuBarAfterWindowOpen();
|
||||
}
|
||||
|
||||
private async installMenuBarAfterWindowOpen(): Promise<Menubar> {
|
||||
|
|
|
@ -73,6 +73,60 @@ export class NativeHostMainService extends Disposable implements INativeHostMain
|
|||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
|
||||
// Events
|
||||
{
|
||||
this.onDidOpenMainWindow = Event.map(this.windowsMainService.onDidOpenWindow, window => window.id);
|
||||
|
||||
this.onDidTriggerWindowSystemContextMenu = Event.any(
|
||||
Event.map(this.windowsMainService.onDidTriggerSystemContextMenu, ({ window, x, y }) => ({ windowId: window.id, x, y })),
|
||||
Event.map(this.auxiliaryWindowsMainService.onDidTriggerSystemContextMenu, ({ window, x, y }) => ({ windowId: window.id, x, y }))
|
||||
);
|
||||
|
||||
this.onDidMaximizeWindow = Event.any(
|
||||
Event.map(this.windowsMainService.onDidMaximizeWindow, window => window.id),
|
||||
Event.map(this.auxiliaryWindowsMainService.onDidMaximizeWindow, window => window.id)
|
||||
);
|
||||
this.onDidUnmaximizeWindow = Event.any(
|
||||
Event.map(this.windowsMainService.onDidUnmaximizeWindow, window => window.id),
|
||||
Event.map(this.auxiliaryWindowsMainService.onDidUnmaximizeWindow, window => window.id)
|
||||
);
|
||||
|
||||
this.onDidChangeWindowFullScreen = Event.any(
|
||||
Event.map(this.windowsMainService.onDidChangeFullScreen, e => ({ windowId: e.window.id, fullscreen: e.fullscreen })),
|
||||
Event.map(this.auxiliaryWindowsMainService.onDidChangeFullScreen, e => ({ windowId: e.window.id, fullscreen: e.fullscreen }))
|
||||
);
|
||||
|
||||
this.onDidBlurMainWindow = Event.filter(Event.fromNodeEventEmitter(app, 'browser-window-blur', (event, window: BrowserWindow) => window.id), windowId => !!this.windowsMainService.getWindowById(windowId));
|
||||
this.onDidFocusMainWindow = Event.any(
|
||||
Event.map(Event.filter(Event.map(this.windowsMainService.onDidChangeWindowsCount, () => this.windowsMainService.getLastActiveWindow()), window => !!window), window => window!.id),
|
||||
Event.filter(Event.fromNodeEventEmitter(app, 'browser-window-focus', (event, window: BrowserWindow) => window.id), windowId => !!this.windowsMainService.getWindowById(windowId))
|
||||
);
|
||||
|
||||
this.onDidBlurMainOrAuxiliaryWindow = Event.any(
|
||||
this.onDidBlurMainWindow,
|
||||
Event.map(Event.filter(Event.fromNodeEventEmitter(app, 'browser-window-blur', (event, window: BrowserWindow) => this.auxiliaryWindowsMainService.getWindowByWebContents(window.webContents)), window => !!window), window => window!.id)
|
||||
);
|
||||
this.onDidFocusMainOrAuxiliaryWindow = Event.any(
|
||||
this.onDidFocusMainWindow,
|
||||
Event.map(Event.filter(Event.fromNodeEventEmitter(app, 'browser-window-focus', (event, window: BrowserWindow) => this.auxiliaryWindowsMainService.getWindowByWebContents(window.webContents)), window => !!window), window => window!.id)
|
||||
);
|
||||
|
||||
this.onDidResumeOS = Event.fromNodeEventEmitter(powerMonitor, 'resume');
|
||||
|
||||
this.onDidChangeColorScheme = this.themeMainService.onDidChangeColorScheme;
|
||||
|
||||
this.onDidChangeDisplay = Event.debounce(Event.any(
|
||||
Event.filter(Event.fromNodeEventEmitter(screen, 'display-metrics-changed', (event: Electron.Event, display: Display, changedMetrics?: string[]) => changedMetrics), changedMetrics => {
|
||||
// Electron will emit 'display-metrics-changed' events even when actually
|
||||
// going fullscreen, because the dock hides. However, we do not want to
|
||||
// react on this event as there is no change in display bounds.
|
||||
return !(Array.isArray(changedMetrics) && changedMetrics.length === 1 && changedMetrics[0] === 'workArea');
|
||||
}),
|
||||
Event.fromNodeEventEmitter(screen, 'display-added'),
|
||||
Event.fromNodeEventEmitter(screen, 'display-removed')
|
||||
), () => { }, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,59 +139,29 @@ export class NativeHostMainService extends Disposable implements INativeHostMain
|
|||
|
||||
//#region Events
|
||||
|
||||
readonly onDidOpenMainWindow = Event.map(this.windowsMainService.onDidOpenWindow, window => window.id);
|
||||
readonly onDidOpenMainWindow: Event<number>;
|
||||
|
||||
readonly onDidTriggerWindowSystemContextMenu = Event.any(
|
||||
Event.map(this.windowsMainService.onDidTriggerSystemContextMenu, ({ window, x, y }) => ({ windowId: window.id, x, y })),
|
||||
Event.map(this.auxiliaryWindowsMainService.onDidTriggerSystemContextMenu, ({ window, x, y }) => ({ windowId: window.id, x, y }))
|
||||
);
|
||||
readonly onDidTriggerWindowSystemContextMenu: Event<{ windowId: number; x: number; y: number }>;
|
||||
|
||||
readonly onDidMaximizeWindow = Event.any(
|
||||
Event.map(this.windowsMainService.onDidMaximizeWindow, window => window.id),
|
||||
Event.map(this.auxiliaryWindowsMainService.onDidMaximizeWindow, window => window.id)
|
||||
);
|
||||
readonly onDidUnmaximizeWindow = Event.any(
|
||||
Event.map(this.windowsMainService.onDidUnmaximizeWindow, window => window.id),
|
||||
Event.map(this.auxiliaryWindowsMainService.onDidUnmaximizeWindow, window => window.id)
|
||||
);
|
||||
readonly onDidMaximizeWindow: Event<number>;
|
||||
readonly onDidUnmaximizeWindow: Event<number>;
|
||||
|
||||
readonly onDidChangeWindowFullScreen = Event.any(
|
||||
Event.map(this.windowsMainService.onDidChangeFullScreen, e => ({ windowId: e.window.id, fullscreen: e.fullscreen })),
|
||||
Event.map(this.auxiliaryWindowsMainService.onDidChangeFullScreen, e => ({ windowId: e.window.id, fullscreen: e.fullscreen }))
|
||||
);
|
||||
readonly onDidChangeWindowFullScreen: Event<{ readonly windowId: number; readonly fullscreen: boolean }>;
|
||||
|
||||
readonly onDidBlurMainWindow = Event.filter(Event.fromNodeEventEmitter(app, 'browser-window-blur', (event, window: BrowserWindow) => window.id), windowId => !!this.windowsMainService.getWindowById(windowId));
|
||||
readonly onDidFocusMainWindow = Event.any(
|
||||
Event.map(Event.filter(Event.map(this.windowsMainService.onDidChangeWindowsCount, () => this.windowsMainService.getLastActiveWindow()), window => !!window), window => window!.id),
|
||||
Event.filter(Event.fromNodeEventEmitter(app, 'browser-window-focus', (event, window: BrowserWindow) => window.id), windowId => !!this.windowsMainService.getWindowById(windowId))
|
||||
);
|
||||
readonly onDidBlurMainWindow: Event<number>;
|
||||
readonly onDidFocusMainWindow: Event<number>;
|
||||
|
||||
readonly onDidBlurMainOrAuxiliaryWindow = Event.any(
|
||||
this.onDidBlurMainWindow,
|
||||
Event.map(Event.filter(Event.fromNodeEventEmitter(app, 'browser-window-blur', (event, window: BrowserWindow) => this.auxiliaryWindowsMainService.getWindowByWebContents(window.webContents)), window => !!window), window => window!.id)
|
||||
);
|
||||
readonly onDidFocusMainOrAuxiliaryWindow = Event.any(
|
||||
this.onDidFocusMainWindow,
|
||||
Event.map(Event.filter(Event.fromNodeEventEmitter(app, 'browser-window-focus', (event, window: BrowserWindow) => this.auxiliaryWindowsMainService.getWindowByWebContents(window.webContents)), window => !!window), window => window!.id)
|
||||
);
|
||||
readonly onDidBlurMainOrAuxiliaryWindow: Event<number>;
|
||||
readonly onDidFocusMainOrAuxiliaryWindow: Event<number>;
|
||||
|
||||
readonly onDidResumeOS = Event.fromNodeEventEmitter(powerMonitor, 'resume');
|
||||
readonly onDidResumeOS: Event<void>;
|
||||
|
||||
readonly onDidChangeColorScheme = this.themeMainService.onDidChangeColorScheme;
|
||||
readonly onDidChangeColorScheme: Event<IColorScheme>;
|
||||
|
||||
private readonly _onDidChangePassword = this._register(new Emitter<{ account: string; service: string }>());
|
||||
readonly onDidChangePassword = this._onDidChangePassword.event;
|
||||
|
||||
readonly onDidChangeDisplay = Event.debounce(Event.any(
|
||||
Event.filter(Event.fromNodeEventEmitter(screen, 'display-metrics-changed', (event: Electron.Event, display: Display, changedMetrics?: string[]) => changedMetrics), changedMetrics => {
|
||||
// Electron will emit 'display-metrics-changed' events even when actually
|
||||
// going fullscreen, because the dock hides. However, we do not want to
|
||||
// react on this event as there is no change in display bounds.
|
||||
return !(Array.isArray(changedMetrics) && changedMetrics.length === 1 && changedMetrics[0] === 'workArea');
|
||||
}),
|
||||
Event.fromNodeEventEmitter(screen, 'display-added'),
|
||||
Event.fromNodeEventEmitter(screen, 'display-removed')
|
||||
), () => { }, 100);
|
||||
readonly onDidChangeDisplay: Event<void>;
|
||||
|
||||
//#endregion
|
||||
|
||||
|
|
|
@ -25,18 +25,20 @@ export class FileStorage extends Disposable {
|
|||
private storage: StorageDatabase = Object.create(null);
|
||||
private lastSavedStorageContents = '';
|
||||
|
||||
private readonly flushDelayer = this._register(new ThrottledDelayer<void>(this.saveStrategy === SaveStrategy.IMMEDIATE ? 0 : 100 /* buffer saves over a short time */));
|
||||
private readonly flushDelayer: ThrottledDelayer<void>;
|
||||
|
||||
private initializing: Promise<void> | undefined = undefined;
|
||||
private closing: Promise<void> | undefined = undefined;
|
||||
|
||||
constructor(
|
||||
private readonly storagePath: URI,
|
||||
private readonly saveStrategy: SaveStrategy,
|
||||
saveStrategy: SaveStrategy,
|
||||
private readonly logService: ILogService,
|
||||
private readonly fileService: IFileService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this.flushDelayer = this._register(new ThrottledDelayer<void>(saveStrategy === SaveStrategy.IMMEDIATE ? 0 : 100 /* buffer saves over a short time */));
|
||||
}
|
||||
|
||||
init(): Promise<void> {
|
||||
|
|
|
@ -328,11 +328,13 @@ export abstract class AbstractStorageService extends Disposable implements IStor
|
|||
|
||||
private initializationPromise: Promise<void> | undefined;
|
||||
|
||||
private readonly flushWhenIdleScheduler = this._register(new RunOnceScheduler(() => this.doFlushWhenIdle(), this.options.flushInterval));
|
||||
private readonly flushWhenIdleScheduler: RunOnceScheduler;
|
||||
private readonly runFlushWhenIdle = this._register(new MutableDisposable());
|
||||
|
||||
constructor(private readonly options: IStorageServiceOptions = { flushInterval: AbstractStorageService.DEFAULT_FLUSH_INTERVAL }) {
|
||||
constructor(options: IStorageServiceOptions = { flushInterval: AbstractStorageService.DEFAULT_FLUSH_INTERVAL }) {
|
||||
super();
|
||||
|
||||
this.flushWhenIdleScheduler = this._register(new RunOnceScheduler(() => this.doFlushWhenIdle(), options.flushInterval));
|
||||
}
|
||||
|
||||
onDidChangeValue(scope: StorageScope.WORKSPACE, key: string | undefined, disposable: DisposableStore): Event<IWorkspaceStorageValueChangeEvent>;
|
||||
|
|
|
@ -17,24 +17,33 @@ import { IAnyWorkspaceIdentifier } from '../../workspace/common/workspace.js';
|
|||
|
||||
export class RemoteStorageService extends AbstractStorageService {
|
||||
|
||||
private readonly applicationStorageProfile = this.initialProfiles.defaultProfile;
|
||||
private readonly applicationStorage = this.createApplicationStorage();
|
||||
private readonly applicationStorageProfile: IUserDataProfile;
|
||||
private readonly applicationStorage: IStorage;
|
||||
|
||||
private profileStorageProfile = this.initialProfiles.currentProfile;
|
||||
private profileStorageProfile: IUserDataProfile;
|
||||
private readonly profileStorageDisposables = this._register(new DisposableStore());
|
||||
private profileStorage = this.createProfileStorage(this.profileStorageProfile);
|
||||
private profileStorage: IStorage;
|
||||
|
||||
private workspaceStorageId = this.initialWorkspace?.id;
|
||||
private workspaceStorageId: string | undefined;
|
||||
private readonly workspaceStorageDisposables = this._register(new DisposableStore());
|
||||
private workspaceStorage = this.createWorkspaceStorage(this.initialWorkspace);
|
||||
private workspaceStorage: IStorage | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly initialWorkspace: IAnyWorkspaceIdentifier | undefined,
|
||||
private readonly initialProfiles: { defaultProfile: IUserDataProfile; currentProfile: IUserDataProfile },
|
||||
initialWorkspace: IAnyWorkspaceIdentifier | undefined,
|
||||
initialProfiles: { defaultProfile: IUserDataProfile; currentProfile: IUserDataProfile },
|
||||
private readonly remoteService: IRemoteService,
|
||||
private readonly environmentService: IEnvironmentService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.applicationStorageProfile = initialProfiles.defaultProfile;
|
||||
this.applicationStorage = this.createApplicationStorage();
|
||||
|
||||
this.profileStorageProfile = initialProfiles.currentProfile;
|
||||
this.profileStorage = this.createProfileStorage(this.profileStorageProfile);
|
||||
|
||||
this.workspaceStorageId = initialWorkspace?.id;
|
||||
this.workspaceStorage = this.createWorkspaceStorage(initialWorkspace);
|
||||
}
|
||||
|
||||
private createApplicationStorage(): IStorage {
|
||||
|
|
|
@ -91,6 +91,8 @@ export class StorageMainService extends Disposable implements IStorageMainServic
|
|||
) {
|
||||
super();
|
||||
|
||||
this.applicationStorage = this._register(this.createApplicationStorage());
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
|
@ -163,7 +165,7 @@ export class StorageMainService extends Disposable implements IStorageMainServic
|
|||
|
||||
//#region Application Storage
|
||||
|
||||
readonly applicationStorage = this._register(this.createApplicationStorage());
|
||||
readonly applicationStorage: IStorageMain;
|
||||
|
||||
private createApplicationStorage(): IStorageMain {
|
||||
this.logService.trace(`StorageMainService: creating application storage`);
|
||||
|
@ -332,13 +334,15 @@ export class ApplicationStorageMainService extends AbstractStorageService implem
|
|||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
readonly whenReady = this.storageMainService.applicationStorage.whenInit;
|
||||
readonly whenReady: Promise<void>;
|
||||
|
||||
constructor(
|
||||
@IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService,
|
||||
@IStorageMainService private readonly storageMainService: IStorageMainService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.whenReady = this.storageMainService.applicationStorage.whenInit;
|
||||
}
|
||||
|
||||
protected doInitialize(): Promise<void> {
|
||||
|
|
|
@ -99,17 +99,19 @@ class UtilityProcessWorker extends Disposable {
|
|||
private readonly _onDidTerminate = this._register(new Emitter<IUtilityProcessWorkerProcessExit>());
|
||||
readonly onDidTerminate = this._onDidTerminate.event;
|
||||
|
||||
private readonly utilityProcess = this._register(new WindowUtilityProcess(this.logService, this.windowsMainService, this.telemetryService, this.lifecycleMainService));
|
||||
private readonly utilityProcess: WindowUtilityProcess;
|
||||
|
||||
constructor(
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@ILogService logService: ILogService,
|
||||
@IWindowsMainService private readonly windowsMainService: IWindowsMainService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@ILifecycleMainService lifecycleMainService: ILifecycleMainService,
|
||||
private readonly configuration: IUtilityProcessWorkerCreateConfiguration
|
||||
) {
|
||||
super();
|
||||
|
||||
this.utilityProcess = this._register(new WindowUtilityProcess(logService, windowsMainService, telemetryService, lifecycleMainService));
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import { IFileService } from '../../files/common/files.js';
|
|||
import { ILifecycleMainService } from '../../lifecycle/electron-main/lifecycleMainService.js';
|
||||
import { ILogService } from '../../log/common/log.js';
|
||||
import { IProductService } from '../../product/common/productService.js';
|
||||
import { IProtocolMainService } from '../../protocol/electron-main/protocol.js';
|
||||
import { IIPCObjectUrl, IProtocolMainService } from '../../protocol/electron-main/protocol.js';
|
||||
import { resolveMarketplaceHeaders } from '../../externalServices/common/marketplace.js';
|
||||
import { IApplicationStorageMainService, IStorageMainService } from '../../storage/electron-main/storageMainService.js';
|
||||
import { ITelemetryService } from '../../telemetry/common/telemetry.js';
|
||||
|
@ -536,7 +536,7 @@ export class CodeWindow extends BaseWindow implements ICodeWindow {
|
|||
|
||||
private customZoomLevel: number | undefined = undefined;
|
||||
|
||||
private readonly configObjectUrl = this._register(this.protocolMainService.createIPCObjectUrl<INativeWindowConfiguration>());
|
||||
private readonly configObjectUrl: IIPCObjectUrl<INativeWindowConfiguration>;
|
||||
private pendingLoadConfig: INativeWindowConfiguration | undefined;
|
||||
private wasLoaded = false;
|
||||
|
||||
|
@ -558,7 +558,7 @@ export class CodeWindow extends BaseWindow implements ICodeWindow {
|
|||
@IDialogMainService private readonly dialogMainService: IDialogMainService,
|
||||
@ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IProtocolMainService private readonly protocolMainService: IProtocolMainService,
|
||||
@IProtocolMainService protocolMainService: IProtocolMainService,
|
||||
@IWindowsMainService private readonly windowsMainService: IWindowsMainService,
|
||||
@IStateService stateService: IStateService,
|
||||
@IInstantiationService instantiationService: IInstantiationService
|
||||
|
@ -567,6 +567,8 @@ export class CodeWindow extends BaseWindow implements ICodeWindow {
|
|||
|
||||
//#region create browser window
|
||||
{
|
||||
this.configObjectUrl = this._register(protocolMainService.createIPCObjectUrl<INativeWindowConfiguration>());
|
||||
|
||||
// Load window state
|
||||
const [state, hasMultipleDisplays] = this.restoreWindowState(config.state);
|
||||
this.windowState = state;
|
||||
|
|
|
@ -210,7 +210,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
|||
|
||||
private readonly windows = new Map<number, ICodeWindow>();
|
||||
|
||||
private readonly windowsStateHandler = this._register(new WindowsStateHandler(this, this.stateService, this.lifecycleMainService, this.logService, this.configurationService));
|
||||
private readonly windowsStateHandler: WindowsStateHandler;
|
||||
|
||||
constructor(
|
||||
private readonly machineId: string,
|
||||
|
@ -219,7 +219,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
|||
private readonly initialUserEnv: IProcessEnvironment,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@ILoggerMainService private readonly loggerService: ILoggerMainService,
|
||||
@IStateService private readonly stateService: IStateService,
|
||||
@IStateService stateService: IStateService,
|
||||
@IPolicyService private readonly policyService: IPolicyService,
|
||||
@IEnvironmentMainService private readonly environmentMainService: IEnvironmentMainService,
|
||||
@IUserDataProfilesMainService private readonly userDataProfilesMainService: IUserDataProfilesMainService,
|
||||
|
@ -238,6 +238,8 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
|
|||
) {
|
||||
super();
|
||||
|
||||
this.windowsStateHandler = this._register(new WindowsStateHandler(this, stateService, this.lifecycleMainService, this.logService, this.configurationService));
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ export class WindowsStateHandler extends Disposable {
|
|||
private static readonly windowsStateStorageKey = 'windowsState';
|
||||
|
||||
get state() { return this._state; }
|
||||
private readonly _state = restoreWindowsState(this.stateService.getItem<ISerializedWindowsState>(WindowsStateHandler.windowsStateStorageKey));
|
||||
private readonly _state: IWindowsState;
|
||||
|
||||
private lastClosedState: IWindowState | undefined = undefined;
|
||||
|
||||
|
@ -70,6 +70,8 @@ export class WindowsStateHandler extends Disposable {
|
|||
) {
|
||||
super();
|
||||
|
||||
this._state = restoreWindowsState(this.stateService.getItem<ISerializedWindowsState>(WindowsStateHandler.windowsStateStorageKey));
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
|
|
|
@ -329,16 +329,23 @@ export function isWorkspaceFolder(thing: unknown): thing is IWorkspaceFolder {
|
|||
|
||||
export class Workspace implements IWorkspace {
|
||||
|
||||
private _foldersMap: TernarySearchTree<URI, WorkspaceFolder> = TernarySearchTree.forUris<WorkspaceFolder>(this._ignorePathCasing, () => true);
|
||||
private foldersMap: TernarySearchTree<URI, WorkspaceFolder>;
|
||||
|
||||
private _folders!: WorkspaceFolder[];
|
||||
get folders(): WorkspaceFolder[] { return this._folders; }
|
||||
set folders(folders: WorkspaceFolder[]) {
|
||||
this._folders = folders;
|
||||
this.updateFoldersMap();
|
||||
}
|
||||
|
||||
constructor(
|
||||
private _id: string,
|
||||
folders: WorkspaceFolder[],
|
||||
private _transient: boolean,
|
||||
private _configuration: URI | null,
|
||||
private _ignorePathCasing: (key: URI) => boolean,
|
||||
private ignorePathCasing: (key: URI) => boolean,
|
||||
) {
|
||||
this.foldersMap = TernarySearchTree.forUris<WorkspaceFolder>(this.ignorePathCasing, () => true);
|
||||
this.folders = folders;
|
||||
}
|
||||
|
||||
|
@ -346,19 +353,10 @@ export class Workspace implements IWorkspace {
|
|||
this._id = workspace.id;
|
||||
this._configuration = workspace.configuration;
|
||||
this._transient = workspace.transient;
|
||||
this._ignorePathCasing = workspace._ignorePathCasing;
|
||||
this.ignorePathCasing = workspace.ignorePathCasing;
|
||||
this.folders = workspace.folders;
|
||||
}
|
||||
|
||||
get folders(): WorkspaceFolder[] {
|
||||
return this._folders;
|
||||
}
|
||||
|
||||
set folders(folders: WorkspaceFolder[]) {
|
||||
this._folders = folders;
|
||||
this.updateFoldersMap();
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
return this._id;
|
||||
}
|
||||
|
@ -380,13 +378,13 @@ export class Workspace implements IWorkspace {
|
|||
return null;
|
||||
}
|
||||
|
||||
return this._foldersMap.findSubstr(resource) || null;
|
||||
return this.foldersMap.findSubstr(resource) || null;
|
||||
}
|
||||
|
||||
private updateFoldersMap(): void {
|
||||
this._foldersMap = TernarySearchTree.forUris<WorkspaceFolder>(this._ignorePathCasing, () => true);
|
||||
this.foldersMap = TernarySearchTree.forUris<WorkspaceFolder>(this.ignorePathCasing, () => true);
|
||||
for (const folder of this.folders) {
|
||||
this._foldersMap.set(folder.uri, folder);
|
||||
this.foldersMap.set(folder.uri, folder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import { IWorkspaceIdentifier } from '../../workspace/common/workspace.js';
|
|||
import { IWorkspacesHistoryMainService } from './workspacesHistoryMainService.js';
|
||||
import { IWorkspacesManagementMainService } from './workspacesManagementMainService.js';
|
||||
import { IWorkspaceBackupInfo, IFolderBackupInfo } from '../../backup/common/backup.js';
|
||||
import { Event } from '../../../base/common/event.js';
|
||||
|
||||
export class WorkspacesMainService implements AddFirstParameterToFunctions<IWorkspacesService, Promise<unknown> /* only methods, not events */, number /* window ID */> {
|
||||
|
||||
|
@ -23,6 +24,7 @@ export class WorkspacesMainService implements AddFirstParameterToFunctions<IWork
|
|||
@IWorkspacesHistoryMainService private readonly workspacesHistoryMainService: IWorkspacesHistoryMainService,
|
||||
@IBackupMainService private readonly backupMainService: IBackupMainService
|
||||
) {
|
||||
this.onDidChangeRecentlyOpened = this.workspacesHistoryMainService.onDidChangeRecentlyOpened;
|
||||
}
|
||||
|
||||
//#region Workspace Management
|
||||
|
@ -52,7 +54,7 @@ export class WorkspacesMainService implements AddFirstParameterToFunctions<IWork
|
|||
|
||||
//#region Workspaces History
|
||||
|
||||
readonly onDidChangeRecentlyOpened = this.workspacesHistoryMainService.onDidChangeRecentlyOpened;
|
||||
readonly onDidChangeRecentlyOpened: Event<void>;
|
||||
|
||||
getRecentlyOpened(windowId: number): Promise<IRecentlyOpened> {
|
||||
return this.workspacesHistoryMainService.getRecentlyOpened();
|
||||
|
|
|
@ -64,7 +64,7 @@ export class WorkspacesManagementMainService extends Disposable implements IWork
|
|||
private readonly _onDidEnterWorkspace = this._register(new Emitter<IWorkspaceEnteredEvent>());
|
||||
readonly onDidEnterWorkspace: Event<IWorkspaceEnteredEvent> = this._onDidEnterWorkspace.event;
|
||||
|
||||
private readonly untitledWorkspacesHome = this.environmentMainService.untitledWorkspacesHome; // local URI that contains all untitled workspaces
|
||||
private readonly untitledWorkspacesHome: URI; // local URI that contains all untitled workspaces
|
||||
|
||||
private untitledWorkspaces: IUntitledWorkspaceInfo[] = [];
|
||||
|
||||
|
@ -76,6 +76,8 @@ export class WorkspacesManagementMainService extends Disposable implements IWork
|
|||
@IDialogMainService private readonly dialogMainService: IDialogMainService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.untitledWorkspacesHome = this.environmentMainService.untitledWorkspacesHome;
|
||||
}
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
|
|
|
@ -243,9 +243,7 @@ interface IExtensionListener<E> {
|
|||
|
||||
class LazyRevivedFileSystemEvents implements FileSystemEvents {
|
||||
|
||||
constructor(private readonly _events: FileSystemEvents) { }
|
||||
|
||||
readonly session = this._events.session;
|
||||
readonly session: number | undefined;
|
||||
|
||||
private _created = new Lazy(() => this._events.created.map(URI.revive) as URI[]);
|
||||
get created(): URI[] { return this._created.value; }
|
||||
|
@ -255,6 +253,10 @@ class LazyRevivedFileSystemEvents implements FileSystemEvents {
|
|||
|
||||
private _deleted = new Lazy(() => this._events.deleted.map(URI.revive) as URI[]);
|
||||
get deleted(): URI[] { return this._deleted.value; }
|
||||
|
||||
constructor(private readonly _events: FileSystemEvents) {
|
||||
this.session = this._events.session;
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServiceShape {
|
||||
|
|
|
@ -27,9 +27,11 @@ export class ExtHostDiskFileSystemProvider {
|
|||
|
||||
class DiskFileSystemProviderAdapter implements vscode.FileSystemProvider {
|
||||
|
||||
private readonly impl = new DiskFileSystemProvider(this.logService);
|
||||
private readonly impl: DiskFileSystemProvider;
|
||||
|
||||
constructor(private readonly logService: ILogService) { }
|
||||
constructor(logService: ILogService) {
|
||||
this.impl = new DiskFileSystemProvider(logService);
|
||||
}
|
||||
|
||||
async stat(uri: vscode.Uri): Promise<vscode.FileStat> {
|
||||
const stat = await this.impl.stat(uri);
|
||||
|
|
|
@ -80,7 +80,7 @@ export class AuxiliaryBarPart extends AbstractPaneCompositePart {
|
|||
|
||||
readonly priority = LayoutPriority.Low;
|
||||
|
||||
private configuration = this.resolveConfiguration();
|
||||
private configuration: IAuxiliaryBarPartConfiguration;
|
||||
|
||||
constructor(
|
||||
@INotificationService notificationService: INotificationService,
|
||||
|
@ -125,6 +125,8 @@ export class AuxiliaryBarPart extends AbstractPaneCompositePart {
|
|||
menuService,
|
||||
);
|
||||
|
||||
this.configuration = this.resolveConfiguration();
|
||||
|
||||
this._register(configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(LayoutSettings.ACTIVITY_BAR_LOCATION)) {
|
||||
this.configuration = this.resolveConfiguration();
|
||||
|
|
|
@ -33,18 +33,20 @@ export class BrowserDialogHandler extends AbstractDialogHandler {
|
|||
'editor.action.clipboardPasteAction'
|
||||
];
|
||||
|
||||
private readonly markdownRenderer = this.instantiationService.createInstance(MarkdownRenderer, {});
|
||||
private readonly markdownRenderer: MarkdownRenderer;
|
||||
|
||||
constructor(
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@ILayoutService private readonly layoutService: ILayoutService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IClipboardService private readonly clipboardService: IClipboardService,
|
||||
@IOpenerService private readonly openerService: IOpenerService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.markdownRenderer = instantiationService.createInstance(MarkdownRenderer, {});
|
||||
}
|
||||
|
||||
async prompt<T>(prompt: IPrompt<T>): Promise<IAsyncPromptResult<T>> {
|
||||
|
|
|
@ -29,7 +29,7 @@ export class BrowserStorageService extends AbstractStorageService {
|
|||
|
||||
private profileStorage: IStorage | undefined;
|
||||
private profileStorageDatabase: IIndexedDBStorageDatabase | undefined;
|
||||
private profileStorageProfile = this.userDataProfileService.currentProfile;
|
||||
private profileStorageProfile: IUserDataProfile;
|
||||
private readonly profileStorageDisposables = this._register(new DisposableStore());
|
||||
|
||||
private workspaceStorage: IStorage | undefined;
|
||||
|
@ -50,6 +50,8 @@ export class BrowserStorageService extends AbstractStorageService {
|
|||
) {
|
||||
super({ flushInterval: BrowserStorageService.BROWSER_DEFAULT_FLUSH_INTERVAL });
|
||||
|
||||
this.profileStorageProfile = this.userDataProfileService.currentProfile;
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue