Skip to content

hyprnux/hyprglass

Repository files navigation

HyprGlass - Liquid Glass inspired plugin for Hyprland

Liquid Glass for Hyprland.

Frosted blur, edge refraction, chromatic aberration, specular highlights — fully customizable, per-theme, on every window and layer surface.

Dark Light
Dark theme Light theme

Installation

hyprpm (recommended)

Builds against your exact Hyprland version, no ABI mismatch headaches:

hyprpm add https://github.com/hyprnux/hyprglass
hyprpm enable hyprglass

Pre-built release

Grab hyprglass.so from Releases. Each release targets a specific Hyprland API version — check the release notes to confirm it matches yours.

hyprctl plugin load /path/to/hyprglass.so

Or persist it in your config:

plugin = /path/to/hyprglass.so

Manual build

make
hyprctl plugin load $(pwd)/hyprglass.so

Configuration

Lua config

The plugin must be loaded before configuring it. Wrap everything in a guard:

if hl.plugin.hyprglass then
    local hg = hl.plugin.hyprglass

    hg.config({
        default_theme = "dark",
        default_preset = "clear",
        tint_color = 0x8899aa22,

        brightness = 0.9,
        dark = { brightness = 0.82 },
        light = { adaptive_boost = 0.5 },

        layers = { enabled = 1 },
    })

    -- Layer surfaces: each call whitelists the namespace and configures it
    hg.layer("waybar", { preset = "subtle", mask_threshold = 0.05 })
    hg.layer("swaync")
    hg.layer("quickshell:bezel", { preset = "ui", mask_threshold = 0.3 })
    hg.layer("debug-panel", { exclude = true })

    -- Presets
    hg.preset("clear", {
        glass_opacity = 0.8,
        blur_strength = 1.5,
        dark = { brightness = 0.7 },
        light = { brightness = 1.2 },
    })

    hg.preset("contrasted", {
        inherits = "high_contrast",
        contrast = 1.2,
        adaptive_dim = 1.5,
        dark = { tint_color = 0x02142aa9 },
    })
end

Legacy .conf config

Deprecated as of Hyprland 0.55, but still supported.

plugin:hyprglass {
    default_theme = dark
    default_preset = clear
    tint_color = 0x8899aa22

    brightness = 0.9
    dark:brightness = 0.82
    light:adaptive_boost = 0.5

    preset = name:clear, glass_opacity:0.8, blur_strength:1.5
    preset = name:clear:dark, brightness:0.7
    preset = name:clear:light, brightness:1.2

    preset = name:contrasted, inherits:high_contrast, contrast:1.2, adaptive_dim:1.5
    preset = name:contrasted:dark, tint_color:0x02142aa9

    layers {
        enabled = 1
        namespaces = waybar, swaync, quickshell:bezel
        exclude_namespaces = debug-panel
        preset = subtle
        namespace_presets = quickshell:bezel:ui
        namespace_mask_thresholds = waybar=0.05, quickshell:bezel=0.3
    }
}

Global settings

Option Type Default Description
enabled bool true (1 in .conf) Enable/disable the effect globally. Per-window tags override this.
default_theme string dark Default theme: dark or light
default_preset string default Default preset name

Overridable settings

Set globally, per theme (dark: / light: prefix in .conf, or dark = {} / light = {} table in Lua), or in a preset.

Settings resolve through: preset chain (theme variant, shared, inherited) then theme override then global value then hardcoded default.

Option Type Global Default Dark Default Light Default Description
blur_strength float 2.0 Blur radius scale (value * 12.0 px)
blur_iterations int 3 Gaussian blur passes (1-5)
refraction_strength float 0.6 Edge refraction intensity (0.0-1.0)
chromatic_aberration float 0.5 Spectral dispersion at edges (0.0-1.0)
fresnel_strength float 0.6 Edge glow intensity (0.0-1.0)
specular_strength float 0.8 Specular highlight brightness (0.0-1.0)
glass_opacity float 1.0 Overall glass opacity (0.0-1.0)
edge_thickness float 0.06 Bezel width, fraction of smallest dimension (0.0-0.15)
tint_color color 0x8899aa22 Glass tint RRGGBBAA hex. Alpha = tint strength
lens_distortion float 0.5 Center dome magnification (0.0-1.0)
brightness float 0.82 1.12 Brightness multiplier
contrast float 0.90 0.92 Contrast around midpoint
saturation float 0.80 0.85 Desaturation (0 = grayscale, 1 = full)
vibrancy float 0.15 0.12 Selective saturation boost
vibrancy_darkness float 0.0 0.0 Vibrancy influence on dark areas (0-1)
adaptive_dim float 0.4 0.0 Dims bright areas behind the glass (white is white 0 -to- 1 white becomes black)
adaptive_boost float 0.0 0.4 Boosts dark areas behind the glass (black is black 0 -to- 1 black becomes white)

in Global Default = falls through to per-theme default. in Dark/Light = inherits global value.

Layer surfaces

The glass effect can be applied to layer surfaces (bars, docks, widgets). Disabled by default.

The effect uses the layer surface opacity as a mask:

  • Partially transparent content (down to ~0.004 opacity) triggers the glass effect
  • Fully transparent areas are ignored

Caveat: Layer shadows count as visible content. Use mask_threshold to set an alpha cutoff higher than your shadow opacity.

Lua config

hg.config({ layers = { enabled = true } })

-- Each call whitelists the namespace and optionally configures it
hg.layer("waybar", { preset = "subtle", mask_threshold = 0.05 })
hg.layer("swaync")
hg.layer("quickshell:bezel", { preset = "ui", mask_threshold = 0.3 })
hg.layer("debug-panel", { exclude = true })
Field Type Description
preset string Preset override for this layer
mask_threshold float Alpha threshold (pixels below this are not glassed). Default 0.001
exclude bool Blacklist this namespace instead of whitelisting it

Legacy .conf config

Option Type Default Description
layers:enabled bool false (0 in .conf) Enable glass on layer surfaces
layers:namespaces string "" Comma-separated namespace whitelist. Empty = all layers
layers:exclude_namespaces string "" Comma-separated namespace blacklist (priority over whitelist)
layers:preset string "" Preset override for all layers
layers:namespace_presets string "" Per-namespace preset (ns:preset pairs, comma-separated)
layers:namespace_mask_thresholds string "" Per-namespace alpha threshold (ns=value pairs, comma-separated)

Layer support hooks into Hyprland's internal render pipeline. This is version-sensitive and may break across Hyprland updates.

Per-window overrides

Control the effect, theme, and preset per window via tags.

Enable / disable

Override the global enabled setting per window via tags:

  • hyprglass_disabled — force the effect off on this window (wins over hyprglass_enabled if both present).
  • hyprglass_enabled — force the effect on this window. Useful with global enabled = false for a whitelist.

Theme

Each window's theme is resolved as:

  1. Window tag hyprglass_theme_light or hyprglass_theme_dark
  2. Fallback to default_theme

Preset

Assign via window rules:

  • hyprglass_preset_<name> — override default_preset for this window

Examples

Lua:

hl.window_rule({ match = { class = "mpv" },       tag = "+hyprglass_disabled" })
hl.window_rule({ match = { fullscreen = true },    tag = "+hyprglass_disabled" })
hl.window_rule({ match = { class = "firefox" },    tag = "+hyprglass_theme_light" })
hl.window_rule({ match = { class = "myterminal" }, tag = "+hyprglass_preset_high_contrast" })

Legacy .conf:

windowrule = tag +hyprglass_disabled, class:mpv
windowrule = tag +hyprglass_disabled, fullscreen:1
windowrule = tag +hyprglass_theme_light, class:firefox
windowrule = tag +hyprglass_preset_high_contrast, class:myterminal

On the fly:

hyprctl dispatch tagwindow +hyprglass_disabled
hyprctl dispatch tagwindow +hyprglass_theme_dark
hyprctl dispatch tagwindow +hyprglass_preset_subtle

Presets

Presets are named config overrides. They can be built-in or user-defined. User presets with the same name override built-in ones.

Each preset can have shared values (theme-agnostic), a dark variant, a light variant, and can inherit from another preset.

Built-in presets

Always available. Activate via default_preset or per-window tags.

Preset Description
high_contrast Punchy colors, strong tinting, good contrast between dark and light themes. Lower blur, stronger refraction.
subtle Minimal glass effect. Light blur, reduced refraction and highlights.
clear Minimal transparent effect. Like a transparent rounded border glass plate.
glass Solid glass block effect with a lot of chromatic aberration.

Note: These presets are starting points. Submit improvements or your own presets through issues or PRs (with screenshots).

User-defined presets

Lua (table syntax):

hg.preset("clear", {
    glass_opacity = 0.8,
    blur_strength = 1.5,
    inherits = "subtle",
    dark = { brightness = 0.7 },
    light = { brightness = 1.2 },
})

Lua (string syntax, backward compat):

hg.preset("name:clear, glass_opacity:0.8, blur_strength:1.5")
hg.preset("name:clear:dark, brightness:0.7")

Legacy .conf:

preset = name:clear, glass_opacity:0.8, blur_strength:1.5
preset = name:clear:dark, brightness:0.7
preset = name:clear:light, brightness:1.2
preset = name:contrasted, inherits:high_contrast, contrast:1.2

Tip: increase the last two hex digits of tint_color for more tint opacity.

How It Works

The window/layer is modeled as a thick convex glass slab. The rendering pipeline per window:

  1. Background sampling — The framebuffer behind the window is captured with padding (content beyond the window boundary is included).
  2. Gaussian blur — Multi-pass two-pass (horizontal + vertical) Gaussian blur for the frosted look.
  3. Glass height field — An SDF-based height profile: 1.0 deep inside the window, smooth S-curve to 0.0 at the edge. The transition width is edge_thickness.
  4. Edge refraction — The height field gradient drives UV displacement. At the center the gradient is near-zero (no distortion). At the edges the gradient is steep, pushing sample UVs outward — pulling in content from beyond the window boundary. This creates natural color bleeding.
  5. Chromatic aberration — R, G, B channels are sampled with slightly different refraction scales (blue bends more), creating spectral fringing at edges.
  6. Center dome lens — Subtle barrel magnification in the flat interior, controlled by lens_distortion.
  7. Frosted tint — Per-theme tone mapping: adaptive luminance-dependent brightness, contrast, desaturation, and vibrancy applied to the blurred background.
  8. Color tint overlay — Configurable color tint.
  9. Fresnel edge glow — Schlick-based fresnel approximation at the glass edge.
  10. Specular highlight + inner shadow — Top-biased highlight and bottom-rim shadow for depth.

For windows, the plugin integrates with Hyprland's render pass system as a DECORATION_LAYER_BOTTOM decoration, drawing before the window surface so the glass shows through transparent windows. For layer surfaces, the plugin hooks renderLayer and uses a temp FBO redirect: the background is sampled and blurred, then Hyprland's surface rendering is redirected into a transparent temporary framebuffer to capture the surface's exact alpha. A post-surface pass then composites the glass effect (masked to visible content only) and the surface content back onto the main framebuffer in a single shader pass.

Unloading

hyprctl plugin unload /path/to/hyprglass.so

Notes

  • The plugin requires Hyprland shadows to be present in the render pipeline. It auto-enables them at load time if disabled — shadow visual values (range, color…) can be zero, only the decoration's presence matters.
  • Layer surface glass uses a function hook on renderLayer, which is a private Hyprland internal. The hook may break on Hyprland updates that change this function's signature.

License

See repository for license details.

About

Hyprland plugin that add blur, lens, difraction, refraction effects to transparent windows. Inspired by Liquid Glass design

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors