From 5c7cef1e78fe21dd296ce38c07a779613e11b8ab Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 27 Sep 2026 21:07:27 +0200 Subject: [PATCH] Keep Hyprland from sliding the OSD in from the corner (#13436) The OSD, the reminder flow and the Wi-Fi QR code now keep a surface that parks as a 1x1 in the corner and grows when shown. They were missing from the layer rule that turns Hyprland's layer animation off for the shell's overlays, so Hyprland animated that growth: the OSD flew in from the left. Add them to the rule, and test that every OverlayWindow's namespace is in it. Co-authored-by: Claude Opus 5.5 --- default/hypr/apps/omarchy-shell.lua | 11 +++++++---- test/shell.d/overlay-window-test.sh | 11 +++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/default/hypr/apps/omarchy-shell.lua b/default/hypr/apps/omarchy-shell.lua index 117deb85..a06630f8 100644 --- a/default/hypr/apps/omarchy-shell.lua +++ b/default/hypr/apps/omarchy-shell.lua @@ -4,10 +4,13 @@ -- Keep the bar instant: no layer-shell fade/slide animation. hl.layer_rule({ match = { namespace = "omarchy-bar" }, no_anim = true, animation = "none" }) --- Launcher, image selector, emojis, clipboard overlays, and keyboard-driven --- panels should pop without compositor layer fades. Panels keep their own --- QML opacity transition for normal open/close, and skip it for panel handoff. -hl.layer_rule({ match = { namespace = "^(omarchy-menu|omarchy-image-selector|omarchy-emojis|omarchy-clipboard|omarchy-keyboard-panel)$" }, no_anim = true, animation = "none" }) +-- Launcher, image selector, emojis, clipboard overlays, the OSD, reminders, the +-- Wi-Fi QR code and keyboard-driven panels should pop without compositor layer +-- animations. The overlays stay mapped between opens and grow from a parked +-- 1x1 when shown, which Hyprland would otherwise animate as a slide in from +-- the corner. Panels keep their own QML opacity transition for normal +-- open/close, and skip it for panel handoff. +hl.layer_rule({ match = { namespace = "^(omarchy-menu|omarchy-image-selector|omarchy-emojis|omarchy-clipboard|omarchy-keyboard-panel|omarchy-osd|omarchy-reminders|omarchy-network-qr)$" }, no_anim = true, animation = "none" }) -- Dev gallery is the main shell workbench; open it maximized like -- SUPER+ALT+F so component previews have the whole workspace. diff --git a/test/shell.d/overlay-window-test.sh b/test/shell.d/overlay-window-test.sh index 8aa61dd4..969d2f86 100644 --- a/test/shell.d/overlay-window-test.sh +++ b/test/shell.d/overlay-window-test.sh @@ -61,6 +61,17 @@ assert( 'the menu unfreezes its layout when the overlay hides' ) +// A kept surface grows from its parked 1x1 when shown, which Hyprland animates +// as a slide in from the corner unless its layer rule turns animation off. +const shellRules = read('default/hypr/apps/omarchy-shell.lua') +const noAnim = /namespace = "\^\(([^)]*)\)\$" \}, no_anim = true/.exec(shellRules) +assert(noAnim, 'the shell overlays share one no-animation layer rule') +const unanimated = noAnim ? noAnim[1].split('|') : [] +for (const file of Object.keys(overlays)) { + const namespace = /WlrLayershell\.namespace: "([^"]+)"/.exec(read(file)) + assert(namespace && unanimated.includes(namespace[1]), `${file} is exempt from Hyprland's layer animation`) +} + // The OSD never takes the keyboard or input, shown or not. const osd = read('shell/plugins/osd/Osd.qml') assert(