From 649e324ac75703c45865ecdeed18e5eb809e917f Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Sat, 20 Sep 2025 17:36:51 +0200 Subject: [PATCH] fixes multi-monitor setup, adds f8-f10 multi monitor keybinds --- .config/hypr/config/keybinds.conf | 9 ++ .config/hypr/config/windowrules.conf | 6 ++ .config/hypr/scripts/monitor-toggle.sh | 132 +++++++++++++++++++++++++ .config/swaylock/lockscript.sh | 5 +- .config/swaylock/matrix.sh | 2 +- 5 files changed, 151 insertions(+), 3 deletions(-) create mode 100755 .config/hypr/scripts/monitor-toggle.sh diff --git a/.config/hypr/config/keybinds.conf b/.config/hypr/config/keybinds.conf index 5b32fe5..cb4046b 100644 --- a/.config/hypr/config/keybinds.conf +++ b/.config/hypr/config/keybinds.conf @@ -167,5 +167,14 @@ binds { # Toggle Waybar bind = $mainMod, W, exec, killall -SIGUSR1 waybar +# ======= Monitors ======= # Toggle Monitor Flip bind = $mainMod, F7, exec, ~/.config/hypr/scripts/rotate_current_screen.sh + +# One-key flip: externals on/off +bind = $mainMod, F8, exec, ~/.config/hypr/scripts/monitor-toggle.sh toggle-externals + +# Explicit profiles +bind = $mainMod, F8, exec, ~/.config/hypr/scripts/monitor-toggle.sh laptop +bind = $mainMod, F9, exec, ~/.config/hypr/scripts/monitor-toggle.sh dual +bind = $mainMod, F10, exec, ~/.config/hypr/scripts/monitor-toggle.sh triple diff --git a/.config/hypr/config/windowrules.conf b/.config/hypr/config/windowrules.conf index 2fd0f56..7cf42b1 100644 --- a/.config/hypr/config/windowrules.conf +++ b/.config/hypr/config/windowrules.conf @@ -13,10 +13,13 @@ windowrule = float, class:^()$,title:^(Open File)$ windowrule = float, class:^(LibreWolf)$,title:^(Picture-in-Picture)$ windowrule = float, class:^(blueman-manager)$ windowrule = float, class:^(xdg-desktop-portal-gtk|xdg-desktop-portal-kde|xdg-desktop-portal-hyprland)(.*)$ +windowrule = float, class:^(pomodorolm)$ +windowrule = float, title:^(Extension:.*)$ windowrule = float, class:^(polkit-gnome-authentication-agent-1|hyprpolkitagent|org.org.kde.polkit-kde-authentication-agent-1)(.*)$ windowrule = float, class:^(CachyOSHello)$ windowrule = float, class:^(zenity)$ windowrule = float, class:^()$,title:^(Steam - Self Updater)$ +windowrule = float, class:^(Zotero)$,title:^(Progress)$ # Increase the opacity windowrule = opacity 0.92, class:^(thunar|nemo|dolphin)$ windowrule = opacity 0.96, class:^(discord|armcord|webcord)$ @@ -24,6 +27,7 @@ windowrule = opacity 0.95, title:^(QQ|Telegram)$ windowrule = opacity 0.95, title:^(NetEase Cloud Music Gtk4)$ windowrule = opacity 1, class:^(kitty)$ # General window rules +windowrule = size 260 340, class:^(pomodorolm)$ windowrule = float, title:^(Picture-in-Picture)$ windowrule = size 960 540, title:^(Picture-in-Picture)$ windowrule = move 25%-, title:^(Picture-in-Picture)$ @@ -34,6 +38,8 @@ windowrule = pin, title:^(danmufloat)$ windowrule = rounding 5, title:^(danmufloat|termfloat)$ windowrule = animation slide right, class:^(kitty|Alacritty)$ windowrule = noblur, class:^(org.mozilla.firefox)$ +windowrule = nodim, class:^(zen)$ +windowrule = float, title:^(Zotero Settings)$ # Decorations related to floating windows on workspaces 1 to 10 windowrule = bordersize 2, floating:1, onworkspace:w[fv1-10] windowrule = bordercolor $color4, floating:1, onworkspace:w[fv1-10] diff --git a/.config/hypr/scripts/monitor-toggle.sh b/.config/hypr/scripts/monitor-toggle.sh new file mode 100755 index 0000000..c3ca5dc --- /dev/null +++ b/.config/hypr/scripts/monitor-toggle.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash +# Quick display control for Hyprland +# Profiles: +# laptop -> keep eDP-2, disable all externals +# dual -> eDP-2 + primary external +# triple -> eDP-2 + both externals +# Toggles: +# toggle-externals -> if any external enabled => laptop; else => triple (or dual if only one preset) +# dpms-toggle-focused -> blank/unblank the currently focused monitor (does NOT change layout) + +set -euo pipefail + +PRIMARY="eDP-2" + +# --- exact enable lines (copy from hyprland.conf) --- +EXT1='desc:Samsung Electric Company S24F350 H4ZR302705, highres@highrr, auto-right, 1' +EXT2='desc:Samsung Electric Company S24F350 H4ZK111233, highres@highrr, auto-right, 1, transform, 1' +# Optional fallback by connector (harmless if not present) +EXT_FALLBACK='HDMI-A-1, highres@highrr, auto-right, 1' + +# Which external is the "main" one you prefer for Dual: +DUAL_MAIN="$EXT1" + +notify() { + if command -v notify-send >/dev/null 2>&1; then + notify-send -a "Hyprland" "$1" "${2:-}" + else + [ -n "${2:-}" ] && printf '%s: %s\n' "$1" "$2" >&2 || printf '%s\n' "$1" >&2 + fi +} + +hypr() { + local out + if ! out="$(hyprctl "$@" 2>&1)"; then + notify "hyprctl failed" "$out" + exit 1 + fi +} + +jqok(){ command -v jq >/dev/null; } +monjson(){ hyprctl -j monitors 2>/dev/null || true; } + +any_external_enabled() { + if jqok; then + monjson | jq -e --arg P "$PRIMARY" '.[] | select(.name!=$P and (.disabled!=true))' >/dev/null + else + hyprctl monitors | awk -v P="$PRIMARY" '/^Monitor /{gsub(/^Monitor[ \t]+/, "", $0); split($0,a," "); if (a[1]!=P){print; exit 0}}' | grep -q . + fi +} + +disable_all_externals() { + if jqok; then + mapfile -t names < <(monjson | jq -r --arg P "$PRIMARY" '.[] | select(.name!=$P) | .name') + else + mapfile -t names < <(hyprctl monitors | awk -v P="$PRIMARY" '/^Monitor /{gsub(/^Monitor[ \t]+/, "", $0); split($0,a," "); if (a[1]!=P) print a[1]}') + fi + for n in "${names[@]:-}"; do + hypr keyword monitor "$n, disable" + done +} + +enable_line() { + local line="$1" + [ -n "$line" ] && hypr keyword monitor "$line" +} + +profile_laptop() { + disable_all_externals + notify "Profile: Laptop-only" "$PRIMARY active, externals disabled" +} + +profile_dual() { + # Ensure only one external is on + disable_all_externals + enable_line "$DUAL_MAIN" + notify "Profile: Dual" "Enabled main external with preferred transform" +} + +profile_triple() { + # Ensure both externals are on (and only those two) + disable_all_externals + enable_line "$EXT1" + enable_line "$EXT2" + # You can drop EXT_FALLBACK if you don't actually need it: + # enable_line "$EXT_FALLBACK" + notify "Profile: Triple" "Enabled both externals" +} + +toggle_externals() { + if any_external_enabled; then + profile_laptop + else + # Prefer triple if we have two presets, else dual + if [ -n "$EXT1" ] && [ -n "$EXT2" ]; then + profile_triple + else + profile_dual + fi + fi +} + +dpms_toggle_focused() { + # Blank/unblank the currently focused output, layout unchanged + local name + if jqok; then + name="$(monjson | jq -r '.[] | select(.focused==true) | .name // empty')" + else + name="$(hyprctl monitors | awk '$1=="Monitor"{gsub(/^Monitor[ \t]+/,""); split($0,a," "); name=a[1]} /focused: yes/{print name; exit}')" + fi + [ -z "$name" ] && { notify "No focused monitor" ""; exit 2; } + hypr dispatch dpms toggle "$name" + notify "DPMS toggle" "$name" +} + +case "${1:-}" in + laptop) profile_laptop ;; + dual) profile_dual ;; + triple) profile_triple ;; + toggle-externals) toggle_externals ;; + dpms-toggle-focused) dpms_toggle_focused ;; + *) + cat <