Skip to content

Commit

Permalink
Do not use electron's remote in event handlers (fixes #3072)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpasero committed Mar 2, 2016
1 parent 91338ed commit 7975b1b
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 110 deletions.
4 changes: 2 additions & 2 deletions src/vs/workbench/electron-browser/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,12 @@ export class ToggleDevToolsAction extends Action {
public static ID = 'workbench.action.toggleDevTools';
public static LABEL = nls.localize('toggleDevTools', "Toggle Developer Tools");

constructor(id: string, label: string) {
constructor(id: string, label: string, @IWindowService private windowService: IWindowService) {
super(id, label);
}

public run(): TPromise<boolean> {
remote.getCurrentWindow().webContents.toggleDevTools();
ipc.send('vscode:toggleDevTools', this.windowService.getWindowId());

return TPromise.as(true);
}
Expand Down
29 changes: 17 additions & 12 deletions src/vs/workbench/electron-browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
var electron = require('electron');
var remote = electron.remote;
var ipc = electron.ipcRenderer;
var windowId = remote.getCurrentWindow().id;

function onError(error, enableDeveloperTools) {
if (enableDeveloperTools) {
remote.getCurrentWindow().webContents.openDevTools();
remote.getCurrentWindow().show();
ipc.send('vscode:openDevTools', windowId);
}

console.error('[uncaught exception]: ' + error);
Expand Down Expand Up @@ -88,9 +88,9 @@
window.addEventListener('keydown', function(e) {
var key = extractKey(e);
if (key === TOGGLE_DEV_TOOLS_KB) {
remote.getCurrentWindow().toggleDevTools();
ipc.send('vscode:toggleDevTools', windowId);
} else if (key === RELOAD_KB) {
ipc.send('vscode:reloadWindow', remote.getCurrentWindow().id);
ipc.send('vscode:reloadWindow', windowId);
}
});
}
Expand Down Expand Up @@ -186,20 +186,25 @@
'enableTypeScriptServiceModeForJS': !!process.env['CODE_TSJS'] || !!process.env['VSCODE_TSJS']
};

var programStart = remote.getGlobal('programStart');
var vscodeStart = remote.getGlobal('vscodeStart');

var timers = window.MonacoEnvironment.timers = {
start: new Date(programStart || vscodeStart),
start: new Date()
};

if (programStart) {
timers.beforeProgram = new Date(programStart);
timers.afterProgram = new Date(vscodeStart);
if (configuration.enablePerformance) {
var programStart = remote.getGlobal('programStart');
var vscodeStart = remote.getGlobal('vscodeStart');

if (programStart) {
timers.beforeProgram = new Date(programStart);
timers.afterProgram = new Date(vscodeStart);
}

timers.vscodeStart = new Date(vscodeStart);
timers.start = new Date(programStart || vscodeStart);
}

timers.vscodeStart = new Date(vscodeStart);
timers.beforeLoad = new Date();

require([
'vs/workbench/workbench.main',
'vs/nls!vs/workbench/workbench.main',
Expand Down
4 changes: 3 additions & 1 deletion src/vs/workbench/electron-browser/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import win = require('vs/workbench/electron-browser/window');

import {ipcRenderer as ipc, webFrame, remote} from 'electron';

const currentWindow = remote.getCurrentWindow();

const TextInputActions: IAction[] = [
new Action('undo', nls.localize('undo', "Undo"), null, true, () => document.execCommand('undo') && TPromise.as(true)),
new Action('redo', nls.localize('redo', "Redo"), null, true, () => document.execCommand('redo') && TPromise.as(true)),
Expand Down Expand Up @@ -58,7 +60,7 @@ export class ElectronIntegration {
public integrate(shellContainer: HTMLElement): void {

// Register the active window
let activeWindow = this.instantiationService.createInstance(win.ElectronWindow, remote.getCurrentWindow(), shellContainer);
let activeWindow = this.instantiationService.createInstance(win.ElectronWindow, currentWindow, shellContainer);
this.windowService.registerWindow(activeWindow);

// Support runAction event
Expand Down
45 changes: 21 additions & 24 deletions src/vs/workbench/electron-browser/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';

import {ipcRenderer as ipc, shell, remote} from 'electron';

const dialog = remote.dialog;

export interface IWindowConfiguration {
window: {
openFilesInNewWindow: boolean;
Expand All @@ -30,6 +32,7 @@ export interface IWindowConfiguration {

export class ElectronWindow {
private win: Electron.BrowserWindow;
private windowId: number;

constructor(
win: Electron.BrowserWindow,
Expand All @@ -41,6 +44,7 @@ export class ElectronWindow {
@IViewletService private viewletService: IViewletService
) {
this.win = win;
this.windowId = win.id;
this.registerListeners();
}

Expand All @@ -49,18 +53,13 @@ export class ElectronWindow {
// React to editor input changes (Mac only)
if (platform.platform === platform.Platform.Mac) {
this.eventService.addListener(EventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => {
// if we dont use setTimeout() here for some reason there is an issue when switching between 2 files side by side
// with the mac trackpad where the editor would think the user wants to select. to reproduce, have 2 files, click
// into the non-focussed one and move the mouse down and see the editor starts to select lines.
setTimeout(() => {
let fileInput = workbenchEditorCommon.asFileEditorInput(e.editorInput, true);
if (fileInput) {
this.win.setRepresentedFilename(fileInput.getResource().fsPath);
} else {
this.win.setRepresentedFilename('');
}
}, 0);
let fileInput = workbenchEditorCommon.asFileEditorInput(e.editorInput, true);
let representedFilename = '';
if (fileInput) {
representedFilename = fileInput.getResource().fsPath;
}

ipc.send('vscode:setRepresentedFilename', this.windowId, representedFilename);
});
}

Expand Down Expand Up @@ -155,36 +154,34 @@ export class ElectronWindow {
}

public reload(): void {
ipc.send('vscode:reloadWindow', this.win.id);
ipc.send('vscode:reloadWindow', this.windowId);
}

public showMessageBox(options: Electron.Dialog.ShowMessageBoxOptions): number {
return remote.dialog.showMessageBox(this.win, options);
return dialog.showMessageBox(this.win, options);
}

public setFullScreen(fullscreen: boolean): void {
this.win.setFullScreen(fullscreen);
public showSaveDialog(options: Electron.Dialog.SaveDialogOptions, callback?: (fileName: string) => void): string {
return dialog.showSaveDialog(this.win, options, callback);
}

public openDevTools(): void {
this.win.webContents.openDevTools();
public setFullScreen(fullscreen: boolean): void {
ipc.send('vscode:setFullScreen', this.windowId, fullscreen); // handled from browser process
}

public isFullScreen(): boolean {
return this.win.isFullScreen();
public openDevTools(): void {
ipc.send('vscode:openDevTools', this.windowId); // handled from browser process
}

public setMenuBarVisibility(visible: boolean): void {
this.win.setMenuBarVisibility(visible);
ipc.send('vscode:setMenuBarVisibility', this.windowId, visible); // handled from browser process
}

public focus(): void {
if (!this.win.isFocused()) {
this.win.focus();
}
ipc.send('vscode:focusWindow', this.windowId); // handled from browser process
}

public flashFrame(): void {
this.win.flashFrame(!this.win.isFocused());
ipc.send('vscode:flashFrame', this.windowId); // handled from browser process
}
}
73 changes: 73 additions & 0 deletions src/vs/workbench/electron-main/windows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,79 @@ export class WindowsManager {
}
});

ipc.on('vscode:setFullScreen', (event, windowId: number, fullscreen: boolean) => {
env.log('IPC#vscode:setFullScreen');

let vscodeWindow = this.getWindowById(windowId);
if (vscodeWindow) {
vscodeWindow.win.setFullScreen(fullscreen);
}
});

ipc.on('vscode:toggleDevTools', (event, windowId: number) => {
env.log('IPC#vscode:toggleDevTools');

let vscodeWindow = this.getWindowById(windowId);
if (vscodeWindow) {
vscodeWindow.win.webContents.toggleDevTools();
}
});

ipc.on('vscode:openDevTools', (event, windowId: number) => {
env.log('IPC#vscode:openDevTools');

let vscodeWindow = this.getWindowById(windowId);
if (vscodeWindow) {
vscodeWindow.win.webContents.openDevTools();
vscodeWindow.win.show();
}
});

ipc.on('vscode:setRepresentedFilename', (event, windowId: number, fileName: string) => {
env.log('IPC#vscode:setRepresentedFilename');

let vscodeWindow = this.getWindowById(windowId);
if (vscodeWindow) {
vscodeWindow.win.setRepresentedFilename(fileName);
}
});

ipc.on('vscode:setMenuBarVisibility', (event, windowId: number, visibility: boolean) => {
env.log('IPC#vscode:setMenuBarVisibility');

let vscodeWindow = this.getWindowById(windowId);
if (vscodeWindow) {
vscodeWindow.win.setMenuBarVisibility(visibility);
}
});

ipc.on('vscode:flashFrame', (event, windowId: number) => {
env.log('IPC#vscode:flashFrame');

let vscodeWindow = this.getWindowById(windowId);
if (vscodeWindow) {
vscodeWindow.win.flashFrame(!vscodeWindow.win.isFocused());
}
});

ipc.on('vscode:focusWindow', (event, windowId: number) => {
env.log('IPC#vscode:focusWindow');

let vscodeWindow = this.getWindowById(windowId);
if (vscodeWindow) {
vscodeWindow.win.focus();
}
});

ipc.on('vscode:setDocumentEdited', (event, windowId: number, edited: boolean) => {
env.log('IPC#vscode:setDocumentEdited');

let vscodeWindow = this.getWindowById(windowId);
if (vscodeWindow && vscodeWindow.win.isDocumentEdited() !== edited) {
vscodeWindow.win.setDocumentEdited(edited);
}
});

ipc.on('vscode:toggleMenuBar', (event, windowId: number) => {
env.log('IPC#vscode:toggleMenuBar');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {asFileEditorInput} from 'vs/workbench/common/editor';
import errors = require('vs/base/common/errors');
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
import URI from 'vs/base/common/uri';
import {IWindowService} from 'vs/workbench/services/window/electron-browser/windowService';
import {EventType as WorkbenchEventType} from 'vs/workbench/common/events';
import {IUntitledEditorService} from 'vs/workbench/services/untitled/common/untitledEditorService';
import {IPartService} from 'vs/workbench/services/part/common/partService';
Expand All @@ -23,7 +24,7 @@ import {IEventService} from 'vs/platform/event/common/event';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle';

import {ipcRenderer as ipc, remote} from 'electron';
import {ipcRenderer as ipc} from 'electron';

export interface IPath {
filePath: string;
Expand Down Expand Up @@ -51,16 +52,16 @@ export class FileTracker implements IWorkbenchContribution {
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IInstantiationService private instantiationService: IInstantiationService,
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
@ILifecycleService private lifecycleService: ILifecycleService
@ILifecycleService private lifecycleService: ILifecycleService,
@IWindowService private windowService: IWindowService
) {
this.toUnbind = [];
this.isDocumentedEdited = false;
this.activeOutOfWorkspaceWatchers = Object.create(null);

// Make sure to reset any previous state
if (plat.platform === plat.Platform.Mac) {
let win = remote.getCurrentWindow();
win.setDocumentEdited(false);
ipc.send('vscode:setDocumentEdited', this.windowService.getWindowId(), false); // handled from browser process
}

this.registerListeners();
Expand Down Expand Up @@ -185,16 +186,10 @@ export class FileTracker implements IWorkbenchContribution {

private updateDocumentEdited(): void {
if (plat.platform === plat.Platform.Mac) {
process.nextTick(() => {
let win = remote.getCurrentWindow();
let isDirtyIndicated = win.isDocumentEdited();
let hasDirtyFiles = this.textFileService.isDirty();
this.isDocumentedEdited = hasDirtyFiles;

if (hasDirtyFiles !== isDirtyIndicated) {
win.setDocumentEdited(hasDirtyFiles);
}
});
let hasDirtyFiles = this.textFileService.isDirty();
this.isDocumentedEdited = hasDirtyFiles;

ipc.send('vscode:setDocumentEdited', this.windowService.getWindowId(), hasDirtyFiles); // handled from browser process
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,10 @@ import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {IModeService} from 'vs/editor/common/services/modeService';

import {remote} from 'electron';
import {IWindowService} from 'vs/workbench/services/window/electron-browser/windowService';

export class TextFileService extends AbstractTextFileService {

private modeService: IModeService;

constructor(
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IInstantiationService instantiationService: IInstantiationService,
Expand All @@ -40,9 +37,11 @@ export class TextFileService extends AbstractTextFileService {
@ITelemetryService telemetryService: ITelemetryService,
@IConfigurationService configurationService: IConfigurationService,
@IEventService eventService: IEventService,
@IModeService modeService: IModeService
@IModeService private modeService: IModeService,
@IWindowService private windowService: IWindowService
) {
super(contextService, instantiationService, configurationService, telemetryService, lifecycleService, eventService);

this.modeService = modeService;

this.init();
Expand Down Expand Up @@ -188,7 +187,7 @@ export class TextFileService extends AbstractTextFileService {
cancelId: buttons.indexOf(cancel)
};

const choice = remote.dialog.showMessageBox(remote.getCurrentWindow(), opts);
const choice = this.windowService.getWindow().showMessageBox(opts);

return buttons[choice].result;
}
Expand Down Expand Up @@ -359,14 +358,14 @@ export class TextFileService extends AbstractTextFileService {

private promptForPathAsync(defaultPath?: string): TPromise<string> {
return new TPromise<string>((c, e) => {
remote.dialog.showSaveDialog(remote.getCurrentWindow(), this.getSaveDialogOptions(defaultPath ? paths.normalize(defaultPath, true) : void 0), (path) => {
this.windowService.getWindow().showSaveDialog(this.getSaveDialogOptions(defaultPath ? paths.normalize(defaultPath, true) : void 0), (path) => {
c(path);
});
});
}

private promptForPathSync(defaultPath?: string): string {
return remote.dialog.showSaveDialog(remote.getCurrentWindow(), this.getSaveDialogOptions(defaultPath ? paths.normalize(defaultPath, true) : void 0));
return this.windowService.getWindow().showSaveDialog(this.getSaveDialogOptions(defaultPath ? paths.normalize(defaultPath, true) : void 0));
}

private getSaveDialogOptions(defaultPath?: string): Electron.Dialog.SaveDialogOptions {
Expand Down
Loading

0 comments on commit 7975b1b

Please sign in to comment.