Skip to content

Instantly share code, notes, and snippets.

@DanH42
Created December 20, 2018 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanH42/40f06c571f544381ba5f3cbe892e6317 to your computer and use it in GitHub Desktop.
Save DanH42/40f06c571f544381ba5f3cbe892e6317 to your computer and use it in GitHub Desktop.
Helper script for performing some useful window manipulation tasks
#!/bin/bash
# Helper script for performing some useful window manipulation tasks
# Version 1.1.2
#
# Dependencies: xdotool
#
# This script should be bound to some keyboard shortcuts, and will target
# whatever window currently has focus. For example:
# Alt+Shift+Left - /path/to/windowctl.sh move_l
# Alt+Shift+Right - /path/to/windowctl.sh move_r
# Alt+Shift+Down - /path/to/windowctl.sh center
# This script works best if all displays are the same width, and assumes they
# are all arranged horizontally.
# wmctl doesn't take window borders into account when setting their position,
# but does include them when getting it. You can get these values by running:
# ./windowctl.sh get_offsets
# and copying the values here. Make sure the terminal you run the command in
# isn't maximized and has a little bit of room on all sides to move around.
WINDOW_BORDER_X=3
WINDOW_BORDER_Y=24
# Width in pixels of your entire workspace (all monitors combined)
# This value could be calculated, but doing so using xdotool is slow (~.5s)
DESKTOP_WIDTH=$[1920 * 3]
# Script begins
eval `xdotool getwindowfocus getdisplaygeometry --shell`
SCREEN_WIDTH=$WIDTH
SCREEN_HEIGHT=$HEIGHT
# Sets $X, $Y, $WIDTH, $HEIGHT
eval `xdotool getwindowfocus getwindowgeometry --shell`
case "$1" in
move_l)
# Move the current window one screen to the left
if [[ $[$X - $SCREEN_WIDTH] -ge 0 ]]; then
SCREEN_L=$[$[$SCREEN_WIDTH * -1] - $WINDOW_BORDER_X]
xdotool getwindowfocus windowmove --relative -- $SCREEN_L $[$WINDOW_BORDER_Y * -1]
fi
;;
move_r)
# Move the current window one screen to the right
if [[ $[$X + $SCREEN_WIDTH] -lt $DESKTOP_WIDTH ]]; then
SCREEN_R=$[$SCREEN_WIDTH - $WINDOW_BORDER_X]
xdotool getwindowfocus windowmove --relative -- $SCREEN_R $[$WINDOW_BORDER_Y * -1]
fi
;;
center)
# Move the current window to the center of the current screen
SCREEN_CENTER_X=$[$[$[$SCREEN_WIDTH - $WIDTH] / 2] - $WINDOW_BORDER_X]
GLOBAL_CENTER_X=$[$SCREEN_CENTER_X + $[$SCREEN_WIDTH * $[$X / $SCREEN_WIDTH]]]
SCREEN_CENTER_Y=$[$[$SCREEN_HEIGHT / 2] - $[$HEIGHT / 2] - $WINDOW_BORDER_Y]
xdotool getwindowfocus windowmove $GLOBAL_CENTER_X $SCREEN_CENTER_Y
;;
get_offsets)
# Calculate appropriate values for window border offset
eval `xdotool getwindowfocus getwindowgeometry --shell`
X_START=$X
Y_START=$Y
xdotool getwindowfocus windowmove --sync --relative -- 0 0
eval `xdotool getwindowfocus getwindowgeometry --shell`
DELTA_X=$[$X - $X_START]
DELTA_Y=$[$Y - $Y_START]
echo WINDOW_BORDER_X=$DELTA_X
echo WINDOW_BORDER_Y=$DELTA_Y
xdotool getwindowfocus windowmove --relative -- $[$DELTA_X * -2] $[$DELTA_Y * -2]
if [[ $WINDOW_BORDER_X -eq $DELTA_X && $WINDOW_BORDER_Y -eq $DELTA_Y ]]; then
echo "# Values match -- no change needed"
fi
;;
debug)
# Print all valules that would be used in calculations
echo WINDOW_BORDER_X=$WINDOW_BORDER_X
echo WINDOW_BORDER_Y=$WINDOW_BORDER_Y
echo DESKTOP_WIDTH=$DESKTOP_WIDTH
echo SCREEN_WIDTH=$SCREEN_WIDTH
echo SCREEN_HEIGHT=$SCREEN_HEIGHT
echo WIDTH=$WIDTH
echo HEIGHT=$HEIGHT
echo X=$X
echo Y=$Y
;;
*)
echo "Valid arguments: move_l, move_r, center, get_offsets, debug"
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment