Merge pull request 'skel/hypr: GSK_RENDERER=cairo + wire up shell layer rules' (#7) from fix/gsk-renderer-black-surfaces into main
This commit is contained in:
commit
2b8eb2f1b6
2 changed files with 161 additions and 0 deletions
|
|
@ -63,6 +63,16 @@ end
|
|||
hl.window_rule({ name = "breadhelp", match = { class = "^(com\\.breadway\\.breadhelp)$" }, float = true, size = { 880, 600 } })
|
||||
hl.window_rule({ name = "bos-netsetup", match = { class = "^(bos-netsetup)$" }, float = true, size = { 700, 560 } })
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Layer-shell rules — blur / ignore-alpha / per-namespace motion for the
|
||||
-- bread shell (breadbar island + osd + notif + panel, breadbox launcher,
|
||||
-- breadclip popup). Theme-driven via ~/.config/hypr/layerrules.json (written
|
||||
-- by `bread-theme layerrules` in the bootstrap below), with a hardcoded
|
||||
-- fallback so a missing/broken theme file can never leave the shell
|
||||
-- unblurred. Without these the launcher and popups get no compositor blur.
|
||||
-- ---------------------------------------------------------------------------
|
||||
pcall(dofile, script_dir .. "ui/rules.lua")
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Environment (vendor-neutral; no GPU-specific vars so it works on Intel/AMD).
|
||||
-- ---------------------------------------------------------------------------
|
||||
|
|
@ -76,6 +86,15 @@ hl.env("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1")
|
|||
hl.env("SDL_VIDEODRIVER", "wayland")
|
||||
hl.env("ELECTRON_OZONE_PLATFORM_HINT", "auto")
|
||||
hl.env("_JAVA_AWT_WM_NONREPARENTING", "1")
|
||||
-- GTK4's default renderer (ngl/vulkan on GTK 4.14+) renders transparent
|
||||
-- layer-shell surfaces as opaque black on wlroots — the whole bread shell
|
||||
-- (breadbox launcher, breadclip popup, breadbar, breadhelp, bos-settings)
|
||||
-- goes black-on-black, and it's worse under a VM's virtio-gpu where no real
|
||||
-- GL/Vulkan context is available. cairo (software) always composites
|
||||
-- transparency correctly; the shell is flat colour/text/icons so there's no
|
||||
-- visible perf cost, and idle memory drops (~40%, no Mesa driver resident).
|
||||
-- Set GSK_RENDERER=gl in the session to override for a GPU-heavy GTK4 app.
|
||||
hl.env("GSK_RENDERER", "cairo")
|
||||
|
||||
-- Optional NVIDIA env from bos-nvidia-setup. Mesa machines have no file.
|
||||
-- bos-nvidia-setup: optional proprietary env; no-op when the file is absent
|
||||
|
|
@ -128,6 +147,12 @@ hl.on("hyprland.start", function()
|
|||
-- Generate the shared bread GUI stylesheet first, so breadbar/breadbox/
|
||||
-- bos-settings load it on start (they also live-reload if it changes).
|
||||
"bread-theme generate",
|
||||
-- Write ~/.config/hypr/layerrules.json from the active shell theme's
|
||||
-- [compositor] table. scripts/ui/rules.lua (loaded above) already ran
|
||||
-- with the hardcoded fallback; this refreshes the JSON for the next
|
||||
-- `hyprctl reload` / theme switch. Harmless if bread-theme lacks the
|
||||
-- verb on an older build.
|
||||
"sh -c 'bread-theme layerrules 2>/dev/null || true'",
|
||||
-- Global dark theme: GTK4/libadwaita + GTK3 theme + icon + cursor.
|
||||
"gsettings set org.gnome.desktop.interface color-scheme prefer-dark",
|
||||
"gsettings set org.gnome.desktop.interface gtk-theme Adwaita-dark",
|
||||
|
|
|
|||
136
iso/airootfs/etc/skel/.config/hypr/scripts/ui/rules.lua
Normal file
136
iso/airootfs/etc/skel/.config/hypr/scripts/ui/rules.lua
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
-- scripts/ui/rules.lua — layer-shell (compositor) rules for the bread shell.
|
||||
--
|
||||
-- Blur / ignore-alpha / per-namespace motion for breadbar (island + osd +
|
||||
-- notif + panel + dismiss), the breadbox launcher, and the breadclip popup.
|
||||
-- Window rules (float/centre for onboarding popups) live in hyprland.lua;
|
||||
-- this file is layer rules only.
|
||||
--
|
||||
-- Theme-driven (bos-ui-demos THEME_SYSTEM_PLAN.md §9): `bread-theme
|
||||
-- layerrules` writes ~/.config/hypr/layerrules.json from the active shell
|
||||
-- theme's [compositor] table — blur / ignore_alpha / blur_popups /
|
||||
-- animation / no_anim, keyed by layer-shell namespace. That table owns
|
||||
-- *appearance* only; placement / workspace / focus are never touched here.
|
||||
-- If the JSON is missing, unreadable, malformed, or anything goes wrong
|
||||
-- while parsing it, apply_hardcoded_layer_rules() runs instead — the exact
|
||||
-- set this file hardcoded before the theme system existed — so a broken or
|
||||
-- absent theme file can never disable compositor blur.
|
||||
|
||||
local LAYERRULES_JSON = os.getenv("HOME") .. "/.config/hypr/layerrules.json"
|
||||
|
||||
local function apply_hardcoded_layer_rules()
|
||||
hl.layer_rule({
|
||||
name = "breadbar-island",
|
||||
match = { namespace = "^breadbar$" },
|
||||
blur = true,
|
||||
ignore_alpha = 0.2,
|
||||
blur_popups = true,
|
||||
animation = "slide top",
|
||||
})
|
||||
|
||||
hl.layer_rule({
|
||||
name = "breadbar-osd",
|
||||
match = { namespace = "^breadbar-osd$" },
|
||||
blur = true,
|
||||
ignore_alpha = 0.2,
|
||||
animation = "slide bottom",
|
||||
})
|
||||
|
||||
hl.layer_rule({
|
||||
name = "breadbar-notif",
|
||||
match = { namespace = "^breadbar-notif$" },
|
||||
blur = true,
|
||||
ignore_alpha = 0.2,
|
||||
animation = "slide right",
|
||||
})
|
||||
|
||||
hl.layer_rule({
|
||||
name = "breadbar-panel",
|
||||
match = { namespace = "^breadbar-panel$" },
|
||||
blur = true,
|
||||
ignore_alpha = 0.2,
|
||||
animation = "slide right",
|
||||
})
|
||||
|
||||
hl.layer_rule({
|
||||
name = "breadbar-dismiss",
|
||||
match = { namespace = "^breadbar-dismiss$" },
|
||||
no_anim = true,
|
||||
})
|
||||
|
||||
hl.layer_rule({
|
||||
match = "breadbox",
|
||||
blur = true,
|
||||
ignore_alpha = 0.2,
|
||||
})
|
||||
end
|
||||
|
||||
-- Parses ~/.config/hypr/layerrules.json into a plain array of per-namespace
|
||||
-- rule tables, sorted by namespace for a deterministic emission order.
|
||||
-- Returns nil (not an error) for anything short of a well-formed, non-empty
|
||||
-- JSON object, so the pcall wrapping this only guards against a genuine Lua
|
||||
-- error (e.g. json.lua failing to load) rather than every malformed case.
|
||||
local function parsed_layer_rules()
|
||||
local json = dofile(os.getenv("HOME") .. "/.config/hypr/scripts/lib/json.lua")
|
||||
local parsed = json.load(LAYERRULES_JSON)
|
||||
if type(parsed) ~= "table" then
|
||||
return nil
|
||||
end
|
||||
|
||||
local namespaces = {}
|
||||
for ns, rule in pairs(parsed) do
|
||||
if type(ns) == "string" and type(rule) == "table" then
|
||||
namespaces[#namespaces + 1] = ns
|
||||
end
|
||||
end
|
||||
if #namespaces == 0 then
|
||||
return nil
|
||||
end
|
||||
table.sort(namespaces)
|
||||
|
||||
local rules = {}
|
||||
for _, ns in ipairs(namespaces) do
|
||||
local r = parsed[ns]
|
||||
rules[#rules + 1] = {
|
||||
namespace = ns,
|
||||
blur = r.blur == true,
|
||||
ignore_alpha = r.ignore_alpha,
|
||||
blur_popups = r.blur_popups == true,
|
||||
animation = r.animation,
|
||||
no_anim = r.no_anim == true,
|
||||
}
|
||||
end
|
||||
return rules
|
||||
end
|
||||
|
||||
-- Emits one hl.layer_rule per parsed namespace. Built as pure data by
|
||||
-- parsed_layer_rules() first (no hl.layer_rule calls during parsing), so a
|
||||
-- parse failure can never leave a partial JSON-derived rule set applied
|
||||
-- before the caller falls back to apply_hardcoded_layer_rules().
|
||||
local function apply_json_layer_rules(rules)
|
||||
for _, r in ipairs(rules) do
|
||||
hl.layer_rule({
|
||||
name = r.namespace,
|
||||
match = { namespace = "^" .. r.namespace .. "$" },
|
||||
blur = r.blur,
|
||||
ignore_alpha = r.ignore_alpha,
|
||||
blur_popups = r.blur_popups,
|
||||
animation = r.animation,
|
||||
no_anim = r.no_anim,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local ok, rules = pcall(parsed_layer_rules)
|
||||
if ok and rules then
|
||||
apply_json_layer_rules(rules)
|
||||
else
|
||||
apply_hardcoded_layer_rules()
|
||||
end
|
||||
|
||||
-- breadclip is not part of the shell theme's [compositor] table yet — always
|
||||
-- hardcoded, regardless of the JSON above.
|
||||
hl.layer_rule({
|
||||
match = "breadclip",
|
||||
blur = true,
|
||||
ignore_alpha = 0.0,
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue