I have two monitors, one is laptop LCD, another is external monitor, both operate in 1680x1050 resolution. If I use xrandr to enable both, I would have 1680x2100 or 3360x1050 combined screen resolution, I am currently using 1680x2100. Since they are physically two separate two monitors/screens and they are not same size, 15.4” and 20”, I would only focus on one of them. Sometimes, I want to move a window to another screen, I would have to drag and drop on another screen. There was always an issue, I didn’t want to change the window’s relative position to the left-top corner which the window is currently on. For example, win A’s position is at 20, 1200, it’s on the bottom screen. The relative position to the screen is 20, 150 (1200-1050). I want to move it to top screen and stay at 20, 150. If I move it back, it will be at 20, 1200, again.

So, I wrote this script:

#!/bin/bash

# Can get from wmctrl -d
S_W=1680
S_H=1050

# Get info of current active window

win_id=$(xprop -root | sed '/_NET_ACTIVE_WINDOW(WINDOW)/ {s/.*\(0x[a-z0-9]\+\)/\1/;q} ; d')

read win_x win_y <<< "$(xwininfo -id $win_id | sed '/Absolute/ {s/[ :a-z-]//gi;p} ; d' | tr '\n' ' ')"
read win_w win_h <<< "$(xwininfo -id $win_id | sed '/\(Width\|Height\)/ {s/[ :a-z-]//gi;p} ; d' | tr '\n' ' ')"
read b_left _ b_top _ <<< "$(xprop -id $win_id | sed '/FRAME.*CARDINAL/ {s/[_=(),a-z]//gi;q} ; d')"

# Remove window decoration
((win_x-=b_left))
((win_y-=b_top))

case "$1" in
  u|up)
    ((win_y-=S_H))
    ((win_y < 0)) && exit 1
    ;;
  d|down)
    ((win_y+=S_H))
    ((win_y >= 2*S_H)) && exit 1
    ;;
  l|left)
    ((win_x-=S_W))
    ((win_x < 0)) && exit 1
    ;;
  r|right)
    ((win_x+=S_W))
    ((win_x >= 2*S_W)) && exit 1
    ;;
  *)
    exit 1
    ;;
esac

# Somehow, the window gets taller in Fluxbox after moves, has to supply height instead of -1
wmctrl -i -r $win_id -e "0,$win_x,$win_y,-1,$win_h"

I bind Win+Up and Win+Down in my ~/.fluxbox/keys:

Mod4 Up :exec move-active-win.sh u
Mod4 Down :exec move-active-win.sh d