Getting and setting window size and position

Jack j4315593 at gmail.com
Wed Sep 3 19:00:33 CEST 2025


The latest version of the code is available here
<https://gist.github.com/mlauronen/cb3dc7bf0e5fa4ef7f86aafaf20e73e1>.

On Wed, Sep 3, 2025 at 4:10 PM Jack <j4315593 at gmail.com> wrote:

> 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.
> Thank you.
>
> #!/bin/bash
>
> if [ $# -ne 2 ]; then
>     echo "Usage: $0 <window_id> <command>"
>     echo "<window_id> can be:"
>     echo "  number      Window ID (e.g., 0x1a0000 or 123456)"
>     echo "  '.'         Current active window"
>     echo "  name        Partial window name (e.g., 'firefox')"
>     echo "Commands:"
>     echo "  -1          lower left corner"
>     echo "  -2          bottom side"
>     echo "  -3          lower right corner"
>     echo "  -4          left side"
>     echo "  -5          full screen"
>     echo "  -6          right side"
>     echo "  -7          upper left corner"
>     echo "  -8          top side"
>     echo "  -9          upper right corner"
>     echo "  -gX,Y,W,H   move and resize"
>     exit 1
> fi
>
> WINDOW_ID="$1"
> COMMAND="$2"
>
> # Handle WINDOW_ID input
> if [ "$WINDOW_ID" = "." ]; then
>     # Get active window ID
>     WINDOW_ID=$(xdotool getactivewindow)
>     if [ -z "$WINDOW_ID" ]; then
>         echo "Error: No active window found"
>         exit 1
>     fi
> elif [[ ! "$WINDOW_ID" =~ ^[0-9]+$ ]]; then
>     # Treat as partial window name if not a number
>     WINDOW_ID=$(wmctrl -l | grep -i "$WINDOW_ID" | head -n 1 | awk '{print
> $1}')
>     if [ -z "$WINDOW_ID" ]; then
>         echo "Error: No window found matching partial name: $1"
>         exit 1
>     fi
> fi
>
> # Verify window ID is valid
> if ! xwininfo -id "$WINDOW_ID" >/dev/null 2>&1; then
>     echo "Error: Invalid window ID: $WINDOW_ID"
>     exit 1
> fi
>
> wmctrl -ir "$WINDOW_ID" -b remove,maximized_vert,maximized_horz
>
> ABSOLUTE_X=$(xwininfo -id "$WINDOW_ID" | grep "Absolute upper-left X:" |
> awk '{print $4}')
> ABSOLUTE_Y=$(xwininfo -id "$WINDOW_ID" | grep "Absolute upper-left Y:" |
> awk '{print $4}')
>
> RELATIVE_X=$(xwininfo -id "$WINDOW_ID" | grep "Relative upper-left X:" |
> awk '{print $4}')
> RELATIVE_Y=$(xwininfo -id "$WINDOW_ID" | grep "Relative upper-left Y:" |
> awk '{print $4}')
>
> WIDTH_FIX=$((-(RELATIVE_X * 2)))
> HEIGHT_FIX=$((-(RELATIVE_Y + RELATIVE_X)))
>
> MONITOR_INFO=$(xrandr --current)
> MONITOR_X=0
> MONITOR_Y=0
> MONITOR_WIDTH=1920
> MONITOR_HEIGHT=1080
>
> # Loop through xrandr output to find the correct monitor based on window
> position
> while read -r line; do
>     if [[ $line =~ ([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+) ]]; then
>         MON_W=${BASH_REMATCH[1]}
>         MON_H=${BASH_REMATCH[2]}
>         MON_X=${BASH_REMATCH[3]}
>         MON_Y=${BASH_REMATCH[4]}
>
>         # Check if the window is within this monitor's coordinates
>         if (( ABSOLUTE_X >= MON_X && ABSOLUTE_X < MON_X + MON_W &&
> ABSOLUTE_Y >= MON_Y && ABSOLUTE_Y < MON_Y + MON_H )); then
>             MONITOR_WIDTH=$MON_W
>             MONITOR_HEIGHT=$MON_H
>             MONITOR_X=$MON_X
>             MONITOR_Y=$MON_Y
>             break
>         fi
>     fi
> done <<< "$MONITOR_INFO"
>
> HALF_WIDTH=$((MONITOR_WIDTH / 2))
> HALF_HEIGHT=$((MONITOR_HEIGHT / 2))
>
> case $COMMAND in
>     -1)
>         xdotool windowmove "$WINDOW_ID" $MONITOR_X $((MONITOR_Y +
> HALF_HEIGHT))
>         xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX))
> $((HALF_HEIGHT + HEIGHT_FIX))
>         ;;
>     -2)
>         xdotool windowmove "$WINDOW_ID" $MONITOR_X $((MONITOR_Y +
> HALF_HEIGHT))
>         xdotool windowsize "$WINDOW_ID" $((MONITOR_WIDTH + WIDTH_FIX))
> $((HALF_HEIGHT + HEIGHT_FIX))
>         ;;
>     -3)
>         xdotool windowmove "$WINDOW_ID" $((MONITOR_X + HALF_WIDTH))
> $((MONITOR_Y + HALF_HEIGHT))
>         xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX))
> $((HALF_HEIGHT + HEIGHT_FIX))
>         ;;
>     -4)
>         xdotool windowmove "$WINDOW_ID" $MONITOR_X $MONITOR_Y
>         xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX))
> $((MONITOR_HEIGHT + HEIGHT_FIX))
>         ;;
>     -5)
>         xdotool windowmove "$WINDOW_ID" $MONITOR_X $MONITOR_Y
>         xdotool windowsize "$WINDOW_ID" $((MONITOR_WIDTH + WIDTH_FIX))
> $((MONITOR_HEIGHT + HEIGHT_FIX))
>         ;;
>     -6)
>         xdotool windowmove "$WINDOW_ID" $((MONITOR_X + HALF_WIDTH))
> $MONITOR_Y
>         xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX))
> $((MONITOR_HEIGHT + HEIGHT_FIX))
>         ;;
>     -7)
>         xdotool windowmove "$WINDOW_ID" $MONITOR_X $MONITOR_Y
>         xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX))
> $((HALF_HEIGHT + HEIGHT_FIX))
>         ;;
>     -8)
>         xdotool windowmove "$WINDOW_ID" $MONITOR_X $MONITOR_Y
>         xdotool windowsize "$WINDOW_ID" $((MONITOR_WIDTH + WIDTH_FIX))
> $((HALF_HEIGHT + HEIGHT_FIX))
>         ;;
>     -9)
>         xdotool windowmove "$WINDOW_ID" $((MONITOR_X + HALF_WIDTH))
> $MONITOR_Y
>         xdotool windowsize "$WINDOW_ID" $((HALF_WIDTH + WIDTH_FIX))
> $((HALF_HEIGHT + HEIGHT_FIX))
>         ;;
>     -g*)
>         GEOM="${COMMAND:2}" # strip "-g"
>         IFS=',' read -r GX GY GW GH <<< "$GEOM"
>         if [[ -n $GX && -n $GY && -n $GW && -n $GH ]]; then
>             xdotool windowmove "$WINDOW_ID" "$GX" "$GY"
>             xdotool windowsize "$WINDOW_ID" "$((GW + WIDTH_FIX))" "$((GH +
> HEIGHT_FIX))"
>         else
>             echo "Error: invalid geometry format. Use -gX,Y,W,H"
>             exit 1
>         fi
>         ;;
>     *)
>         echo "Error: Unknown command: $COMMAND"
>         exit 1
>         ;;
> esac
>
>
> On Wed, Sep 3, 2025 at 10:43 AM Jack <j4315593 at gmail.com> wrote:
>
>> 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 :)
>>
>> On Wed, Sep 3, 2025 at 10:29 AM killermoehre <killermoehre at gmx.net>
>> wrote:
>>
>>> Am Mittwoch, dem 03.09.2025 um 10:17 +0300 schrieb Jack:
>>>
>>> Unfortunately, *built-in commands cannot be used* 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.
>>>
>>> A really long time ago I wrote
>>> https://github.com/killermoehre/window-gridder for this purpose, but
>>> abondend it, because Xfwm4 hat inbuild what I need and it has problems with
>>> client side decorations.
>>>
>>> You can use it at a starting point.
>>>
>>> But IMHO it sounds like you want more of a tiling WM and not a floating
>>> one, right? Xfce allows to simply *replace* the current WM with another
>>> one. I wrote https://wiki.xfce.org/howto/other_window_manager for this.
>>> _______________________________________________
>>> Xfce mailing list
>>> Xfce at xfce.org
>>> https://mail.xfce.org/mailman/listinfo/xfce
>>> http://www.xfce.org
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.xfce.org/pipermail/xfce/attachments/20250903/fdda8307/attachment-0001.htm>


More information about the Xfce mailing list