├── clicksnap.png ├── CHANGELOG.md ├── README.md └── clicksnap /clicksnap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/napcok/clicksnap/HEAD/clicksnap.png -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | 3 | ### 7.05.2021 4 | - option to disable "outer_gap" 5 | 6 | ### 4.05.2021 7 | - ignore Dock type windows, like tint2 panel 8 | - better size and position calculation with gap 9 | - handle undecorated windows 10 | - handle gap 11 | 12 | ### 3.05.2021 13 | - initial "quick and dirty" version 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # clicksnap 2 | 3 | clicksnap for Openbox - click on the appropriate area of the window to snap it in a given direction. 4 | Works with active and inactive windows. 5 | Configurable gap between windows. 6 | 7 | *(Far from perfection, but imho already enough good to use)* 8 | 9 | See it in action: https://www.youtube.com/watch?v=UzgUYYXnRww 10 | 11 | ## Requirements 12 | - wmctrl 13 | - xdotool 14 | - xwininfo 15 | 16 | ## Installation 17 | 18 | Add this mousebind action to context Frame: 19 | 20 | 21 | 22 | 23 | clicksnap 24 | 25 | 26 | 27 | 28 | ## Usage 29 | clicksnap is binded to Ctrl + Left Mouse Click 30 | Click inside window you like to move. 31 | There are 9 areas ... see screenshot :) 32 | 33 | ![clicksnap](clicksnap.png "clicksnap areas") 34 | 35 | ## Configuration 36 | 37 | Edit variables on top of script 38 | 39 | ### Configuration 40 | # Gap between windows 41 | GAP="32" 42 | show_outer_gap="true" 43 | # TITLEBAR HEIGHT - no idea how to find it from cli 44 | TITLEBAR_HEIGHT="20" 45 | # Activate moved windows? 46 | activate_window="false" 47 | ### End Configuration 48 | -------------------------------------------------------------------------------- /clicksnap: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### clicksnap - click on the appropriate area of the window to snap it in a given direction. 3 | # Works with active and inactive windows 4 | # Author: Daniel Napora 5 | # https://maboxlinux.org 6 | # 7 | ### Configuration 8 | # Gap between windows 9 | GAP="32" 10 | show_outer_gap="true" 11 | # TITLEBAR HEIGHT - no idea how to find it from cli 12 | TITLEBAR_HEIGHT="20" 13 | # Activate moved windows? 14 | activate_window="false" 15 | ### End Configuration 16 | 17 | 18 | eval $(xdotool getmouselocation --shell) 19 | Mouse_x="$X" 20 | Mouse_y="$Y" 21 | 22 | HEX_ID=$(printf '0x%x\n' $WINDOW) 23 | 24 | CHILD_ID=$(xwininfo -id $HEX_ID -children|grep "\"" | awk '{print $1}') 25 | if xwininfo -id $CHILD_ID -wm |grep Dock ; then exit 0 ;fi # Ignore Dock eg. tint2 26 | if xwininfo -id $CHILD_ID -wm |grep Undecorated ; then # Undecorated 27 | T="0" 28 | else # Decorated 29 | T="$TITLEBAR_HEIGHT" 30 | fi 31 | 32 | ## OUTER GAP 33 | if [[ "$show_outer_gap" == "true" ]]; then OUT_GAP="$GAP" ; else OUT_GAP="0" ; fi 34 | echo "OUT_GAP: $OUT_GAP" 35 | 36 | eval $(xdotool getwindowgeometry --shell $WINDOW) 37 | Win_x="$X" 38 | Win_y="$Y" 39 | Win_width="$WIDTH" 40 | Win_height="$HEIGHT" 41 | 42 | Rel_x="$((Mouse_x-Win_x))" 43 | Rel_y="$((Mouse_y-Win_y))" 44 | 45 | pos_x="$(((Mouse_x-Win_x)/(Win_width/3)))" 46 | pos_y="$(((Mouse_y-Win_y)/(Win_height/3)))" 47 | POS_CODE="$pos_x$pos_y" 48 | 49 | OFFSET=$(wmctrl -d |grep "*" | awk -F' ' '{print $8}') 50 | REALSIZE=$(wmctrl -d |grep "*" | awk -F' ' '{print $9}') 51 | 52 | AVAIL_X="${REALSIZE%x*}" 53 | AVAIL_Y="${REALSIZE#*x}" 54 | 55 | OFF_X="${OFFSET%,*}" 56 | OFF_Y="${OFFSET#*,}" 57 | 58 | case $POS_CODE in 59 | 00) # top-left 60 | W=$((AVAIL_X/2-OUT_GAP-GAP/2)) H=$((AVAIL_Y/2-T-OUT_GAP-GAP/2)) X=$((0+OFF_X+OUT_GAP)) Y=$((0+OFF_Y+OUT_GAP));; 61 | 10) # top 62 | W=$((AVAIL_X-OUT_GAP*2)) H=$((AVAIL_Y/2-T-OUT_GAP-GAP/2)) X=$((0+OFF_X+OUT_GAP)) Y=$((0+OFF_Y+OUT_GAP));; 63 | 20) # top-right 64 | W=$((AVAIL_X/2-OUT_GAP-GAP/2)) H=$((AVAIL_Y/2-T-OUT_GAP-GAP/2)) X=$((AVAIL_X/2+OFF_X+GAP/2)) Y=$((0+OFF_Y+OUT_GAP));; 65 | 01) # left 66 | W=$((AVAIL_X/2-OUT_GAP-GAP/2)) H=$((AVAIL_Y-T-OUT_GAP*2)) X=$((0+OFF_X+OUT_GAP)) Y=$((0+OFF_Y+OUT_GAP));; 67 | 11) # center 68 | W=$((AVAIL_X/8*6-OFF_X)) H=$((AVAIL_Y/8*6-T)) X=$((AVAIL_X/8+OFF_X/2)) Y=$((AVAIL_Y/8+OFF_Y/2));; 69 | 21) # right 70 | W=$((AVAIL_X/2-OUT_GAP-GAP/2)) H=$((AVAIL_Y-T-OUT_GAP*2)) X=$((AVAIL_X/2+OFF_X+GAP/2)) Y=$((0+OFF_Y+OUT_GAP));; 71 | 02) # bottom-left 72 | W=$((AVAIL_X/2-OUT_GAP-GAP/2)) H=$((AVAIL_Y/2-T-OUT_GAP-GAP/2)) X=$((0+OFF_X+OUT_GAP)) Y=$((AVAIL_Y/2+OFF_Y+GAP/2));; 73 | 12) # bottom 74 | W=$((AVAIL_X-OUT_GAP*2)) H=$((AVAIL_Y/2-T-OUT_GAP-GAP/2)) X=$((0+OFF_X+OUT_GAP)) Y=$((AVAIL_Y/2+OFF_Y+GAP/2));; 75 | 22) # bottom-right 76 | W=$((AVAIL_X/2-OUT_GAP-GAP/2)) H=$((AVAIL_Y/2-T-OUT_GAP-GAP/2)) X=$((AVAIL_X/2+OFF_X+GAP/2)) Y=$((AVAIL_Y/2+OFF_Y+GAP/2));; 77 | esac 78 | 79 | xdotool windowsize $WINDOW $W $H 80 | xdotool windowmove $WINDOW $X $Y 81 | if [ $activate_window == "true" ]; then xdotool windowactivate $WINDOW; fi 82 | --------------------------------------------------------------------------------