Find the xfce4-panel that launched the script?

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Locked
Misko_2083

Find the xfce4-panel that launched the script?

Post by Misko_2083 »

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
Level 4
Posts: 443
Joined: Fri Sep 23, 2016 10:19 am

Re: Find the xfce4-panel that launched the script?

Post by FreedomTruth »

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

Re: Find the xfce4-panel that launched the script?

Post by Misko_2083 »

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
Locked

Return to “Scripts & Bash”