From c8410a61bbdf3e1945359874e60aed2b2c54380b Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Wed, 20 Jun 2018 17:45:27 -0400 Subject: [PATCH 01/19] Add WIP transparency implementation --- package.json | 1 + src/vs/code/electron-main/window.ts | 56 ++++++++++++++++++- src/vs/platform/windows/common/windows.ts | 2 + .../browser/parts/editor/tabsTitleControl.ts | 2 +- src/vs/workbench/common/theme.ts | 19 +++---- .../electron-browser/main.contribution.ts | 15 +++++ src/vs/workbench/electron-browser/shell.ts | 2 +- yarn.lock | 4 ++ 8 files changed, 84 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 7e92f6392d7ed..9833d3b65a415 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.0-next.2", "vscode-xterm": "3.5.0-beta15", + "windows-swca": "^1.1.1", "yauzl": "^2.9.1" }, "devDependencies": { diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 22e6ea4675481..285819943de79 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -129,7 +129,7 @@ export class CodeWindow implements ICodeWindow { backgroundColor = '#171717'; // https://github.com/electron/electron/issues/5150 } - const options: Electron.BrowserWindowConstructorOptions = { + let options: Electron.BrowserWindowConstructorOptions = { width: this.windowState.width, height: this.windowState.height, x: this.windowState.x, @@ -145,11 +145,16 @@ export class CodeWindow implements ICodeWindow { } }; + const windowConfig = this.configurationService.getValue('window'); + if (isLinux) { options.icon = path.join(this.environmentService.appRoot, 'resources/linux/code.png'); // Windows and Mac are better off using the embedded icon(s) - } - const windowConfig = this.configurationService.getValue('window'); + options.transparent = windowConfig.transparent; // TODO: requires hardware acceleration off + if (options.transparent) { + this.stateService.setItem(CodeWindow.themeBackgroundStorageKey, 'transparent'); + } + } if (isMacintosh) { options.acceptFirstMouse = true; // enabled by default @@ -173,6 +178,13 @@ export class CodeWindow implements ICodeWindow { if (isDev) { useCustomTitleStyle = false; // not enabled when developing due to https://github.com/electron/electron/issues/3647 } + + // TODO + //if (windowConfig && windowConfig.vibrancy && windowConfig.vibrancy !== 'none') { + // options.backgroundColor = '#00000000'; + // this.stateService.setItem(CodeWindow.themeBackgroundStorageKey, 'transparent'); + // options.vibrancy = windowConfig.vibrancy; + //} } else { useCustomTitleStyle = windowConfig && windowConfig.titleBarStyle === 'custom'; // Must be specified on Windows/Linux } @@ -189,6 +201,18 @@ export class CodeWindow implements ICodeWindow { } } + const isWin10 = true; // TODO + let compAttribSet = false; + if (isWindows && windowConfig && windowConfig.compositionAttribute && windowConfig.compositionAttribute !== 'none') { + if (isWin10 && useCustomTitleStyle) { + options.backgroundColor = '#00000000'; + this.stateService.setItem(CodeWindow.themeBackgroundStorageKey, 'transparent'); + compAttribSet = true; + } else { + // TODO: DwmEnableBlurBehind for older OSes. + } + } + // Create the browser window. this._win = new BrowserWindow(options); this._id = this._win.id; @@ -197,6 +221,32 @@ export class CodeWindow implements ICodeWindow { this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any } + if (compAttribSet && isWin10) { + const { SetWindowCompositionAttribute, AccentState } = require.__$__nodeRequire('windows-swca') as any; + + let attribValue: number; + switch (windowConfig.compositionAttribute) { + case 'acrylic': + if (/* TODO: test OS build 17063*/true) { + attribValue = AccentState.ACCENT_ENABLE_FLUENT; + } + break; + + case 'blur': + attribValue = AccentState.ACCENT_ENABLE_BLURBEHIND; + break; + + case 'transparent': + attribValue = AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT; + break; + } + + // using a small alpha because acrylic bugs out at full transparency. + SetWindowCompositionAttribute(this._win, attribValue, 0x01000000); + } else if (compAttribSet) { + // TODO: DwnEnableBlurBehind + } + if (isFullscreenOrMaximized) { this._win.maximize(); diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 08102ecfce238..c2a0598ffe79d 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -240,6 +240,8 @@ export interface IWindowSettings { closeWhenEmpty: boolean; smoothScrollingWorkaround: boolean; clickThroughInactive: boolean; + transparent: boolean; + compositionAttribute: 'none' | 'transparent' | 'blur' | 'acrylic'; } export enum OpenContext { diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index 8934bb9925f44..834006ca4e035 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -1109,7 +1109,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { // Fade out styles via linear gradient (when tabs are set to shrink) if (theme.type !== 'hc') { - const workbenchBackground = WORKBENCH_BACKGROUND(theme); + const workbenchBackground = theme.getColor(WORKBENCH_BACKGROUND); const editorBackgroundColor = theme.getColor(editorBackground); const editorGroupHeaderTabsBackground = theme.getColor(EDITOR_GROUP_HEADER_TABS_BACKGROUND); const editorDragAndDropBackground = theme.getColor(EDITOR_DRAG_AND_DROP_BACKGROUND); diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index dc310d1c9f080..004eb29cfe7b6 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -9,18 +9,13 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService'; import { Color } from 'vs/base/common/color'; -// < --- Workbench (not customizable) --- > - -export function WORKBENCH_BACKGROUND(theme: ITheme): Color { - switch (theme.type) { - case 'dark': - return Color.fromHex('#252526'); - case 'light': - return Color.fromHex('#F3F3F3'); - default: - return Color.fromHex('#000000'); - } -} +// < --- Workbench --- > + +export const WORKBENCH_BACKGROUND = registerColor('workbench.background', { + dark: '#252526', + light: '#F3F3F3', + hc: '#000000' +}, nls.localize('workbenchBackground', "Top-level background color. Not seen unless other elements have a transparent color.")); // < --- Tabs --- > diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 8ff4d6a55bf2e..d8dd28899c463 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -460,6 +460,21 @@ configurationRegistry.registerConfiguration({ 'scope': ConfigurationScope.APPLICATION, 'description': nls.localize('window.clickThroughInactive', "If enabled, clicking on an inactive window will both activate the window and trigger the element under the mouse if it is clickable. If disabled, clicking anywhere on an inactive window will activate it only and a second click is required on the element."), 'included': isMacintosh + }, + 'window.transparent': { + 'type': 'boolean', + 'default': false, + 'scope': ConfigurationScope.APPLICATION, + 'description': nls.localize('window.transparent', "Makes window ARGB. Needs color customizations or a transparent theme to affect appearance."), + 'included': isLinux + }, + 'window.compositionAttribute': { + 'type': 'string', + 'enum': ['none', 'transparent', 'blur', 'acrylic'], + 'default': 'none', + 'scope': ConfigurationScope.APPLICATION, + 'description': nls.localize('window.compositionAttribute', "Changes window composition attribute. Transparent and Acrylic are only available on Windows 10. Furthermore, Acrylic requires the April 2018 update. Needs color customizations or a transparent theme to affect appearance."), + 'included': isWindows } } }); diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index e4320501ecd24..c111bacc67aaf 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -584,7 +584,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { } // We need to set the workbench background color so that on Windows we get subpixel-antialiasing. - const workbenchBackground = WORKBENCH_BACKGROUND(theme); + const workbenchBackground = theme.getColor(WORKBENCH_BACKGROUND); collector.addRule(`.monaco-workbench { background-color: ${workbenchBackground}; }`); // Scrollbars diff --git a/yarn.lock b/yarn.lock index 1a8735b5551fc..ca69d5a987580 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6311,6 +6311,10 @@ windows-process-tree@0.2.2: dependencies: nan "^2.6.2" +windows-swca@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/windows-swca/-/windows-swca-1.1.1.tgz#0b3530278c67d408baac71c3a6aeb16d55318bf8" + wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" From f2a6835d578b3bc7534f8553de5b76140c027848 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Wed, 20 Jun 2018 17:53:03 -0400 Subject: [PATCH 02/19] Move windows-swca to dev dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9833d3b65a415..0d18cf0e62c4e 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,6 @@ "vscode-ripgrep": "^1.0.1", "vscode-textmate": "^4.0.0-next.2", "vscode-xterm": "3.5.0-beta15", - "windows-swca": "^1.1.1", "yauzl": "^2.9.1" }, "devDependencies": { @@ -136,6 +135,7 @@ "optionalDependencies": { "windows-foreground-love": "0.1.0", "windows-mutex": "^0.2.0", - "windows-process-tree": "0.2.2" + "windows-process-tree": "0.2.2", + "windows-swca": "^1.1.1" } } From 80e213479f874856dc8b21e4e8e9458e0d9a927c Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Thu, 21 Jun 2018 09:30:37 -0400 Subject: [PATCH 03/19] Make Linux transparency functional, add macOS vibrancy --- src/main.js | 16 ++++++++ src/vs/code/electron-main/window.ts | 38 ++++++++++--------- src/vs/platform/windows/common/windows.ts | 1 + .../electron-browser/main.contribution.ts | 12 +++++- 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/src/main.js b/src/main.js index 135637642741f..9df2cc7bda3fe 100644 --- a/src/main.js +++ b/src/main.js @@ -397,6 +397,22 @@ global.getOpenUrls = function () { return openUrls; }; +// Linux: disable hardware acceleration when transparent window is enabled +try { + if (process.platform === 'linux') { + const configFile = path.join(getUserDataPath(), 'User', 'settings.json'); + if (fs.existsSync(configFile)) { + const config = JSON.parse(stripComments(fs.readFileSync(configFile, 'utf8'))); + if (config['window.transparent']) { + app.commandLine.appendSwitch('enable-transparent-visuals'); + app.disableHardwareAcceleration(); + } + } + } +} catch (err) { + console.error(err); +} + // use '/CachedData'-directory to store // node/v8 cached data. let nodeCachedDataDir = getNodeCachedDataDir().then(function (value) { diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 285819943de79..df4d9ce32befd 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -116,6 +116,11 @@ export class CodeWindow implements ICodeWindow { this.registerListeners(); } + private setTransparentInfo(options: Electron.BrowserWindowConstructorOptions): void { + options.backgroundColor = '#00000000'; + this.stateService.setItem(CodeWindow.themeBackgroundStorageKey, 'transparent'); + } + private createBrowserWindow(config: IWindowCreationOptions): void { // Load window state @@ -150,9 +155,10 @@ export class CodeWindow implements ICodeWindow { if (isLinux) { options.icon = path.join(this.environmentService.appRoot, 'resources/linux/code.png'); // Windows and Mac are better off using the embedded icon(s) - options.transparent = windowConfig.transparent; // TODO: requires hardware acceleration off + // Make sure hardware acceleration is actually disabled. + options.transparent = windowConfig && windowConfig.transparent && app.getGPUFeatureStatus().gpu_compositing !== 'enabled'; if (options.transparent) { - this.stateService.setItem(CodeWindow.themeBackgroundStorageKey, 'transparent'); + this.setTransparentInfo(options); } } @@ -179,12 +185,10 @@ export class CodeWindow implements ICodeWindow { useCustomTitleStyle = false; // not enabled when developing due to https://github.com/electron/electron/issues/3647 } - // TODO - //if (windowConfig && windowConfig.vibrancy && windowConfig.vibrancy !== 'none') { - // options.backgroundColor = '#00000000'; - // this.stateService.setItem(CodeWindow.themeBackgroundStorageKey, 'transparent'); - // options.vibrancy = windowConfig.vibrancy; - //} + if (windowConfig && windowConfig.vibrancy && windowConfig.vibrancy !== 'none') { + this.setTransparentInfo(options); + options.vibrancy = windowConfig.vibrancy; + } } else { useCustomTitleStyle = windowConfig && windowConfig.titleBarStyle === 'custom'; // Must be specified on Windows/Linux } @@ -202,14 +206,14 @@ export class CodeWindow implements ICodeWindow { } const isWin10 = true; // TODO - let compAttribSet = false; + let needsWinTransparency = false; if (isWindows && windowConfig && windowConfig.compositionAttribute && windowConfig.compositionAttribute !== 'none') { if (isWin10 && useCustomTitleStyle) { - options.backgroundColor = '#00000000'; - this.stateService.setItem(CodeWindow.themeBackgroundStorageKey, 'transparent'); - compAttribSet = true; - } else { - // TODO: DwmEnableBlurBehind for older OSes. + this.setTransparentInfo(options); + needsWinTransparency = true; + } else if (!isWin10 && windowConfig.compositionAttribute === 'blur') { + this.setTransparentInfo(options); + needsWinTransparency = true; } } @@ -221,7 +225,7 @@ export class CodeWindow implements ICodeWindow { this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any } - if (compAttribSet && isWin10) { + if (needsWinTransparency && isWin10) { const { SetWindowCompositionAttribute, AccentState } = require.__$__nodeRequire('windows-swca') as any; let attribValue: number; @@ -243,8 +247,8 @@ export class CodeWindow implements ICodeWindow { // using a small alpha because acrylic bugs out at full transparency. SetWindowCompositionAttribute(this._win, attribValue, 0x01000000); - } else if (compAttribSet) { - // TODO: DwnEnableBlurBehind + } else if (needsWinTransparency) { + // TODO: DwnEnableBlurBehindWindow } if (isFullscreenOrMaximized) { diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index c2a0598ffe79d..9e33bc68cba73 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -242,6 +242,7 @@ export interface IWindowSettings { clickThroughInactive: boolean; transparent: boolean; compositionAttribute: 'none' | 'transparent' | 'blur' | 'acrylic'; + vibrancy: 'none' | 'appearance-based' | 'light' | 'dark' | 'titlebar' | 'medium-light' | 'ultra-dark'; } export enum OpenContext { diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index d8dd28899c463..46fe0f351ad10 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -465,7 +465,7 @@ configurationRegistry.registerConfiguration({ 'type': 'boolean', 'default': false, 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('window.transparent', "Makes window ARGB. Needs color customizations or a transparent theme to affect appearance."), + 'description': nls.localize('window.transparent', "Makes window ARGB. Needs color customizations or a transparent theme to affect appearance. IMPORTANT: Disables hardware acceleration."), 'included': isLinux }, 'window.compositionAttribute': { @@ -473,8 +473,16 @@ configurationRegistry.registerConfiguration({ 'enum': ['none', 'transparent', 'blur', 'acrylic'], 'default': 'none', 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('window.compositionAttribute', "Changes window composition attribute. Transparent and Acrylic are only available on Windows 10. Furthermore, Acrylic requires the April 2018 update. Needs color customizations or a transparent theme to affect appearance."), + 'description': nls.localize('window.compositionAttribute', "Changes window composition attribute. Requires custom titlebar to be active on Windows 10, but not required for earlier OSes. Transparent and Acrylic are only available on Windows 10. Furthermore, Acrylic requires the April 2018 update. Needs color customizations or a transparent theme to affect appearance."), 'included': isWindows + }, + 'window.vibrancy': { + 'type': 'string', + 'enum': ['none', 'appearance-based', 'light', 'dark', 'titlebar', 'medium-light', 'ultra-dark'], + 'default': 'none', + 'scope': ConfigurationScope.APPLICATION, + 'description': nls.localize('window.vibrancy', "Sets window vibrancy effect. Needs color customizations or a transparent theme to affect appearance."), + 'included': isMacintosh && parseFloat(os.release()) >= 14 } } }); From 7b0758abcfdeb792004b37e2711f046da2e1eddd Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Thu, 21 Jun 2018 09:36:32 -0400 Subject: [PATCH 04/19] Add Windows 10 check --- src/vs/code/electron-main/window.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index df4d9ce32befd..782a7d19146b4 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -7,6 +7,7 @@ import * as path from 'path'; import * as objects from 'vs/base/common/objects'; +import * as os from 'os'; import * as nls from 'vs/nls'; import URI from 'vs/base/common/uri'; import { IStateService } from 'vs/platform/state/common/state'; @@ -205,7 +206,7 @@ export class CodeWindow implements ICodeWindow { } } - const isWin10 = true; // TODO + const isWin10 = isWindows && parseFloat(os.release()) >= 10; let needsWinTransparency = false; if (isWindows && windowConfig && windowConfig.compositionAttribute && windowConfig.compositionAttribute !== 'none') { if (isWin10 && useCustomTitleStyle) { From 49b2ae6b2ad3204788bc84d9fe8b4a86076deff8 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Thu, 21 Jun 2018 09:40:48 -0400 Subject: [PATCH 05/19] Simplify Windows transparency check --- src/vs/code/electron-main/window.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 782a7d19146b4..3d7b84282011b 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -207,15 +207,11 @@ export class CodeWindow implements ICodeWindow { } const isWin10 = isWindows && parseFloat(os.release()) >= 10; - let needsWinTransparency = false; - if (isWindows && windowConfig && windowConfig.compositionAttribute && windowConfig.compositionAttribute !== 'none') { - if (isWin10 && useCustomTitleStyle) { - this.setTransparentInfo(options); - needsWinTransparency = true; - } else if (!isWin10 && windowConfig.compositionAttribute === 'blur') { - this.setTransparentInfo(options); - needsWinTransparency = true; - } + const needsWinTransparency = + isWindows && windowConfig && windowConfig.compositionAttribute && windowConfig.compositionAttribute !== 'none' && + ((isWin10 && useCustomTitleStyle) || (!isWin10 && windowConfig.compositionAttribute === 'blur')); + if (needsWinTransparency) { + this.setTransparentInfo(options); } // Create the browser window. From 57dd9bd179d3d88fd3b73d6b161870cdd75fee51 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Fri, 22 Jun 2018 13:39:41 -0400 Subject: [PATCH 06/19] Add relauncher contributions, Windows 7 blur behind and version gate for acrylic --- package.json | 3 ++- src/vs/code/electron-main/window.ts | 9 +++++--- .../relauncher.contribution.ts | 21 +++++++++++++++++++ yarn.lock | 6 +++++- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 0d18cf0e62c4e..02440e36ec95b 100644 --- a/package.json +++ b/package.json @@ -133,9 +133,10 @@ "url": "https://github.com/Microsoft/vscode/issues" }, "optionalDependencies": { + "windows-blurbehind": "1.0.0", "windows-foreground-love": "0.1.0", "windows-mutex": "^0.2.0", "windows-process-tree": "0.2.2", - "windows-swca": "^1.1.1" + "windows-swca": "1.1.1" } } diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 3d7b84282011b..ebdf7f6407fe9 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -225,10 +225,11 @@ export class CodeWindow implements ICodeWindow { if (needsWinTransparency && isWin10) { const { SetWindowCompositionAttribute, AccentState } = require.__$__nodeRequire('windows-swca') as any; - let attribValue: number; + let attribValue = AccentState.ACCENT_DISABLED; switch (windowConfig.compositionAttribute) { case 'acrylic': - if (/* TODO: test OS build 17063*/true) { + // Fluent/acrylic flag was introduced in Windows 10 build 17063 (between FCU and April 2018 update) + if (parseInt(os.release().split('.')[2]) >= 17063) { attribValue = AccentState.ACCENT_ENABLE_FLUENT; } break; @@ -245,7 +246,9 @@ export class CodeWindow implements ICodeWindow { // using a small alpha because acrylic bugs out at full transparency. SetWindowCompositionAttribute(this._win, attribValue, 0x01000000); } else if (needsWinTransparency) { - // TODO: DwnEnableBlurBehindWindow + const { DwmEnableBlurBehindWindow } = require.__$__nodeRequire('windows-blurbehind') as any; + + DwmEnableBlurBehindWindow(this._win, true); } if (isFullscreenOrMaximized) { diff --git a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts index cc504052f716d..cd544a28b3960 100644 --- a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts +++ b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts @@ -34,6 +34,9 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution { private toDispose: IDisposable[] = []; + private transparent: boolean; + private compositionAttribute: 'none' | 'transparent' | 'blur' | 'acrylic'; + private vibrancy: 'none' | 'appearance-based' | 'light' | 'dark' | 'titlebar' | 'medium-light' | 'ultra-dark'; private titleBarStyle: 'native' | 'custom'; private nativeTabs: boolean; private clickThroughInactive: boolean; @@ -77,6 +80,24 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution { private onConfigurationChange(config: IConfiguration, notify: boolean): void { let changed = false; + // Linux transparency + if (isLinux && config.window && typeof config.window.transparent === 'boolean' && config.window.transparent !== this.transparent) { + this.transparent = config.window.transparent; + changed = true; + } + + // Windows Composition Attribute + if (isWindows && config.window && config.window.compositionAttribute !== this.compositionAttribute) { + this.compositionAttribute = config.window.compositionAttribute; + changed = true; + } + + // macOS vibrancy + if (isMacintosh && config.window && config.window.vibrancy !== this.vibrancy) { + this.vibrancy = config.window.vibrancy; + changed = true; + } + // Titlebar style if (config.window && config.window.titleBarStyle !== this.titleBarStyle && (config.window.titleBarStyle === 'native' || config.window.titleBarStyle === 'custom')) { this.titleBarStyle = config.window.titleBarStyle; diff --git a/yarn.lock b/yarn.lock index ca69d5a987580..60d50776dfda0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6294,6 +6294,10 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" +windows-blurbehind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/windows-blurbehind/-/windows-blurbehind-1.0.0.tgz#050efb988704c44335bdc3efefd757f6e463b8ac" + windows-foreground-love@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/windows-foreground-love/-/windows-foreground-love-0.1.0.tgz#948e4beac0733cd58624710cc09432b7e8bf3521" @@ -6311,7 +6315,7 @@ windows-process-tree@0.2.2: dependencies: nan "^2.6.2" -windows-swca@^1.1.1: +windows-swca@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/windows-swca/-/windows-swca-1.1.1.tgz#0b3530278c67d408baac71c3a6aeb16d55318bf8" From e0425aa4735a924e167313f2fafc2913d9104139 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Fri, 22 Jun 2018 14:29:32 -0400 Subject: [PATCH 07/19] Add enumDescriptions for window.compositionAttribute --- src/vs/workbench/electron-browser/main.contribution.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 46fe0f351ad10..260465ae205e0 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -471,9 +471,15 @@ configurationRegistry.registerConfiguration({ 'window.compositionAttribute': { 'type': 'string', 'enum': ['none', 'transparent', 'blur', 'acrylic'], + 'enumDescriptions': [ + nls.localize('window.compositionAttribute.none', "No special effect or transparency."), + nls.localize('window.compositionAttribute.transparent', "Transparent. Requires at least Windows 10."), + nls.localize('window.compositionAttribute.blur', "Transparent and blurred."), + nls.localize('window.compositionAttribute.acrylic', "Transparent, blurred and grain effect. Requires the Windows 10 April 2018 update and can present various graphical glitches when there is not at least one window other than VS Code maximised.") + ], 'default': 'none', 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('window.compositionAttribute', "Changes window composition attribute. Requires custom titlebar to be active on Windows 10, but not required for earlier OSes. Transparent and Acrylic are only available on Windows 10. Furthermore, Acrylic requires the April 2018 update. Needs color customizations or a transparent theme to affect appearance."), + 'description': nls.localize('window.compositionAttribute', "Changes window composition attribute. Requires custom titlebar to be active on Windows 10, but not required for earlier versions. Needs color customizations or a transparent theme to affect appearance."), 'included': isWindows }, 'window.vibrancy': { From bcc62792f9ef8fa369d86b8d5f4c6a64f10a239c Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sat, 23 Jun 2018 11:18:21 -0400 Subject: [PATCH 08/19] Fix various rendering bugs --- src/vs/code/electron-main/window.ts | 5 ++-- .../browser/viewParts/minimap/minimap.ts | 3 +- .../editor/common/view/minimapCharRenderer.ts | 30 +++++++++++++++++++ .../electron-browser/terminalInstance.ts | 3 +- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index ebdf7f6407fe9..8efb2cf9bd647 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -226,11 +226,13 @@ export class CodeWindow implements ICodeWindow { const { SetWindowCompositionAttribute, AccentState } = require.__$__nodeRequire('windows-swca') as any; let attribValue = AccentState.ACCENT_DISABLED; + let color = 0x00000000; switch (windowConfig.compositionAttribute) { case 'acrylic': // Fluent/acrylic flag was introduced in Windows 10 build 17063 (between FCU and April 2018 update) if (parseInt(os.release().split('.')[2]) >= 17063) { attribValue = AccentState.ACCENT_ENABLE_FLUENT; + color = 0x01000000; // using a small alpha because acrylic bugs out at full transparency. } break; @@ -243,8 +245,7 @@ export class CodeWindow implements ICodeWindow { break; } - // using a small alpha because acrylic bugs out at full transparency. - SetWindowCompositionAttribute(this._win, attribValue, 0x01000000); + SetWindowCompositionAttribute(this._win, attribValue, color); } else if (needsWinTransparency) { const { DwmEnableBlurBehindWindow } = require.__$__nodeRequire('windows-blurbehind') as any; diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index 5f8337eb5a915..49206d65ac3e7 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -417,6 +417,7 @@ class MinimapBuffers { const backgroundR = background.r; const backgroundG = background.g; const backgroundB = background.b; + const backgroundA = background.a; let result = new Uint8ClampedArray(WIDTH * HEIGHT * 4); let offset = 0; @@ -425,7 +426,7 @@ class MinimapBuffers { result[offset] = backgroundR; result[offset + 1] = backgroundG; result[offset + 2] = backgroundB; - result[offset + 3] = 255; + result[offset + 3] = backgroundA; offset += 4; } } diff --git a/src/vs/editor/common/view/minimapCharRenderer.ts b/src/vs/editor/common/view/minimapCharRenderer.ts index f9b331f8da31f..f0e34b90baeaf 100644 --- a/src/vs/editor/common/view/minimapCharRenderer.ts +++ b/src/vs/editor/common/view/minimapCharRenderer.ts @@ -136,10 +136,12 @@ export class MinimapCharRenderer { const backgroundR = backgroundColor.r; const backgroundG = backgroundColor.g; const backgroundB = backgroundColor.b; + const backgroundA = backgroundColor.a; const deltaR = color.r - backgroundR; const deltaG = color.g - backgroundG; const deltaB = color.b - backgroundB; + const deltaA = color.a - backgroundA; const dest = target.data; const sourceOffset = chIndex * Constants.x2_CHAR_HEIGHT * Constants.x2_CHAR_WIDTH; @@ -149,12 +151,14 @@ export class MinimapCharRenderer { dest[destOffset + 0] = backgroundR + deltaR * c; dest[destOffset + 1] = backgroundG + deltaG * c; dest[destOffset + 2] = backgroundB + deltaB * c; + dest[destOffset + 3] = backgroundA + deltaA * c; } { const c = x2CharData[sourceOffset + 1] / 255; dest[destOffset + 4] = backgroundR + deltaR * c; dest[destOffset + 5] = backgroundG + deltaG * c; dest[destOffset + 6] = backgroundB + deltaB * c; + dest[destOffset + 7] = backgroundA + deltaA * c; } destOffset += outWidth; @@ -163,12 +167,14 @@ export class MinimapCharRenderer { dest[destOffset + 0] = backgroundR + deltaR * c; dest[destOffset + 1] = backgroundG + deltaG * c; dest[destOffset + 2] = backgroundB + deltaB * c; + dest[destOffset + 3] = backgroundA + deltaA * c; } { const c = x2CharData[sourceOffset + 3] / 255; dest[destOffset + 4] = backgroundR + deltaR * c; dest[destOffset + 5] = backgroundG + deltaG * c; dest[destOffset + 6] = backgroundB + deltaB * c; + dest[destOffset + 7] = backgroundA + deltaA * c; } destOffset += outWidth; @@ -177,12 +183,14 @@ export class MinimapCharRenderer { dest[destOffset + 0] = backgroundR + deltaR * c; dest[destOffset + 1] = backgroundG + deltaG * c; dest[destOffset + 2] = backgroundB + deltaB * c; + dest[destOffset + 3] = backgroundA + deltaA * c; } { const c = x2CharData[sourceOffset + 5] / 255; dest[destOffset + 4] = backgroundR + deltaR * c; dest[destOffset + 5] = backgroundG + deltaG * c; dest[destOffset + 6] = backgroundB + deltaB * c; + dest[destOffset + 7] = backgroundA + deltaA * c; } destOffset += outWidth; @@ -191,12 +199,14 @@ export class MinimapCharRenderer { dest[destOffset + 0] = backgroundR + deltaR * c; dest[destOffset + 1] = backgroundG + deltaG * c; dest[destOffset + 2] = backgroundB + deltaB * c; + dest[destOffset + 3] = backgroundA + deltaA * c; } { const c = x2CharData[sourceOffset + 7] / 255; dest[destOffset + 4] = backgroundR + deltaR * c; dest[destOffset + 5] = backgroundG + deltaG * c; dest[destOffset + 6] = backgroundB + deltaB * c; + dest[destOffset + 7] = backgroundA + deltaA * c; } } @@ -213,10 +223,12 @@ export class MinimapCharRenderer { const backgroundR = backgroundColor.r; const backgroundG = backgroundColor.g; const backgroundB = backgroundColor.b; + const backgroundA = backgroundColor.a; const deltaR = color.r - backgroundR; const deltaG = color.g - backgroundG; const deltaB = color.b - backgroundB; + const deltaA = color.a - backgroundA; const dest = target.data; const sourceOffset = chIndex * Constants.x1_CHAR_HEIGHT * Constants.x1_CHAR_WIDTH; @@ -226,6 +238,7 @@ export class MinimapCharRenderer { dest[destOffset + 0] = backgroundR + deltaR * c; dest[destOffset + 1] = backgroundG + deltaG * c; dest[destOffset + 2] = backgroundB + deltaB * c; + dest[destOffset + 3] = backgroundA + deltaA * c; } destOffset += outWidth; @@ -234,6 +247,7 @@ export class MinimapCharRenderer { dest[destOffset + 0] = backgroundR + deltaR * c; dest[destOffset + 1] = backgroundG + deltaG * c; dest[destOffset + 2] = backgroundB + deltaB * c; + dest[destOffset + 3] = backgroundA + deltaA * c; } } @@ -250,14 +264,17 @@ export class MinimapCharRenderer { const backgroundR = backgroundColor.r; const backgroundG = backgroundColor.g; const backgroundB = backgroundColor.b; + const backgroundA = backgroundColor.a; const deltaR = color.r - backgroundR; const deltaG = color.g - backgroundG; const deltaB = color.b - backgroundB; + const deltaA = color.a - backgroundA; const colorR = backgroundR + deltaR * c; const colorG = backgroundG + deltaG * c; const colorB = backgroundB + deltaB * c; + const colorA = backgroundA + deltaA * c; const dest = target.data; let destOffset = dy * outWidth + dx * Constants.RGBA_CHANNELS_CNT; @@ -265,11 +282,13 @@ export class MinimapCharRenderer { dest[destOffset + 0] = colorR; dest[destOffset + 1] = colorG; dest[destOffset + 2] = colorB; + dest[destOffset + 3] = colorA; } { dest[destOffset + 4] = colorR; dest[destOffset + 5] = colorG; dest[destOffset + 6] = colorB; + dest[destOffset + 7] = colorA; } destOffset += outWidth; @@ -277,11 +296,13 @@ export class MinimapCharRenderer { dest[destOffset + 0] = colorR; dest[destOffset + 1] = colorG; dest[destOffset + 2] = colorB; + dest[destOffset + 3] = colorA; } { dest[destOffset + 4] = colorR; dest[destOffset + 5] = colorG; dest[destOffset + 6] = colorB; + dest[destOffset + 7] = colorA; } destOffset += outWidth; @@ -289,11 +310,13 @@ export class MinimapCharRenderer { dest[destOffset + 0] = colorR; dest[destOffset + 1] = colorG; dest[destOffset + 2] = colorB; + dest[destOffset + 3] = colorA; } { dest[destOffset + 4] = colorR; dest[destOffset + 5] = colorG; dest[destOffset + 6] = colorB; + dest[destOffset + 7] = colorA; } destOffset += outWidth; @@ -301,11 +324,13 @@ export class MinimapCharRenderer { dest[destOffset + 0] = colorR; dest[destOffset + 1] = colorG; dest[destOffset + 2] = colorB; + dest[destOffset + 3] = colorA; } { dest[destOffset + 4] = colorR; dest[destOffset + 5] = colorG; dest[destOffset + 6] = colorB; + dest[destOffset + 7] = colorA; } } @@ -322,14 +347,17 @@ export class MinimapCharRenderer { const backgroundR = backgroundColor.r; const backgroundG = backgroundColor.g; const backgroundB = backgroundColor.b; + const backgroundA = backgroundColor.a; const deltaR = color.r - backgroundR; const deltaG = color.g - backgroundG; const deltaB = color.b - backgroundB; + const deltaA = color.a - backgroundA; const colorR = backgroundR + deltaR * c; const colorG = backgroundG + deltaG * c; const colorB = backgroundB + deltaB * c; + const colorA = backgroundA + deltaA * c; const dest = target.data; @@ -338,6 +366,7 @@ export class MinimapCharRenderer { dest[destOffset + 0] = colorR; dest[destOffset + 1] = colorG; dest[destOffset + 2] = colorB; + dest[destOffset + 3] = colorA; } destOffset += outWidth; @@ -345,6 +374,7 @@ export class MinimapCharRenderer { dest[destOffset + 0] = colorR; dest[destOffset + 1] = colorG; dest[destOffset + 2] = colorB; + dest[destOffset + 3] = colorA; } } } diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index 6203b5c5c9771..ab0a826bd27a3 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -286,7 +286,8 @@ export class TerminalInstance implements ITerminalInstance { rightClickSelectsWord: config.rightClickBehavior === 'selectWord', // TODO: Guess whether to use canvas or dom better rendererType: config.rendererType === 'auto' ? 'canvas' : config.rendererType, - experimentalCharAtlas: config.experimentalTextureCachingStrategy + experimentalCharAtlas: config.experimentalTextureCachingStrategy, + allowTransparency: true }); if (this._shellLaunchConfig.initialText) { this._xterm.writeln(this._shellLaunchConfig.initialText); From 005b173a5dd1e5319efa3156563c742eb996c6c8 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sat, 23 Jun 2018 11:32:08 -0400 Subject: [PATCH 09/19] Use app.getPath instead of getUserDataPath --- src/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.js b/src/main.js index 55b30fd606503..9c44280fb6f67 100644 --- a/src/main.js +++ b/src/main.js @@ -409,7 +409,7 @@ global.getOpenUrls = function () { // Linux: disable hardware acceleration when transparent window is enabled try { if (process.platform === 'linux') { - const configFile = path.join(getUserDataPath(), 'User', 'settings.json'); + const configFile = path.join(app.getPath('userData'), 'User', 'settings.json'); if (fs.existsSync(configFile)) { const config = JSON.parse(stripComments(fs.readFileSync(configFile, 'utf8'))); if (config['window.transparent']) { From 759338db812b0861e6eb09832058b66477aef74d Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Fri, 7 Sep 2018 10:34:32 -0400 Subject: [PATCH 10/19] Add missing comma, fix build issue --- .../parts/terminal/electron-browser/terminalInstance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index 5fdeda8c69479..d0abb5e1f52cf 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -293,7 +293,7 @@ export class TerminalInstance implements ITerminalInstance { rightClickSelectsWord: config.rightClickBehavior === 'selectWord', // TODO: Guess whether to use canvas or dom better rendererType: config.rendererType === 'auto' ? 'canvas' : config.rendererType, - allowTransparency: true + allowTransparency: true, // TODO: Remove this once the setting is removed upstream experimentalCharAtlas: 'dynamic' }); From cabf2a0e7682f90763a07f27bbc5cefaddfe849a Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Mon, 1 Oct 2018 12:09:38 -0400 Subject: [PATCH 11/19] Fix build errors --- src/vs/code/electron-main/window.ts | 9 ++------- .../splash/electron-browser/partsSplash.contribution.ts | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 3fe72af62eb02..144f104f06e17 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -27,7 +27,7 @@ import { IBackupMainService } from 'vs/platform/backup/common/backup'; import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; import * as perf from 'vs/base/common/performance'; import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/node/extensionGalleryService'; -import { getBackgroundColor } from 'vs/code/electron-main/theme'; +import { getBackgroundColor, THEME_BG_STORAGE_KEY } from 'vs/code/electron-main/theme'; export interface IWindowCreationOptions { state: IWindowState; @@ -113,7 +113,7 @@ export class CodeWindow implements ICodeWindow { private setTransparentInfo(options: Electron.BrowserWindowConstructorOptions): void { options.backgroundColor = '#00000000'; - this.stateService.setItem(CodeWindow.themeBackgroundStorageKey, 'transparent'); + this.stateService.setItem(THEME_BG_STORAGE_KEY, 'transparent'); } private createBrowserWindow(config: IWindowCreationOptions): void { @@ -124,11 +124,6 @@ export class CodeWindow implements ICodeWindow { // in case we are maximized or fullscreen, only show later after the call to maximize/fullscreen (see below) const isFullscreenOrMaximized = (this.windowState.mode === WindowMode.Maximized || this.windowState.mode === WindowMode.Fullscreen); - let backgroundColor = this.getBackgroundColor(); - if (isMacintosh && backgroundColor.toUpperCase() === CodeWindow.DEFAULT_BG_DARK) { - backgroundColor = '#171717'; // https://github.com/electron/electron/issues/5150 - } - const options: Electron.BrowserWindowConstructorOptions = { width: this.windowState.width, height: this.windowState.height, diff --git a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts index 5f76b802ea5a6..73328f4d5a4e2 100644 --- a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts +++ b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts @@ -71,7 +71,7 @@ class PartsSplash { this.lastBackground = colorInfo.editorBackground; // the color needs to be in hex - const backgroundColor = this._themeService.getTheme().getColor(editorBackground) || themes.WORKBENCH_BACKGROUND(this._themeService.getTheme()); + const backgroundColor = this._themeService.getTheme().getColor(editorBackground) || this._themeService.getTheme().getColor(themes.WORKBENCH_BACKGROUND); this.broadcastService.broadcast({ channel: 'vscode:changeColorTheme', payload: JSON.stringify({ baseTheme, background: Color.Format.CSS.formatHex(backgroundColor) }) }); } } From f7761cfa3c2592dcc6b2eed3079b4ff8f79e8b4c Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Fri, 2 Nov 2018 22:41:49 -0400 Subject: [PATCH 12/19] Fix build error --- .../relauncher/electron-browser/relauncher.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts index a0a7420cff414..fbc9b7c45689d 100644 --- a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts +++ b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts @@ -15,7 +15,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { RunOnceScheduler } from 'vs/base/common/async'; import { URI } from 'vs/base/common/uri'; import { isEqual } from 'vs/base/common/resources'; -import { isLinux, isMacintosh } from 'vs/base/common/platform'; +import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { equals } from 'vs/base/common/objects'; From 2c30a0ae592dcd0c238a529b878c1deb37e96e43 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sat, 1 Dec 2018 21:20:56 -0500 Subject: [PATCH 13/19] Fix hygiene checks --- src/vs/code/electron-main/window.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index f21a7e2ac50d4..964fcc585a456 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -178,8 +178,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { options.frame = false; } } - - if (isMacintosh && windowConfig && windowConfig.vibrancy && windowConfig.vibrancy !== 'none') { + + if (isMacintosh && windowConfig && windowConfig.vibrancy && windowConfig.vibrancy !== 'none') { this.setTransparentInfo(options); options.vibrancy = windowConfig.vibrancy; } From 44535081b46e6b3a7870d4930f14aad8ddf94625 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sun, 3 Mar 2019 00:51:45 -0500 Subject: [PATCH 14/19] Update windows-swca to latest version, drop windows 7 support --- package.json | 3 +- src/vs/code/electron-main/app.ts | 4 +-- src/vs/code/electron-main/theme.ts | 6 +++- src/vs/code/electron-main/window.ts | 31 +++++++------------ .../electron-browser/shell.contribution.ts | 6 ++-- .../relauncher.contribution.ts | 2 +- .../partsSplash.contribution.ts | 4 ++- yarn.lock | 18 ++++++----- 8 files changed, 38 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index 9c1c233bf89c5..c283c65d50bee 100644 --- a/package.json +++ b/package.json @@ -146,10 +146,9 @@ "url": "https://github.com/Microsoft/vscode/issues" }, "optionalDependencies": { - "windows-blurbehind": "1.0.0", "windows-foreground-love": "0.1.0", "windows-mutex": "0.2.1", "windows-process-tree": "0.2.3", - "windows-swca": "1.1.1" + "windows-swca": "2.0.1" } } diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index ce0240ad7d222..8a09022f3bf9a 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -63,7 +63,7 @@ import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc'; import { hasArgs } from 'vs/platform/environment/node/argv'; import { RunOnceScheduler } from 'vs/base/common/async'; import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu'; -import { storeBackgroundColor } from 'vs/code/electron-main/theme'; +import { storeColors } from 'vs/code/electron-main/theme'; import { nativeSep, join } from 'vs/base/common/paths'; import { homedir } from 'os'; import { localize } from 'vs/nls'; @@ -293,7 +293,7 @@ export class CodeApplication extends Disposable { // Theme changes if (event === 'vscode:changeColorTheme' && typeof payload === 'string') { - storeBackgroundColor(this.stateService, JSON.parse(payload)); + storeColors(this.stateService, JSON.parse(payload)); } } diff --git a/src/vs/code/electron-main/theme.ts b/src/vs/code/electron-main/theme.ts index 5518c38404aaf..e0c35e78f9649 100644 --- a/src/vs/code/electron-main/theme.ts +++ b/src/vs/code/electron-main/theme.ts @@ -14,7 +14,7 @@ const DEFAULT_BG_HC_BLACK = '#000000'; const THEME_STORAGE_KEY = 'theme'; const THEME_BG_STORAGE_KEY = 'themeBackground'; -export function storeBackgroundColor(stateService: IStateService, data: { baseTheme: string, background: string }): void { +export function storeColors(stateService: IStateService, data: { baseTheme: string, background: string }): void { stateService.setItem(THEME_STORAGE_KEY, data.baseTheme); stateService.setItem(THEME_BG_STORAGE_KEY, data.background); } @@ -41,4 +41,8 @@ export function getBackgroundColor(stateService: IStateService): string { } return background; +} + +export function setBackgroundColor(stateService: IStateService, background: string): void { + stateService.setItem(THEME_BG_STORAGE_KEY, background); } \ No newline at end of file diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 18a49f7d33f6f..5f823d01aefcb 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -24,7 +24,7 @@ import { IBackupMainService } from 'vs/platform/backup/common/backup'; import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; import * as perf from 'vs/base/common/performance'; import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/node/extensionGalleryService'; -import { getBackgroundColor, THEME_BG_STORAGE_KEY } from 'vs/code/electron-main/theme'; +import { getBackgroundColor, setBackgroundColor } from 'vs/code/electron-main/theme'; import { IStorageMainService } from 'vs/platform/storage/node/storageMainService'; import { RunOnceScheduler } from 'vs/base/common/async'; @@ -115,7 +115,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { private setTransparentInfo(options: Electron.BrowserWindowConstructorOptions): void { options.backgroundColor = '#00000000'; - this.stateService.setItem(THEME_BG_STORAGE_KEY, 'transparent'); + setBackgroundColor(this.stateService, 'transparent'); } private createBrowserWindow(config: IWindowCreationOptions): void { @@ -187,10 +187,10 @@ export class CodeWindow extends Disposable implements ICodeWindow { options.vibrancy = windowConfig.vibrancy; } - const isWin10 = isWindows && parseFloat(os.release()) >= 10; const needsWinTransparency = - isWindows && windowConfig && windowConfig.compositionAttribute && windowConfig.compositionAttribute !== 'none' && - ((isWin10 && useCustomTitleStyle) || (!isWin10 && windowConfig.compositionAttribute === 'blur')); + isWindows && windowConfig && windowConfig.compositionAttribute && + windowConfig.compositionAttribute !== 'none' && parseFloat(os.release()) >= 10 && + useCustomTitleStyle; if (needsWinTransparency) { this.setTransparentInfo(options); } @@ -203,34 +203,27 @@ export class CodeWindow extends Disposable implements ICodeWindow { this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any } - if (needsWinTransparency && isWin10) { - const { SetWindowCompositionAttribute, AccentState } = require.__$__nodeRequire('windows-swca') as any; - - let attribValue = AccentState.ACCENT_DISABLED; - let color = 0x00000000; + if (needsWinTransparency) { + const { ACCENT_STATE, SetWindowCompositionAttribute } = require.__$__nodeRequire('windows-swca'); + let attribValue = ACCENT_STATE.ACCENT_DISABLED; switch (windowConfig.compositionAttribute) { case 'acrylic': // Fluent/acrylic flag was introduced in Windows 10 build 17063 (between FCU and April 2018 update) if (parseInt(os.release().split('.')[2]) >= 17063) { - attribValue = AccentState.ACCENT_ENABLE_FLUENT; - color = 0x01000000; // using a small alpha because acrylic bugs out at full transparency. + attribValue = ACCENT_STATE.ACCENT_ENABLE_ACRYLICBLURBEHIND; } break; case 'blur': - attribValue = AccentState.ACCENT_ENABLE_BLURBEHIND; + attribValue = ACCENT_STATE.ACCENT_ENABLE_BLURBEHIND; break; case 'transparent': - attribValue = AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT; + attribValue = ACCENT_STATE.ACCENT_ENABLE_TRANSPARENTGRADIENT; break; } - SetWindowCompositionAttribute(this._win, attribValue, color); - } else if (needsWinTransparency) { - const { DwmEnableBlurBehindWindow } = require.__$__nodeRequire('windows-blurbehind') as any; - - DwmEnableBlurBehindWindow(this._win, true); + SetWindowCompositionAttribute(this._win.getNativeWindowHandle(), attribValue, 0x00000001); } if (isFullscreenOrMaximized) { diff --git a/src/vs/workbench/electron-browser/shell.contribution.ts b/src/vs/workbench/electron-browser/shell.contribution.ts index 3532d6bf2923b..99551f4f13019 100644 --- a/src/vs/workbench/electron-browser/shell.contribution.ts +++ b/src/vs/workbench/electron-browser/shell.contribution.ts @@ -639,14 +639,14 @@ configurationRegistry.registerConfiguration({ 'enum': ['none', 'transparent', 'blur', 'acrylic'], 'enumDescriptions': [ nls.localize('window.compositionAttribute.none', "No special effect or transparency."), - nls.localize('window.compositionAttribute.transparent', "Transparent. Requires at least Windows 10."), + nls.localize('window.compositionAttribute.transparent', "Transparent."), nls.localize('window.compositionAttribute.blur', "Transparent and blurred."), nls.localize('window.compositionAttribute.acrylic', "Transparent, blurred and grain effect. Requires the Windows 10 April 2018 update and can present various graphical glitches when there is not at least one window other than VS Code maximised.") ], 'default': 'none', 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('window.compositionAttribute', "Changes window composition attribute. Requires custom titlebar to be active on Windows 10, but not required for earlier versions. Needs color customizations or a transparent theme to affect appearance."), - 'included': isWindows + 'description': nls.localize('window.compositionAttribute', "Changes window composition attribute. Requires custom titlebar to be active. Needs color customizations or a transparent theme to affect appearance."), + 'included': isWindows && parseFloat(os.release()) >= 10 }, 'window.vibrancy': { 'type': 'string', diff --git a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts index 5efdfeb8baac7..8c51c1d3e55c2 100644 --- a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts +++ b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts @@ -15,7 +15,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { RunOnceScheduler } from 'vs/base/common/async'; import { URI } from 'vs/base/common/uri'; import { isEqual } from 'vs/base/common/resources'; -import { isLinux, isMacintosh } from 'vs/base/common/platform'; +import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { equals } from 'vs/base/common/objects'; diff --git a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts index d6c84ba14b84d..ebcbd79804bb0 100644 --- a/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts +++ b/src/vs/workbench/parts/splash/electron-browser/partsSplash.contribution.ts @@ -81,7 +81,9 @@ class PartsSplash { // the color needs to be in hex const backgroundColor = this._themeService.getTheme().getColor(editorBackground) || this._themeService.getTheme().getColor(themes.WORKBENCH_BACKGROUND); - this.broadcastService.broadcast({ channel: 'vscode:changeColorTheme', payload: JSON.stringify({ baseTheme, background: Color.Format.CSS.formatHex(backgroundColor) }) }); + if (backgroundColor) { + this.broadcastService.broadcast({ channel: 'vscode:changeColorTheme', payload: JSON.stringify({ baseTheme, background: Color.Format.CSS.formatHex(backgroundColor) }) }); + } } } diff --git a/yarn.lock b/yarn.lock index ffc3801e3724a..48b380620abab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -39,6 +39,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.12.tgz#e15a9d034d9210f00320ef718a50c4a799417c47" integrity sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A== +"@types/node@^10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== + "@types/semver@^5.4.0", "@types/semver@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" @@ -9562,10 +9567,6 @@ window-size@0.1.0: resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= -windows-blurbehind@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/windows-blurbehind/-/windows-blurbehind-1.0.0.tgz#050efb988704c44335bdc3efefd757f6e463b8ac" - windows-foreground-love@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/windows-foreground-love/-/windows-foreground-love-0.1.0.tgz#948e4beac0733cd58624710cc09432b7e8bf3521" @@ -9586,9 +9587,12 @@ windows-process-tree@0.2.3: dependencies: nan "^2.10.0" -windows-swca@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/windows-swca/-/windows-swca-1.1.1.tgz#0b3530278c67d408baac71c3a6aeb16d55318bf8" +windows-swca@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/windows-swca/-/windows-swca-2.0.1.tgz#25d78ce25251292061494a0ad07c02282b28b4e3" + integrity sha512-flj+HD6RUemZUvKKguLLnMUOYkQSgDu9qrhUIO4cydvtb/x+sxU8XmpZUtugYuydcdikB9zsCOMgKnAqIQ+7nw== + dependencies: + "@types/node" "^10.12.18" winreg@^1.2.4: version "1.2.4" From 24f56c349f2b41a55255102603302d6c444988c0 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Tue, 16 Apr 2019 23:14:01 -0400 Subject: [PATCH 15/19] Just send 0 to SetWindowCompositionAttribute --- src/vs/code/electron-main/window.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 99a1df0ea3c8b..57c57cfb395a4 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -231,7 +231,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { break; } - SetWindowCompositionAttribute(this._win.getNativeWindowHandle(), attribValue, 0x00000001); + SetWindowCompositionAttribute(this._win.getNativeWindowHandle(), attribValue, 0); } if (isFullscreenOrMaximized) { From c29d4c802584c231a52f2359d192953e766b0184 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Tue, 16 Apr 2019 23:26:26 -0400 Subject: [PATCH 16/19] Fix build errors --- src/vs/workbench/browser/parts/editor/tabsTitleControl.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index 4c516b4c4c1e7..b6ceeea4a43c8 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -1230,12 +1230,12 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { const editorDragAndDropBackground = theme.getColor(EDITOR_DRAG_AND_DROP_BACKGROUND); let adjustedTabBackground: Color | undefined; - if (editorGroupHeaderTabsBackground && editorBackgroundColor) { + if (editorGroupHeaderTabsBackground && editorBackgroundColor && workbenchBackground) { adjustedTabBackground = editorGroupHeaderTabsBackground.flatten(editorBackgroundColor, editorBackgroundColor, workbenchBackground); } let adjustedTabDragBackground: Color | undefined; - if (editorGroupHeaderTabsBackground && editorBackgroundColor && editorDragAndDropBackground && editorBackgroundColor) { + if (editorGroupHeaderTabsBackground && editorBackgroundColor && editorDragAndDropBackground && editorBackgroundColor && workbenchBackground) { adjustedTabDragBackground = editorGroupHeaderTabsBackground.flatten(editorBackgroundColor, editorDragAndDropBackground, editorBackgroundColor, workbenchBackground); } From dd3a6ac6ab4e7b6e9802931f84a579a1af3af226 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Tue, 2 Jul 2019 15:00:17 -0400 Subject: [PATCH 17/19] Update acrylic effect description --- src/vs/code/electron-main/theme.ts | 48 ------------------- .../electron-browser/main.contribution.ts | 2 +- 2 files changed, 1 insertion(+), 49 deletions(-) delete mode 100644 src/vs/code/electron-main/theme.ts diff --git a/src/vs/code/electron-main/theme.ts b/src/vs/code/electron-main/theme.ts deleted file mode 100644 index e0c35e78f9649..0000000000000 --- a/src/vs/code/electron-main/theme.ts +++ /dev/null @@ -1,48 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { isWindows, isMacintosh } from 'vs/base/common/platform'; -import { systemPreferences } from 'electron'; -import { IStateService } from 'vs/platform/state/common/state'; - -const DEFAULT_BG_LIGHT = '#FFFFFF'; -const DEFAULT_BG_DARK = '#1E1E1E'; -const DEFAULT_BG_HC_BLACK = '#000000'; - -const THEME_STORAGE_KEY = 'theme'; -const THEME_BG_STORAGE_KEY = 'themeBackground'; - -export function storeColors(stateService: IStateService, data: { baseTheme: string, background: string }): void { - stateService.setItem(THEME_STORAGE_KEY, data.baseTheme); - stateService.setItem(THEME_BG_STORAGE_KEY, data.background); -} - -export function getBackgroundColor(stateService: IStateService): string { - if (isWindows && systemPreferences.isInvertedColorScheme()) { - return DEFAULT_BG_HC_BLACK; - } - - let background = stateService.getItem(THEME_BG_STORAGE_KEY, null); - if (!background) { - let baseTheme: string; - if (isWindows && systemPreferences.isInvertedColorScheme()) { - baseTheme = 'hc-black'; - } else { - baseTheme = stateService.getItem(THEME_STORAGE_KEY, 'vs-dark').split(' ')[0]; - } - - background = (baseTheme === 'hc-black') ? DEFAULT_BG_HC_BLACK : (baseTheme === 'vs' ? DEFAULT_BG_LIGHT : DEFAULT_BG_DARK); - } - - if (isMacintosh && background.toUpperCase() === DEFAULT_BG_DARK) { - background = '#171717'; // https://github.com/electron/electron/issues/5150 - } - - return background; -} - -export function setBackgroundColor(stateService: IStateService, background: string): void { - stateService.setItem(THEME_BG_STORAGE_KEY, background); -} \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 446a93781ded4..711e787fbf789 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -531,7 +531,7 @@ import product from 'vs/platform/product/node/product'; nls.localize('window.compositionAttribute.none', "No special effect or transparency."), nls.localize('window.compositionAttribute.transparent', "Transparent."), nls.localize('window.compositionAttribute.blur', "Transparent and blurred."), - nls.localize('window.compositionAttribute.acrylic', "Transparent, blurred and grain effect. Requires the Windows 10 April 2018 update and can present various graphical glitches when there is not at least one window other than VS Code maximised.") + nls.localize('window.compositionAttribute.acrylic', "Transparent, heavily blurred and grainy. Requires the Windows 10 April 2018 update, and has lag issues when dragging the window in the May 2019 update.") ], 'default': 'none', 'scope': ConfigurationScope.APPLICATION, From cc027c43c7125942ad0a68d56b94d4690177239d Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Tue, 2 Jul 2019 16:15:54 -0400 Subject: [PATCH 18/19] Add hot reload of vibrancy and composition attribute --- src/vs/code/electron-main/window.ts | 122 ++++++++++-------- .../relauncher.contribution.ts | 16 +-- 2 files changed, 66 insertions(+), 72 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index bcdb193d78aef..d72c99cf2d6d6 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -111,20 +111,12 @@ export class CodeWindow extends Disposable implements ICodeWindow { this.registerListeners(); } - private setTransparentInfo(options: Electron.BrowserWindowConstructorOptions): void { - options.backgroundColor = '#00000000'; - //setBackgroundColor(this.stateService, 'transparent'); - } - private createBrowserWindow(config: IWindowCreationOptions): void { // Load window state const [state, hasMultipleDisplays] = this.restoreWindowState(config.state); this.windowState = state; - // in case we are maximized or fullscreen, only show later after the call to maximize/fullscreen (see below) - const isFullscreenOrMaximized = (this.windowState.mode === WindowMode.Maximized || this.windowState.mode === WindowMode.Fullscreen); - const options: Electron.BrowserWindowConstructorOptions = { width: this.windowState.width, height: this.windowState.height, @@ -133,7 +125,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { backgroundColor: this.themeMainService.getBackgroundColor(), minWidth: CodeWindow.MIN_WIDTH, minHeight: CodeWindow.MIN_HEIGHT, - show: !isFullscreenOrMaximized, + show: false, title: product.nameLong, webPreferences: { // By default if Code is in the background, intervals and timeouts get throttled, so we @@ -144,22 +136,22 @@ export class CodeWindow extends Disposable implements ICodeWindow { } }; - const windowConfig = this.configurationService.getValue('window'); - if (isLinux) { options.icon = path.join(this.environmentService.appRoot, 'resources/linux/code.png'); // Windows and Mac are better off using the embedded icon(s) // Make sure hardware acceleration is actually disabled. - options.transparent = windowConfig && windowConfig.transparent && app.getGPUFeatureStatus().gpu_compositing !== 'enabled'; - if (options.transparent) { - this.setTransparentInfo(options); - } + //options.transparent = windowConfig && windowConfig.transparent && app.getGPUFeatureStatus().gpu_compositing !== 'enabled'; + //if (options.transparent) { + // options.backgroundColor = '#00000000'; + //} } if (isMacintosh && !this.useNativeFullScreen()) { options.fullscreenable = false; // enables simple fullscreen mode } + const windowConfig = this.configurationService.getValue('window'); + if (isMacintosh) { options.acceptFirstMouse = true; // enabled by default @@ -182,19 +174,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } - if (isMacintosh && windowConfig && windowConfig.vibrancy && windowConfig.vibrancy !== 'none') { - this.setTransparentInfo(options); - options.vibrancy = windowConfig.vibrancy; - } - - const needsWinTransparency = - isWindows && windowConfig && windowConfig.compositionAttribute && - windowConfig.compositionAttribute !== 'none' && parseFloat(os.release()) >= 10 && - useCustomTitleStyle; - if (needsWinTransparency) { - this.setTransparentInfo(options); - } - // Create the browser window. this._win = new BrowserWindow(options); this._id = this._win.id; @@ -203,28 +182,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { this._win.setSheetOffset(22); // offset dialogs by the height of the custom title bar if we have any } - if (needsWinTransparency) { - const { ACCENT_STATE, SetWindowCompositionAttribute } = require.__$__nodeRequire('windows-swca'); - let attribValue = ACCENT_STATE.ACCENT_DISABLED; - switch (windowConfig.compositionAttribute) { - case 'acrylic': - // Fluent/acrylic flag was introduced in Windows 10 build 17063 (between FCU and April 2018 update) - if (parseInt(os.release().split('.')[2]) >= 17063) { - attribValue = ACCENT_STATE.ACCENT_ENABLE_ACRYLICBLURBEHIND; - } - break; - - case 'blur': - attribValue = ACCENT_STATE.ACCENT_ENABLE_BLURBEHIND; - break; - - case 'transparent': - attribValue = ACCENT_STATE.ACCENT_ENABLE_TRANSPARENTGRADIENT; - break; - } - - SetWindowCompositionAttribute(this._win.getNativeWindowHandle(), attribValue, 0); - } + this.applyTransparency(windowConfig); // TODO@Ben (Electron 4 regression): when running on multiple displays where the target display // to open the window has a larger resolution than the primary display, the window will not size @@ -244,19 +202,67 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } - if (isFullscreenOrMaximized) { + if (this.windowState.mode === WindowMode.Maximized) { this._win.maximize(); + } else if (this.windowState.mode === WindowMode.Fullscreen) { + this.setFullScreen(true); + } - if (this.windowState.mode === WindowMode.Fullscreen) { - this.setFullScreen(true); - } + // to reduce flicker from the default window size to maximize, we only show after maximize + // also prevents temporary background flash when transparency is set. + this._win.show(); + + this._lastFocusTime = Date.now(); // since we show directly, we need to set the last focus time too + } + + private setWindowsCompositionAttribute(attribute: 'acrylic' | 'blur' | 'transparent' | 'none'): void { + const { ACCENT_STATE, SetWindowCompositionAttribute } = require.__$__nodeRequire('windows-swca'); + let attribValue = ACCENT_STATE.ACCENT_DISABLED; + switch (attribute) { + case 'acrylic': + // Fluent/acrylic flag was introduced in Windows 10 build 17063 (between FCU and April 2018 update) + if (parseInt(os.release().split('.')[2]) >= 17063) { + attribValue = ACCENT_STATE.ACCENT_ENABLE_ACRYLICBLURBEHIND; + } + break; + + case 'blur': + attribValue = ACCENT_STATE.ACCENT_ENABLE_BLURBEHIND; + break; - if (!this._win.isVisible()) { - this._win.show(); // to reduce flicker from the default window size to maximize, we only show after maximize + case 'transparent': + attribValue = ACCENT_STATE.ACCENT_ENABLE_TRANSPARENTGRADIENT; + break; + } + + SetWindowCompositionAttribute(this._win.getNativeWindowHandle(), attribValue, 0); + } + + private applyTransparency(windowConfig: IWindowSettings): void { + let applied = false; + + if (windowConfig) { + if (isWindows && parseFloat(os.release()) >= 10) { + if (windowConfig.compositionAttribute && windowConfig.compositionAttribute !== 'none' && this.hasHiddenTitleBarStyle()) { + this.setWindowsCompositionAttribute(windowConfig.compositionAttribute); + applied = true; + } else { + this.setWindowsCompositionAttribute('none'); + } + } else if (isMacintosh && parseFloat(os.release()) >= 14) { + if (windowConfig.vibrancy && windowConfig.vibrancy !== 'none') { + this._win.setVibrancy(windowConfig.vibrancy); + applied = true; + } else { + // Documentation says to pass null to remove vibrancy but this is not reflected in the typings + this._win.setVibrancy(null as any); + } + } else if (isLinux) { + // TODO } } - this._lastFocusTime = Date.now(); // since we show directly, we need to set the last focus time too + this._win.setBackgroundColor(applied ? '#00000000' : this.themeMainService.getBackgroundColor()); } hasHiddenTitleBarStyle(): boolean { @@ -519,6 +525,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { this._win.removeAllListeners('swipe'); } } + + this.applyTransparency(this.configurationService.getValue('window')); } private registerNavigationListenerOn(command: 'swipe' | 'app-command', back: 'left' | 'browser-backward', forward: 'right' | 'browser-forward', acrossEditors: boolean) { diff --git a/src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts b/src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts index 90eca7a840046..833857482a4bd 100644 --- a/src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts +++ b/src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts @@ -15,7 +15,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { RunOnceScheduler } from 'vs/base/common/async'; import { URI } from 'vs/base/common/uri'; import { isEqual } from 'vs/base/common/resources'; -import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform'; +import { isLinux, isMacintosh } from 'vs/base/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; @@ -31,8 +31,6 @@ interface IConfiguration extends IWindowsConfiguration { export class SettingsChangeRelauncher extends Disposable implements IWorkbenchContribution { private transparent: boolean; - private compositionAttribute: 'none' | 'transparent' | 'blur' | 'acrylic'; - private vibrancy: 'none' | 'appearance-based' | 'light' | 'dark' | 'titlebar' | 'medium-light' | 'ultra-dark'; private titleBarStyle: 'native' | 'custom'; private nativeTabs: boolean; private nativeFullScreen: boolean; @@ -66,18 +64,6 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo changed = true; } - // Windows Composition Attribute - if (isWindows && config.window && config.window.compositionAttribute !== this.compositionAttribute) { - this.compositionAttribute = config.window.compositionAttribute; - changed = true; - } - - // macOS vibrancy - if (isMacintosh && config.window && config.window.vibrancy !== this.vibrancy) { - this.vibrancy = config.window.vibrancy; - changed = true; - } - // Titlebar style if (config.window && config.window.titleBarStyle !== this.titleBarStyle && (config.window.titleBarStyle === 'native' || config.window.titleBarStyle === 'custom')) { this.titleBarStyle = config.window.titleBarStyle; From 77f386e3e0728fd909933db7a4dd79c7a279542b Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Tue, 2 Jul 2019 19:25:12 -0400 Subject: [PATCH 19/19] Rename setWindowsCompositionAttribute --- src/vs/code/electron-main/window.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index d72c99cf2d6d6..f99e850c63347 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -215,7 +215,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { this._lastFocusTime = Date.now(); // since we show directly, we need to set the last focus time too } - private setWindowsCompositionAttribute(attribute: 'acrylic' | 'blur' | 'transparent' | 'none'): void { + private setCompositionAttribute(attribute: 'acrylic' | 'blur' | 'transparent' | 'none'): void { const { ACCENT_STATE, SetWindowCompositionAttribute } = require.__$__nodeRequire('windows-swca'); let attribValue = ACCENT_STATE.ACCENT_DISABLED; switch (attribute) { @@ -244,10 +244,10 @@ export class CodeWindow extends Disposable implements ICodeWindow { if (windowConfig) { if (isWindows && parseFloat(os.release()) >= 10) { if (windowConfig.compositionAttribute && windowConfig.compositionAttribute !== 'none' && this.hasHiddenTitleBarStyle()) { - this.setWindowsCompositionAttribute(windowConfig.compositionAttribute); + this.setCompositionAttribute(windowConfig.compositionAttribute); applied = true; } else { - this.setWindowsCompositionAttribute('none'); + this.setCompositionAttribute('none'); } } else if (isMacintosh && parseFloat(os.release()) >= 14) { if (windowConfig.vibrancy && windowConfig.vibrancy !== 'none') { @@ -262,6 +262,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } + // FIXME: on windows, background is pitchblack at startup until the user changes the composition attribute in settings this._win.setBackgroundColor(applied ? '#00000000' : this.themeMainService.getBackgroundColor()); }