winfuncs.sh (12367B)
1 #!/bin/bash 2 3 #todo: 4 # cancel for tile function 5 # determine what windows are maximized and re-max after the "window select" function 6 # determine what windows are non-resizable by the user so that the script doesn't resize them 7 # cascade also shaded windows 8 9 # winfuncs.sh select 10 # winfuncs.sh tile 11 # winfuncs.sh tiletwo 12 # winfuncs.sh tiletwol 13 # winfuncs.sh tiletwor 14 # winfuncs.sh tilethree 15 # winfuncs.sh tilethreev 16 # winfuncs.sh stacktwo 17 # winfuncs.sh cascade 18 # winfuncs.sh showdesktop 19 20 # set gaps (0 removes gaps) 21 outer_gaps=5 22 inner_gaps=5 23 24 # set gaps for 'select' mode 25 expose_gaps=20 26 27 # set desktop dimensions 28 display_width=$(xdotool getdisplaygeometry | cut -d" " -f1) 29 display_height=$(xdotool getdisplaygeometry | cut -d" " -f2) 30 31 # desktop height without panel(s) 32 desktop_height=$(xprop -root _NET_WORKAREA | awk '{ print $6 }' | cut -d"," -f1) 33 34 # window decorations 35 window_id=$(xdotool getactivewindow) 36 titlebar_offset=$(xwininfo -id "$window_id" | awk '/Relative upper-left Y:/ { print $4 }') 37 38 # top panel 39 top_bar=$(xprop -root _NET_WORKAREA | awk '{ print $4 }' | cut -d"," -f1) 40 41 # bottom panel (not needed) 42 bottom_bar=`expr $display_height - $desktop_height - $top_bar` 43 44 function get_desktop_dim { 45 if (( ${#DIM[@]} == 0 )) ; then 46 DIM=(`expr $display_width - $outer_gaps \* 2` `expr $desktop_height - $outer_gaps \* 2`) 47 fi 48 } 49 50 # which workspace we're on 51 function get_workspace { 52 if [[ "$DTOP" == "" ]] ; then 53 DTOP=`xdotool get_desktop` 54 fi 55 } 56 57 function is_desktop { 58 xwininfo -id "$*" | grep '"Desktop"' 59 return "$?" 60 } 61 62 function get_visible_window_ids { 63 if (( ${#WDOWS[@]} == 0 )) ; then 64 WDOWS=(`xdotool search --desktop $DTOP --onlyvisible "" 2>/dev/null`) 65 fi 66 } 67 68 function win_showdesktop { 69 get_workspace 70 get_visible_window_ids 71 72 command="search --desktop $DTOP \"\"" 73 74 if (( ${#WDOWS[@]} > 0 )) ; then 75 command="$command windowminimize %@" 76 else 77 command="$command windowraise %@" 78 fi 79 80 echo "$command" | xdotool - 81 } 82 83 function win_tile_two { 84 get_desktop_dim 85 86 wid1=`xdotool selectwindow 2>/dev/null` 87 88 is_desktop "$wid1" && return 89 90 wid2=`xdotool selectwindow 2>/dev/null` 91 92 is_desktop "$wid2" && return 93 94 half_w=`expr ${DIM[0]} / 2` 95 win_h=${DIM[1]} 96 97 commands="windowsize $wid1 `expr $half_w - $inner_gaps` `expr $win_h - $titlebar_offset`" 98 commands="$commands windowsize $wid2 `expr $half_w - $inner_gaps` `expr $win_h - $titlebar_offset`" 99 commands="$commands windowmove $wid1 $outer_gaps `expr $top_bar + $outer_gaps`" 100 commands="$commands windowmove $wid2 `expr $half_w + $outer_gaps + $inner_gaps` `expr $top_bar + $outer_gaps`" 101 commands="$commands windowraise $wid1" 102 commands="$commands windowraise $wid2" 103 104 wmctrl -i -r $wid1 -b remove,maximized_vert,maximized_horz 105 wmctrl -i -r $wid2 -b remove,maximized_vert,maximized_horz 106 107 echo "$commands" | xdotool - 108 } 109 110 function win_tile_two_left { 111 get_desktop_dim 112 113 wid1=`xdotool selectwindow 2>/dev/null` 114 115 is_desktop "$wid1" && return 116 117 wid2=`xdotool selectwindow 2>/dev/null` 118 119 is_desktop "$wid2" && return 120 121 half_w=`expr ${DIM[0]} / 3` 122 win_h=${DIM[1]} 123 124 commands="windowsize $wid1 `expr $half_w \* 2 - $inner_gaps` `expr $win_h - $titlebar_offset`" 125 commands="$commands windowsize $wid2 `expr $half_w - $inner_gaps` `expr $win_h - $titlebar_offset`" 126 commands="$commands windowmove $wid1 $outer_gaps `expr $top_bar + $outer_gaps`" 127 commands="$commands windowmove $wid2 `expr $half_w \* 2 + $outer_gaps + $inner_gaps` `expr $top_bar + $outer_gaps`" 128 commands="$commands windowraise $wid1" 129 commands="$commands windowraise $wid2" 130 131 wmctrl -i -r $wid1 -b remove,maximized_vert,maximized_horz 132 wmctrl -i -r $wid2 -b remove,maximized_vert,maximized_horz 133 134 echo "$commands" | xdotool - 135 } 136 137 function win_tile_two_right { 138 get_desktop_dim 139 140 wid1=`xdotool selectwindow 2>/dev/null` 141 142 is_desktop "$wid1" && return 143 144 wid2=`xdotool selectwindow 2>/dev/null` 145 146 is_desktop "$wid2" && return 147 148 half_w=`expr ${DIM[0]} / 3` 149 win_h=${DIM[1]} 150 151 commands="windowsize $wid1 `expr $half_w - $inner_gaps` `expr $win_h - $titlebar_offset`" 152 commands="$commands windowsize $wid2 `expr $half_w \* 2 - $inner_gaps` `expr $win_h - $titlebar_offset`" 153 commands="$commands windowmove $wid1 $outer_gaps `expr $top_bar + $outer_gaps`" 154 commands="$commands windowmove $wid2 `expr $half_w + $outer_gaps + $inner_gaps` `expr $top_bar + $outer_gaps`" 155 commands="$commands windowraise $wid1" 156 commands="$commands windowraise $wid2" 157 158 wmctrl -i -r $wid1 -b remove,maximized_vert,maximized_horz 159 wmctrl -i -r $wid2 -b remove,maximized_vert,maximized_horz 160 161 echo "$commands" | xdotool - 162 } 163 164 function win_stack_two { 165 get_desktop_dim 166 167 wid1=`xdotool selectwindow 2>/dev/null` 168 169 is_desktop "$wid1" && return 170 171 wid2=`xdotool selectwindow 2>/dev/null` 172 173 is_desktop "$wid2" && return 174 175 win_w=${DIM[0]} 176 half_h=`expr ${DIM[1]} / 2` 177 178 commands="windowsize $wid1 `expr $win_w` `expr $half_h - $titlebar_offset - $inner_gaps`" 179 commands="$commands windowsize $wid2 `expr $win_w` `expr $half_h - $titlebar_offset - $inner_gaps`" 180 commands="$commands windowmove $wid1 $outer_gaps `expr $top_bar + $outer_gaps`" 181 commands="$commands windowmove $wid2 $outer_gaps `expr $half_h + $top_bar + $outer_gaps + $inner_gaps`" 182 commands="$commands windowraise $wid1" 183 commands="$commands windowraise $wid2" 184 185 wmctrl -i -r $wid1 -b remove,maximized_vert,maximized_horz 186 wmctrl -i -r $wid2 -b remove,maximized_vert,maximized_horz 187 188 echo "$commands" | xdotool - 189 } 190 191 192 function win_tile_three { 193 get_desktop_dim 194 195 wid1=`xdotool selectwindow 2>/dev/null` 196 197 is_desktop "$wid1" && return 198 199 wid2=`xdotool selectwindow 2>/dev/null` 200 201 is_desktop "$wid2" && return 202 203 wid3=`xdotool selectwindow 2>/dev/null` 204 205 is_desktop "$wid3" && return 206 207 win_h=${DIM[1]} 208 half_w=`expr ${DIM[0]} / 2` 209 half_h=`expr ${win_h} / 2` 210 211 commands="windowsize $wid1 `expr $half_w - $inner_gaps` `expr $win_h - $titlebar_offset`" 212 commands="$commands windowsize $wid2 `expr $half_w - $inner_gaps` `expr $half_h - $titlebar_offset - $inner_gaps`" 213 commands="$commands windowsize $wid3 `expr $half_w - $inner_gaps` `expr $half_h - $titlebar_offset - $inner_gaps`" 214 commands="$commands windowmove $wid1 $outer_gaps `expr $top_bar + $outer_gaps`" 215 commands="$commands windowmove $wid2 `expr $half_w + $outer_gaps + $inner_gaps` `expr $top_bar + $outer_gaps`" 216 commands="$commands windowmove $wid3 `expr $half_w + $outer_gaps + $inner_gaps` `expr $half_h + $top_bar + $outer_gaps + $inner_gaps`" 217 commands="$commands windowraise $wid1" 218 commands="$commands windowraise $wid2" 219 commands="$commands windowraise $wid3" 220 221 wmctrl -i -r $wid1 -b remove,maximized_vert,maximized_horz 222 wmctrl -i -r $wid2 -b remove,maximized_vert,maximized_horz 223 wmctrl -i -r $wid3 -b remove,maximized_vert,maximized_horz 224 225 echo "$commands" | xdotool - 226 } 227 228 function win_tile_three_v { 229 get_desktop_dim 230 231 wid1=`xdotool selectwindow 2>/dev/null` 232 233 is_desktop "$wid1" && return 234 235 wid2=`xdotool selectwindow 2>/dev/null` 236 237 is_desktop "$wid2" && return 238 239 wid3=`xdotool selectwindow 2>/dev/null` 240 241 is_desktop "$wid3" && return 242 243 win_h=${DIM[1]} 244 half_w=`expr ${DIM[0]} / 3` 245 246 commands="windowsize $wid1 `expr $half_w - $inner_gaps` `expr $win_h - $titlebar_offset`" 247 commands="$commands windowsize $wid2 `expr $half_w - $inner_gaps` `expr $win_h - $titlebar_offset`" 248 commands="$commands windowsize $wid3 `expr $half_w - $inner_gaps` `expr $win_h - $titlebar_offset`" 249 commands="$commands windowmove $wid1 $outer_gaps `expr $top_bar + $outer_gaps`" 250 commands="$commands windowmove $wid2 `expr $half_w + $outer_gaps + $inner_gaps / 2` `expr $top_bar + $outer_gaps`" 251 commands="$commands windowmove $wid3 `expr $half_w \* 2 + $outer_gaps + $inner_gaps` `expr $top_bar + $outer_gaps`" 252 commands="$commands windowraise $wid1" 253 commands="$commands windowraise $wid2" 254 commands="$commands windowraise $wid3" 255 256 wmctrl -i -r $wid1 -b remove,maximized_vert,maximized_horz 257 wmctrl -i -r $wid2 -b remove,maximized_vert,maximized_horz 258 wmctrl -i -r $wid3 -b remove,maximized_vert,maximized_horz 259 260 echo "$commands" | xdotool - 261 } 262 263 function win_tile { 264 get_workspace 265 get_visible_window_ids 266 267 (( ${#WDOWS[@]} < 1 )) && return; 268 269 get_desktop_dim 270 271 # determine how many rows and columns we need 272 cols=`echo "sqrt(${#WDOWS[@]})" | bc` 273 rows=$cols 274 wins=`expr $rows \* $cols` 275 276 if (( "$wins" < "${#WDOWS[@]}" )) ; then 277 cols=`expr $cols + 1` 278 wins=`expr $rows \* $cols` 279 if (( "$wins" < "${#WDOWS[@]}" )) ; then 280 rows=`expr $rows + 1` 281 wins=`expr $rows \* $cols` 282 fi 283 fi 284 285 (( $cols < 1 )) && cols=1; 286 (( $rows < 1 )) && rows=1; 287 288 win_w=`expr ${DIM[0]} / $cols` 289 win_h=`expr ${DIM[1]} / $rows` 290 291 # do tiling 292 x=0; y=0; commands="" 293 for window in ${WDOWS[@]} ; do 294 wmctrl -i -r $window -b remove,maximized_vert,maximized_horz 295 296 commands="$commands windowsize $window `expr $win_w - $inner_gaps \* 2` `expr $win_h - $titlebar_offset - $inner_gaps \* 2`" 297 commands="$commands windowmove $window `expr $x \* $win_w + $outer_gaps` `expr $y \* $win_h + $top_bar + $outer_gaps`" 298 299 x=`expr $x + 1` 300 if (( $x > `expr $cols - 1` )) ; then 301 x=0 302 y=`expr $y + 1` 303 fi 304 done 305 306 echo "$commands" | xdotool - 307 } 308 309 function expose { 310 get_workspace 311 get_visible_window_ids 312 313 (( ${#WDOWS[@]} < 1 )) && return; 314 315 get_desktop_dim 316 317 # determine how many rows and columns we need 318 cols=`echo "sqrt(${#WDOWS[@]})" | bc` 319 rows=$cols 320 wins=`expr $rows \* $cols` 321 322 if (( "$wins" < "${#WDOWS[@]}" )) ; then 323 cols=`expr $cols + 1` 324 wins=`expr $rows \* $cols` 325 if (( "$wins" < "${#WDOWS[@]}" )) ; then 326 rows=`expr $rows + 1` 327 wins=`expr $rows \* $cols` 328 fi 329 fi 330 331 (( $cols < 1 )) && cols=1; 332 (( $rows < 1 )) && rows=1; 333 334 win_w=`expr ${DIM[0]} / $cols` 335 win_h=`expr ${DIM[1]} / $rows` 336 337 # do tiling 338 x=0; y=0; commands="" 339 for window in ${WDOWS[@]} ; do 340 wmctrl -i -r $window -b remove,maximized_vert,maximized_horz 341 342 commands="$commands windowsize $window `expr $win_w - $expose_gaps \* 2` `expr $win_h - $titlebar_offset - $expose_gaps \* 2`" 343 commands="$commands windowmove $window `expr $x \* $win_w + $expose_gaps` `expr $y \* $win_h + $top_bar + $expose_gaps`" 344 345 x=`expr $x + 1` 346 if (( $x > `expr $cols - 1` )) ; then 347 x=0 348 y=`expr $y + 1` 349 fi 350 done 351 352 echo "$commands" | xdotool - 353 } 354 355 function win_cascade { 356 get_workspace 357 get_visible_window_ids 358 359 (( ${#WDOWS[@]} < 1 )) && return; 360 361 x=0; y=0; commands="" 362 for window in ${WDOWS[@]} ; do 363 wmctrl -i -r $window -b remove,maximized_vert,maximized_horz 364 365 commands="$commands windowsize $window 1024 640" 366 commands="$commands windowmove $window `expr $x + $outer_gaps` `expr $y + $top_bar + $outer_gaps`" 367 368 x=`expr $x + 100` 369 y=`expr $y + 80` 370 done 371 372 echo "$commands" | xdotool - 373 } 374 375 function win_select { 376 get_workspace 377 get_visible_window_ids 378 379 (( ${#WDOWS[@]} < 1 )) && return; 380 381 # store window positions and widths 382 i=0 383 for window in ${WDOWS[@]} ; do 384 GEO=`xdotool getwindowgeometry $window | grep Geometry | sed 's/.* \([0-9].*\)/\1/g'`; 385 height[$i]=`echo $GEO | sed 's/\(.*\)x.*/\1/g'` 386 width[$i]=`echo $GEO | sed 's/.*x\(.*\)/\1/g'` 387 388 # ( xwininfo gives position not ignoring titlebars and borders, unlike xdotool ) 389 POS=(`xwininfo -stats -id $window | grep 'geometry ' | sed 's/.*[-+]\([0-9]*[-+][0-9*]\)/\1/g' | sed 's/[+-]/ /g'`) 390 posx[$i]=${POS[0]} 391 posy[$i]=${POS[1]} 392 393 i=`expr $i + 1` 394 done 395 396 # tile windows 397 expose 398 399 # select a window 400 wid=`xdotool selectwindow 2>/dev/null` 401 402 is_desktop "$wid" && return 403 404 # restore window positions and widths 405 i=0; commands="" 406 for (( i=0; $i<${#WDOWS[@]}; i++ )) ; do 407 commands="$commands windowsize ${WDOWS[i]} ${height[$i]} ${width[$i]}" 408 commands="$commands windowmove ${WDOWS[i]} ${posx[$i]} ${posy[$i]}" 409 done 410 411 commands="$commands windowraise $wid" 412 413 echo "$commands" | xdotool - 414 } 415 416 for command in ${@} ; do 417 if [[ "$command" == "tile" ]] ; then 418 win_tile 419 elif [[ "$command" == "select" ]] ; then 420 win_select 421 elif [[ "$command" == "tiletwo" ]] ; then 422 win_tile_two 423 elif [[ "$command" == "tiletwol" ]] ; then 424 win_tile_two_left 425 elif [[ "$command" == "tiletwor" ]] ; then 426 win_tile_two_right 427 elif [[ "$command" == "stacktwo" ]] ; then 428 win_stack_two 429 elif [[ "$command" == "tilethree" ]] ; then 430 win_tile_three 431 elif [[ "$command" == "tilethreev" ]] ; then 432 win_tile_three_v 433 elif [[ "$command" == "cascade" ]] ; then 434 win_cascade 435 elif [[ "$command" == "showdesktop" ]] ; then 436 win_showdesktop 437 fi 438 done