|
|
|
|
@@ -0,0 +1,73 @@
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
# Float + resize (to 781x702) + center the Bitwarden browser-extension pop-out window.
|
|
|
|
|
#
|
|
|
|
|
# Why this exists instead of a window rule: Hyprland's `float`/`center`/`size`
|
|
|
|
|
# rules are "static" — evaluated exactly once, at the instant a window is
|
|
|
|
|
# created — and this popup opens with the generic title "Zen Browser" (same
|
|
|
|
|
# initialTitle/initialClass as the main browser window), only updating to
|
|
|
|
|
# "Extension: (Bitwarden Password Manager) - Bitwarden..." a moment after
|
|
|
|
|
# it's already mapped. By then the static rule has already missed its one
|
|
|
|
|
# chance and there's no field available at creation time to tell the popup
|
|
|
|
|
# apart from a normal browser window. See layout/windowrules.lua and
|
|
|
|
|
# https://github.com/hyprwm/Hyprland/issues/7402 for the same problem class.
|
|
|
|
|
#
|
|
|
|
|
# No socat/ncat is installed, so instead of an event-driven IPC listener this
|
|
|
|
|
# just polls `hyprctl clients` at a short interval with jq (already
|
|
|
|
|
# installed).
|
|
|
|
|
#
|
|
|
|
|
# Dispatch syntax note: Hyprland 0.55+'s Lua config changed `hyprctl dispatch`
|
|
|
|
|
# to take a literal Lua expression calling hl.dsp.* (e.g.
|
|
|
|
|
# `hyprctl dispatch 'hl.dsp.window.center()'`), not the old
|
|
|
|
|
# "centerwindow"-style dispatcher strings. Verified live against the real
|
|
|
|
|
# API in /usr/share/hypr/stubs/hl.meta.lua before wiring this in.
|
|
|
|
|
#
|
|
|
|
|
# Why it re-asserts for a few seconds instead of firing once: right after the
|
|
|
|
|
# popup leaves the tiled layout, Hyprland briefly re-tiles the sibling window
|
|
|
|
|
# to fill the freed space, and during that reflow this popup was observed
|
|
|
|
|
# reporting `floating: false` again for one poll tick — snapping it back to
|
|
|
|
|
# its old tiled geometry. Re-asserting float+center for a short settle window
|
|
|
|
|
# after first detection rides that out. After the settle window it's left
|
|
|
|
|
# alone, so a manual re-tile/move by you later isn't fought.
|
|
|
|
|
|
|
|
|
|
TITLE_PATTERN='Extension: \(Bitwarden Password Manager\)'
|
|
|
|
|
POLL_INTERVAL=0.3
|
|
|
|
|
SETTLE_TICKS=6 # ~2s of re-assertion after first detection, at POLL_INTERVAL
|
|
|
|
|
TARGET_WIDTH=781
|
|
|
|
|
TARGET_HEIGHT=702
|
|
|
|
|
|
|
|
|
|
declare -A ticks_left # address -> remaining re-assert ticks
|
|
|
|
|
|
|
|
|
|
while true; do
|
|
|
|
|
sleep "$POLL_INTERVAL"
|
|
|
|
|
|
|
|
|
|
# Forget any tracked window that's no longer open.
|
|
|
|
|
open_addresses=$(hyprctl clients -j | jq -r '.[].address')
|
|
|
|
|
for addr in "${!ticks_left[@]}"; do
|
|
|
|
|
grep -qF "$addr" <<<"$open_addresses" || unset 'ticks_left[$addr]'
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# Process substitution (not a pipe) so the while loop runs in this shell
|
|
|
|
|
# and its writes to ticks_left actually persist across iterations.
|
|
|
|
|
while IFS= read -r win; do
|
|
|
|
|
title=$(jq -r '.title' <<<"$win")
|
|
|
|
|
[[ "$title" =~ $TITLE_PATTERN ]] || continue
|
|
|
|
|
|
|
|
|
|
address=$(jq -r '.address' <<<"$win")
|
|
|
|
|
floating=$(jq -r '.floating' <<<"$win")
|
|
|
|
|
|
|
|
|
|
# First time we've seen this window: start its settle window.
|
|
|
|
|
[[ -v ticks_left[$address] ]] || ticks_left[$address]=$SETTLE_TICKS
|
|
|
|
|
|
|
|
|
|
# Already floating and past its settle window: leave it alone.
|
|
|
|
|
[[ "$floating" == "true" && ${ticks_left[$address]} -le 0 ]] && continue
|
|
|
|
|
|
|
|
|
|
hyprctl dispatch "hl.dsp.focus({ window = \"address:$address\" })" >/dev/null
|
|
|
|
|
hyprctl dispatch 'hl.dsp.window.float({ action = "enable" })' >/dev/null
|
|
|
|
|
# resize({x=W,y=H}) sets the absolute size (not a delta) — verified live.
|
|
|
|
|
# Must happen before center(), since resizing shifts what "centered" means.
|
|
|
|
|
hyprctl dispatch "hl.dsp.window.resize({ x = $TARGET_WIDTH, y = $TARGET_HEIGHT })" >/dev/null
|
|
|
|
|
hyprctl dispatch 'hl.dsp.window.center()' >/dev/null
|
|
|
|
|
|
|
|
|
|
ticks_left[$address]=$((ticks_left[$address] - 1))
|
|
|
|
|
done < <(hyprctl clients -j | jq -c '.[] | {address, title, floating}')
|
|
|
|
|
done
|