About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Misko_2083
Post
by Misko_2083 » Fri Apr 06, 2018 9:13 am
How can I find out from which xfce4-panel was a script launched?
Situation: From a custom panel launcher, some script is launched and that script detects the panel and it's position, height and geometry.
Let's say the script uses xdotool to detect the mouse pointer position when being run from a launcher.
Code: Select all
# Get current mouse position
out="$(xdotool getmouselocation)"
out=(${out//[^0-9 ]/})
X="${out[0]}"
Y="${out[1]}"
How can I find out if the point with coordinates X, Y is in that panel?
Let's say I have two panels.
Code: Select all
wmctrl -l -G
0x01600005 -1 0 1049 1920 31 x77 xfce4-panel
0x01600051 -1 0 307 37 466 x77 xfce4-panel
Last edited by
LockBot on Wed Dec 28, 2022 7:16 am, edited 1 time in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
FreedomTruth
Level 4
Posts: 443 Joined: Fri Sep 23, 2016 10:19 am
Post
by FreedomTruth » Fri Apr 06, 2018 11:55 pm
I think your method of grabbing mouse (x,y) and comparing it with the panel's dimensions given by wmctrl would indeed work; however, it may be simpler to use the window id returned with xdotool getmouselocation and compare it with wmctrl window id.
Code: Select all
# Get current mouse position
out="$(xdotool getmouselocation)"
out=(${out//[^0-9 ]/})
# X="${out[0]}"
# Y="$(out[1]}"
# xdotool getmouselocation returns a decimal window id and wmctrl gives a hexadecimal id.
WindowID=$(printf "0x%08x" ${out[3]})
geo=$(wmctrl -l -G | grep $WindowID)
geo=(${geo//[^0-9 ]/})
# Panel 1 we will name 0-1049-1920-31
# Panel 2 we will name 0-307-37-466
PanelName="${geo[2]}-${geo[3]}-${geo[4]}-${geo[5]}"
if [ $PanelName == "0-1049-1920-31" ]; then
echo "Panel $PanelName"
# do stuff for this panel launcher
elif [ "$PanelName" == "0-307-37-466" ]; then
echo "Panel $PanelName"
# do other stuff for this launcher
else
# Mouse wasn't over either panel ...
:
fi
Misko_2083
Post
by Misko_2083 » Wed Apr 18, 2018 11:20 pm
Thanks for the reply.
I wanted to position the yad window properly near the notification icon on all the possible screen corners.
Found something that works but only in cases when there are 2 or less monitors.
Code: Select all
#!/bin/bash
# volume notification icon
#
ERR(){ echo "ERROR: $1" 1>&2; }
declare -i DEPCOUNT=0
for DEP in /usr/bin/{xdotool,yad,notify-send}; {
[ -x "$DEP" ] || {
ERR "$LINENO Dependency '$DEP' not met."
DEPCOUNT+=1
}
}
[ $DEPCOUNT -eq 0 ] || exit 1
export YAD_AUDIO=$(mktemp -u --tmpdir YAD_AUDIO.XXXXXXXX)
mkfifo "$YAD_AUDIO"
trap "rm -f $YAD_AUDIO" EXIT
function get_volume(){
vol=$(amixer get Master | grep "\[on\]\|\[off\]")
vol=( $vol )
# Fredx181 check for pulseaudio
[ $(pidof pulseaudio) ] && CURVOL=$(echo ${vol[4]} | sed 's/[][%]//g') || CURVOL=$(echo ${vol[3]} | sed 's/[][%]//g')
}
export -f get_volume
YAD_AUDIO_audio(){
# Get current mouse position
out="$(xdotool getmouselocation)"
out=(${out//[^0-9 ]/})
current_x="${out[0]}"
current_y="${out[1]}"
# set window class
YAD_CLASS="YAD_AUDIO"
# Unmap the window if the script is relaunched
pids="$(xdotool search --class "$YAD_CLASS")"
wpid="$(xdotool getwindowfocus)"
for pid in $pids; do
# Compares window class pid with the pid of a window in focus
if [[ "$pid" == "$wpid" ]]; then
xdotool windowunmap $pid &>/dev/null
exit 1
fi
done
get_volume
# Format xrandr output
xrandr="$(xrandr | grep -w "connected" | grep -o "[0-9]\+x[0-9]\++[0-9]\++[0-9]\+" | tr "x+" " " | sort -nk 4)"
# Get num of monitors
num_screens=$(echo "$xrandr" | wc -l)
[ "$num_screens" -gt 2 ] && echo "Script cannot deal with more than 2 monitors" >&2 && exit 1
# Get screen resolution
screen_left=($(echo "$xrandr" | head -1))
[ "$num_screens" -gt 1 ] && screen_right=($(echo "$xrandr" | tail -1))
# Calculate current monitor and relative position to this monitor
if [ "$num_screens" -gt 1 ] && [ "$current_x" -gt "${screen_right[2]}" ]; then
current_screen=(${screen_right[*]})
current_x=$(($current_x-${screen_right[2]}))
else
current_screen=(${screen_left[*]})
fi
# Check relative position
if [ "$current_y" -lt "$((${current_screen[1]}*1/4))" ]; then # IN-TOP
var_key="top"
elif [ "$current_y" -gt "$((${current_screen[1]}*3/4))" ]; then # IN-BOTTOM
var_key="bottom"
fi
if [ "$current_x" -lt "$((${current_screen[0]}*1/4))" ]; then # IN-LEFT
var_key="${var_key}left"
elif [ "$current_x" -gt "$((${current_screen[0]}*3/4))" ]; then # IN-RIGHT
var_key="${var_key}right"
fi
[ ! "$var_key" ] && var_key="center"
#echo "$var_key"
case ${var_key} in
top) current_x=$(($current_x-250))
;;
topleft) : #skip
;;
topright) current_x=$(($current_x-295))
;;
bottom) current_x=$(($current_y-210))
;;
bottomleft) current_y=$(($current_y-210))
;;
bottomright) current_x=$(($current_x-295))
current_y=$(($current_y-210))
;;
left) :
;;
right) current_x=$(($current_x-310))
;;
center) :
;;
esac
PLUG=$(($RANDOM * $$))
yad --plug=$PLUG --tabnum=1 --scale \
--print-partial \
--text=" Volume Control " \
--min-value=0 --max-value=100 \
--image="preferences-desktop-sound" \
--borders="12" \
--value="$CURVOL" 2> /dev/null | \
while read VOL; do
amixer sset 'Master' "$VOL%" 2>&1 >/dev/null
set_notification_icon $(printf "%3d" "$VOL") 2>&1 >$YAD_AUDIO
done &
yad --plug=$PLUG --tabnum=2 --text="" --form --field="Mute/Unmute":fbtn "bash -c 'alsa_toggle'" &
yad --paned --key=$PLUG --tab="Tab 1" --tab="Tab 2" --width=300 --height=200 \
--posy=$current_y --posx=$current_x \
--no-buttons \
--undecorated \
--close-on-unfocus \
--on-top \
--skip-taskbar \
--sticky \
--class="$YAD_CLASS"
}
export -f YAD_AUDIO_audio
function set_notification_icon
{
LANG=C.UTF-8
if amixer | grep -E -A 6 -B 0 'Master|Headphone|Speaker' | grep '\[off\]'; then
amixer set Master unmute
amixer set Speaker unmute
amixer set Headphone unmute
get_volume
set_notification_icon $(printf "%3d" "$CURVOL") 2>&1 >$YAD_AUDIO
fi
if [[ "$1" -ge "68" ]]; then
echo "icon:notification-audio-volume-high"
elif [[ "$1" -ge "34" && "$1" -lt "68" ]]; then
echo "icon:notification-audio-volume-medium"
elif [[ "$1" -ge "1" && "$1" -lt "34" ]]; then
echo "icon:notification-audio-volume-low"
elif [[ "$1" -lt "1" ]]; then
echo "icon:notification-audio-volume-off"
fi
echo "tooltip:Volume $1 %"
echo "menu:About!sh -c 'notify-send -i notification-audio-volume-high -t 8000 \"Volume Control\" \"by Misko_2083\"'!gtk-about||Quit!quit!gtk-quit"
}
export -f set_notification_icon
function alsa_toggle(){
if amixer | grep -E -A 6 -B 0 'Master|Headphone|Speaker' | grep '\[off\]'; then
amixer set Master unmute
amixer set Speaker unmute
amixer set Headphone unmute
get_volume
set_notification_icon $(printf "%3d" "$CURVOL") 2>&1 >$YAD_AUDIO
else
echo "icon:notification-audio-volume-muted" 2>&1 >$YAD_AUDIO
amixer set Master mute
fi
}
export -f alsa_toggle
exec 3<> $YAD_AUDIO
yad --notification --command="bash -c 'YAD_AUDIO_audio'" \
--listen <&3 & notifpid=$!
# Don't set the icon untill the yad notification is ready
# until there is a window name do -> sleep
until xdotool getwindowname $(xdotool search --pid "$notifpid" 2>/dev/null | tail -1) &>/dev/null; do
# sleep until the window opens
sleep 1
done
# Set intitial volume icon
get_volume
set_notification_icon $(printf "%3d" "$CURVOL") >&3
# Waits for notification to exit
wait $notifpid
exec 3>&-
exit 0