Strange, I'm using Compiz on daily basis, but just tested the script under JWM and 'always-on-top' also works fine for me.The only real issue I am experiencing so far is that I can't get the radar screen to sit on top of other windows - it always stays in the background behind everything else[...]
Did you check wmctrl permissions?
Also, what will happen when, after launching radar, you'll type directly (open terminal in folder where wmctrl is):
Code: Select all
./wmctrl -r "OneSwitch - Radar/Menu" -b add,above
Done. I too think it's more comfortable.1) After I use the "choose action" window to select "click" radar drops back automatically into the "choose direction" mode. Initially that seemed efficient, but now I find it makes it harder to do a "repeated key click". Would it create any adverse problems if that was changed so that after selecting "click" the "choose action" dialog would reappear? Example: when I am using xvkbd I sometimes need to repeatedly click backspace, delete, or page down etc. It would be nice to be able to repeat a keyclick without going through a new "move" procedure. (I guess different users might have a different preference, so I could keep two separate versions of radar to accomodate both methods)
I reduced number of possible directions from 71 to 35 since some of intermediate degrees were being disregarded by xdotool.2) The radar sweep is now more jerky than it was previously. It is not a problem but I wondered if this was a deliberate choice, or just a byproduct of the script being "busier" than before?
Now cursor really goes where radar shows and indeed - CPU suffers 2xLess.
Code: Select all
#!/bin/bash
# Radar v0.5
# Req.: Gtkdialog >= 0.8.0, xdotool, detect_key, wmctrl, xwininfo, getcurpos, awk, tr
# POSITION can be one of these:
# CENTER, TOP-LEFT, TOP, TOP-RIGHT, BOTTOM-LEFT, BOTTOM, BOTTOM-RIGHT
POSITION=BOTTOM-RIGHT
# =============================================================================
# Init
# =============================================================================
# Exit if another instance is already running
sleep 0.1
[ `pidof $(basename $(readlink -e "$0")) -o %PPID | wc -w` -gt 1 ] && exit
APPDIR="$(dirname $(readlink -e "$0"))"
POSITION="`echo $POSITION | tr [:lower:] [:upper:]`"
TEMPDIR=/dev/shm/one_switch_temp
mkdir $TEMPDIR
# Delete tempdir and kill all subprocesses on exit
trap 'rm -rf $TEMPDIR; killall detect_key; kill $GTKPID' EXIT
export PIC=$TEMPDIR/cursor_pic
export ROTATION=$TEMPDIR/cursor_rotate
export MENU_1_STATE=$TEMPDIR/menu1_state
export MODE=$TEMPDIR/mode
export DELAY4MENU=$TEMPDIR/delay4menu
export DELAY4RADAR=$TEMPDIR/delay4radar
echo -10 > $ROTATION
echo 0 > $MENU_1_STATE
echo radar > $MODE
echo 4 > $DELAY4RADAR
PRESS=/tmp/switch_state
[ -f $PRESS ] && rm $PRESS
PAUSE="key 119 state 0"
"$APPDIR/detect_key" /dev/input/event0 > $PRESS &
# Read current screen resolution
read MAXX MAXY <<< `xwininfo -root | awk 'NR>=8&&NR<=9 {print $2}'`
# =============================================================================
# Gtkdialog structures
# =============================================================================
export PREVIEW='
<window title="OneSwitch - Radar/Menu" width-request="74" height-request="74" decorated="false" skip-pager-hint="true" skip-taskbar-hint="true" resizable="false">
<pixmap>
<variable>PICTURE</variable>
<input file>'"$PIC"'</input>
</pixmap>
<timer visible="false" milliseconds="true" interval="200">
<action>animate</action>
<action>refresh:PICTURE</action>
</timer>
</window>
'
# =============================================================================
# Functions
# =============================================================================
wait_for_switch () {
until [ "`grep "$PAUSE" $PRESS`" ]; do
sleep 0.1
done
}
set_position () {
case "$POSITION" in
"CENTER" ) CX=$(($MAXX/2-37)); CY=$(($MAXY/2-37)) ;;
"TOP-LEFT" ) CX=0; CY=32 ;;
"BOTTOM-LEFT" ) CX=0; CY=$(($MAXY-32-74)) ;;
"TOP-RIGHT" ) CX=$(($MAXX-74)); CY=32 ;;
"TOP" ) CX=$(($MAXX/2-37)); CY=32 ;;
"BOTTOM" ) CX=$(($MAXX/2-37)); CY=$(($MAXY-32-74)) ;;
* ) CX=$(($MAXX-74)); CY=$(($MAXY-32-74)) ;;
esac
}
animate () {
case "`cat $MODE`" in
"radar" )
read DEG < $ROTATION
read DELAY < $DELAY4RADAR
if [ $DEG = 0 ] || [ $DEG = 90 ] || [ $DEG = 180 ] || [ $DEG = 270 ]; then
[ $DELAY -gt 0 ] && ((DELAY--)) && echo $DELAY > $DELAY4RADAR && exit
else
echo 4 > $DELAY4RADAR
fi
DEG=$(($DEG+10))
[ "$DEG" -ge 360 ] && DEG=0
echo $DEG > $ROTATION
# Create svg pic
echo '<svg width="64" height="64" xmlns="http://www.w3.org/2000/svg">
<circle cx="32" cy="32" r="28" stroke="red" fill="none" stroke-width="3" />
<line x1="32" y1="32" x2="32" y2="4" stroke="black" stroke-width="3" transform="rotate('$DEG' 32 32)" />
</svg>' > $PIC
;;
"freeze" )
exit
;;
"menu" )
read DELAY < $DELAY4MENU
if [ $DELAY -gt 0 ]; then
((DELAY--)); echo $DELAY > $DELAY4MENU
else
echo 4 > $DELAY4MENU
case "`cat $MENU_1_STATE`" in
0) POS=0; echo 1 > $MENU_1_STATE ;;
1) POS=16; echo 2 > $MENU_1_STATE ;;
2) POS=32; echo 3 > $MENU_1_STATE ;;
3) POS=48; echo 0 > $MENU_1_STATE ;;
esac
echo '<svg width="64" height="64" xmlns="http://www.w3.org/2000/svg">
<text font-family="DejaVu Sans" font-size="13" font-weight="bold">
<tspan x="12" y="12">Move</tspan>
<tspan x="14" y="28">Click</tspan>
<tspan x="1" y="44">Db-Click</tspan>
<tspan x="3" y="60">Rt-Click</tspan>
</text>
<rect x="0" y="'$POS'" width="64" height="16" stroke="darkgreen" fill="green" stroke-width="2" opacity="0.5" />
</svg>' > $PIC
fi
;;
esac
}
export -f animate && animate
# =============================================================================
# MAIN LOOP
# =============================================================================
set_position
gtkdialog -G 64x64+$CX+$CY -p PREVIEW & GTKPID=$!
sleep 1
"$APPDIR/wmctrl" -r "OneSwitch - Radar/Menu" -b add,above
# Infinite loop
while :; do
wait_for_switch
: > $PRESS
echo freeze > $MODE
read DEG < $ROTATION
# Move cursor until switch signal will appear again
until [ "`grep "$PAUSE" $PRESS`" ]; do
xdotool mousemove_relative --polar $DEG 6
read X Y <<< `getcurpos`
[ $X -ge $(($MAXX-1)) ] && X=1 && xdotool mousemove $X $Y
[ $X -le 0 ] && X=$MAXX && xdotool mousemove $X $Y
[ $Y -ge $(($MAXY-1)) ] && Y=1 && xdotool mousemove $X $Y
[ $Y -le 0 ] && Y=$MAXY && xdotool mousemove $X $Y
sleep 0.1
done
while :; do
: > $PRESS
echo 0 > $DELAY4MENU
echo 0 > $MENU_1_STATE
echo menu > $MODE
wait_for_switch
echo freeze > $MODE
case "`cat $MENU_1_STATE`" in
1) break ;;
2) xdotool click 1 ;;
3) xdotool click --repeat 2 1 ;;
0) xdotool click 3 ;;
esac
sleep 0.5
done
echo radar > $MODE
echo 0 > $DELAY4MENU
echo 0 > $MENU_1_STATE
: > $PRESS
done
# =============================================================================
A bit different approach, using dzen2 (wmctrl no needed, dzen acts as a dock): a top or bottom bar with rolling options. No radar picture, but arrows instead (only 8 directions).
See attached tgz.
Greetings!