提交 b68e2baa 编写于 作者: B Benjamin Pasero

Consider introducing ctrl+q to close all windows on Linux and Window to...

Consider introducing ctrl+q to close all windows on Linux and Window to compliment hot exit (fixes #15261)
上级 4bb8312b
...@@ -298,7 +298,7 @@ export class VSCodeMenu { ...@@ -298,7 +298,7 @@ export class VSCodeMenu {
const hide = new MenuItem({ label: nls.localize('mHide', "Hide {0}", product.nameLong), role: 'hide', accelerator: 'Command+H' }); const hide = new MenuItem({ label: nls.localize('mHide', "Hide {0}", product.nameLong), role: 'hide', accelerator: 'Command+H' });
const hideOthers = new MenuItem({ label: nls.localize('mHideOthers', "Hide Others"), role: 'hideothers', accelerator: 'Command+Alt+H' }); const hideOthers = new MenuItem({ label: nls.localize('mHideOthers', "Hide Others"), role: 'hideothers', accelerator: 'Command+Alt+H' });
const showAll = new MenuItem({ label: nls.localize('mShowAll', "Show All"), role: 'unhide' }); const showAll = new MenuItem({ label: nls.localize('mShowAll', "Show All"), role: 'unhide' });
const quit = new MenuItem({ label: nls.localize('miQuit', "Quit {0}", product.nameLong), click: () => this.quit(), accelerator: 'Command+Q' }); const quit = new MenuItem({ label: nls.localize('miQuit', "Quit {0}", product.nameLong), click: () => this.windowsService.quit(), accelerator: this.getAccelerator('workbench.action.quit', 'Command+Q') });
const actions = [about]; const actions = [about];
actions.push(...checkForUpdates); actions.push(...checkForUpdates);
...@@ -356,7 +356,7 @@ export class VSCodeMenu { ...@@ -356,7 +356,7 @@ export class VSCodeMenu {
const closeFolder = this.createMenuItem(nls.localize({ key: 'miCloseFolder', comment: ['&& denotes a mnemonic'] }, "Close &&Folder"), 'workbench.action.closeFolder'); const closeFolder = this.createMenuItem(nls.localize({ key: 'miCloseFolder', comment: ['&& denotes a mnemonic'] }, "Close &&Folder"), 'workbench.action.closeFolder');
const closeEditor = this.createMenuItem(nls.localize({ key: 'miCloseEditor', comment: ['&& denotes a mnemonic'] }, "Close &&Editor"), 'workbench.action.closeActiveEditor'); const closeEditor = this.createMenuItem(nls.localize({ key: 'miCloseEditor', comment: ['&& denotes a mnemonic'] }, "Close &&Editor"), 'workbench.action.closeActiveEditor');
const exit = this.createMenuItem(nls.localize({ key: 'miExit', comment: ['&& denotes a mnemonic'] }, "E&&xit"), () => this.quit()); const exit = new MenuItem({ label: mnemonicLabel(nls.localize({ key: 'miExit', comment: ['&& denotes a mnemonic'] }, "E&&xit")), accelerator: this.getAccelerator('workbench.action.quit'), click: () => this.windowsService.quit() });
arrays.coalesce([ arrays.coalesce([
newFile, newFile,
...@@ -408,25 +408,6 @@ export class VSCodeMenu { ...@@ -408,25 +408,6 @@ export class VSCodeMenu {
return new MenuItem({ label: mnemonicLabel(nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences")), submenu: preferencesMenu }); return new MenuItem({ label: mnemonicLabel(nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences")), submenu: preferencesMenu });
} }
private quit(): void {
// If the user selected to exit from an extension development host window, do not quit, but just
// close the window unless this is the last window that is opened.
const vscodeWindow = this.windowsService.getFocusedWindow();
if (vscodeWindow && vscodeWindow.isPluginDevelopmentHost && this.windowsService.getWindowCount() > 1) {
vscodeWindow.win.close();
}
// Otherwise: normal quit
else {
setTimeout(() => {
this.isQuitting = true;
app.quit();
}, 10 /* delay this because there is an issue with quitting while the menu is open */);
}
}
private setOpenRecentMenu(openRecentMenu: Electron.Menu): void { private setOpenRecentMenu(openRecentMenu: Electron.Menu): void {
openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedEditor', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed Editor"), 'workbench.action.reopenClosedEditor')); openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedEditor', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed Editor"), 'workbench.action.reopenClosedEditor'));
...@@ -869,7 +850,7 @@ export class VSCodeMenu { ...@@ -869,7 +850,7 @@ export class VSCodeMenu {
}); });
} }
private getAccelerator(actionId: string): string { private getAccelerator(actionId: string, fallback?: string): string {
if (actionId) { if (actionId) {
const resolvedKeybinding = this.mapResolvedKeybindingToActionId[actionId]; const resolvedKeybinding = this.mapResolvedKeybindingToActionId[actionId];
if (resolvedKeybinding) { if (resolvedKeybinding) {
...@@ -881,11 +862,12 @@ export class VSCodeMenu { ...@@ -881,11 +862,12 @@ export class VSCodeMenu {
} }
const lastKnownKeybinding = this.mapLastKnownKeybindingToActionId[actionId]; const lastKnownKeybinding = this.mapLastKnownKeybindingToActionId[actionId];
if (lastKnownKeybinding) {
return lastKnownKeybinding; // return the last known keybining (chance of mismatch is very low unless it changed) return lastKnownKeybinding; // return the last known keybining (chance of mismatch is very low unless it changed)
}
} }
return void (0); return fallback;
} }
private openAboutDialog(): void { private openAboutDialog(): void {
......
...@@ -119,6 +119,7 @@ export interface IWindowsMainService { ...@@ -119,6 +119,7 @@ export interface IWindowsMainService {
removeFromRecentPathsList(paths: string[]): void; removeFromRecentPathsList(paths: string[]): void;
clearRecentPathsList(): void; clearRecentPathsList(): void;
toggleMenuBar(windowId: number): void; toggleMenuBar(windowId: number): void;
quit(): void;
} }
export class WindowsManager implements IWindowsMainService { export class WindowsManager implements IWindowsMainService {
...@@ -1219,4 +1220,21 @@ export class WindowsManager implements IWindowsMainService { ...@@ -1219,4 +1220,21 @@ export class WindowsManager implements IWindowsMainService {
this.logService.log('#setJumpList', error); // since setJumpList is relatively new API, make sure to guard for errors this.logService.log('#setJumpList', error); // since setJumpList is relatively new API, make sure to guard for errors
} }
} }
public quit(): void {
// If the user selected to exit from an extension development host window, do not quit, but just
// close the window unless this is the last window that is opened.
const vscodeWindow = this.getFocusedWindow();
if (vscodeWindow && vscodeWindow.isPluginDevelopmentHost && this.getWindowCount() > 1) {
vscodeWindow.win.close();
}
// Otherwise: normal quit
else {
setTimeout(() => {
app.quit();
}, 10 /* delay to unwind callback stack (IPC) */);
}
}
} }
\ No newline at end of file
...@@ -37,6 +37,7 @@ export interface IWindowsService { ...@@ -37,6 +37,7 @@ export interface IWindowsService {
unmaximizeWindow(windowId: number): TPromise<void>; unmaximizeWindow(windowId: number): TPromise<void>;
setDocumentEdited(windowId: number, flag: boolean): TPromise<void>; setDocumentEdited(windowId: number, flag: boolean): TPromise<void>;
toggleMenuBar(windowId: number): TPromise<void>; toggleMenuBar(windowId: number): TPromise<void>;
quit(): TPromise<void>;
// Global methods // Global methods
// TODO@joao: rename, shouldn't this be openWindow? // TODO@joao: rename, shouldn't this be openWindow?
......
...@@ -30,6 +30,7 @@ export interface IWindowsChannel extends IChannel { ...@@ -30,6 +30,7 @@ export interface IWindowsChannel extends IChannel {
call(command: 'unmaximizeWindow', arg: number): TPromise<void>; call(command: 'unmaximizeWindow', arg: number): TPromise<void>;
call(command: 'setDocumentEdited', arg: [number, boolean]): TPromise<void>; call(command: 'setDocumentEdited', arg: [number, boolean]): TPromise<void>;
call(command: 'toggleMenuBar', arg: number): TPromise<void>; call(command: 'toggleMenuBar', arg: number): TPromise<void>;
call(command: 'quit'): TPromise<void>;
call(command: 'windowOpen', arg: [string[], boolean]): TPromise<void>; call(command: 'windowOpen', arg: [string[], boolean]): TPromise<void>;
call(command: 'openNewWindow'): TPromise<void>; call(command: 'openNewWindow'): TPromise<void>;
call(command: 'showWindow', arg: number): TPromise<void>; call(command: 'showWindow', arg: number): TPromise<void>;
...@@ -80,6 +81,7 @@ export class WindowsChannel implements IWindowsChannel { ...@@ -80,6 +81,7 @@ export class WindowsChannel implements IWindowsChannel {
case 'showWindow': return this.service.showWindow(arg); case 'showWindow': return this.service.showWindow(arg);
case 'getWindows': return this.service.getWindows(); case 'getWindows': return this.service.getWindows();
case 'getWindowCount': return this.service.getWindowCount(); case 'getWindowCount': return this.service.getWindowCount();
case 'quit': return this.service.quit();
case 'log': return this.service.log(arg[0], arg[1]); case 'log': return this.service.log(arg[0], arg[1]);
case 'closeExtensionHostWindow': return this.service.closeExtensionHostWindow(arg); case 'closeExtensionHostWindow': return this.service.closeExtensionHostWindow(arg);
case 'showItemInFolder': return this.service.showItemInFolder(arg); case 'showItemInFolder': return this.service.showItemInFolder(arg);
...@@ -173,6 +175,10 @@ export class WindowsChannelClient implements IWindowsService { ...@@ -173,6 +175,10 @@ export class WindowsChannelClient implements IWindowsService {
return this.channel.call('toggleMenuBar', windowId); return this.channel.call('toggleMenuBar', windowId);
} }
quit(): TPromise<void> {
return this.channel.call('quit');
}
windowOpen(paths: string[], forceNewWindow?: boolean): TPromise<void> { windowOpen(paths: string[], forceNewWindow?: boolean): TPromise<void> {
return this.channel.call('windowOpen', [paths, forceNewWindow]); return this.channel.call('windowOpen', [paths, forceNewWindow]);
} }
......
...@@ -260,6 +260,11 @@ export class WindowsService implements IWindowsService, IDisposable { ...@@ -260,6 +260,11 @@ export class WindowsService implements IWindowsService, IDisposable {
return TPromise.as(null); return TPromise.as(null);
} }
quit(): TPromise<void> {
this.windowsMainService.quit();
return TPromise.as(null);
}
private openFileForURI(filePath: string): TPromise<void> { private openFileForURI(filePath: string): TPromise<void> {
const cli = assign(Object.create(null), this.environmentService.args, { goto: true }); const cli = assign(Object.create(null), this.environmentService.args, { goto: true });
const pathsToOpen = [filePath]; const pathsToOpen = [filePath];
......
...@@ -22,6 +22,7 @@ import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser ...@@ -22,6 +22,7 @@ import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser
import { CloseEditorAction, KeybindingsReferenceAction, ReportIssueAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, ToggleMenuBarAction, CloseFolderAction, CloseWindowAction, SwitchWindow, NewWindowAction, CloseMessagesAction } from 'vs/workbench/electron-browser/actions'; import { CloseEditorAction, KeybindingsReferenceAction, ReportIssueAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, ToggleMenuBarAction, CloseFolderAction, CloseWindowAction, SwitchWindow, NewWindowAction, CloseMessagesAction } from 'vs/workbench/electron-browser/actions';
import { MessagesVisibleContext, NoEditorsVisibleContext, InZenModeContext } from 'vs/workbench/electron-browser/workbench'; import { MessagesVisibleContext, NoEditorsVisibleContext, InZenModeContext } from 'vs/workbench/electron-browser/workbench';
import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { IWindowsService } from 'vs/platform/windows/common/windows';
const closeEditorOrWindowKeybindings: IKeybindings = { primary: KeyMod.CtrlCmd | KeyCode.KEY_W, win: { primary: KeyMod.CtrlCmd | KeyCode.F4, secondary: [KeyMod.CtrlCmd | KeyCode.KEY_W] } }; const closeEditorOrWindowKeybindings: IKeybindings = { primary: KeyMod.CtrlCmd | KeyCode.KEY_W, win: { primary: KeyMod.CtrlCmd | KeyCode.F4, secondary: [KeyMod.CtrlCmd | KeyCode.KEY_W] } };
...@@ -87,6 +88,18 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ ...@@ -87,6 +88,18 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
primary: KeyChord(KeyCode.Escape, KeyCode.Escape) primary: KeyChord(KeyCode.Escape, KeyCode.Escape)
}); });
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'workbench.action.quit',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
handler(accessor: ServicesAccessor) {
const windowsService = accessor.get(IWindowsService);
windowsService.quit();
},
when: void 0,
primary: KeyMod.CtrlCmd | KeyCode.KEY_Q,
win: { primary: KeyMod.Alt | KeyCode.F4 }
});
// Configuration: Workbench // Configuration: Workbench
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration); const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
configurationRegistry.registerConfiguration({ configurationRegistry.registerConfiguration({
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册