Make application transparency opt-in (#14253)
* Make application transparency opt-in * Use the transparency helper for Kanagawa * Address transparency review findings * Toggle transparency for opaque windows too
This commit is contained in:
1 parent
6520ac7d25
commit
54e3b53b88
19 files changed
+55
-62
No files matched your search
@@ -2,6 +2,18 @@
|
||||
|
||||
# omarchy:summary=Toggles transparency for the currently focused window.
|
||||
|
||||
addr=$(hyprctl activewindow -j | jq -r '.address')
|
||||
hyprctl dispatch "hl.dsp.window.set_prop({ window = \"address:$addr\", prop = \"opaque\", value = \"toggle\" })" >/dev/null 2>&1 || \
|
||||
hyprctl dispatch setprop "address:$addr" opaque toggle
|
||||
set -euo pipefail
|
||||
|
||||
addr=$(hyprctl activewindow -j | jq -r '.address // empty')
|
||||
[[ -n $addr ]] || exit 0
|
||||
|
||||
window="address:$addr"
|
||||
opacity=$(hyprctl getprop "$window" opacity)
|
||||
inactive_opacity=$(hyprctl getprop "$window" opacity_inactive)
|
||||
|
||||
if [[ $opacity == "1" && $inactive_opacity == "1" ]]; then
|
||||
hyprctl dispatch "hl.dsp.window.tag({ window = \"$window\", tag = \"+transparent\" })"
|
||||
hyprctl dispatch "hl.dsp.window.set_prop({ window = \"$window\", prop = \"opaque\", value = \"false\" })"
|
||||
else
|
||||
hyprctl dispatch "hl.dsp.window.set_prop({ window = \"$window\", prop = \"opaque\", value = \"toggle\" })"
|
||||
fi
|
||||
@@ -1,5 +1,10 @@
|
||||
-- Change the default Omarchy look'n'feel.
|
||||
|
||||
-- Opt another application in to Omarchy's standard transparency.
|
||||
-- Find its class with: hyprctl clients
|
||||
-- o.transparent_window("my-app")
|
||||
-- o.transparent_window("my-app", "0.9 0.85") -- Custom active/inactive opacity.
|
||||
|
||||
-- https://wiki.hypr.land/Configuring/Basics/Variables/#general
|
||||
-- hl.config({
|
||||
-- general = {
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
-- Browser tags and styling.
|
||||
o.window("((google-)?[cC]hrom(e|ium)|[bB]rave-browser|[mM]icrosoft-edge|Vivaldi-stable|helium)", { tag = "+chromium-based-browser" })
|
||||
o.window("([fF]irefox|zen|librewolf)", { tag = "+firefox-based-browser" })
|
||||
o.window({ tag = "chromium-based-browser" }, { tag = "-default-opacity", tile = true, opacity = "1.0 0.985" })
|
||||
o.window({ tag = "firefox-based-browser" }, { tag = "-default-opacity", opacity = "1.0 0.985" })
|
||||
o.window({ tag = "chromium-based-browser" }, { tile = true })
|
||||
|
||||
-- Video apps: remove chromium browser tag so they don't get opacity applied.
|
||||
-- Video apps: remove the chromium browser tag so they can float.
|
||||
o.window("(^.+-youtube\\.com__.*$|^.+-app\\.zoom\\.us__wc_home.*$)", { tag = "-chromium-based-browser" })
|
||||
o.window("(^.+-youtube\\.com__.*$|^.+-app\\.zoom\\.us__wc_home.*$)", { tag = "-default-opacity" })
|
||||
|
||||
-- Hide screen sharing notification windows.
|
||||
o.window({ title = ".*is sharing.*" }, { workspace = "special silent" })
|
||||
@@ -1,12 +1,9 @@
|
||||
-- DaVinci Resolve window focus handling. Kept fully opaque: the default
|
||||
-- translucency distorts colour-critical grading work.
|
||||
-- DaVinci Resolve window focus handling.
|
||||
o.window(".*[Rr]esolve.*", {
|
||||
float = true,
|
||||
stay_focused = true,
|
||||
-- Prevent modal dialog pointer warps when focus follows the mouse.
|
||||
no_follow_mouse = true,
|
||||
tag = "-default-opacity",
|
||||
opacity = "1 1",
|
||||
})
|
||||
|
||||
o.window({ class = ".*[Rr]esolve.*", title = "^DaVinci Resolve( Studio)? - .+$" }, { fullscreen = true })
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
-- Hermes Desktop's frameless HUD manages its own geometry.
|
||||
o.window({ class = "^Hermes$", title = "^Hermes HUD$" }, {
|
||||
tag = "-default-opacity",
|
||||
float = true,
|
||||
border_size = 0,
|
||||
opacity = "1 1",
|
||||
})
|
||||
@@ -1,3 +1,5 @@
|
||||
-- Float LocalSend and fzf file picker.
|
||||
o.window("(Share|localsend)", { float = true, center = true })
|
||||
o.window("localsend", { size = { 1100, 700 } })
|
||||
local localsend = "(org\\.localsend\\.)?localsend(_app)?"
|
||||
o.window("Share", { float = true, center = true })
|
||||
o.window(localsend, { float = true, center = true, size = { 1100, 700 } })
|
||||
o.transparent_window(localsend)
|
||||
@@ -1,24 +1,20 @@
|
||||
-- Picture-in-picture overlays.
|
||||
o.window({ title = "(Picture.?in.?[Pp]icture)" }, { tag = "+pip" })
|
||||
o.window({ tag = "pip" }, {
|
||||
tag = "-default-opacity",
|
||||
float = true,
|
||||
pin = true,
|
||||
size = { 600, 338 },
|
||||
keep_aspect_ratio = true,
|
||||
border_size = 0,
|
||||
opacity = "1 1",
|
||||
move = { "(monitor_w-window_w-40)", "(monitor_h*0.04)" },
|
||||
})
|
||||
|
||||
-- Google Meet PiP uses the meeting title instead of "Picture-in-Picture".
|
||||
o.window({ tag = "chromium-based-browser", title = "^Meet - .+" }, {
|
||||
tag = "-default-opacity",
|
||||
float = true,
|
||||
pin = true,
|
||||
size = { 600, 338 },
|
||||
keep_aspect_ratio = true,
|
||||
border_size = 0,
|
||||
opacity = "1 1",
|
||||
move = { "(monitor_w-window_w-40)", "(monitor_h-window_h-40)" },
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
o.window("qemu", { tag = "-default-opacity", opacity = "1 1" })
|
||||
@@ -1,6 +1,4 @@
|
||||
o.window("com.libretro.RetroArch", {
|
||||
fullscreen = true,
|
||||
tag = "-default-opacity",
|
||||
opacity = "1 1",
|
||||
idle_inhibit = "fullscreen",
|
||||
})
|
||||
@@ -1,4 +1,3 @@
|
||||
o.window("steam", { float = true, idle_inhibit = "fullscreen" })
|
||||
o.window({ class = "steam", title = "Steam" }, { center = true, size = { 1100, 700 } })
|
||||
o.window("steam.*", { tag = "-default-opacity", opacity = "1 1" })
|
||||
o.window({ class = "steam", title = "Friends List" }, { size = { 460, 800 } })
|
||||
@@ -37,20 +37,6 @@ o.window("org.omarchy.screensaver", { animation = "slide" })
|
||||
-- where its fullscreen rule cannot take fullscreen from a window.
|
||||
o.window("org.omarchy.screensaver", { workspace = "special:screensaver silent" })
|
||||
|
||||
-- No transparency on media windows.
|
||||
o.window(
|
||||
"^(zoom|vlc|mpv|org.kde.kdenlive|com.obsproject.Studio|com.github.PintaProject.Pinta|imv|org.gnome.NautilusPreviewer)$",
|
||||
{
|
||||
tag = "-default-opacity",
|
||||
}
|
||||
)
|
||||
o.window(
|
||||
"^(zoom|vlc|mpv|org.kde.kdenlive|com.obsproject.Studio|com.github.PintaProject.Pinta|imv|org.gnome.NautilusPreviewer)$",
|
||||
{
|
||||
opacity = "1 1",
|
||||
}
|
||||
)
|
||||
|
||||
-- Popped window rounding.
|
||||
o.window({ tag = "pop" }, { rounding = 8 })
|
||||
|
||||
|
||||
@@ -16,10 +16,8 @@ o.window("^WebcamOverlay-large$", {
|
||||
-- The dedicated app id keeps this out of mpv's generic centered floating rules,
|
||||
-- so the camera appears at its final corner position.
|
||||
o.window({ class = "^WebcamOverlay-(small|medium|large)$", title = "^WebcamOverlay$" }, {
|
||||
tag = "-default-opacity",
|
||||
float = true,
|
||||
pin = true,
|
||||
no_initial_focus = true,
|
||||
no_dim = true,
|
||||
opacity = "1 1",
|
||||
})
|
||||
@@ -1,5 +0,0 @@
|
||||
-- Keep the Windows VM display opaque instead of applying the default window opacity.
|
||||
o.window({ class = "^xfreerdp$", title = "^Windows VM - Omarchy$" }, {
|
||||
tag = "-default-opacity",
|
||||
opacity = "1 1",
|
||||
})
|
||||
@@ -16,7 +16,7 @@ o.bind("XF86Calculator", "Calculator", "omacalc")
|
||||
o.bind_toggle("SUPER + SHIFT + SPACE", "Toggle top bar", "bar")
|
||||
o.bind("SUPER + CTRL + SPACE", "Background switcher", { menu = "background" })
|
||||
o.bind("SUPER + SHIFT + CTRL + SPACE", "Theme menu", { menu = "theme" })
|
||||
o.bind("SUPER + BACKSPACE", "Toggle window transparency", "omarchy-hyprland-window-transparency-toggle")
|
||||
o.bind("SUPER + BACKSPACE", "Toggle transparency on a window", "omarchy-hyprland-window-transparency-toggle")
|
||||
o.bind("SUPER + SHIFT + BACKSPACE", "Toggle window gaps", "omarchy-hyprland-window-gaps-toggle")
|
||||
o.bind("SUPER + CTRL + BACKSPACE", "Toggle single-window square aspect", "omarchy-hyprland-window-single-square-aspect-toggle")
|
||||
o.bind_toggle("SUPER + CTRL + ALT + F", "Toggle full screen desktop", "fullscreen-desktop")
|
||||
|
||||
@@ -223,3 +223,8 @@ function o.window(match, rules)
|
||||
|
||||
hl.window_rule(rules)
|
||||
end
|
||||
|
||||
-- Opt a window in to Omarchy's standard active/inactive transparency.
|
||||
function o.transparent_window(match, opacity)
|
||||
o.window(match, { opacity = opacity or "0.985 0.96" })
|
||||
end
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
o.window(".*", { suppress_event = "maximize" })
|
||||
|
||||
-- Tag all windows for default opacity (apps can override with -default-opacity tag).
|
||||
o.window(".*", { tag = "+default-opacity" })
|
||||
|
||||
-- Fix some dragging issues with XWayland.
|
||||
o.window(
|
||||
{
|
||||
@@ -18,8 +15,12 @@ o.window(
|
||||
{ no_focus = true }
|
||||
)
|
||||
|
||||
-- App-specific tweaks (may remove default-opacity tag).
|
||||
-- App-specific tweaks and terminal tags.
|
||||
require("default.hypr.apps")
|
||||
|
||||
-- Apply default opacity after apps have had a chance to opt out.
|
||||
o.window({ tag = "default-opacity" }, { opacity = "0.985 0.96" })
|
||||
-- Terminals (including TUIs) and these desktop apps opt in to transparency.
|
||||
o.transparent_window({ tag = "terminal" })
|
||||
o.transparent_window("(omawrite|1[pP]assword|com\\.onepassword\\.OnePassword|org\\.gnome\\.Nautilus)")
|
||||
|
||||
-- The transparency hotkey opts otherwise opaque windows in with this tag.
|
||||
o.transparent_window({ tag = "transparent" })
|
||||
@@ -0,0 +1,12 @@
|
||||
echo "Add an example for opting applications in to transparency"
|
||||
|
||||
looknfeel="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/looknfeel.lua"
|
||||
if [[ -f $looknfeel ]] && ! rg -Fq 'o.transparent_window("my-app")' "$looknfeel"; then
|
||||
cat >>"$looknfeel" <<'LUA'
|
||||
|
||||
-- Opt another application in to Omarchy's standard transparency.
|
||||
-- Find its class with: hyprctl clients
|
||||
-- o.transparent_window("my-app")
|
||||
-- o.transparent_window("my-app", "0.9 0.85") -- Custom active/inactive opacity.
|
||||
LUA
|
||||
fi
|
||||
@@ -5,7 +5,6 @@ set -euo pipefail
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
windows_vm_command="$ROOT/bin/omarchy-windows-vm"
|
||||
windows_vm_rules="$ROOT/default/hypr/apps/windows-vm.lua"
|
||||
|
||||
rg -q '^ restart: "no"$' "$windows_vm_command" ||
|
||||
fail "Windows VM uses manual startup by default"
|
||||
@@ -16,14 +15,7 @@ if rg -q '^ restart: unless-stopped$' "$windows_vm_command"; then
|
||||
fi
|
||||
pass "Windows VM does not restart automatically at boot"
|
||||
|
||||
# Tolerate either shell quoting of the argument -- what must not drift is the
|
||||
# title itself, since the Hyprland rule below matches on it.
|
||||
# Tolerate either shell quoting of the argument.
|
||||
rg -q 'title:"?Windows VM - Omarchy"' "$windows_vm_command" ||
|
||||
fail "Windows VM launches FreeRDP with its expected title"
|
||||
rg -q 'class = "\^xfreerdp\$", title = "\^Windows VM - Omarchy\$"' "$windows_vm_rules" ||
|
||||
fail "Windows VM opacity rule targets its FreeRDP window"
|
||||
rg -q 'tag = "-default-opacity"' "$windows_vm_rules" ||
|
||||
fail "Windows VM opts out of default opacity"
|
||||
rg -q 'opacity = "1 1"' "$windows_vm_rules" ||
|
||||
fail "Windows VM stays fully opaque"
|
||||
pass "Windows VM stays fully opaque"
|
||||
pass "Windows VM launches FreeRDP with its expected title"
|
||||
@@ -15,4 +15,4 @@ hl.config({
|
||||
})
|
||||
|
||||
-- Kanagawa backdrop is too strong for default opacity.
|
||||
o.window({ tag = "terminal" }, { opacity = "0.99 0.985" })
|
||||
o.transparent_window({ tag = "terminal" }, "0.99 0.985")
|
||||
Reference in new issue
Block a user