<div dir="ltr">The latest version of the code is available <a href="https://gist.github.com/mlauronen/cb3dc7bf0e5fa4ef7f86aafaf20e73e1">here</a>.</div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Wed, Sep 3, 2025 at 4:10 PM Jack <<a href="mailto:j4315593@gmail.com">j4315593@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Here’s my script, which gets the job done. It should work with both terminal-style and regular application windows in a multi-monitor setup.<br>Thank you.<br><br>#!/bin/bash<br><br>if [ $# -ne 2 ]; then<br> echo "Usage: $0 <window_id> <command>"<br> echo "<window_id> can be:"<br> echo " number Window ID (e.g., 0x1a0000 or 123456)"<br> echo " '.' Current active window"<br> echo " name Partial window name (e.g., 'firefox')"<br> echo "Commands:"<br> echo " -1 lower left corner"<br> echo " -2 bottom side"<br> echo " -3 lower right corner"<br> echo " -4 left side"<br> echo " -5 full screen"<br> echo " -6 right side"<br> echo " -7 upper left corner"<br> echo " -8 top side"<br> echo " -9 upper right corner"<br> echo " -gX,Y,W,H move and resize"<br> exit 1<br>fi<br><br>WINDOW_ID="$1"<br>COMMAND="$2"<br><br># Handle WINDOW_ID input<br>if [ "$WINDOW_ID" = "." ]; then<br> # Get active window ID<br> WINDOW_ID=$(xdotool getactivewindow)<br> if [ -z "$WINDOW_ID" ]; then<br> echo "Error: No active window found"<br> exit 1<br> fi<br>elif [[ ! "$WINDOW_ID" =~ ^[0-9]+$ ]]; then<br> # Treat as partial window name if not a number<br> WINDOW_ID=$(wmctrl -l | grep -i "$WINDOW_ID" | head -n 1 | awk '{print $1}')<br> if [ -z "$WINDOW_ID" ]; then<br> echo "Error: No window found matching partial name: $1"<br> exit 1<br> fi<br>fi<br><br># Verify window ID is valid<br>if ! xwininfo -id "$WINDOW_ID" >/dev/null 2>&1; then<br> echo "Error: Invalid window ID: $WINDOW_ID"<br> exit 1<br>fi<br><br>wmctrl -ir "$WINDOW_ID" -b remove,maximized_vert,maximized_horz<br><br>ABSOLUTE_X=$(xwininfo -id "$WINDOW_ID" | grep "Absolute upper-left X:" | awk '{print $4}')<br>ABSOLUTE_Y=$(xwininfo -id "$WINDOW_ID" | grep "Absolute upper-left Y:" | awk '{print $4}')<br><br>RELATIVE_X=$(xwininfo -id "$WINDOW_ID" | grep "Relative upper-left X:" | awk '{print $4}')<br>RELATIVE_Y=$(xwininfo -id "$WINDOW_ID" | grep "Relative upper-left Y:" | awk '{print $4}')<br><br>WIDTH_FIX=$((-(RELATIVE_X * 2)))<br>HEIGHT_FIX=$((-(RELATIVE_Y + RELATIVE_X)))<br><br>MONITOR_INFO=$(xrandr --current)<br>MONITOR_X=0<br>MONITOR_Y=0<br>MONITOR_WIDTH=1920<br>MONITOR_HEIGHT=1080<br><br># Loop through xrandr output to find the correct monitor based on window position<br>while read -r line; do<br> if [[ $line =~ ([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+) ]]; then<br> MON_W=${BASH_REMATCH[1]}<br> MON_H=${BASH_REMATCH[2]}<br> MON_X=${BASH_REMATCH[3]}<br> MON_Y=${BASH_REMATCH[4]}<br> <br> # Check if the window is within this monitor's coordinates<br> if (( ABSOLUTE_X >= MON_X && ABSOLUTE_X < MON_X + MON_W && ABSOLUTE_Y >= MON_Y && ABSOLUTE_Y < MON_Y + MON_H )); then<br> MONITOR_WIDTH=$MON_W<br> MONITOR_HEIGHT=$MON_H<br> MONITOR_X=$MON_X<br> MONITOR_Y=$MON_Y<br> break<br> fi<br> fi<br>done <<< "$MONITOR_INFO"<br><br>HALF_WIDTH=$((MONITOR_WIDTH / 2))<br>HALF_HEIGHT=$((MONITOR_HEIGHT / 2))<br><br>case $COMMAND in<br> -1)<br> xdotool windowmove "$WINDOW_ID" $MONITOR_X $((MONITOR_Y + HALF_HEIGHT))<br> xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX)) $((HALF_HEIGHT + HEIGHT_FIX))<br> ;;<br> -2)<br> xdotool windowmove "$WINDOW_ID" $MONITOR_X $((MONITOR_Y + HALF_HEIGHT))<br> xdotool windowsize "$WINDOW_ID" $((MONITOR_WIDTH + WIDTH_FIX)) $((HALF_HEIGHT + HEIGHT_FIX))<br> ;;<br> -3)<br> xdotool windowmove "$WINDOW_ID" $((MONITOR_X + HALF_WIDTH)) $((MONITOR_Y + HALF_HEIGHT))<br> xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX)) $((HALF_HEIGHT + HEIGHT_FIX))<br> ;;<br> -4)<br> xdotool windowmove "$WINDOW_ID" $MONITOR_X $MONITOR_Y<br> xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX)) $((MONITOR_HEIGHT + HEIGHT_FIX))<br> ;;<br> -5)<br> xdotool windowmove "$WINDOW_ID" $MONITOR_X $MONITOR_Y<br> xdotool windowsize "$WINDOW_ID" $((MONITOR_WIDTH + WIDTH_FIX)) $((MONITOR_HEIGHT + HEIGHT_FIX))<br> ;;<br> -6)<br> xdotool windowmove "$WINDOW_ID" $((MONITOR_X + HALF_WIDTH)) $MONITOR_Y<br> xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX)) $((MONITOR_HEIGHT + HEIGHT_FIX))<br> ;;<br> -7)<br> xdotool windowmove "$WINDOW_ID" $MONITOR_X $MONITOR_Y<br> xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX)) $((HALF_HEIGHT + HEIGHT_FIX))<br> ;;<br> -8)<br> xdotool windowmove "$WINDOW_ID" $MONITOR_X $MONITOR_Y<br> xdotool windowsize "$WINDOW_ID" $((MONITOR_WIDTH + WIDTH_FIX)) $((HALF_HEIGHT + HEIGHT_FIX))<br> ;;<br> -9)<br> xdotool windowmove "$WINDOW_ID" $((MONITOR_X + HALF_WIDTH)) $MONITOR_Y<br> xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX)) $((HALF_HEIGHT + HEIGHT_FIX))<br> ;;<br> -g*)<br> GEOM="${COMMAND:2}" # strip "-g"<br> IFS=',' read -r GX GY GW GH <<< "$GEOM"<br> if [[ -n $GX && -n $GY && -n $GW && -n $GH ]]; then<br> xdotool windowmove "$WINDOW_ID" "$GX" "$GY"<br> xdotool windowsize "$WINDOW_ID" "$((GW + WIDTH_FIX))" "$((GH + HEIGHT_FIX))"<br> else<br> echo "Error: invalid geometry format. Use -gX,Y,W,H"<br> exit 1<br> fi<br> ;;<br> *)<br> echo "Error: Unknown command: $COMMAND"<br> exit 1<br> ;;<br>esac<div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 3, 2025 at 10:43 AM Jack <<a href="mailto:j4315593@gmail.com" target="_blank">j4315593@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">I have three monitors running six virtual desktops, all filled with applications some are tiled and some are floating. I'm currently writing a script to manage them, but it's making me consider just switching to i3 :)</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 3, 2025 at 10:29 AM killermoehre <<a href="mailto:killermoehre@gmx.net" target="_blank">killermoehre@gmx.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><p>Am Mittwoch, dem 03.09.2025 um 10:17 +0300 schrieb Jack:</p>
<blockquote type="cite">
<p>Unfortunately, <strong>built-in commands cannot be used</strong> because after using them, the window size can no longer be changed programmatically (ie. from the scripts). This is because if you switch to another desktop and then return, the window manager no longer correctly remembers the modified window sizes. This is precisely why I'm creating my own script for this purpose.</p>
</blockquote>
<p>A really long time ago I wrote <a href="https://github.com/killermoehre/window-gridder" target="_blank">https://github.com/killermoehre/window-gridder</a> for this purpose, but abondend it, because Xfwm4 hat inbuild what I need and it has problems with client side decorations.</p>
<p>You can use it at a starting point.</p>
<p>But IMHO it sounds like you want more of a tiling WM and not a floating one, right? Xfce allows to simply <em>replace</em> the current WM with another one. I wrote <a href="https://wiki.xfce.org/howto/other_window_manager" target="_blank">https://wiki.xfce.org/howto/other_window_manager</a> for this.</p>
_______________________________________________<br>
Xfce mailing list<br>
<a href="mailto:Xfce@xfce.org" target="_blank">Xfce@xfce.org</a><br>
<a href="https://mail.xfce.org/mailman/listinfo/xfce" rel="noreferrer" target="_blank">https://mail.xfce.org/mailman/listinfo/xfce</a><br>
<a href="http://www.xfce.org" rel="noreferrer" target="_blank">http://www.xfce.org</a><br>
</blockquote></div></div>
</blockquote></div>
</blockquote></div>