This is how I managed to a basic Window tiling running on standard Linux Mint 22.1 x86_64 Cimminon

  • Save this into a file and make it executable e.g. ~/bin/send_windows_to.sh
  • Open Keyboard config > Shortcuts > Add Custom Shortcut
  • Give it a nice name and this command ~/bin/send_windows_to.sh topright
  • Set the Shortcut /hotkey
  • done

#!/bin/bash
# Resize and move the active window to the specified position
# The percentages are based on a 100% width and height of the screen
# Usage: send_windows_to.sh {topleft|topcenter|topright|bottomleft|bottomcenter|bottomright|maxleft|maxcenter|maxright}
#
# Requires wmctrl and xdotool to be installed
# wmctrl: sudo apt install wmctrl
# xdotool: sudo apt install xdotool
#
# Works with custom keyboard shortcuts with Linux Mint 22.1 x86_64 Cinnamon
#
# Layout designed for widescreen (5120x2160) 3x2 with 25/50/25 by 50/50

echo
# set -e -x

# Function to get current window position and size
get_window_info() {
  local window_id=$(xdotool getactivewindow)
  local position=$(xdotool getwindowgeometry $window_id | grep Position | awk '{print $2}')
  local geometry=$(xdotool getwindowgeometry $window_id | grep Geometry | awk '{print $2}')
  local screen_size=$(xdpyinfo | grep dimensions | awk '{print $2}')
  echo "$position $geometry $screen_size"
}

# Function to check if window is in specific position
is_window_at() {
  echo $@

  read expected_x expected_y expected_width expected_height <<< ${POSITIONS[$@]}
  local tolerance=100  # Pixel tolerance for comparison

  local window_info=$(get_window_info)
  local position=$(echo $window_info | awk '{print $1}')
  local geometry=$(echo $window_info | awk '{print $2}')
  local screen_size=$(echo $window_info | awk '{print $3}')

  local screen_width=$(echo $screen_size | cut -d 'x' -f1)
  local screen_height=$(echo $screen_size | cut -d 'x' -f2)

  local x=$(echo $position | cut -d ',' -f1)
  local y=$(echo $position | cut -d ',' -f2)
  local width=$(echo $geometry | cut -d 'x' -f1)
  local height=$(echo $geometry | cut -d 'x' -f2)

  local target_x=$(( screen_width  expected_x / 100 ))
  local target_y=$(( screen_height  expected_y / 100 ))
  local target_width=$(( screen_width  expected_width / 100 ))
  local target_height=$(( screen_height  expected_height / 100 ))

  # Check if window is within tolerance of target position and size
  if (( x >= target_x - tolerance && x <= target_x + tolerance )) && \
     (( y >= target_y - tolerance && y <= target_y + tolerance )) && \
     (( width >= target_width - tolerance && width <= target_width + tolerance )) && \
     (( height >= target_height - tolerance && height <= target_height + tolerance )); then
    return 0  # Success, window is at expected position
  else
    return 1  # Failure, window is not at expected position
  fi
}

# Define positions as associative array (dictionary)
declare -A POSITIONS
# Format: "X Y WIDTH HEIGHT"
POSITIONS["topleft"]="0 0 25 50"
POSITIONS["topcenter"]="25 0 50 50"
POSITIONS["topright"]="75 0 25 50"
POSITIONS["bottomleft"]="0 50 25 50"
POSITIONS["bottomcenter"]="25 50 50 50"
POSITIONS["bottomright"]="75 50 25 50"
POSITIONS["maxleft"]="0 0 26 100"
POSITIONS["maxcenter"]="25 0 50 100"
POSITIONS["maxright"]="75 0 25 100"
POSITIONS["maxright70"]="25 0 75 100"

POSITION="$1"

# Validate position
if [[ ! -v POSITIONS[$POSITION] ]]; then
  echo "Usage: $0 {topleft|topcenter|topright|bottomleft|bottomcenter|bottomright|maxleft|maxcenter|maxright}"
  exit 1
fi

# Parse the position values
read X Y WIDTH HEIGHT <<< ${POSITIONS[$POSITION]}

echo "$X $Y $WIDTH $HEIGHT"
echo $(is_window_at  <<< ${POSITIONS[$POSITION]})
# Special case for topcenter to toggle to maxcenter if already at topcenter
if [[ "$POSITION" == "topcenter" ]] && is_window_at "topcenter"; then
  echo "++++++++++++++++++++++Toggling to maxcenter++++++++++++++++++++++"
  read X Y WIDTH HEIGHT <<< ${POSITIONS["maxcenter"]}
fi
# Special case for maxcenter to toggle to maxright70 if already at maxcenter
if [[ "$POSITION" == "topcenter" ]] && is_window_at "maxcenter"; then
  echo "++++++++++++++++++++++Toggling to maxright70++++++++++++++++++++++"
  read X Y WIDTH HEIGHT <<< ${POSITIONS["maxright70"]}
fi
# Special case for maxcenter to toggle to maxright70 if already at maxcenter
if [[ "$POSITION" == "maxleft" ]] && is_window_at "maxleft"; then
  echo "++++++++++++++++++++++Toggling to maxright70++++++++++++++++++++++"
  read X Y WIDTH HEIGHT <<< ${POSITIONS["topleft"]}
fi
X=$((X))
Y=$((Y))
WIDTH=$((WIDTH))
HEIGHT=$((HEIGHT))
# Remove maximized state
wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz
sleep 0.1
#
xdotool getactivewindow windowsize ${WIDTH}% ${HEIGHT}%
xdotool getwindowfocus windowmove ${X}% ${Y}%

No comments

The author does not allow comments to this entry