Skip to content

Instantly share code, notes, and snippets.

@anthroid
Last active February 22, 2021 22:40
Show Gist options
  • Save anthroid/3df99d2e291db72cfeacefb874aa8a58 to your computer and use it in GitHub Desktop.
Save anthroid/3df99d2e291db72cfeacefb874aa8a58 to your computer and use it in GitHub Desktop.
Vibrancy patch for VS Code @ 11cd760 (macOS)
diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts
index 3ca7fa2b74..08dd8e8876 100644
--- a/src/vs/platform/windows/common/windows.ts
+++ b/src/vs/platform/windows/common/windows.ts
@@ -115,6 +115,7 @@ export interface IWindowSettings {
readonly closeWhenEmpty: boolean;
readonly clickThroughInactive: boolean;
readonly enableExperimentalMainProcessWorkspaceStorage: boolean;
+ readonly vibrancy: 'none' | 'appearance-based' | 'light' | 'dark' | 'titlebar' | 'medium-light' | 'ultra-dark' | 'content' | 'window';
}
export function getTitleBarStyle(configurationService: IConfigurationService): 'native' | 'custom' {
diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts
index a68581665d..898c59bda8 100644
--- a/src/vs/platform/windows/electron-main/window.ts
+++ b/src/vs/platform/windows/electron-main/window.ts
@@ -144,11 +144,14 @@ export class CodeWindow extends Disposable implements ICodeWindow {
minHeight: WindowMinimumSize.HEIGHT,
show: !isFullscreenOrMaximized,
title: product.nameLong,
+ transparent: true,
+ visualEffectState: 'active',
webPreferences: {
preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-browser/preload.js', require).fsPath,
v8CacheOptions: browserCodeLoadingCacheStrategy,
enableWebSQL: false,
- enableRemoteModule: false,
+ enableRemoteModule: true,
+ nodeIntegration: true,
spellcheck: false,
nativeWindowOpen: true,
webviewTag: true,
@@ -220,6 +223,8 @@ 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
}
+ this.applyTransparency(windowConfig);
+
// TODO@bpasero (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
// correctly unless we set the bounds again (https://github.com/microsoft/vscode/issues/74872)
@@ -271,6 +276,21 @@ export class CodeWindow extends Disposable implements ICodeWindow {
this.registerListeners();
}
+ private applyTransparency(windowConfig: IWindowSettings | undefined): void {
+ let applied = false;
+ if (windowConfig) {
+ if (isMacintosh && parseFloat(release()) >= 14) {
+ if (windowConfig.vibrancy && windowConfig.vibrancy !== 'none') {
+ this._win.setVibrancy(windowConfig.vibrancy);
+ applied = true;
+ } else {
+ this._win.setVibrancy(null as any);
+ }
+ }
+ }
+ this._win.setBackgroundColor(applied ? '#00000000' : this.themeMainService.getBackgroundColor());
+ }
+
private pendingLoadConfig: INativeWindowConfiguration | undefined;
private currentConfig: INativeWindowConfiguration | undefined;
@@ -684,6 +704,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
this.logService.trace(`Setting proxy to '${proxyRules}', bypassing '${proxyBypassRules}'`);
this._win.webContents.session.setProxy({ proxyRules, proxyBypassRules, pacScript: '' });
}
+
+ this.applyTransparency(this.configurationService.getValue<IWindowSettings>('window'));
}
addTabbedWindow(window: ICodeWindow): void {
diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts
index 3d56e920f1..1d24c87f49 100644
--- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts
+++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts
@@ -1858,18 +1858,18 @@ registerThemingParticipant((theme, collector) => {
// - if we have a contrast border (which draws an outline - https://github.com/microsoft/vscode/issues/109117)
// - on Safari (https://github.com/microsoft/vscode/issues/108996)
if (theme.type !== 'hc' && !isSafari && !activeContrastBorderColor) {
- 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);
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);
}
diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
index 52a1f2f459..1f94d3972e 100644
--- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
+++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
@@ -20,10 +20,10 @@ import { EditorResourceAccessor, Verbosity, SideBySideEditor } from 'vs/workbenc
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
-import { TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_BORDER, WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme';
+import { TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_BORDER } from 'vs/workbench/common/theme';
import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
-import { Color } from 'vs/base/common/color';
+import { Color, RGBA } from 'vs/base/common/color';
import { trim } from 'vs/base/common/strings';
import { EventType, EventHelper, Dimension, isAncestor, append, $, addDisposableListener, runAtThisOrScheduleAtNextAnimationFrame, prepend } from 'vs/base/browser/dom';
import { CustomMenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl';
@@ -429,7 +429,11 @@ export class TitlebarPart extends Part implements ITitleService {
// To benefit from LCD font rendering, we must ensure that we always set an
// opaque background color. As such, we compute an opaque color given we know
// the background color is the workbench background.
- return color.isOpaque() ? color : color.makeOpaque(WORKBENCH_BACKGROUND(theme));
+ if (color.isOpaque()) {
+ return color;
+ } else {
+ return new Color(new RGBA(color.rgba.r, color.rgba.g, color.rgba.b, 1));
+ }
}) || '';
this.element.style.backgroundColor = titleBackground;
diff --git a/src/vs/workbench/browser/style.ts b/src/vs/workbench/browser/style.ts
index 5028f89cc5..bf33b8d1a0 100644
--- a/src/vs/workbench/browser/style.ts
+++ b/src/vs/workbench/browser/style.ts
@@ -21,7 +21,7 @@ registerThemingParticipant((theme, collector) => {
}
// Background (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}; }`);
// Icon defaults
diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts
index 272f767d2e..4ec122a406 100644
--- a/src/vs/workbench/common/theme.ts
+++ b/src/vs/workbench/common/theme.ts
@@ -5,21 +5,15 @@
import { localize } from 'vs/nls';
import { registerColor, editorBackground, contrastBorder, transparent, editorWidgetBackground, textLinkForeground, lighten, darken, focusBorder, activeContrastBorder, editorWidgetForeground, editorErrorForeground, editorWarningForeground, editorInfoForeground, treeIndentGuidesStroke, errorForeground } from 'vs/platform/theme/common/colorRegistry';
-import { IColorTheme } from 'vs/platform/theme/common/themeService';
import { Color } from 'vs/base/common/color';
-// < --- Workbench (not customizable) --- >
-
-export function WORKBENCH_BACKGROUND(theme: IColorTheme): 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'
+}, localize('workbenchBackground', "Top-level background color. Not seen unless other elements have a transparent color."));
// < --- Tabs --- >
diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts
index 9b83bc6107..551101ba98 100644
--- a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts
+++ b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts
@@ -25,6 +25,7 @@ import { registerThemingParticipant, IColorTheme, ICssStyleCollector } from 'vs/
import { foreground, listActiveSelectionForeground, listActiveSelectionBackground, listInactiveSelectionForeground, listInactiveSelectionBackground, listFocusForeground, listFocusBackground, listHoverForeground, listHoverBackground } from 'vs/platform/theme/common/colorRegistry';
import { WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
+import { Color } from 'vs/base/common/color';
export const EXTENSION_LIST_ELEMENT_HEIGHT = 62;
@@ -232,16 +233,19 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
const foregroundColor = theme.getColor(foreground);
+ let workbenchBackground = theme.getColor(WORKBENCH_BACKGROUND);
+ if (workbenchBackground === undefined) {
+ workbenchBackground = Color.fromHex('#000000');
+ }
if (foregroundColor) {
- const authorForeground = foregroundColor.transparent(.9).makeOpaque(WORKBENCH_BACKGROUND(theme));
+ const authorForeground = foregroundColor.transparent(.9).makeOpaque(workbenchBackground);
collector.addRule(`.extensions-list .monaco-list .monaco-list-row:not(.disabled) .author { color: ${authorForeground}; }`);
- const disabledExtensionForeground = foregroundColor.transparent(.5).makeOpaque(WORKBENCH_BACKGROUND(theme));
+ const disabledExtensionForeground = foregroundColor.transparent(.5).makeOpaque(workbenchBackground);
collector.addRule(`.extensions-list .monaco-list .monaco-list-row.disabled { color: ${disabledExtensionForeground}; }`);
}
-
const listActiveSelectionForegroundColor = theme.getColor(listActiveSelectionForeground);
if (listActiveSelectionForegroundColor) {
- const backgroundColor = theme.getColor(listActiveSelectionBackground) || WORKBENCH_BACKGROUND(theme);
+ const backgroundColor = theme.getColor(listActiveSelectionBackground) || workbenchBackground;
const authorForeground = listActiveSelectionForegroundColor.transparent(.9).makeOpaque(backgroundColor);
collector.addRule(`.extensions-list .monaco-list:focus .monaco-list-row:not(.disabled).focused.selected .author { color: ${authorForeground}; }`);
collector.addRule(`.extensions-list .monaco-list:focus .monaco-list-row:not(.disabled).selected .author { color: ${authorForeground}; }`);
@@ -252,7 +256,7 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
const listInactiveSelectionForegroundColor = theme.getColor(listInactiveSelectionForeground);
if (listInactiveSelectionForegroundColor) {
- const backgroundColor = theme.getColor(listInactiveSelectionBackground) || WORKBENCH_BACKGROUND(theme);
+ const backgroundColor = theme.getColor(listInactiveSelectionBackground) || workbenchBackground;
const authorForeground = listInactiveSelectionForegroundColor.transparent(.9).makeOpaque(backgroundColor);
collector.addRule(`.extensions-list .monaco-list .monaco-list-row:not(.disabled).selected .author { color: ${authorForeground}; }`);
const disabledExtensionForeground = listInactiveSelectionForegroundColor.transparent(.5).makeOpaque(backgroundColor);
@@ -261,7 +265,7 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
const listFocusForegroundColor = theme.getColor(listFocusForeground);
if (listFocusForegroundColor) {
- const backgroundColor = theme.getColor(listFocusBackground) || WORKBENCH_BACKGROUND(theme);
+ const backgroundColor = theme.getColor(listFocusBackground) || workbenchBackground;
const authorForeground = listFocusForegroundColor.transparent(.9).makeOpaque(backgroundColor);
collector.addRule(`.extensions-list .monaco-list:focus .monaco-list-row:not(.disabled).focused .author { color: ${authorForeground}; }`);
const disabledExtensionForeground = listFocusForegroundColor.transparent(.5).makeOpaque(backgroundColor);
@@ -270,7 +274,7 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
const listHoverForegroundColor = theme.getColor(listHoverForeground);
if (listHoverForegroundColor) {
- const backgroundColor = theme.getColor(listHoverBackground) || WORKBENCH_BACKGROUND(theme);
+ const backgroundColor = theme.getColor(listHoverBackground) || workbenchBackground;
const authorForeground = listHoverForegroundColor.transparent(.9).makeOpaque(backgroundColor);
collector.addRule(`.extensions-list .monaco-list .monaco-list-row:hover:not(.disabled):not(.selected):.not(.focused) .author { color: ${authorForeground}; }`);
const disabledExtensionForeground = listHoverForegroundColor.transparent(.5).makeOpaque(backgroundColor);
diff --git a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts
index 04fd316a86..100fc5b35f 100644
--- a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts
+++ b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts
@@ -1171,8 +1171,12 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
collector.addRule(`.keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list:not(.focused) .monaco-list-row.focused.odd:not(.selected):not(:hover) { background-color: ${oddRowBackgroundColor}; }`);
const foregroundColor = theme.getColor(foreground);
+ let workbenchBackground = theme.getColor(WORKBENCH_BACKGROUND);
+ if (workbenchBackground === undefined) {
+ workbenchBackground = Color.fromHex('#000000');
+ }
if (foregroundColor) {
- const whenForegroundColor = foregroundColor.transparent(.8).makeOpaque(WORKBENCH_BACKGROUND(theme));
+ const whenForegroundColor = foregroundColor.transparent(.8).makeOpaque(workbenchBackground);
collector.addRule(`.keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list-row > .column > .code { color: ${whenForegroundColor}; }`);
const whenForegroundColorForOddRow = foregroundColor.transparent(.8).makeOpaque(oddRowBackgroundColor);
collector.addRule(`.keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list-row.odd > .column > .code { color: ${whenForegroundColorForOddRow}; }`);
diff --git a/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts
index db5f64070d..f2fed73c78 100644
--- a/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts
+++ b/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts
@@ -111,9 +111,11 @@ class PartsSplash {
this._lastBackground = colorInfo.editorBackground;
// the color needs to be in hex
- const backgroundColor = this._themeService.getColorTheme().getColor(editorBackground) || themes.WORKBENCH_BACKGROUND(this._themeService.getColorTheme());
- const payload = JSON.stringify({ baseTheme, background: Color.Format.CSS.formatHex(backgroundColor) });
- ipcRenderer.send('vscode:changeColorTheme', this._nativeHostService.windowId, payload);
+ const backgroundColor = this._themeService.getColorTheme().getColor(editorBackground) || this._themeService.getColorTheme().getColor(themes.WORKBENCH_BACKGROUND);
+ if (backgroundColor) {
+ const payload = JSON.stringify({ baseTheme, background: Color.Format.CSS.formatHex(backgroundColor) });
+ ipcRenderer.send('vscode:changeColorTheme', this._nativeHostService.windowId, payload);
+ }
}
}
diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
index cbbab36147..b931af4457 100644
--- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
+++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
@@ -418,7 +418,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
fastScrollSensitivity: editorOptions.fastScrollSensitivity,
scrollSensitivity: editorOptions.mouseWheelScrollSensitivity,
rendererType: config.rendererType === 'auto' || config.rendererType === 'experimentalWebgl' ? 'canvas' : config.rendererType,
- wordSeparator: config.wordSeparators
+ wordSeparator: config.wordSeparators,
+ allowTransparency: true
});
this._xterm = xterm;
this._xtermCore = (xterm as any)._core as XTermCore;
diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts
index 1b1971fd14..b5b3fbaa85 100644
--- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts
+++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts
@@ -279,6 +279,14 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
'default': false,
'scope': ConfigurationScope.APPLICATION,
'description': localize('window.localize', "Enables workspace storage access from the main process. Requires a restart to take effect."),
+ },
+ 'window.vibrancy': {
+ 'type': 'string',
+ 'enum': ['none', 'appearance-based', 'light', 'dark', 'titlebar', 'medium-light', 'ultra-dark', 'content', 'window'],
+ 'default': 'none',
+ 'scope': ConfigurationScope.APPLICATION,
+ 'description': localize('window.vibrancy', "Makes window transparent.\nDefine `workbench.background` in theme or color customizations to affect appearance."),
+ 'included': isMacintosh
}
}
});
@anthroid
Copy link
Author

To apply:

  1. Clone microsoft/vscode (ideally reset to commit 11cd760 to avoid any conflicts).
  2. Copy this vibrancy.patch file to the root of the cloned repository: cp /path/to/vibrancy.patch /path/to/cloned/vscode
  3. Apply the patch: git apply vibrancy.patch
  4. Install the dependencies, build, and run per the instructions
  5. Important: In your settings.json, add the following line: "window.vibrancy": "dark"
  6. Important: Your theme (or workbench.colorCustomizations) must set the workbench.background color. For example, for maximum root window transparency, set workbench.background to #00000000 (8 zeros)
  7. Important: Your theme (or workbench.colorCustomizations) must set transparency for the elements that should be transparent, or they will be opaque. So for example, set sideBar.background to #202020C0.
  8. You can set elements individually and leave editor.background fully opaque if you prefer a fully opaque editor and transparent sidebar.

@anthroid
Copy link
Author

Example workbench.colorCustomizations entry for the Dark+ (default dark) theme here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment