├── 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 | 
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 |
--------------------------------------------------------------------------------