diff --git a/src/vs/base/parts/sandbox/common/electronTypes.ts b/src/vs/base/parts/sandbox/common/electronTypes.ts index 43fa75079d4..ef8c1026be2 100644 --- a/src/vs/base/parts/sandbox/common/electronTypes.ts +++ b/src/vs/base/parts/sandbox/common/electronTypes.ts @@ -217,24 +217,6 @@ export interface FileFilter { name: string; } -export interface OpenDevToolsOptions { - /** - * Opens the devtools with specified dock state, can be `left`, `right`, `bottom`, - * `undocked`, `detach`. Defaults to last used dock state. In `undocked` mode it's - * possible to dock back. In `detach` mode it's not. - */ - mode: ('left' | 'right' | 'bottom' | 'undocked' | 'detach'); - /** - * Whether to bring the opened devtools window to the foreground. The default is - * `true`. - */ - activate?: boolean; - /** - * A title for the DevTools window (only in `undocked` or `detach` mode). - */ - title?: string; -} - interface InputEvent { // Docs: https://electronjs.org/docs/api/structures/input-event diff --git a/src/vs/platform/native/common/native.ts b/src/vs/platform/native/common/native.ts index 344d45395ed..a27a17adf99 100644 --- a/src/vs/platform/native/common/native.ts +++ b/src/vs/platform/native/common/native.ts @@ -6,7 +6,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { Event } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; -import { MessageBoxOptions, MessageBoxReturnValue, OpenDevToolsOptions, OpenDialogOptions, OpenDialogReturnValue, SaveDialogOptions, SaveDialogReturnValue } from 'vs/base/parts/sandbox/common/electronTypes'; +import { MessageBoxOptions, MessageBoxReturnValue, OpenDialogOptions, OpenDialogReturnValue, SaveDialogOptions, SaveDialogReturnValue } from 'vs/base/parts/sandbox/common/electronTypes'; import { ISerializableCommandAction } from 'vs/platform/action/common/action'; import { INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; @@ -178,7 +178,7 @@ export interface ICommonNativeHostService { exit(code: number): Promise; // Development - openDevTools(options?: Partial & INativeHostOptions): Promise; + openDevTools(options?: INativeHostOptions): Promise; toggleDevTools(options?: INativeHostOptions): Promise; // Perf Introspection diff --git a/src/vs/platform/native/electron-main/nativeHostMainService.ts b/src/vs/platform/native/electron-main/nativeHostMainService.ts index 6c49504e712..4ccaa6b165a 100644 --- a/src/vs/platform/native/electron-main/nativeHostMainService.ts +++ b/src/vs/platform/native/electron-main/nativeHostMainService.ts @@ -5,7 +5,7 @@ import * as fs from 'fs'; import { exec } from 'child_process'; -import { app, BrowserWindow, clipboard, Display, Menu, MessageBoxOptions, MessageBoxReturnValue, OpenDevToolsOptions, OpenDialogOptions, OpenDialogReturnValue, powerMonitor, SaveDialogOptions, SaveDialogReturnValue, screen, shell, webContents } from 'electron'; +import { app, BrowserWindow, clipboard, Display, Menu, MessageBoxOptions, MessageBoxReturnValue, OpenDialogOptions, OpenDialogReturnValue, powerMonitor, SaveDialogOptions, SaveDialogReturnValue, screen, shell, webContents } from 'electron'; import { arch, cpus, freemem, loadavg, platform, release, totalmem, type } from 'os'; import { promisify } from 'util'; import { memoize } from 'vs/base/common/decorators'; @@ -33,7 +33,7 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { IPartsSplash } from 'vs/platform/theme/common/themeService'; import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService'; import { ICodeWindow } from 'vs/platform/window/electron-main/window'; -import { IColorScheme, IOpenedAuxiliaryWindow, IOpenedMainWindow, IOpenEmptyWindowOptions, IOpenWindowOptions, IPoint, IRectangle, IWindowOpenable } from 'vs/platform/window/common/window'; +import { IColorScheme, IOpenedAuxiliaryWindow, IOpenedMainWindow, IOpenEmptyWindowOptions, IOpenWindowOptions, IPoint, IRectangle, IWindowOpenable, useWindowControlsOverlay } from 'vs/platform/window/common/window'; import { IWindowsMainService, OpenContext } from 'vs/platform/windows/electron-main/windows'; import { isWorkspaceIdentifier, toWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; import { IWorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService'; @@ -855,14 +855,28 @@ export class NativeHostMainService extends Disposable implements INativeHostMain //#region Development - async openDevTools(windowId: number | undefined, options?: Partial & INativeHostOptions): Promise { + async openDevTools(windowId: number | undefined, options?: INativeHostOptions): Promise { const window = this.windowById(options?.targetWindowId, windowId); - window?.win?.webContents.openDevTools(options?.mode ? { mode: options.mode, activate: options.activate } : undefined); + + let mode: 'bottom' | undefined = undefined; + if (isLinux && useWindowControlsOverlay(this.configurationService)) { + mode = 'bottom'; // TODO@bpasero WCO and devtools collide with default option 'right' + } + window?.win?.webContents.openDevTools(mode ? { mode } : undefined); } async toggleDevTools(windowId: number | undefined, options?: INativeHostOptions): Promise { const window = this.windowById(options?.targetWindowId, windowId); - window?.win?.webContents.toggleDevTools(); + const webContents = window?.win?.webContents; + if (!webContents) { + return; + } + + if (isLinux && useWindowControlsOverlay(this.configurationService) && !webContents.isDevToolsOpened()) { + webContents.openDevTools({ mode: 'bottom' }); // TODO@bpasero WCO and devtools collide with default option 'right' + } else { + webContents.toggleDevTools(); + } } //#endregion diff --git a/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts index 7bcb272f0ae..c19ad7c8899 100644 --- a/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-sandbox/workbenchTestServices.ts @@ -143,7 +143,7 @@ export class TestNativeHostService implements INativeHostService { async closeWindow(): Promise { } async quit(): Promise { } async exit(code: number): Promise { } - async openDevTools(options?: Partial & INativeHostOptions | undefined): Promise { } + async openDevTools(): Promise { } async toggleDevTools(): Promise { } async resolveProxy(url: string): Promise { return undefined; } async lookupAuthorization(authInfo: AuthInfo): Promise { return undefined; }