cssnode.jselectrontransparentblur

How do I blur an electron BrowserWindow with transparency


Question

Is it possible to make a BrowserWindow, in electron, transparent with blur? In that it blurs all background content, including apps and the wallpaper.

And if possible, how would I accomplish this?

Examples

Here are some code I've tried.
index.js:

let win = new BrowserWindow({
    fullscreen: true,
    fullscreenable: false,
    frame: false,
    skipTaskbar: true,
    resizable: false,
    movable: false,
    show: false,
    alwaysOnTop: true,
    transparent: true
})

style.css:

html, body {
    width: 100vw;
    height: 100vh;
    margin: 0;
    padding: 0;
    background-color: rgba(0, 0, 0, 0.5);
    color: rgb(255, 255, 255);
    backdrop-filter: blur(4px);
}

The html is just a body with a h1 tag with text in it.
Although this only creates a black background in the window.

I read something about this:

webPreferences: {
    experimentalFeatures: true
}

But can't get it to work.

Environment

I have compton running. Maybey it has to do with that. Or the compositing engine in general?

Thanks in advance!


Solution

  • electron-acrylic-window

    Actually, it is possible, with a little bit of magic. I have no idea why nobody pointed that out, but there exists a small utility called electron-acrylic-window, which allows you to do exactly that. You can choose between the acrylic ("frosted") and blur effects, as well as change the color of the window and the opacity.

    Under the hood, it uses node-gyp and low-level C++ code to render the page however you like. It's pretty easy to implement in JavaScript.

    Drawbacks

    Sample usage

    index.js

    import { BrowserWindow } from 'electron-acrylic-window'; // ESM
    // const { BrowserWindow } = require('electron-acrylic-window'); // CommonJS
    
    const win = new BrowserWindow({
        ...,
        frame: false,
        vibrancy: {
            theme: 'light', // (default) or 'dark' or '#rrggbbaa'
            effect: 'acrylic', // (default) or 'blur'
            disableOnBlur: true, // (default)
        }
    });
    
    // alternatively use these to
    // dynamically change vibrancy
    win.setVibrancy([options])
    // or
    setVibrancy(win, [options])
    

    style.css

    body {
        background-color: transparent;
    }
    
    .foo {
        background-color: black;
    }