handy: hide force-shown windows at boot
Handy ignores --start-hidden whenever the tray icon is disabled: without
a tray it force-shows the main window as the only way back in
(lib.rs: `if should_force_show || !should_hide || !tray_available`).
Since both instances run tray-less (GUI access is via the SUPER+G /
SUPER+SHIFT+G binds instead), both windows opened on workspace 1 at
every boot.
Add handy-boot-hide: polls for the first two Handy windows after boot
and dispatches a close on each — Handy intercepts close and hides the
window instead of quitting, which is exactly the hidden state
--start-hidden would have produced. Wired into the Hyprland autostart
after both instances launch.
Note: the Lua config provider parses `hyprctl dispatch` args as a Lua
expression, so the script uses the dispatcher form
`hl.dsp.window.close({ window = 'address:…' })`.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016vLKT7j9KJEsJ4mEVbGyqp
This commit is contained in:
@@ -21,6 +21,7 @@ hl.monitor({ output = "DP-3", mode = "highres", position = "auto", scale = "auto
|
|||||||
|
|
||||||
-- Set programs that you use
|
-- Set programs that you use
|
||||||
local terminal = "ghostty"
|
local terminal = "ghostty"
|
||||||
|
local multiplexer = os.getenv("HOME") .. "/.local/bin/herdr"
|
||||||
local fileManager = "nautilus"
|
local fileManager = "nautilus"
|
||||||
local browser = "brave"
|
local browser = "brave"
|
||||||
local menu = "wofi --show drun"
|
local menu = "wofi --show drun"
|
||||||
@@ -29,6 +30,7 @@ local pwManager = "bitwarden-desktop"
|
|||||||
-- Hyprland's session PATH is /usr/local/bin:/usr/bin — no ~/.local/bin —
|
-- Hyprland's session PATH is /usr/local/bin:/usr/bin — no ~/.local/bin —
|
||||||
-- so user scripts need their absolute path in autostart and binds.
|
-- so user scripts need their absolute path in autostart and binds.
|
||||||
local handyNo = os.getenv("HOME") .. "/.local/bin/handy-no"
|
local handyNo = os.getenv("HOME") .. "/.local/bin/handy-no"
|
||||||
|
local handyBootHide = os.getenv("HOME") .. "/.local/bin/handy-boot-hide"
|
||||||
|
|
||||||
|
|
||||||
-------------------
|
-------------------
|
||||||
@@ -45,9 +47,12 @@ hl.on("hyprland.start", function()
|
|||||||
hl.exec_cmd("nextcloud --background")
|
hl.exec_cmd("nextcloud --background")
|
||||||
hl.exec_cmd("handy --start-hidden") -- English instance (parakeet)
|
hl.exec_cmd("handy --start-hidden") -- English instance (parakeet)
|
||||||
hl.exec_cmd(handyNo .. " start") -- Norwegian instance (whisper-large-v3), private D-Bus + own data dir
|
hl.exec_cmd(handyNo .. " start") -- Norwegian instance (whisper-large-v3), private D-Bus + own data dir
|
||||||
|
-- Handy ignores --start-hidden when the tray icon is off (it force-shows
|
||||||
|
-- the window as its only way back in), so hide the first two windows here.
|
||||||
|
hl.exec_cmd(handyBootHide)
|
||||||
|
|
||||||
-- Launch apps on specific workspaces (window rules below)
|
-- Launch apps on specific workspaces (window rules below)
|
||||||
hl.exec_cmd("ghostty -e tmux")
|
hl.exec_cmd("ghostty -e " .. multiplexer)
|
||||||
hl.exec_cmd("brave")
|
hl.exec_cmd("brave")
|
||||||
hl.exec_cmd("steam")
|
hl.exec_cmd("steam")
|
||||||
end)
|
end)
|
||||||
@@ -243,8 +248,12 @@ hl.bind(mainMod .. " + SHIFT + G", hl.dsp.exec_cmd(handyNo .. " gui"))
|
|||||||
hl.bind("SUPER + SHIFT + L", hl.dsp.exec_cmd("hyprlock"))
|
hl.bind("SUPER + SHIFT + L", hl.dsp.exec_cmd("hyprlock"))
|
||||||
|
|
||||||
-- System shutdown and reboot with confirmation
|
-- System shutdown and reboot with confirmation
|
||||||
hl.bind(mainMod .. " + Q", hl.dsp.exec_cmd([=[if [[ $(wofi --dmenu --prompt="Shutdown?" --width=200 --height=100 <<< $'Yes\nNo') == "Yes" ]]; then pkill brave; systemctl poweroff; fi]=]))
|
hl.bind(mainMod .. " + Q",
|
||||||
hl.bind(mainMod .. " + R", hl.dsp.exec_cmd([=[if [[ $(wofi --dmenu --prompt="Reboot?" --width=200 --height=100 <<< $'Yes\nNo') == "Yes" ]]; then pkill brave; systemctl reboot; fi]=]))
|
hl.dsp.exec_cmd(
|
||||||
|
[=[if [[ $(wofi --dmenu --prompt="Shutdown?" --width=200 --height=100 <<< $'Yes\nNo') == "Yes" ]]; then pkill brave; systemctl poweroff; fi]=]))
|
||||||
|
hl.bind(mainMod .. " + R",
|
||||||
|
hl.dsp.exec_cmd(
|
||||||
|
[=[if [[ $(wofi --dmenu --prompt="Reboot?" --width=200 --height=100 <<< $'Yes\nNo') == "Yes" ]]; then pkill brave; systemctl reboot; fi]=]))
|
||||||
|
|
||||||
-- Move focus with mainMod + hjkl
|
-- Move focus with mainMod + hjkl
|
||||||
hl.bind(mainMod .. " + h", hl.dsp.focus({ direction = "left" }))
|
hl.bind(mainMod .. " + h", hl.dsp.focus({ direction = "left" }))
|
||||||
@@ -273,10 +282,14 @@ hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
|
|||||||
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
|
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
|
||||||
|
|
||||||
-- Laptop multimedia keys for volume and LCD brightness
|
-- Laptop multimedia keys for volume and LCD brightness
|
||||||
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true, repeating = true })
|
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"),
|
||||||
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true, repeating = true })
|
{ locked = true, repeating = true })
|
||||||
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true, repeating = true })
|
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"),
|
||||||
hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true, repeating = true })
|
{ locked = true, repeating = true })
|
||||||
|
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"),
|
||||||
|
{ locked = true, repeating = true })
|
||||||
|
hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"),
|
||||||
|
{ locked = true, repeating = true })
|
||||||
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s 10%+"), { locked = true, repeating = true })
|
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s 10%+"), { locked = true, repeating = true })
|
||||||
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 10%-"), { locked = true, repeating = true })
|
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 10%-"), { locked = true, repeating = true })
|
||||||
|
|
||||||
|
|||||||
Executable
+21
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Handy force-shows its main window at startup whenever the tray icon is
|
||||||
|
# disabled (lib.rs: "If start_hidden but tray is disabled, we must show
|
||||||
|
# the window anyway" — it can't know the SUPER+G/SHIFT+G binds are the
|
||||||
|
# way back in). So --start-hidden alone can't keep the two instances
|
||||||
|
# hidden at boot. Instead: watch for the first two Handy windows and
|
||||||
|
# dispatch a close — Handy intercepts close and hides the window.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
hidden=0
|
||||||
|
for _ in $(seq 1 150); do # ~30 s window after boot
|
||||||
|
while read -r addr; do
|
||||||
|
# Lua-form dispatch: the Lua config provider parses hyprctl
|
||||||
|
# dispatch args as a Lua expression.
|
||||||
|
hyprctl dispatch "hl.dsp.window.close({ window = 'address:$addr' })" >/dev/null
|
||||||
|
hidden=$((hidden + 1))
|
||||||
|
done < <(hyprctl clients -j | jq -r '.[] | select(.class == "handy") | .address')
|
||||||
|
[ "$hidden" -ge 2 ] && exit 0
|
||||||
|
sleep 0.2
|
||||||
|
done
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user