microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
158.83k stars 27.77k forks source link

Allow for transparent / vibrant window theme #32257

Closed sergeysova closed 4 years ago

sergeysova commented 6 years ago

image

Maybe it can be enabled with { transparent: true, vibrancy: 'dark' } ?

https://github.com/electron/electron/pull/7898 — Vibrancy PR https://electron.atom.io/docs/api/frameless-window/#transparent-window

zmitry commented 6 years ago

Awesome

zbandhan commented 6 years ago

Is it possible to make activity bar slightly thin? However I love it

rianadon commented 6 years ago

This is amazing. I'm not sure if something like this would be able to achieved on Windows as well (it might just take a lot more effort than MacOS), but it would fit in with the new Fluent Design System.

bpasero commented 6 years ago

@LestaD do you have a working prototype of what you suggested via { transparent: true, vibrancy: 'dark' } ?

sergeysova commented 6 years ago

@bpasero I can try to make it

bpasero commented 6 years ago

@LestaD so far I was not able to use the vibrancy effect of Electron, could also be related to the fact that we are not on latest Electron.

sergeysova commented 6 years ago

@bpasero I enabled vibrancy in VSCode 1.15

wnd.setVibrancy('dark'):

image

wnd.setVibrancy('ultra-dark')

image

sergeysova commented 6 years ago
// Open devTools in any vscode window
wnds = electron.remote.BrowserWindow.getAllWindows()
win = new electron.remote.BrowserWindow({ width: 600, height: 500, frame: false, transparent: true, vibrancy: 'dark', show: false })

// with wnds[0].getURL() find any window with title != "Code"
source = wnds[1]

win.loadURL(source.getURL())
win.show()
// next open and undock DevTools
win.openDevTools()

Next with Elements tab add that style before </body>:

<style>
.monaco-shell, .monaco-workbench
{
  background-color: transparent !important;
}
</style>

Then uncheck background-color in next elements:

That it:

image

sergeysova commented 6 years ago

Dark

image

sergeysova commented 6 years ago

Ultra Dark

image

rianadon commented 6 years ago

I tried this on Windows and unfortunately it doesn't work (so Electron's API for this must still be supported on only MacOS). However I did find an npm package named electron-vibrancy that supports Windows 10 and got the following results:

image

I had to disable the window frame because the vibrancy effect doesn't play well with it, so if this were to be implemented for Windows too some kind of custom titlebar would need to be added. I think there's already an open issue for that.

I don't know if there's any way to get more of a blur like @LestaD's pictures which still look much better than I was able to get, but it's a step closer.

bpasero commented 6 years ago

@LestaD followed your steps and cannot make it work, care to open a PR for me to test it out? Do I need to enable something in macOS to see it?

sylveon commented 6 years ago

@rianadon that's because it's using the undocumented SetWindowCompositionAttribute function in Windows. No you can't have a higher blur radius. BTW what you suggest is missing shadows, and you can't resize it by grabbing the window borders because you used transparent: true.

Here's an example with Discord:

If you look near the Explorer window, you can see the shadow is still there. The window was created with the following options:

    var mainWindowOptions = {
      title: "Discord",
      backgroundColor: '#00000000',
      width: DEFAULT_WIDTH,
      height: DEFAULT_HEIGHT,
      minWidth: MIN_WIDTH,
      minHeight: MIN_HEIGHT,
      transparent: false,
      frame: false,
      resizable: true,
      show: isVisible,
      thickFrame: true,
      webPreferences: {
        blinkFeatures: "EnumerateDevices,AudioOutputDevices"
      }
    };

And SetWindowCompositionAttribute was called like this:

HWND hWnd = FindWindow("Chrome_WidgetWin_1", NULL);
ACCENTPOLICY policy = { 3, 2, 0xaa000000, 0 }; // ACCENT_ENABLE_BLURBEHIND=3
WINCOMPATTRDATA data = { 19, &policy, sizeof(ACCENTPOLICY) }; // WCA_ACCENT_POLICY=19
SetWindowCompositionAttribute(hWnd, &data);

So now after creating a window like this and calling the API, any zone of your app that is transparent will have the blur effect and you still keep the shadow and resize borders on the window. The only remaining matter would be implementing a titlebar and drag area (maximise, minimize and Aero Snap is handled by Windows, something that using transparent: true (which electron-vibrancy absolutely requires) would require us to implement it ourselves)

I think a custom way for Windows would be better than using electron-vibrancy. However it seems fine to use it on macOS. BTW vibrancy support is now in official electron, so might as well completely drop electron-vibrancy: https://github.com/electron/electron/pull/7898

rianadon commented 6 years ago

@sylveon My experiment was not a suggestion on the way VS Code should implement this; it was only to see if such a vibrancy effect was possible on Windows.

I used electron-vibrancy as my Electron and Windows API knowledge is quite limited. But as you said it has a few major shortcomings, so, should this be done well, using it wouldn't be a good idea.

I tried using options similar to what you suggested to get the effect with shadows, but for some reason the background of the window becomes solid black. I'm 99.9% sure I typed eight 0s.

What Electron version did you use (maybe this matters?), and would you mind sharing the rest of the code the options are from?

Thanks!

sylveon commented 6 years ago

Unfortunately since this is a modification of Discord (a closed-source program), sharing the source code would potentially lead me into trouble.

The background is solid black until you call SetWindowCompositionAttribute on it, only after it will become blurred:

gif

The program I used in my GIF comes from here: http://glass8.eu/files/SetWindowCompositionAttribute.7z

Electron version of my Discord is 1.4.12

BTW, if you want complete control of the blur's color via the application itself, use 0x00000000 (instead of 0xaa000000 or 0xdd000000) as the color for SetWindowCompositionAttribute then set the background color of your app via CSS/however you like. For example:

body {
    background-color: rgba(150, 0, 0, 0);
}
rianadon commented 6 years ago

Gotcha.

It turns out I set the opacity of some elements to 80% and the dark color of the blur combined with the opacity made everything look black.

Changing the blur color to 0x00000000 did the trick. However I still had to use 80% opacities to color the blur as setting the body background color to something with 0 opacity didn't change anything.

Thanks for the help. I'd still have to wait for one of the many Windows custom titlebar issues to reach a consensus to do any more with this though.

sylveon commented 6 years ago

Yeah a custom titlebar is required, because blur doesn't plays well with non-borderless windows:

image

rianadon commented 6 years ago

Since it seems it will take a while for a consensus to be reached on what kind of titlebar VS Code should have, I went with the Metro app style and incorporated the color that's shown on macOS currently (since I was modifying the existing macOS custom titlebar anyways):

image

@bpasero if this looks good I could write a PR for the titlebar on Windows. Or would it be better to wait for one of the designs in https://github.com/Microsoft/vscode/issues/17060 to be decided upon?

sylveon commented 6 years ago

Depending on how node-gyp is complex (I never used it), I could try getting a PR for blur on Windows working after that.

BTW @rianadon looks nice :)

rianadon commented 6 years ago

Thank you @sylveon!

easyaspi314 commented 6 years ago

Light

Light theme

Colors:
  • Active title bar: rgba(0, 0, 0, 0.1)
  • Activity Bar: rgba(0, 0, 0, 0.4)
  • Sidebar, Tab container: transparent
  • Inactive tab: rgba(255, 255, 255, 0.25) (not exactly sure how I feel about it though)


I like where this is headed!

I wouldn't use it though…but it sure looks nice. !["Kids these days and their thinking that they need 16 terabytes of RAM and a 32 GHz 1024-core processor."](https://user-images.githubusercontent.com/6258309/33911199-92006cc4-df5f-11e7-9484-b83d682a840a.png "\"Kids these days and their thinking that they need 16 terabytes of RAM and a 32 GHz 1024-core processor.\"")

sylveon commented 6 years ago

Looks a bit too transparent to me, I would be distracted as hell

patrys commented 6 years ago

I think this should follow the acrylic material guidelines: https://docs.microsoft.com/en-us/windows/uwp/design/style/acrylic

sylveon commented 6 years ago

Unfortunately, the Fluent transparency effect is not available for Win32 apps right now. Insider Build 17063 does have it, and I can use it fine on Terminus, another Electron app:

It also is buggy right now, so I'd wait for it to get more stable before trying anything. The fact it's only available on 17063 or higher means we would need to use the old blur effect on older versions (which is also still available in 17063). So in my opinion, which kind of effect should be a configuration option: simply transparent, old blur effect, new fluent effect and no transparency at all. This should please everyone.

patrys commented 6 years ago

@sylveon I'm aware that it's currently only officially exposed in the insiders build. I'm not sure it's worth implementing a workaround though as it seems the panel could easily remain solid on machines that don't support the new properties and it's quite possible that by the time this change is released in VS Code the platform API will already hit the stable channel.

sylveon commented 6 years ago

Changing the effect type is just changing the value of an enum, so it isn't really a workaround, just a configuration option. Also nothing is official or an API, the method used to reach this effect is undocumented and will probably remain so. Also Microsoft, if you're reading this, please document this/expose it in a documented API. The potential of it is awesome, and could easily gain a lot of users (AMD themselves are also relying on this undocumented stuff for their driver control panel)

rianadon commented 6 years ago

That fluent effect looks great @sylveon!

Both this effect and the pre-17063 use undocumented APIs, so as I see it there shouldn't be much difference between them. It should be easy enough to support both.

sylveon commented 6 years ago

Yeah, it's easy enough to support blur, fluent and regular transparency all at the same time. Just change the value of an enum between ACCENT_ENABLE_TRANSPARENTGRADIENT (just transparent), ACCENT_ENABLE_BLURBEHIND (old blur effect) and ACCENT_ENABLE_FLUENT (fluent effect) when applying the effect. If the user disables it, just apply ACCENT_DISABLED to return to normal effect-less behavior. See the pastebin I posted yesterday.

sylveon commented 6 years ago

👀

Now that I've got the base working, having it on macOS shouldn't be an issue. Instead of setting thickFrame to true and changing the composition attribute, set vibrancy and transparent to true. The rest should be completely platform-independent.

patrys commented 6 years ago

Windows design guidelines suggest having two panels set to 80% and 60%, would that work here for the action bar and the explorer pane?

sylveon commented 6 years ago

I haven't got node-gyp working, and I had issues with node-ffi. So this is still a hack, requiring me to run third party tools to set the composition attribute of the window.

Ideally, since it's just CSS rules, you would be able to configure opacity per-element.

sylveon commented 6 years ago

Good news: I've managed to develop a binding for the SetWindowCompositionAttribute API, and successfully use it in the VSCode codebase. When #39972 is merged, I would be able to send a PR adding the effects (because as I've shown earlier, it works only when non-stock titlebars are used)

sylveon commented 6 years ago

I've put up a working build here: https://github.com/sylveon/vscode/tree/transparency You can try the effect by changing the window.transparency setting. You still need to edit some CSS rules with the dev tools so that some parts of the GUI show the transparency effect (basically make it so that background-color is transparent all the way to the root <body>). I've got no idea if macOS works, it would be great if someone tests.

lucasqueiroz commented 6 years ago

@sylveon I can check on macOS next week

JamesLear92 commented 6 years ago

@sylveon I can't get this to compile no matter what! :'( Running w10 x64 17074 build, node v8.9.4, python 2.73

Seems to fail after [monaco.d.ts] Finished monaco.d.ts generation

sylveon commented 6 years ago

I'm not psychic yet, I can't read the error message on your screen.

Maybe you didn't ran "yarn", because I added a new dep.

2018-01-25 19:35 UTC−05:00, Omniusz notifications@github.com:

@sylveon I can't get this to compile no matter what! :'( Running w10 x64 17074 build, node v8.9.4, python 2.73

Seems to fail after [monaco.d.ts] Finished monaco.d.ts generation

-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/Microsoft/vscode/issues/32257#issuecomment-360647866

-- Envoyé de mon Gmail

sylveon commented 6 years ago

Looks like the build failed. Probably because windows-swca a hard dependency of window.ts but it only installs on Windows. Silly mistake from my part.

I'll fix that tomorrow. As for the build issue on Windows, I'd also need logs. Because it Works On My Machine™

2018-01-25 22:54 UTC−05:00, Lucas Queiroz notifications@github.com:

@sylveon I'm not being able to run it either, but on Ubuntu 17.10 I ran yarn successfully in the transparent branch, then ran yarn run watch to build, and in another terminal, after the build finished, I tried running ./scripts/code.sh, but then I get the following error:

{ errorCode: 'load',  moduleId: 'vs/code/electron-main/main',
  neededBy: [ '===anonymous1===' ],
  detail:
   { Error: ENOENT: no such file or directory, open
'/home/lucas/Documents/vscode/out/vs/code/electron-main/main.js'
     errno: -2,
     code: 'ENOENT',
     syscall: 'open',
     path: '/home/lucas/Documents/vscode/out/vs/code/electron-main/main.js'
} }

Then it just hangs in there forever...

-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/Microsoft/vscode/issues/32257#issuecomment-360677669

-- Envoyé de mon Gmail

lucasqueiroz commented 6 years ago

@sylveon I removed my comment because I thought it was a problem with something I did, but apparently not :P I haven't tried it on Windows yet though.

sylveon commented 6 years ago

@lucasqueiroz fixed now

lucasqueiroz commented 6 years ago

@sylveon It now launches the app but it's not transparent :/

sylveon commented 6 years ago

I do not know how to implement transparency on Linux, so I left it out for now. I do have a Arch install so I'll research that tomorrow.

sylveon commented 6 years ago

I did get it working on Linux: (the blur effect is done via the compositor here, outside of VS Code's control)

It has one major drawback however: you need, according to this, disable GPU acceleration and enable transparent visuals with two command line switches provided to Electron. I'm not sure if it's even possible to "set" those at runtime, when Electron and the Chromium engine are already done initializing.

lucasqueiroz commented 6 years ago

@sylveon where do I pass those switches? On the code.sh script, or when it starts up, I just type them and press enter? I'm a complete noob with electron, my bad.

JamesLear92 commented 6 years ago

@sylveon I got it to work in the end, but I needed to use npm 4.6.1 installed globally instead of 5.6.0.

While it seems to be working and is happy, I am getting a compile error with the following message:

"vscode/extensions/typescript/src/utils/api.ts(15,3): Type 'string | null' is not assignable to type 'string'."

I am running typescript 2.6.2. I have never coded in typescript so I'm not entirely sure what the issue is.

EDIT: While VSCode is up and running, transparency is not working, with this warning message: '"window.transparency" is an unknown configuration'

sylveon commented 6 years ago

Sorry for the late answer

@lucasqueiroz yeah to the code.sh script. Although it won't do much since I haven't checked in the code for Linux support yet. But for this to work automatically vscode would need a kind of system for the script to read those settings and apply the correct parameters. I'm pretty sure it can be done easily using jq, but that would require another external dependency for Linux machines (vscode depending on gvfs just to be able to delete items is already weird enough lol)

@Omniusz the contribution guide recommends yarn, try using that. As for your window.transparency issue, are you sure you checked out the transparency branch and not master?

JamesLear92 commented 6 years ago

@sylveon Cheers for getting back to me :) I completed the following steps in an elevated Powershell window:

At this stage, I have tried the following combinations:

and

and

and

There were a lot of other ways I tried to get this to work but alas no luck. While compiling I do notice the ""vscode/extensions/typescript/src/utils/api.ts(15,3): Type 'string | null' is not assignable to type 'string'."" error does occur.

This is more of a curiosity, since your implementation looks incredible. I appreicate any help you can give, but it's not vital that I run this.

I can compile the master branch fine though I might add.

sylveon commented 6 years ago

@Omniusz according to the wiki you need to use yarn for dependency resolution too.

The complete process looks like this:

git clone https://github.com/sylveon/vscode
cd vscode
git checkout transparency
yarn # Notice how here we used yarn to acquire the deps. You probably where missing some info from the yarn lockfile
yarn run watch

once it's done building, in another terminal:

.\scripts\code.bat
sylveon commented 6 years ago

@lucasqueiroz I've pushed commits that does not requires you to pass any flags. Hardware acceleration is now automatically disabled when you launch VSCode with the windows.transparency option set to transparent on Linux.

patrys commented 6 years ago

There's a popular UI theme for Atom using setVibrancy: https://github.com/fv0/native-ui

native-ui

JamesLear92 commented 6 years ago

@sylveon Hi, thanks for your help, I did get this running in the end :) I found that I could set the transparency in the user settings for everything except monaco-workbench windows