Register
It is currently Mon Apr 23, 2018 6:51 pm

How to position a popup window near the yad notification ico


All times are UTC - 6 hours


Post new topic Reply to topic  [ 2 posts ] 
Author Message
 PostPosted: Thu Apr 05, 2018 3:57 am   

Joined: Thu Apr 05, 2018 2:25 am
Posts: 2
This is a little complicated question.

I have a script that uses yad (yet another dialog version 0.40) as UI. https://github.com/v1cont/yad/releases
The script launches a volume notification icon in the xfce notification area.
Righ-click on the icon displays a popup menu.
Left-click on the notification icon launches and also closes an undecorated popup window that closes if it loses focus.
That window is supposed to be positioned near the notification icon.
In order to achive that, the script gets the current mouse position when the notification icon is clicked.
After that script calculates the relative position of the mouse cursor on the screen.
Code:
#!/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(){

# 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))

# Get current mouse position
out="$(xdotool getmouselocation)"
out=(${out//[^0-9 ]/})
current_x="${out[0]}"
current_y="${out[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"

# Manually correct the position
# I would like better method here
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
    set_notification_icon $(printf "%3d" "$VOL") 2>&1 >$YAD_AUDIO
    amixer sset 'Master' "$VOL%" 2>&1 >/dev/null
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 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

I would like is to find out which xfce4-panel does the notification icon belongs to.
Then based on that panel geometry and it's relative position on the screen calculate where to position the yad window.
I probably need to get the position of the mouse cursor, like the current method, and calculate if the cursor is clicked inside the panel geometry and find out the absolute position of the panel on screen.
How do I do that?

I can get the list of xfce4-panel's with wmctrl along with geometry and position...
Code:
wmctrl -l -G
0x01600004 -1 0    1049 1920 31   r22 xfce4-panel
0x01600037 -1 0    307  37   466  r22 xfce4-panel

...but figuring out in which panel was the mouse clicked appears difficult. o_O

Any help would be appreciated.
Misko


Top
 Profile  
 PostPosted: Thu Apr 05, 2018 10:19 am   

Joined: Mon Oct 20, 2014 9:53 am
Posts: 574
This is not a shell question.
And i do not read pages of code unrelated to the problem.
Be short, be precise.

You might want to use "xwininfo" to get all needed information.
Implement a fallback for the case that "yad" or "xwininfo" is not installed.
Which happens to be on most distributions.

Additional hint: Most DEs have a environment variable called WINDOWID


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 26 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP