winpwnr.sh
winpwnr.sh is a one-liner Haikus’ hey front-end with the only intent to domate windows
#! /bin/sh
Usage()
{
echo "usage: ${script_name} -option <value>
-a select the application by name
-l list windows for the selected application
-s select application's window by ID number or title
-d avoid to overlap the Deskbar
-t change the title of the selected window
-f force fullscreen for the selected window, no value is needed
-w show the selected window on {x} workspace(s),
you can set multiple values separated by any character, like
\"1,2,4,5\" or \"5.6.1\", use \"all\" to show it in every workspace
-p move the selected window by x,y pixels (relative)
-P move the selected window to x,y (absolute) position
-L change the LOOK of the selected window:
- b OR bordered
- n OR no-border
- t OR titled
- d OR document
- m OR modal
- f OR floating
-F change the FEEL of the selected window:
- n OR normal
- ms OR modal-subset
- mp OR modal-app
- ml OR modal-all
- fs OR floating-subset
- fp OR floating-app
- fl OR floating-all
-G change the FLAGS of the selected window, multiple valuese are accepted separated by commas
- nm OR not-movable
- nr OR not-resizable
- nh OR not-h-resizable
- nv OR not-v-resizable
- fs OR accept-first-click
- nc OR not-closable
- nz OR not-zoomable
- af OR avoid-front
- nw OR no-workspace-activation
- as OR avoid-focus
- nb OR not-minimizable
- na OR not_anchored
- sp OR same-position
- ce OR close-on-escape
-M minimize the selected window (1, t, true, on, y, yes / 0, f, false, off, n, no / toggle)
-A active the selected window (1, t, true, on, y, yes / 0, f, false, off, n, no / toggle)
-m move the selected window against the edges and corners of the screen:
7 8 9 ul u ur up-left up up-right
4 5 6 OR l c r OR left center right
1 2 3 dl d dr down-left down down-right
-H as the -m option but the selected window will be moved to the edges resized to half the screen size, a quarter of the screen size to the corners
-r resize the frame of the selected window to width,height, centered with respect to the original window and avoiding going out of bounds"
>&2
exit
}
CheckArgs()
{
if [ $(echo -n "$1" | wc -c) -eq 2 ] && [ $(echo -n "$1" | awk '/-/{print}') ]
then
shift $((OPTIND-1))
return 1
fi
}
SetWorkspace ()
{
[ "$1" != "all" ] && hey -o "${app_name}" set Workspaces of Window "${win_ID}" to `echo -n $1 | awk '{for(i=1;i<=NF;i++) print ($i-1)}' FS="[^0-9]" | sort -u | awk '{val+=2^($0)} END {print val}'` || hey -o "${app_name}" set Workspaces of Window "${win_ID}" to -1
}
EnlistWindows()
{
for (( i=0;i<=`echo $(hey "${app_name}" Count of Window | awk '/result/{print $4}') - 1 | bc`;i++ )); do echo -n "$i) ";hey "${app_name}" get Title of Window "$i" | awk '/result/{print $4}' FS="\""; done
}
ChangeTitle ()
{
hey -o "${app_name}" set Title of Window "${win_ID}" TO "$1"
}
ResizeFrame()
{
PeekDesktop
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[\
$((echo -n "$1,"; hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}'; echo -n ${dt_frame}) | awk '{\
if ($1<$9) {x_pos=int($3+(($5-$3-$1)/2)); wx_pos=x_pos+$1; if (x_pos<0) {wx_pos-=x_pos;x_pos=0;};if (wx_pos>$9){delta=(wx_pos-$9);wx_pos-=delta;x_pos-=delta;}}\
else {x_pos=0;wx_pos=$9;};\
if ($2<$10) {y_pos=int($4+(($6-$4-$2)/2)); wy_pos=y_pos+$2; if (y_pos<0) {wy_pos-=y_pos;y_pos=0;};if (wy_pos>$10){delta=(wy_pos-$10);wy_pos-=delta;y_pos-=delta;}}\
else {y_pos=0;wy_pos=$10;};\
print x_pos,y_pos,wx_pos,wy_pos}' FS="," OFS=",")]
}
PlaceOnEdges()
{
PeekDesktop
case $1 in
7|ul|up-left)
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print $5,$6,$5+($3-$1),$6+($4-$2)}' FS="," OFS=",")]
;;
8|u|up)
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print int(($7-($3-$1))/2),$6,int(($7+($3-$1))/2),$6+($4-$2)}' FS="," OFS=",")]
;;
9|ur|up-right)
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print ($7-($3-$1)),$6,$7,$6+($4-$2)}' FS="," OFS=",")]
;;
4|l|left)
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print $5,int(($8-($4-$2))/2),$5+($3-$1),int(($8+($4-$2))/2)}' FS="," OFS=",")]
;;
5|c|center)
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print int(($7-($3-$1))/2),int(($8-($4-$2))/2),int(($7+($3-$1))/2),int(($8+($4-$2))/2)}' FS="," OFS=",")]
;;
6|r|right)
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print ($7-($3-$1)),int(($8-($4-$2))/2),$7,int(($8+($4-$2))/2)}' FS="," OFS=",")]
;;
1|dl|down-left)
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print $5,($8-($4-$2)),$5+($3-$1),$8}' FS="," OFS=",")]
;;
2|d|down)
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print ($7-($3-$1))/2,($8-($4-$2)),int(($7+($3-$1))/2),$8}' FS="," OFS=",")]
;;
3|dr|down-right) # lower right corner. half screen size
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print ($7-($3-$1)),($8-($4-$2)),$7,$8}' FS="," OFS=",")]
;;
*)
Usage
;;
esac
}
SplitOnEdges()
{
PeekDesktop
case $1 in
7|ul|up-left) # upper left corner, 1/4 screen size
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print $1,$2,int($3/2),int($4/2)}' FS="," OFS=",")]
;;
8|u|up) # upper half screen height
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print $1,$2,$3,int($4/2)}' FS="," OFS=",")]
;;
9|ur|up-right) # upper right corner, 1/4 screen size
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print int($3/2),$2,$3,int($4/2)}' FS="," OFS=",")]
;;
4|l|left) # left half screen width
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print $1,$2,int($3/2),$4}' FS="," OFS=",")]
;;
5|c|center) # middle screen, half screen size
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print int($3/4),int($4/4),int($3*3/4),int($4*3/4)}' FS="," OFS=",")]
;;
6|r|right) # right half screen width
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print int($3/2),$2,$3,$4}' FS="," OFS=",")]
;;
1|dl|down-left) # lower left corner. half screen size
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print $1,int($4/2),int($3/2),$4}' FS="," OFS=",")]
;;
2|d|down) # lower half screen height
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print $1,int($4/2),$3,$4}' FS="," OFS=",")]
;;
3|dr|down-right) # lower right corner. half screen size
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print int($3/2),int($4/2),$3,$4}' FS="," OFS=",")]
;;
*)
Usage
;;
esac
}
FullScreen()
{
PeekDesktop
hey -o "${app_name}" set Frame of Window "${win_ID}" to BRect[${dt_frame}]
}
ChangeLook()
{
case $1 in
b|bordered)
hey -o "${app_name}" set Look of Window "${win_ID}" to 20
;;
n|no-border)
hey -o "${app_name}" set Look of Window "${win_ID}" to 19
;;
t|titled)
hey -o "${app_name}" set Look of Window "${win_ID}" to 1
;;
d|document)
hey -o "${app_name}" set Look of Window "${win_ID}" to 11
;;
m|modal)
hey -o "${app_name}" set Look of Window "${win_ID}" to 3
;;
f|floating)
hey -o "${app_name}" set Look of Window "${win_ID}" to 7
;;
*)
Usage
;;
esac
}
ChangeFeel()
{
case $1 in
n|normal)
hey -o "${app_name}" set Feel of Window "${win_ID}" to 0
;;
ms|modal-subset)
hey -o "${app_name}" set Feel of Window "${win_ID}" to 2
;;
mp|modal-app)
hey -o "${app_name}" set Feel of Window "${win_ID}" to 1
;;
ml|modal-all)
hey -o "${app_name}" set Feel of Window "${win_ID}" to 3
;;
fs|floating-subset)
hey -o "${app_name}" set Feel of Window "${win_ID}" to 5
;;
fp|floating-app)
hey -o "${app_name}" set Feel of Window "${win_ID}" to 4
;;
fl|floating-all)
hey -o "${app_name}" set Feel of Window "${win_ID}" to 6
;;
*)
Usage
;;
esac
}
SumFlags()
{
case $1 in
nm|not-movable)
let flags+=1
;;
nr|not-resizable)
let flags+=2
;;
nh|not-h-resizable)
let flags+=4
;;
nv|not-v-resizable)
let flags+=8
;;
fs|accept-first-click)
let flags+=16
;;
nc|not-closable)
let flags+=32
;;
nz|not-zoomable)
let flags+=64
;;
af|avoid-front)
let flags+=128
;;
nw|no-workspace-activation)
let flags+=256
;;
as|avoid-focus)
let flags+=8192
;;
nb|not-minimizable)
let flags+=16384
;;
na|not_anchored)
let flags+=131072
;;
sp|same-position)
let flags+=2097152
;;
ce|close-on-escape)
let flags+=8388608
;;
r| reset)
flags=1572864
;;
*)
Usage
;;
esac
}
ChangeFlags()
{
flags=1572864
while read line; do
SumFlags ${line}
done <<< $( echo $1 | tr "," "\\n" )
hey -o "${app_name}" set Flags of Window "${win_ID}" to ${flags}
}
ToggleActive()
{
case $1 in
1|t|true|on|y|yes)
hey -o "${app_name}" set Active of Window "${win_ID}" to true
;;
0|f|false|off|n|no)
hey -o "${app_name}" set Active of Window "${win_ID}" to false
;;
toggle)
active=`hey -o "${app_name}" get Active of Window "${win_ID}"`
[ "${active}" == "true" ] && ToggleActive 0 || ToggleActive 1
;;
*)
Usage
;;
esac
}
ToggleMinimize()
{
case $1 in
1|t|true|on|y|yes)
hey -o "${app_name}" set Minimize of Window "${win_ID}" to true
;;
0|f|false|off|n|no)
hey -o "${app_name}" set Minimize of Window "${win_ID}" to false
;;
toggle)
minimized=`hey -o "${app_name}" get Minimize of Window "${win_ID}"`
[ "${minimized}" == "true" ] && ToggleMinimize 0 || ToggleMinimize 1
;;
*)
Usage
;;
esac
}
AbsPositionIt ()
{
hey -o "${app_name}" let Window "${win_ID}" do MoveTo BPoint[$1]
}
RelPositionIt ()
{
hey -o "${app_name}" let Window "${win_ID}" do MoveBy BPoint[$1]
#\$((echo -n "$1,"; hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s",$0}') | awk '{print $3+$1,$4+$2}' FS="," OFS=",")]
}
PeekDesktop ()
{
dt_frame=$((hey Tracker get Frame of Window 0 | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${db_frame}) | awk '{\
if (($5!=0) && ($7==$3 )) {print "0","0",$5,$4};\
if (($5==0) && ($7!=$3)) {print $7,"0",$3,$4};\
if (($7-$5)==($3-$1)) {if ($6!=0) {print "0","0",$3, $6}\
else {print "0",$8,$3,$4}}\
}' FS="," OFS=",")
}
PeekDeskbar ()
{
db_frame=$(hey Deskbar get Frame of Window 0 | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s",$0}')
}
###############
# main script #
###############
script_name="$(basename ${0})"
db_frame="0,0,0,0"
if [ $# -ne 0 ]
then
while getopts "a:dhlfs:t:w:L:F:p:P:m:H:r:M:A:G:" script_opt
do
case ${script_opt} in
a)
app_name="$OPTARG"
;;
l)
[ -n "${app_name}" ] && EnlistWindows
exit
;;
s)
[ -n "${app_name}" ] && win_ID="$OPTARG" || Usage
;;
P)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && AbsPositionIt "$OPTARG"
else
Usage
fi
;;
p)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && RelPositionIt "$OPTARG"
else
Usage
fi
;;
d)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
PeekDeskbar
else
Usage
fi
;;
m)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && PlaceOnEdges "$OPTARG"
else
Usage
fi
;;
H)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && SplitOnEdges "$OPTARG"
else
Usage
fi
;;
f)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
FullScreen
else
Usage
fi
;;
t)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && ChangeTitle "$OPTARG"
else
Usage
fi
;;
w)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && SetWorkspace "$OPTARG"
else
Usage
fi
;;
r)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && ResizeFrame "$OPTARG"
else
Usage
fi
;;
L)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && ChangeLook "$OPTARG"
else
Usage
fi
;;
F)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && ChangeFeel "$OPTARG"
else
Usage
fi
;;
G)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && ChangeFlags "$OPTARG"
else
Usage
fi
;;
A)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && ToggleActive "$OPTARG"
else
Usage
fi
;;
M)
if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
then
CheckArgs "$OPTARG"
[ $? -ne 1 ] && ToggleMinimize "$OPTARG"
else
Usage
fi
;;
h|*)
Usage
;;
esac
done
else
Usage
fi
exit
Pratical example
winpwnr.sh -a Terminal -s 0 -d -H up
move the first opened Terminal window to the upper screen edge occupying half screen vertically, full screen width but avoiding to overlap the Deskbar
winpwnr.sh -a Pe -s Snippets -r 400,400 -m left -w all - G not-closable,not-movable,not-resizable,not-zoomable,not-minimizable -L bordered
Pe’s snippets window is resized to a 400 px squared frame, moved against left screen edge, freeze its position, removing window title tab, shown on all workspaces
I think this can be useful running in a boot script