WinTricks

misko_2083

Found this script on LXLE, and it's really interesting.
Wasn't hard to make it run on VSIDO. I've just changed three lines to make it compatible with fluxbox :)
Tiles up windows and allows you to choose one. When you choose a window it resizes the windows back to original dimensions and brings selected window to focus.
The script start's when the mouse pointer stays longer than a second in the  top left corner of the screen. Uses xautolock daemon to detect mouse pointer position.
xautolock -locker "/usr/local/bin/winfuncs 'select'" -corners +000 -cornerdelay 1
So the autostart command would be.
xautolock -locker "/usr/local/bin/winfuncs 'select'" -corners +000 -cornerdelay 1 &
But first => apt-get install xautolock
Here is the script => /usr/local/bin/winfuncs
#!/bin/bash
# todo:
# cancel for tile functions
# determine what windows are maximized and re-max after the "window select" function
# determine what windows are non-resizable by the user so that the script doesn't resize them
# cascade also shaded windows
# which workspace we're on

function get_workspace {
        if [[ "$DTOP" == "" ]] ; then
            DTOP=`xdotool get_desktop`
        fi
}

function is_desktop {
xwininfo -id "$*" | grep '"Desktop"'
return "$?"
}

function get_visible_window_ids {
if (( ${#WDOWS[@]} == 0 )) ; then
WDOWS=(`xdotool search --desktop $DTOP --onlyvisible "" 2>/dev/null`)
fi
}

function get_desktop_dim {
#desktop dimensions
if (( ${#DIM[@]} == 0 )) ; then
DIM=(`wmctrl -d | egrep "^0" | sed 's/.*DG: \([0-9]*x[0-9]*\).*/\1/g' | sed 's/x/ /g'`)
fi
}

function win_showdesktop {
get_workspace
get_visible_window_ids

command="search --desktop $DTOP \"\""

if (( ${#WDOWS[@]} > 0 )) ; then
command="$command windowminimize %@"
else
command="$command windowraise %@"
fi

echo "$command" | xdotool -
}

function win_tile_two {
get_desktop_dim
wid1=`xdotool selectwindow 2>/dev/null`

is_desktop "$wid1" && return

wid2=`xdotool selectwindow 2>/dev/null`

is_desktop "$wid2" && return

half_w=`expr ${DIM[0]} / 2`

commands="windowsize $wid1 $half_w ${DIM[1]}"
commands="$commands windowsize $wid2 $half_w ${DIM[1]}"
commands="$commands windowmove $wid1 0 0"
commands="$commands windowmove $wid2 $half_w 0"
commands="$commands windowactivate $wid1"
commands="$commands windowactivate $wid2"

wmctrl -i -r $wid1 -b remove,maximized_vert,maximized_horz
wmctrl -i -r $wid2 -b remove,maximized_vert,maximized_horz

echo "$commands" | xdotool -
}

function win_tile {
get_workspace
get_visible_window_ids

(( ${#WDOWS[@]} < 1 )) && return;

get_desktop_dim

# determine how many rows and columns we need
cols=`echo "sqrt(${#WDOWS[@]})" | bc`
rows=$cols
wins=`expr $rows \* $cols`

if (( "$wins" < "${#WDOWS[@]}" )) ; then
cols=`expr $cols + 1`
wins=`expr $rows \* $cols`
if (( "$wins" < "${#WDOWS[@]}" )) ; then
    rows=`expr $rows + 1`
    wins=`expr $rows \* $cols`
fi
fi

(( $cols < 1 )) && cols=1;
(( $rows < 1 )) && rows=1;

win_w=`expr ${DIM[0]} / $cols`
win_h=`expr ${DIM[1]} / $rows`

# do tiling
x=0; y=0; commands=""
for window in ${WDOWS[@]} ; do
wmctrl -i -r $window -b remove,maximized_vert,maximized_horz

commands="$commands windowsize $window $win_w $win_h"
commands="$commands windowmove $window `expr $x \* $win_w` `expr $y \* $win_h`"

x=`expr $x + 1`
if (( $x > `expr $cols - 1` )) ; then
    x=0
    y=`expr $y + 1`
fi
done

echo "$commands" | xdotool -
}

function win_cascade {
get_workspace
get_visible_window_ids

(( ${#WDOWS[@]} < 1 )) && return;

x=0; y=0; commands=""
for window in ${WDOWS[@]} ; do
wmctrl -i -r $window -b remove,maximized_vert,maximized_horz

commands="$commands windowsize $window 640 480"
commands="$commands windowmove $window $x $y"

x=`expr $x + 22`
  y=`expr $y + 22`
done

echo "$commands" | xdotool -
}

function win_select {
get_workspace
get_visible_window_ids

(( ${#WDOWS[@]} < 1 )) && return;

# store window positions and widths
i=0
for window in ${WDOWS[@]} ; do
GEO=`xdotool getwindowgeometry $window | grep Geometry | sed 's/.* \([0-9].*\)/\1/g'`;
height[$i]=`echo $GEO | sed 's/\(.*\)x.*/\1/g'`
width[$i]=`echo $GEO | sed 's/.*x\(.*\)/\1/g'`

# ( xwininfo gives position not ignoring titlebars and borders, unlike xdotool )
POS=(`xwininfo -stats -id $window | grep 'geometry ' | sed 's/.*[-+]\([0-9]*[-+][0-9*]\)/\1/g' | sed 's/[+-]/ /g'`)
posx[$i]=${POS[0]}
posy[$i]=${POS[1]}

i=`expr $i + 1`
done

# tile windows
win_tile

# select a window
wid=`xdotool selectwindow 2>/dev/null`

is_desktop "$wid" && return

# restore window positions and widths
i=0; commands=""
for (( i=0; $i<${#WDOWS[@]}; i++ )) ; do
commands="$commands windowsize ${WDOWS[i]} ${height[$i]} ${width[$i]}"
commands="$commands windowmove ${WDOWS[i]} ${posx[$i]} ${posy[$i]}"
done

commands="$commands windowactivate $wid"

echo "$commands" | xdotool -
}

for command in ${@} ; do
if [[ "$command" == "tile" ]] ; then
win_tile
elif [[ "$command" == "select" ]] ; then
win_select
elif [[ "$command" == "tiletwo" ]] ; then
win_tile_two
elif [[ "$command" == "cascade" ]] ; then
win_cascade
elif [[ "$command" == "showdesktop" ]] ; then
win_showdesktop
fi
done

The script can do some more stuff with windows
/usr/local/bin/winfuncs 'showdesktop'
/usr/local/bin/winfuncs 'cascade'
/usr/local/bin/winfuncs 'tile'
/usr/local/bin/winfuncs 'tiletwo'
"Tile Two" is interesting, it tiles two windows next to each other.

Snap

#1
Thanks for sharing.

It seems a cool way to do it for those (like me) who don't like to have skippy-xd on board. the old and good cb-hotcorners script by corenominal might be another way to launch it instead of xautolock if you don't mind to use python. It needs wmctrl, xdotool & python-xlib

cb-hotcorners:

#!/usr/bin/env python
# cb-hotcorners:
# A script for adding hot corners to Openbox.
# Written for CrunchBang Linux <http://crunchbang.org/>
# by Philip Newborough <corenominal@corenominal.org>
# ----------------------------------------------------------------------
# License:
#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#                    Version 2, December 2004
#
# Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
#
# Everyone is permitted to copy and distribute verbatim or modified
# copies of this license document, and changing it is allowed as long
# as the name is changed.
#
#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
#  0. You just DO WHAT THE FUCK YOU WANT TO.
# ----------------------------------------------------------------------

from Xlib import display
from Xlib.ext.xtest import fake_input
from Xlib import X
from subprocess import Popen, PIPE, STDOUT
import sys, time, os, ConfigParser, re

check_intervall = 0.2

p = Popen(['xdotool','getdisplaygeometry'], stdout=PIPE, stderr=STDOUT)
Dimensions = p.communicate()
Dimensions = Dimensions[0].replace('\n', '')
Dimensions = Dimensions.split(' ')
width = int(Dimensions[0])
height = int(Dimensions[1])
hw = width / 2
rt = width - 1
bt = height - 1

def print_usage():
print "cb-hotcorners: usage:"
print "  --help          show this message and exit"
print "  --kill          attempt to kill any running instances"
print "  --daemon        run daemon and listen for cursor triggers"
print ""
exit()

if len(sys.argv) < 2 or sys.argv[1] == "--help":
print_usage()

elif sys.argv[1] == "--kill":
print "Attempting to kill any running instances..."
os.system('pkill -9 -f cb-hotcorners')
exit()

elif sys.argv[1] == "--daemon":
Config = ConfigParser.ConfigParser()
cfgdir = os.getenv("HOME")+"/.config/cb-hotcorners"
rcfile = cfgdir+"/cb-hotcornersrc"
bounce = 40
disp = display.Display()
root=display.Display().screen().root

def mousepos():
data = root.query_pointer()._data
return data["root_x"], data["root_y"], data["mask"]

def mousemove(x, y):
fake_input(disp, X.MotionNotify, x=x, y=y)
disp.sync()

try:
cfgfile = open(rcfile)
except IOError as e:
if not os.path.exists(cfgdir):
os.makedirs(cfgdir)
cfgfile = open(rcfile,'w')
Config.add_section('Hot Corners')
Config.set('Hot Corners','top_left_corner_command', 'gmrun')
Config.set('Hot Corners','top_right_corner_command', '')
Config.set('Hot Corners','bottom_left_corner_command', '')
Config.set('Hot Corners','bottom_right_corner_command', '')
Config.write(cfgfile)
cfgfile.close()

while True:
Config.read(rcfile)
time.sleep(check_intervall)
pos = mousepos()

if pos[0] == 0 and pos[1] == 0:
if Config.get('Hot Corners','top_left_corner_command') != '':
time.sleep(0.2)
pos = mousepos()
if pos[0] == 0 and pos[1] == 0:
mousemove(pos[0] + bounce, pos[1] + bounce)
os.system('(' + Config.get('Hot Corners','top_left_corner_command') + ') &')
mousemove(pos[0] + bounce, pos[1] + bounce)
time.sleep(2)

elif pos[0] == rt and pos[1] == 0:
if Config.get('Hot Corners','top_right_corner_command') != '':
time.sleep(0.2)
pos = mousepos()
if pos[0] == rt and pos[1] == 0 :
mousemove(pos[0] - bounce, pos[1] + bounce)
os.system('(' + Config.get('Hot Corners','top_right_corner_command') + ') &')
mousemove(pos[0] - bounce, pos[1] + bounce)
time.sleep(2)

elif pos[0] == 0 and pos[1] == bt:
if Config.get('Hot Corners','bottom_left_corner_command') != '':
time.sleep(0.2)
pos = mousepos()
if pos[0] == 0 and pos[1] == bt:
mousemove(pos[0] + bounce, pos[1] - bounce)
os.system('(' + Config.get('Hot Corners','bottom_left_corner_command') + ') &')
mousemove(pos[0] + bounce, pos[1] - bounce)
time.sleep(2)

elif pos[0] == rt and pos[1] == bt:
if Config.get('Hot Corners','bottom_right_corner_command') != '':
time.sleep(0.2)
pos = mousepos()
if pos[0] == rt and pos[1] == bt:
mousemove(pos[0] - bounce, pos[1] - bounce)
os.system('(' + Config.get('Hot Corners','bottom_right_corner_command') + ') &')
mousemove(pos[0] - bounce, pos[1] - bounce)
time.sleep(2)

else:
print_usage()


You can add it to the fluxbox startup (or ~/.xinitrc, or whatever,,,) and at fist run it will create a ~/.config/cb-hotcornersrc file that you can edit for your tricks. Here's an example: (this is an abandoned/forgotten config attempt to get some xdotool goodness from it. Some of the commented lines may not work, but you'll get the idea. All this reminded me II should go over it again).

[Hot Corners]
#TOP LEFT
top_left_corner_command = rofi -show window -font "snap 10" -fg "#505050" -bg "#000000" -hlfg "#ffb964" -hlbg "#000000" -o 85
#top_left_corner_command = xdotool behave_screen_edge top exec notify-send test
#top_left_corner_command = xdotool key --clearmodifiers "alt+Tab"
#top_left_corner_command = xdotool key "alt+Tab"

#TOP RIGHT
#top_right_corner_command = rofi -show window -font "snap 10" -fg "#505050" -bg "#000000" -hlfg "#ffb964" -hlbg "#000000" -o 85
top_right_corner_command = xfce4-terminal --drop-down
#top_right_corner_command = xdotool behave_screen_edge top exec notify-send test

#BOTTOM LEFT
#bottom_left_corner_command = dmenu_extended_run
#bottom_left_corner_command = xdotool key --clearmodifiers "alt+space"  ## knupfer
#bottom_left_corner_command = xdotool key --clearmodifiers "alt+mousewheel" ## Cycle desktops???
#bottom_left_corner_command = xdotool key --clearmodifiers "alt+Tab"
#bottom_left_corner_command = xdotool key "alt+Tab"
#bottom_left_corner_command = xdotool key "alt+F4"
bottom_left_corner_command = rofi -show run -font "snap 10" -fg "#505050" -bg "#000000" -hlfg "#ffb964" -hlbg "#000000" -o 85

#BOTTOM RIGHT
bottom_right_corner_command = xdotool behave_screen_edge top exec notify-send test
#bottom_right_corner_command = rofi -show run -font "snap 10" -fg "#505050" -bg "#000000" -hlfg "#ffb964" -hlbg "#000000" -o 85
#bottom_right_corner_command = xfce4-appfinder --collapsed
#bottom_right_corner_command = xdotool key "alt+Tab"
#bottom_right_corner_command = xdotool key --clearmodifiers "super+mousewheel"

misko_2083

@Snap Thanks for sharing. I will have a look tomorrow.  It's very late in this time zone. :)

seppalta

#3
Nice script, Misko, I think.  I'm trying to use it with Openbox.  Going to upper left corner tiles the open windows as described, but leaves the mouse pointer as an "x", which untiles (restores the original windows set-up) as soon as I click something.  That is not very useful.  What am I missing?  Where did you find the original script on LXLE?

misko_2083

Quote from: seppalta on December 18, 2015, 07:17:27 AM
Nice script, Misko, I think.  I'm trying to use it with Openbox.  Going to upper left corner tiles the open windows as described, but leaves the mouse pointer as an "x", which untiles (restores the original windows set-up) as soon as I click something.  That is not very useful.  What am I missing?  Where did you find the original script on LXLE?
Yes it tiles the windows so you can select one to bring it to focus.
If you just want to tile windows use:
xautolock -locker "/usr/local/bin/winfuncs 'tile'" -corners +000 -cornerdelay 1
or tile two which allows you to select two windows and tile them next to each other
xautolock -locker "/usr/local/bin/winfuncs 'tiletwo'" -corners +000 -cornerdelay 1
Cascade is also interesting:
xautolock -locker "/usr/local/bin/winfuncs 'cascade'" -corners +000 -cornerdelay 1
Found the script on a live LXLE running in a Virtual Machine. I think the script file was in /usr/local/bin

seppalta

Quote from: misko_2083 on December 19, 2015, 02:00:05 AM
Yes it tiles the windows so you can select one to bring it to focus.
Thanks, Misko.  Got it now.  No qualifier; it is really a nice script!

misko_2083

Quote from: seppalta on December 19, 2015, 04:45:55 AM
Quote from: misko_2083 on December 19, 2015, 02:00:05 AM
Yes it tiles the windows so you can select one to bring it to focus.
Thanks, Misko.  Got it now.  No qualifier; it is really a nice script!
Yeah, I agree Seppalta. Usefull little thing.  :)