diff --git a/mango/local-bin/mangowm-move-all-windows b/mango/local-bin/mangowm-move-all-windows new file mode 100755 index 0000000..3011197 --- /dev/null +++ b/mango/local-bin/mangowm-move-all-windows @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +set -euo pipefail + +if ! command -v mmsg >/dev/null 2>&1; then + echo "error: mmsg not found" >&2 + exit 1 +fi + +mode="${1:-all}" +case "$mode" in + all|single) ;; + *) + echo "usage: $(basename "$0") [single]" >&2 + exit 2 + ;; +esac + +mapfile -t outputs < <(mmsg -O | awk 'NF { print $1 }') +out_count=${#outputs[@]} + +if (( out_count == 0 )); then + echo "error: no monitors detected" >&2 + exit 1 +fi +if (( out_count == 1 )); then + echo "info: only one monitor connected, nothing to move" + exit 0 +fi +if (( out_count > 2 )); then + echo "error: script supports max 2 monitors, found ${out_count}" >&2 + exit 2 +fi + +active="$(mmsg -g -o | awk '$2=="selmon" && $3=="1" { print $1; exit }')" +if [[ -z "$active" ]]; then + active="${outputs[0]}" +fi + +target="" +for out in "${outputs[@]}"; do + if [[ "$out" != "$active" ]]; then + target="$out" + break + fi +done + +if [[ -z "$target" ]]; then + echo "error: failed to determine target monitor" >&2 + exit 1 +fi + +get_active_tag() { + local mon="$1" + local active_mask + active_mask="$(mmsg -g -t | awk -v m="$mon" '$1==m && $2=="tags" && $3 ~ /^[0-9]+$/ && $4 ~ /^[0-9]+$/ { print $4; exit }')" + if [[ ! "$active_mask" =~ ^[0-9]+$ ]]; then + echo 1 + return + fi + + for tag in {1..9}; do + if (( active_mask & (1 << (tag - 1)) )); then + echo "$tag" + return + fi + done + echo 1 +} + +get_tag_clients() { + local mon="$1" tag="$2" + local n + n="$(mmsg -g -t | awk -v m="$mon" -v t="$tag" '$1==m && $2=="tag" && $3==t { print $5; exit }')" + if [[ "$n" =~ ^[0-9]+$ ]]; then + echo "$n" + else + echo 0 + fi +} + +get_total_clients() { + local mon="$1" + local n + n="$(mmsg -g -t | awk -v m="$mon" '$1==m && $2=="clients" { print $3; exit }')" + if [[ "$n" =~ ^[0-9]+$ ]]; then + echo "$n" + else + echo 0 + fi +} + +if [[ "$mode" == "single" ]]; then + echo "move-single: active=${active} target=${target}" + mmsg -o "$active" -s -d "tagmon,${target},1" >/dev/null + echo "move-single: done" + exit 0 +fi + +target_tag="$(get_active_tag "$target")" +source_total="$(get_total_clients "$active")" + +if (( source_total == 0 )); then + echo "info: no windows on active monitor (${active})" + exit 0 +fi + +echo "move-all: active=${active} target=${target} target_tag=${target_tag} total=${source_total}" + +moved=0 +for tag in {1..9}; do + while :; do + before="$(get_tag_clients "$active" "$tag")" + (( before > 0 )) || break + + mmsg -o "$active" -s -t "$tag" >/dev/null + mmsg -o "$active" -s -d "tagcrossmon,${target_tag},${target}" >/dev/null + mmsg -s -d "focusmon,${active}" >/dev/null || true + + after="$(get_tag_clients "$active" "$tag")" + if (( after < before )); then + (( moved += (before - after) )) + else + echo "warn: no progress on tag=${tag}; stopping this tag" + break + fi + done +done + +left="$(get_total_clients "$active")" +echo "move-all: done moved=${moved} left_on_source=${left} from=${active} to=${target} tag=${target_tag}" diff --git a/mango/mango/keybindings.conf b/mango/mango/keybindings.conf index 2beb142..c6469e9 100644 --- a/mango/mango/keybindings.conf +++ b/mango/mango/keybindings.conf @@ -20,6 +20,8 @@ bind=SUPER+ALT,p,spawn,mangowm-screenshot bind=SUPER+ALT+CTRL,p,spawn,mangowm-screenshot screen # - screen capture/record bind=SUPER+ALT,v,spawn,mangowm-screenrecord +# - monitor select capture/record +bind=SUPER+ALT+CTRL,v,spawn,mangowm-screenrecord screen bind=SUPER,Return,spawn,ghostty bind=SUPER,e,spawn,thunar @@ -75,7 +77,8 @@ bind=ALT,x,switch_proportion_preset, # switch layout bind=SUPER,n,switch_layout bind=SUPER,comma,setlayout,tile -bind=SUPER,period,setlayout,scroller +bind=SUPER,period,setlayout,tgmix +bind=SUPER,slash,setlayout,scroller # tag switch bind=ALT,Left,viewtoleft,0 @@ -106,9 +109,13 @@ bind=Alt,7,tagsilent,7,0 bind=Alt,8,tagsilent,8,0 bind=Alt,9,tagsilent,9,0 -# window monitor shift -bind=ALT+SHIFT,Left,tagmon,left -bind=ALT+SHIFT,Right,tagmon,right +# move window to another monitor shift +# bind=ALT+SHIFT,Left,tagmon,left +# bind=ALT+SHIFT,Right,tagmon,right + +# move all/single windows to another monitor +bind=ALT+SHIFT,m,spawn,~/.local/bin/mangowm-move-all-windows +bind=ALT+SHIFT,s,spawn,~/.local/bin/mangowm-move-all-windows single # gaps # bind=ALT+SHIFT,X,incgaps,1