parent
1aa0bb83bc
commit
6cb06b7cb5
17 changed files with 3757 additions and 7351 deletions
2
.yarnrc
2
.yarnrc
|
@ -1,3 +1,3 @@
|
||||||
disturl "https://atom.io/download/electron"
|
disturl "https://atom.io/download/electron"
|
||||||
target "2.0.0-beta.7"
|
target "1.7.12"
|
||||||
runtime "electron"
|
runtime "electron"
|
||||||
|
|
|
@ -29,7 +29,7 @@ set ELECTRON_ENABLE_LOGGING=1
|
||||||
set ELECTRON_ENABLE_STACK_DUMPING=1
|
set ELECTRON_ENABLE_STACK_DUMPING=1
|
||||||
|
|
||||||
:: Launch Code
|
:: Launch Code
|
||||||
%CODE% --inspect=5874 out\cli.js . %*
|
%CODE% --debug=5874 out\cli.js . %*
|
||||||
popd
|
popd
|
||||||
|
|
||||||
endlocal
|
endlocal
|
||||||
|
|
|
@ -32,7 +32,7 @@ function code() {
|
||||||
VSCODE_DEV=1 \
|
VSCODE_DEV=1 \
|
||||||
ELECTRON_ENABLE_LOGGING=1 \
|
ELECTRON_ENABLE_LOGGING=1 \
|
||||||
ELECTRON_ENABLE_STACK_DUMPING=1 \
|
ELECTRON_ENABLE_STACK_DUMPING=1 \
|
||||||
"$CODE" --inspect=5874 "$ROOT/out/cli.js" . "$@"
|
"$CODE" --debug=5874 "$ROOT/out/cli.js" . "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
code "$@"
|
code "$@"
|
||||||
|
|
|
@ -3,10 +3,6 @@
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
|
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
|
||||||
ROOT=$(dirname "$(dirname "$(realpath "$0")")")
|
ROOT=$(dirname "$(dirname "$(realpath "$0")")")
|
||||||
|
|
||||||
# On Linux with Electron 2.0.x running out of a VM causes
|
|
||||||
# a freeze so we only enable this flag on macOS
|
|
||||||
export ELECTRON_ENABLE_LOGGING=1
|
|
||||||
else
|
else
|
||||||
ROOT=$(dirname "$(dirname "$(readlink -f $0)")")
|
ROOT=$(dirname "$(dirname "$(readlink -f $0)")")
|
||||||
fi
|
fi
|
||||||
|
@ -44,6 +40,7 @@ function code() {
|
||||||
export NODE_ENV=development
|
export NODE_ENV=development
|
||||||
export VSCODE_DEV=1
|
export VSCODE_DEV=1
|
||||||
export VSCODE_CLI=1
|
export VSCODE_CLI=1
|
||||||
|
export ELECTRON_ENABLE_LOGGING=1
|
||||||
export ELECTRON_ENABLE_STACK_DUMPING=1
|
export ELECTRON_ENABLE_STACK_DUMPING=1
|
||||||
|
|
||||||
# Launch Code
|
# Launch Code
|
||||||
|
|
|
@ -4,10 +4,6 @@
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
|
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
|
||||||
ROOT=$(dirname $(dirname $(realpath "$0")))
|
ROOT=$(dirname $(dirname $(realpath "$0")))
|
||||||
|
|
||||||
# On Linux with Electron 2.0.x running out of a VM causes
|
|
||||||
# a freeze so we only enable this flag on macOS
|
|
||||||
export ELECTRON_ENABLE_LOGGING=1
|
|
||||||
else
|
else
|
||||||
ROOT=$(dirname $(dirname $(readlink -f $0)))
|
ROOT=$(dirname $(dirname $(readlink -f $0)))
|
||||||
fi
|
fi
|
||||||
|
@ -29,6 +25,7 @@ test -d node_modules || yarn
|
||||||
node build/lib/electron.js || ./node_modules/.bin/gulp electron
|
node build/lib/electron.js || ./node_modules/.bin/gulp electron
|
||||||
|
|
||||||
# Unit Tests
|
# Unit Tests
|
||||||
|
export ELECTRON_ENABLE_LOGGING=1
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
cd $ROOT ; ulimit -n 4096 ; \
|
cd $ROOT ; ulimit -n 4096 ; \
|
||||||
"$CODE" \
|
"$CODE" \
|
||||||
|
|
1193
src/typings/electron.d.ts
vendored
1193
src/typings/electron.d.ts
vendored
File diff suppressed because it is too large
Load diff
4428
src/typings/node.d.ts
vendored
4428
src/typings/node.d.ts
vendored
File diff suppressed because it is too large
Load diff
|
@ -146,7 +146,7 @@ function showContextMenu(e) {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
menu.popup({ window: remote.getCurrentWindow() });
|
menu.popup(remote.getCurrentWindow());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,6 @@ import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc';
|
||||||
import { setUnexpectedErrorHandler } from 'vs/base/common/errors';
|
import { setUnexpectedErrorHandler } from 'vs/base/common/errors';
|
||||||
import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener';
|
import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener';
|
||||||
import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
|
import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
|
||||||
import { join } from 'path';
|
|
||||||
import { copy, exists, rename } from 'vs/base/node/pfs';
|
|
||||||
|
|
||||||
export class CodeApplication {
|
export class CodeApplication {
|
||||||
|
|
||||||
|
@ -264,10 +262,6 @@ export class CodeApplication {
|
||||||
this.logService.debug(`from: ${this.environmentService.appRoot}`);
|
this.logService.debug(`from: ${this.environmentService.appRoot}`);
|
||||||
this.logService.debug('args:', this.environmentService.args);
|
this.logService.debug('args:', this.environmentService.args);
|
||||||
|
|
||||||
// Handle local storage (TODO@Ben remove me after a while)
|
|
||||||
this.logService.trace('Handling localStorage if needed...');
|
|
||||||
return this.handleLocalStorage().then(() => {
|
|
||||||
|
|
||||||
// Make sure we associate the program with the app user model id
|
// Make sure we associate the program with the app user model id
|
||||||
// This will help Windows to associate the running program with
|
// This will help Windows to associate the running program with
|
||||||
// any shortcut that is pinned to the taskbar and prevent showing
|
// any shortcut that is pinned to the taskbar and prevent showing
|
||||||
|
@ -302,7 +296,6 @@ export class CodeApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise.then(() => {
|
return promise.then(() => {
|
||||||
|
|
||||||
// Setup Auth Handler
|
// Setup Auth Handler
|
||||||
const authHandler = appInstantiationService.createInstance(ProxyAuthHandler);
|
const authHandler = appInstantiationService.createInstance(ProxyAuthHandler);
|
||||||
this.toDispose.push(authHandler);
|
this.toDispose.push(authHandler);
|
||||||
|
@ -314,7 +307,6 @@ export class CodeApplication {
|
||||||
appInstantiationService.invokeFunction(accessor => this.afterWindowOpen(accessor));
|
appInstantiationService.invokeFunction(accessor => this.afterWindowOpen(accessor));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private resolveMachineId(): TPromise<string> {
|
private resolveMachineId(): TPromise<string> {
|
||||||
|
@ -332,36 +324,6 @@ export class CodeApplication {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleLocalStorage(): TPromise<void> {
|
|
||||||
const localStorageFile = join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage');
|
|
||||||
const localStorageJournalFile = join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage-journal');
|
|
||||||
const localStorageBackupFile = join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage.vscbak');
|
|
||||||
const localStorageJournalBackupFile = join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage-journal.vscbak');
|
|
||||||
|
|
||||||
// Electron 1.7.12: Restore storage
|
|
||||||
if (process.versions.electron === '1.7.12') {
|
|
||||||
return exists(localStorageBackupFile).then(localStorageBackupFileExists => {
|
|
||||||
return exists(localStorageJournalBackupFile).then(localStorageJournalBackupFileExists => {
|
|
||||||
return TPromise.join([
|
|
||||||
localStorageBackupFileExists ? rename(localStorageBackupFile, localStorageFile) : TPromise.as(void 0),
|
|
||||||
localStorageJournalBackupFileExists ? rename(localStorageJournalBackupFile, localStorageJournalFile) : TPromise.as(void 0)
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
}).then(() => void 0, () => void 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Electron 2.0: Backup
|
|
||||||
else {
|
|
||||||
return exists(localStorageBackupFile).then(backupExists => {
|
|
||||||
if (backupExists) {
|
|
||||||
return void 0; // do not backup if backup already exists
|
|
||||||
}
|
|
||||||
|
|
||||||
return copy(localStorageFile, localStorageBackupFile).then(() => copy(localStorageJournalFile, localStorageJournalBackupFile));
|
|
||||||
}).then(() => void 0, () => void 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private initServices(machineId: string): IInstantiationService {
|
private initServices(machineId: string): IInstantiationService {
|
||||||
const services = new ServiceCollection();
|
const services = new ServiceCollection();
|
||||||
|
|
||||||
|
|
|
@ -186,6 +186,23 @@ export class CodeWindow implements ICodeWindow {
|
||||||
this._win = new BrowserWindow(options);
|
this._win = new BrowserWindow(options);
|
||||||
this._id = this._win.id;
|
this._id = this._win.id;
|
||||||
|
|
||||||
|
// Bug in Electron (https://github.com/electron/electron/issues/10862). On multi-monitor setups,
|
||||||
|
// it can happen that the position we set to the window is not the correct one on the display.
|
||||||
|
// To workaround, we ask the window for its position and set it again if not matching.
|
||||||
|
// This only applies if the window is not fullscreen or maximized and multiple monitors are used.
|
||||||
|
if (isWindows && !isFullscreenOrMaximized) {
|
||||||
|
try {
|
||||||
|
if (screen.getAllDisplays().length > 1) {
|
||||||
|
const [x, y] = this._win.getPosition();
|
||||||
|
if (x !== this.windowState.x || y !== this.windowState.y) {
|
||||||
|
this._win.setPosition(this.windowState.x, this.windowState.y, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.logService.warn(`Unexpected error fixing window position on windows with multiple windows: ${err}\n${err.stack}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (useCustomTitleStyle) {
|
if (useCustomTitleStyle) {
|
||||||
this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any
|
this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any
|
||||||
}
|
}
|
||||||
|
@ -938,6 +955,11 @@ export class CodeWindow implements ICodeWindow {
|
||||||
this.touchBarGroups.push(groupTouchBar);
|
this.touchBarGroups.push(groupTouchBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ugly workaround for native crash on macOS 10.12.1. We are not
|
||||||
|
// leveraging the API for changing the ESC touch bar item.
|
||||||
|
// See https://github.com/electron/electron/issues/10442
|
||||||
|
(<any>this._win)._setEscapeTouchBarItem = () => { };
|
||||||
|
|
||||||
this._win.setTouchBar(new TouchBar({ items: this.touchBarGroups }));
|
this._win.setTouchBar(new TouchBar({ items: this.touchBarGroups }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ export class DarwinUpdateService extends AbstractUpdateService {
|
||||||
|
|
||||||
protected setUpdateFeedUrl(quality: string): boolean {
|
protected setUpdateFeedUrl(quality: string): boolean {
|
||||||
try {
|
try {
|
||||||
electron.autoUpdater.setFeedURL({ url: createUpdateURL('darwin', quality) });
|
electron.autoUpdater.setFeedURL(createUpdateURL('darwin', quality));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// application is very likely not signed
|
// application is very likely not signed
|
||||||
this.logService.error('Failed to set update feed URL');
|
this.logService.error('Failed to set update feed URL');
|
||||||
|
|
|
@ -24,17 +24,14 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
||||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||||
import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility';
|
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility';
|
||||||
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||||
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme';
|
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme';
|
||||||
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||||
import { CompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBar';
|
import { CompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBar';
|
||||||
import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositebar/compositeBarActions';
|
import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositebar/compositeBarActions';
|
||||||
import { isMacintosh } from 'vs/base/common/platform';
|
|
||||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
|
||||||
import { Dimension, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
|
||||||
import { Color } from 'vs/base/common/color';
|
|
||||||
import { ViewLocation, ViewsRegistry } from 'vs/workbench/common/views';
|
import { ViewLocation, ViewsRegistry } from 'vs/workbench/common/views';
|
||||||
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||||
|
import { Dimension } from 'vs/base/browser/dom';
|
||||||
|
|
||||||
export class ActivitybarPart extends Part {
|
export class ActivitybarPart extends Part {
|
||||||
|
|
||||||
|
@ -62,8 +59,7 @@ export class ActivitybarPart extends Part {
|
||||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||||
@IInstantiationService private instantiationService: IInstantiationService,
|
@IInstantiationService private instantiationService: IInstantiationService,
|
||||||
@IPartService private partService: IPartService,
|
@IPartService private partService: IPartService,
|
||||||
@IThemeService themeService: IThemeService,
|
@IThemeService themeService: IThemeService
|
||||||
@ILifecycleService private lifecycleService: ILifecycleService
|
|
||||||
) {
|
) {
|
||||||
super(id, { hasTitle: false }, themeService);
|
super(id, { hasTitle: false }, themeService);
|
||||||
|
|
||||||
|
@ -142,27 +138,6 @@ export class ActivitybarPart extends Part {
|
||||||
// Top Actionbar with action items for each viewlet action
|
// Top Actionbar with action items for each viewlet action
|
||||||
this.createGlobalActivityActionBar($('.global-activity').appendTo($result).getHTMLElement());
|
this.createGlobalActivityActionBar($('.global-activity').appendTo($result).getHTMLElement());
|
||||||
|
|
||||||
// TODO@Ben: workaround for https://github.com/Microsoft/vscode/issues/45700
|
|
||||||
// It looks like there are rendering glitches on macOS with Chrome 61 when
|
|
||||||
// using --webkit-mask with a background color that is different from the image
|
|
||||||
// The workaround is to promote the element onto its own drawing layer. We do
|
|
||||||
// this only after the workbench has loaded because otherwise there is ugly flicker.
|
|
||||||
if (isMacintosh) {
|
|
||||||
this.lifecycleService.when(LifecyclePhase.Running).then(() => {
|
|
||||||
scheduleAtNextAnimationFrame(() => { // another delay...
|
|
||||||
scheduleAtNextAnimationFrame(() => { // ...to prevent more flickering on startup
|
|
||||||
registerThemingParticipant((theme, collector) => {
|
|
||||||
const activityBarForeground = theme.getColor(ACTIVITY_BAR_FOREGROUND);
|
|
||||||
if (activityBarForeground && !activityBarForeground.equals(Color.white)) {
|
|
||||||
// only apply this workaround if the color is different from the image one (white)
|
|
||||||
collector.addRule('.monaco-workbench .activitybar > .content > .composite-bar > .monaco-action-bar .action-label { will-change: transform; }');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result.getHTMLElement();
|
return $result.getHTMLElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ import { IIntegrityService } from 'vs/platform/integrity/common/integrity';
|
||||||
import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl';
|
import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl';
|
||||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||||
import { ExtensionService } from 'vs/workbench/services/extensions/electron-browser/extensionService';
|
import { ExtensionService } from 'vs/workbench/services/extensions/electron-browser/extensionService';
|
||||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||||
|
@ -83,7 +83,7 @@ import { HashService } from 'vs/workbench/services/hash/node/hashService';
|
||||||
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
|
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme';
|
import { WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme';
|
||||||
import { stat, existsSync } from 'fs';
|
import { stat } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { ILocalizationsChannel, LocalizationsChannelClient } from 'vs/platform/localizations/common/localizationsIpc';
|
import { ILocalizationsChannel, LocalizationsChannelClient } from 'vs/platform/localizations/common/localizationsIpc';
|
||||||
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
|
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
|
||||||
|
@ -128,7 +128,6 @@ export class WorkbenchShell {
|
||||||
private lifecycleService: LifecycleService;
|
private lifecycleService: LifecycleService;
|
||||||
private mainProcessServices: ServiceCollection;
|
private mainProcessServices: ServiceCollection;
|
||||||
private notificationService: INotificationService;
|
private notificationService: INotificationService;
|
||||||
private mainProcessClient: IPCClient;
|
|
||||||
|
|
||||||
private container: HTMLElement;
|
private container: HTMLElement;
|
||||||
private toUnbind: IDisposable[];
|
private toUnbind: IDisposable[];
|
||||||
|
@ -140,9 +139,7 @@ export class WorkbenchShell {
|
||||||
private configuration: IWindowConfiguration;
|
private configuration: IWindowConfiguration;
|
||||||
private workbench: Workbench;
|
private workbench: Workbench;
|
||||||
|
|
||||||
private hasLocalStorageData: boolean;
|
constructor(container: HTMLElement, coreServices: ICoreServices, mainProcessServices: ServiceCollection, private mainProcessClient: IPCClient, configuration: IWindowConfiguration) {
|
||||||
|
|
||||||
constructor(container: HTMLElement, coreServices: ICoreServices, mainProcessServices: ServiceCollection, mainProcessClient: IPCClient, configuration: IWindowConfiguration) {
|
|
||||||
this.container = container;
|
this.container = container;
|
||||||
|
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
|
@ -155,13 +152,9 @@ export class WorkbenchShell {
|
||||||
this.storageService = coreServices.storageService;
|
this.storageService = coreServices.storageService;
|
||||||
|
|
||||||
this.mainProcessServices = mainProcessServices;
|
this.mainProcessServices = mainProcessServices;
|
||||||
this.mainProcessClient = mainProcessClient;
|
|
||||||
|
|
||||||
this.toUnbind = [];
|
this.toUnbind = [];
|
||||||
this.previousErrorTime = 0;
|
this.previousErrorTime = 0;
|
||||||
|
|
||||||
// TODO@Ben remove me later
|
|
||||||
this.hasLocalStorageData = !!this.storageService.get('releaseNotes/lastVersion', StorageScope.GLOBAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private createContents(parent: HTMLElement): HTMLElement {
|
private createContents(parent: HTMLElement): HTMLElement {
|
||||||
|
@ -227,11 +220,6 @@ export class WorkbenchShell {
|
||||||
if (!this.environmentService.extensionTestsPath && this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
|
if (!this.environmentService.extensionTestsPath && this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
|
||||||
this.logLocalStorageMetrics();
|
this.logLocalStorageMetrics();
|
||||||
}
|
}
|
||||||
|
|
||||||
// localStorage migration (TODO@Ben remove me later)
|
|
||||||
if (!this.environmentService.extensionTestsPath) {
|
|
||||||
this.logLocalStorageMigrationStatus();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return workbench;
|
return workbench;
|
||||||
|
@ -306,17 +294,17 @@ export class WorkbenchShell {
|
||||||
}
|
}
|
||||||
|
|
||||||
perf.mark('willReadLocalStorage');
|
perf.mark('willReadLocalStorage');
|
||||||
const readyToSend = this.storageService.getBoolean('localStorageMetricsReadyToSend4');
|
const readyToSend = this.storageService.getBoolean('localStorageMetricsReadyToSend2');
|
||||||
perf.mark('didReadLocalStorage');
|
perf.mark('didReadLocalStorage');
|
||||||
|
|
||||||
if (!readyToSend) {
|
if (!readyToSend) {
|
||||||
this.storageService.store('localStorageMetricsReadyToSend4', true);
|
this.storageService.store('localStorageMetricsReadyToSend2', true);
|
||||||
return; // avoid logging localStorage metrics directly after the update, we prefer cold startup numbers
|
return; // avoid logging localStorage metrics directly after the update, we prefer cold startup numbers
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.storageService.getBoolean('localStorageMetricsSent4')) {
|
if (!this.storageService.getBoolean('localStorageMetricsSent2')) {
|
||||||
perf.mark('willWriteLocalStorage');
|
perf.mark('willWriteLocalStorage');
|
||||||
this.storageService.store('localStorageMetricsSent4', true);
|
this.storageService.store('localStorageMetricsSent2', true);
|
||||||
perf.mark('didWriteLocalStorage');
|
perf.mark('didWriteLocalStorage');
|
||||||
|
|
||||||
perf.mark('willStatLocalStorage');
|
perf.mark('willStatLocalStorage');
|
||||||
|
@ -334,7 +322,7 @@ export class WorkbenchShell {
|
||||||
"size": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
"size": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
this.telemetryService.publicLog('localStorageTimers4', {
|
this.telemetryService.publicLog('localStorageTimers2', {
|
||||||
'statTime': perf.getDuration('willStatLocalStorage', 'didStatLocalStorage'),
|
'statTime': perf.getDuration('willStatLocalStorage', 'didStatLocalStorage'),
|
||||||
'accessTime': perf.getDuration('willAccessLocalStorage', 'didAccessLocalStorage'),
|
'accessTime': perf.getDuration('willAccessLocalStorage', 'didAccessLocalStorage'),
|
||||||
'firstReadTime': perf.getDuration('willReadWorkspaceIdentifier', 'didReadWorkspaceIdentifier'),
|
'firstReadTime': perf.getDuration('willReadWorkspaceIdentifier', 'didReadWorkspaceIdentifier'),
|
||||||
|
@ -347,38 +335,6 @@ export class WorkbenchShell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private logLocalStorageMigrationStatus(): void {
|
|
||||||
if (product.quality === 'insider' && !this.storageService.getBoolean('localStorageMigrationStatusLogged')) {
|
|
||||||
this.storageService.store('localStorageMigrationStatusLogged', true);
|
|
||||||
|
|
||||||
stat(join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage.vscbak'), (error, stat) => {
|
|
||||||
// if we have a backup of localStorage it means a migration was attempted
|
|
||||||
// by Electron 2.0. We log to telemetry if we had data initially which means
|
|
||||||
// the migration was successful.
|
|
||||||
if (stat) {
|
|
||||||
/* __GDPR__
|
|
||||||
"localStorageMigrationStatus" : {
|
|
||||||
"platform": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
|
||||||
"arch": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
|
||||||
"migrated": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
|
||||||
"size": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
|
||||||
"sqliteStillExists": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
|
||||||
"sqliteJournalExists": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
this.telemetryService.publicLog('localStorageMigrationStatus', {
|
|
||||||
'platform': process.platform,
|
|
||||||
'arch': process.arch,
|
|
||||||
'migrated': this.hasLocalStorageData,
|
|
||||||
'size': stat.size,
|
|
||||||
'sqliteStillExists': existsSync(join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage')),
|
|
||||||
'sqliteJournalExists': existsSync(join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage-journal'))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private initServiceCollection(container: HTMLElement): [IInstantiationService, ServiceCollection] {
|
private initServiceCollection(container: HTMLElement): [IInstantiationService, ServiceCollection] {
|
||||||
const serviceCollection = new ServiceCollection();
|
const serviceCollection = new ServiceCollection();
|
||||||
serviceCollection.set(IWorkspaceContextService, this.contextService);
|
serviceCollection.set(IWorkspaceContextService, this.contextService);
|
||||||
|
|
|
@ -13,24 +13,6 @@ import { Protocol } from 'vs/base/parts/ipc/node/ipc.net';
|
||||||
import { createConnection } from 'net';
|
import { createConnection } from 'net';
|
||||||
import { Event, filterEvent } from 'vs/base/common/event';
|
import { Event, filterEvent } from 'vs/base/common/event';
|
||||||
|
|
||||||
// TODO@ben: with Electron 2.x and node.js 8.x the "natives" module
|
|
||||||
// can cause a native crash (see https://github.com/nodejs/node/issues/19891 and
|
|
||||||
// https://github.com/electron/electron/issues/10905). To prevent this from
|
|
||||||
// happening we essentially blocklist this module from getting loaded in any
|
|
||||||
// extension by patching the node require() function.
|
|
||||||
(function () {
|
|
||||||
const Module = require.__$__nodeRequire('module') as any;
|
|
||||||
const originalLoad = Module._load;
|
|
||||||
|
|
||||||
Module._load = function (request) {
|
|
||||||
if (request === 'natives') {
|
|
||||||
throw new Error('Either the extension or a NPM dependency is using the "natives" node module which is unsupported as it can cause a crash of the extension host. Click [here](https://go.microsoft.com/fwlink/?linkid=871887) to find out more');
|
|
||||||
}
|
|
||||||
|
|
||||||
return originalLoad.apply(this, arguments);
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
interface IRendererConnection {
|
interface IRendererConnection {
|
||||||
protocol: IMessagePassingProtocol;
|
protocol: IMessagePassingProtocol;
|
||||||
initData: IInitData;
|
initData: IInitData;
|
||||||
|
@ -146,6 +128,8 @@ createExtHostProtocol().then(protocol => {
|
||||||
return extensionHostMain.start();
|
return extensionHostMain.start();
|
||||||
}).catch(err => console.error(err));
|
}).catch(err => console.error(err));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function patchExecArgv() {
|
function patchExecArgv() {
|
||||||
// when encountering the prevent-inspect flag we delete this
|
// when encountering the prevent-inspect flag we delete this
|
||||||
// and the prior flag
|
// and the prior flag
|
||||||
|
|
|
@ -16,8 +16,8 @@ import { Queue } from 'vs/base/common/async';
|
||||||
import { stat, writeFile } from 'vs/base/node/pfs';
|
import { stat, writeFile } from 'vs/base/node/pfs';
|
||||||
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
||||||
import { IWorkspaceContextService, Workspace, WorkbenchState, IWorkspaceFolder, toWorkspaceFolders, IWorkspaceFoldersChangeEvent, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceContextService, Workspace, WorkbenchState, IWorkspaceFolder, toWorkspaceFolders, IWorkspaceFoldersChangeEvent, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||||
import { isLinux, isWindows, isMacintosh } from 'vs/base/common/platform';
|
|
||||||
import { IFileService } from 'vs/platform/files/common/files';
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
|
import { isLinux } from 'vs/base/common/platform';
|
||||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||||
import { ConfigurationChangeEvent, ConfigurationModel, DefaultConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
|
import { ConfigurationChangeEvent, ConfigurationModel, DefaultConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
|
||||||
import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData } from 'vs/platform/configuration/common/configuration';
|
||||||
|
@ -349,19 +349,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
|
||||||
const folderPath = URI.file(singleFolderWorkspaceIdentifier);
|
const folderPath = URI.file(singleFolderWorkspaceIdentifier);
|
||||||
return stat(folderPath.fsPath)
|
return stat(folderPath.fsPath)
|
||||||
.then(workspaceStat => {
|
.then(workspaceStat => {
|
||||||
let ctime: number;
|
const ctime = isLinux ? workspaceStat.ino : workspaceStat.birthtime.getTime(); // On Linux, birthtime is ctime, so we cannot use it! We use the ino instead!
|
||||||
if (isLinux) {
|
|
||||||
ctime = workspaceStat.ino; // Linux: birthtime is ctime, so we cannot use it! We use the ino instead!
|
|
||||||
} else if (isMacintosh) {
|
|
||||||
ctime = workspaceStat.birthtime.getTime(); // macOS: birthtime is fine to use as is
|
|
||||||
} else if (isWindows) {
|
|
||||||
if (typeof workspaceStat.birthtimeMs === 'number') {
|
|
||||||
ctime = Math.floor(workspaceStat.birthtimeMs); // Windows: fix precision issue in node.js 8.x to get 7.x results (see https://github.com/nodejs/node/issues/19897)
|
|
||||||
} else {
|
|
||||||
ctime = workspaceStat.birthtime.getTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const id = createHash('md5').update(folderPath.fsPath).update(ctime ? String(ctime) : '').digest('hex');
|
const id = createHash('md5').update(folderPath.fsPath).update(ctime ? String(ctime) : '').digest('hex');
|
||||||
const folder = URI.file(folderPath.fsPath);
|
const folder = URI.file(folderPath.fsPath);
|
||||||
return new Workspace(id, getBaseLabel(folder), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime);
|
return new Workspace(id, getBaseLabel(folder), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime);
|
||||||
|
|
|
@ -18,7 +18,6 @@ import { unmnemonicLabel } from 'vs/base/common/labels';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { IContextMenuDelegate, ContextSubMenu, IEvent } from 'vs/base/browser/contextmenu';
|
import { IContextMenuDelegate, ContextSubMenu, IEvent } from 'vs/base/browser/contextmenu';
|
||||||
import { once } from 'vs/base/common/functional';
|
|
||||||
|
|
||||||
export class ContextMenuService implements IContextMenuService {
|
export class ContextMenuService implements IContextMenuService {
|
||||||
|
|
||||||
|
@ -43,15 +42,7 @@ export class ContextMenuService implements IContextMenuService {
|
||||||
}
|
}
|
||||||
|
|
||||||
return TPromise.timeout(0).then(() => { // https://github.com/Microsoft/vscode/issues/3638
|
return TPromise.timeout(0).then(() => { // https://github.com/Microsoft/vscode/issues/3638
|
||||||
const onHide = once(() => {
|
const menu = this.createMenu(delegate, actions);
|
||||||
if (delegate.onHide) {
|
|
||||||
delegate.onHide(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._onDidContextMenu.fire();
|
|
||||||
});
|
|
||||||
|
|
||||||
const menu = this.createMenu(delegate, actions, onHide);
|
|
||||||
const anchor = delegate.getAnchor();
|
const anchor = delegate.getAnchor();
|
||||||
let x: number, y: number;
|
let x: number, y: number;
|
||||||
|
|
||||||
|
@ -70,18 +61,16 @@ export class ContextMenuService implements IContextMenuService {
|
||||||
x *= zoom;
|
x *= zoom;
|
||||||
y *= zoom;
|
y *= zoom;
|
||||||
|
|
||||||
menu.popup({
|
menu.popup(remote.getCurrentWindow(), { x: Math.floor(x), y: Math.floor(y), positioningItem: delegate.autoSelectFirstItem ? 0 : void 0 });
|
||||||
window: remote.getCurrentWindow(),
|
this._onDidContextMenu.fire();
|
||||||
x: Math.floor(x),
|
if (delegate.onHide) {
|
||||||
y: Math.floor(y),
|
delegate.onHide(undefined);
|
||||||
positioningItem: delegate.autoSelectFirstItem ? 0 : void 0,
|
}
|
||||||
callback: () => onHide()
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private createMenu(delegate: IContextMenuDelegate, entries: (IAction | ContextSubMenu)[], onHide: () => void): Electron.Menu {
|
private createMenu(delegate: IContextMenuDelegate, entries: (IAction | ContextSubMenu)[]): Electron.Menu {
|
||||||
const menu = new remote.Menu();
|
const menu = new remote.Menu();
|
||||||
const actionRunner = delegate.actionRunner || new ActionRunner();
|
const actionRunner = delegate.actionRunner || new ActionRunner();
|
||||||
|
|
||||||
|
@ -90,7 +79,7 @@ export class ContextMenuService implements IContextMenuService {
|
||||||
menu.append(new remote.MenuItem({ type: 'separator' }));
|
menu.append(new remote.MenuItem({ type: 'separator' }));
|
||||||
} else if (e instanceof ContextSubMenu) {
|
} else if (e instanceof ContextSubMenu) {
|
||||||
const submenu = new remote.MenuItem({
|
const submenu = new remote.MenuItem({
|
||||||
submenu: this.createMenu(delegate, e.entries, onHide),
|
submenu: this.createMenu(delegate, e.entries),
|
||||||
label: unmnemonicLabel(e.label)
|
label: unmnemonicLabel(e.label)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -102,13 +91,6 @@ export class ContextMenuService implements IContextMenuService {
|
||||||
type: !!e.checked ? 'checkbox' : !!e.radio ? 'radio' : void 0,
|
type: !!e.checked ? 'checkbox' : !!e.radio ? 'radio' : void 0,
|
||||||
enabled: !!e.enabled,
|
enabled: !!e.enabled,
|
||||||
click: (menuItem, win, event) => {
|
click: (menuItem, win, event) => {
|
||||||
|
|
||||||
// To preserve pre-electron-2.x behaviour, we first trigger
|
|
||||||
// the onHide callback and then the action.
|
|
||||||
// Fixes https://github.com/Microsoft/vscode/issues/45601
|
|
||||||
onHide();
|
|
||||||
|
|
||||||
// Run action which will close the menu
|
|
||||||
this.runAction(actionRunner, e, delegate, event);
|
this.runAction(actionRunner, e, delegate, event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -193,13 +193,13 @@ export class ExtensionHostProcessWorker {
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
// Print out extension host output
|
// Print out extension host output
|
||||||
onDebouncedOutput(output => {
|
onDebouncedOutput(data => {
|
||||||
const inspectorUrlMatch = !this._environmentService.isBuilt && output.data && output.data.match(/ws:\/\/([^\s]+)/);
|
const inspectorUrlIndex = !this._environmentService.isBuilt && data.data && data.data.indexOf('chrome-devtools://');
|
||||||
if (inspectorUrlMatch) {
|
if (inspectorUrlIndex >= 0) {
|
||||||
console.log(`%c[Extension Host] %cdebugger inspector at chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${inspectorUrlMatch[1]}`, 'color: blue', 'color: black');
|
console.log(`%c[Extension Host] %cdebugger inspector at ${data.data.substr(inspectorUrlIndex)}`, 'color: blue', 'color: black');
|
||||||
} else {
|
} else {
|
||||||
console.group('Extension Host');
|
console.group('Extension Host');
|
||||||
console.log(output.data, ...output.format);
|
console.log(data.data, ...data.format);
|
||||||
console.groupEnd();
|
console.groupEnd();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue