Change the top panel opacity when a window is maximized

This script sets the top panel to full transparency if no maximized window is on the current workspace.
Sort of like Dynamic Transparency with budgie-panel’s in Solus.
Whenever there is a maximized window on a workspace the top panel will turn off transparency.

  • The only issue is that clock applet opacity isn’t changing.

Save, make executable, run on startup

#!/bin/bash
# Requires: xprop

##################################
# Adjust values to suit
PANEL=top
PANEL_ALPHA_REGULAR=0
PANEL_ALPHA_MAXIMUM=1
##################################
##################################
# don't change anything below here

gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/top/background/ type "color"

CURR=0
while true
do
	MAX_FND=0
	for w in $(xprop -notype -root _NET_CLIENT_LIST 2>/dev/null | cut -d'#' -f2 | tr ',' '\n' | awk '{print $1}')
   	do 
                if [[ "$(xprop -id $w -notype _NET_WM_DESKTOP 2>/dev/null | cut -d' ' -f3)" -eq "$(xprop -root -notype _NET_CURRENT_DESKTOP 2>/dev/null | cut -d' ' -f3)" ]]
                then

		   if xprop -id $w _NET_WM_STATE | grep -E "MAXIMIZED_HORZ.*MAXIMIZED_VERT" > /dev/null 2>&1
		   then
			if xprop -id $w WM_STATE | grep -E "window state: Normal" > /dev/null 2>&1
			then
				MAX_FND=1
				break
			fi
		   fi
                fi
	done

	if [[ $MAX_FND -eq 1 && $CURR -eq 0 ]]
	then
		gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/${PANEL}/background/ color "rgba(60,59,55,$PANEL_ALPHA_MAXIMUM)"
		CURR=1			
	elif [[ $MAX_FND -eq 0 && $CURR -eq 1 ]]
	then
		gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/${PANEL}/background/ color "rgba(60,59,55,$PANEL_ALPHA_REGULAR)"
		CURR=0
	fi

	sleep 1
done
exit 0
7 Likes

what WM are you using as i just can’t get that script to work at all. I’m using ubuntu mate 18.04 with compiz reloaded and gtk-window-decorator for window decorations.

Compiz sets the _NET_WM_STATE X window properties in this order MAXIMIZED_VERT, MAXIMIZED_HORZ.
If you change this line

 if xprop -id $w _NET_WM_STATE | grep -E "MAXIMIZED_HORZ.*MAXIMIZED_VERT" > /dev/null 2>&1

to

   if xprop -id $w _NET_WM_STATE | grep -E "MAXIMIZED_HORZ.*MAXIMIZED_VERT|MAXIMIZED_VERT.*MAXIMIZED_HORZ" > /dev/null 2>&1

The script will work on all WMs.

2 Likes

well i put some thought into it and tried to extend the script to dynamically load the panel color from the current theme, so far it works okay with most themes but i do need some help from someone more familiar with gtk theming to truly make this work flawless with any theme

here's a link to the github repo Mate Dynamic Panel Transparency

1 Like

It would slow down the script. Check if the theme name has changed and if so then find the background color.
I'm not sure if you want to go through all the css and find the right key.
That would be expensive. Here is a python script https://stackoverflow.com/questions/50644945/get-color-scheme-from-gtk#50676665

Have you tried this?

1 Like

That will do. Thanks.

1 Like

I've sent this to @EDX-0 in a PM but want to share with
others.
@EDX-0's script looks into theme's CSS files to find the color.
Another way of making the script to follow gtk theme
is to check when the theme changes, switch the panel
background to "none" and then with the ImageMagick
find the dominant color of the panel.
It should change when the theme is changed,
but don't know how it will work with a lot of panel plugins in the panel.

#!/bin/bash
# Requires: xprop, imagemagick

##################################
# Adjust values to suit
PANEL=top
PANEL_ALPHA_REGULAR=0.65
PANEL_ALPHA_MAXIMUM=0.90
##################################
##################################
# don't change anything below here

gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/top/background/ type "none"
if [[ "${PANEL}" == "top" ]]; then
    PANEL_XID="$(xwininfo -root -children \
           | awk '/[Tt]op\ [Pp]anel.*[Mm]ate-[Pp]anel/ {print $1}')"
elif [[ "${PANEL}" == "bottom" ]]; then
        PANEL_XID="$(xwininfo -root -children \
           | awk '/[Bb]ottom\ [Pp]anel.*[Mm]ate-[Pp]anel/ {print $1}')"
elif [[ "${PANEL}" == "left" ]]; then
        PANEL_XID="$(xwininfo -root -children \
           | awk '/[Ll]eft\ [Pp]anel.*[Mm]ate-[Pp]anel/ {print $1}')"
elif [[ "${PANEL}" == "right" ]]; then
        PANEL_XID="$(xwininfo -root -children \
           | awk '/[Rr]ight\ [Pp]anel.*[Mm]ate-[Pp]anel/ {print $1}')"
else
    echo "Unknown panel position"; exit 1
fi

 COL="$(import -window ${PANEL_XID} -colorspace sRGB -set colorspace RGB -format %c histogram:info: \
      | sort -r -n | head -n 1 | grep -oE "rgb.*" | grep -oE "[0-9]*,[0-9]*,[0-9]*")"

GTK_THEME="$(gsettings get org.mate.interface gtk-theme)"
gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/top/background/ type "color"

CURR=0
while true
do
    # Theme changed
    if [[ "${GTK_THEME}" != "$(gsettings get org.mate.interface gtk-theme)" ]]
    then
        GTK_THEME="$(gsettings get org.mate.interface gtk-theme)"
		gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/top/background/ type "none"
         COL="$(import -window ${PANEL_XID} -colorspace sRGB -set colorspace RGB -format %c histogram:info: \
      | sort -r -n | head -n 1 | grep -oE "rgb.*" | grep -oE "[0-9]*,[0-9]*,[0-9]*")"
		gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/${PANEL}/background/ type "color"
    fi

	MAX_FND=0
	for w in $(xprop -notype -root _NET_CLIENT_LIST 2>/dev/null | cut -d'#' -f2 | tr ',' '\n' | awk '{print $1}')
   	do 
                if [[ "$(xprop -id $w -notype _NET_WM_DESKTOP 2>/dev/null | cut -d' ' -f3)" -eq "$(xprop -root -notype _NET_CURRENT_DESKTOP 2>/dev/null | cut -d' ' -f3)" ]]
                then
		   if xprop -id $w _NET_WM_STATE | grep -E "MAXIMIZED_HORZ.*MAXIMIZED_VERT|MAXIMIZED_VERT.*MAXIMIZED_HORZ" > /dev/null 2>&1
		   then
			if xprop -id $w WM_STATE | grep -E "window state: Normal" > /dev/null 2>&1
			then
				MAX_FND=1
				break
			fi
		   fi
                fi
	done

	if [[ $MAX_FND -eq 1 && $CURR -eq 0 ]]
	then

        gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/${PANEL}/background/ color "rgba(${COL},$PANEL_ALPHA_MAXIMUM)"
echo "rgba(${COL},$PANEL_ALPHA_MAXIMUM)"
		CURR=1			
	elif [[ $MAX_FND -eq 0 && $CURR -eq 1 ]]
	then

gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/${PANEL}/background/ color "rgba(${COL},$PANEL_ALPHA_REGULAR)"
echo "rgba(${COL},$PANEL_ALPHA_REGULAR)"
		CURR=0
	fi
	

	sleep 1
done
exit 0
1 Like

I was sending the script to run in sh (dash) as a way to recover the performance lost from having to retrieve the color from the css and converting it from hex to decimal, but this is overall a smarter idea and tackles the problem my idea had that themes with light backgrounds would have light panels when they shouldn't like ambiance MATE.
I will try to give it a thoroughly test to see if it breaks with some theme or a cluttered panel, but so far what i've tested has worked really nice.

after playing some more with this new version of the script i found it has a rather wonky behaviour when you change themes as the average panel color is apparently read not just as the average of the current theme but the average of the current and previous themes, however if you kill the script and re-run it after you set on a theme the script works as intended.

While the color and transparency is changed, the panel color is like a moving target.
The script may have to wait until the panel is repainted.

    # Theme changed
    if [[ "${GTK_THEME}" != "$(gsettings get org.mate.interface gtk-theme)" ]]
    then
        GTK_THEME="$(gsettings get org.mate.interface gtk-theme)"
		gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/top/background/ type "none"
         sleep 2
         COL="$(import -window ${PANEL_XID} -colorspace sRGB -set colorspace RGB -format %c histogram:info: \
      | sort -r -n | head -n 1 | grep -oE "rgb.*" | grep -oE "[0-9]*,[0-9]*,[0-9]*")"
		gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/${PANEL}/background/ type "color"
    fi

here's a posix shell compatible version because there will always be someone who wants the extra speed of shells like dash

#!/bin/sh
# Requires: xprop, imagemagick

##################################
# Adjust values to suit
PANEL=top
PANEL_ALPHA_REGULAR=0.65
PANEL_ALPHA_MAXIMUM=0.90
##################################
##################################
# don't change anything below here

gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/top/background/ type "none"
sleep 1
if [ "${PANEL}" = "top" ]; then
    PANEL_XID="$(xwininfo -root -children \
           | awk '/[Tt]op\ [Pp]anel.*[Mm]ate-[Pp]anel/ {print $1}')"
elif [ "${PANEL}" = "bottom" ]; then
        PANEL_XID="$(xwininfo -root -children \
           | awk '/[Bb]ottom\ [Pp]anel.*[Mm]ate-[Pp]anel/ {print $1}')"
elif [ "${PANEL}" = "left" ]; then
        PANEL_XID="$(xwininfo -root -children \
           | awk '/[Ll]eft\ [Pp]anel.*[Mm]ate-[Pp]anel/ {print $1}')"
elif [ "${PANEL}" = "right" ]; then
        PANEL_XID="$(xwininfo -root -children \
           | awk '/[Rr]ight\ [Pp]anel.*[Mm]ate-[Pp]anel/ {print $1}')"
else
    echo "Unknown panel position"; exit 1
fi

 COL="$(import -window "${PANEL_XID}" -colorspace sRGB -set colorspace RGB -format %c histogram:info: \
      | sort -r -n | head -n 1 | grep -oE "rgb.*" | grep -oE "[0-9]*,[0-9]*,[0-9]*")"

GTK_THEME="$(gsettings get org.mate.interface gtk-theme)"
gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/top/background/ type "color"

CURR=0
while true
do
    # Theme changed
    if [ "${GTK_THEME}" != "$(gsettings get org.mate.interface gtk-theme)" ]
    then
        GTK_THEME="$(gsettings get org.mate.interface gtk-theme)"
		gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/top/background/ type "none"
        sleep 2
         COL="$(import -window "${PANEL_XID}" -colorspace sRGB -set colorspace RGB -format %c histogram:info: \
      | sort -r -n | head -n 1 | grep -oE "rgb.*" | grep -oE "[0-9]*,[0-9]*,[0-9]*")"
		gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/${PANEL}/background/ type "color"
    fi

	MAX_FND=0
	for w in $(xprop -notype -root _NET_CLIENT_LIST 2>/dev/null | cut -d'#' -f2 | tr ',' '\n' | awk '{print $1}')
   	do 
                if [ "$(xprop -id "$w" -notype _NET_WM_DESKTOP 2>/dev/null | cut -d' ' -f3)" -eq "$(xprop -root -notype _NET_CURRENT_DESKTOP 2>/dev/null | cut -d' ' -f3)" ]
                then
		   if xprop -id "$w" _NET_WM_STATE | grep -E "MAXIMIZED_HORZ.*MAXIMIZED_VERT|MAXIMIZED_VERT.*MAXIMIZED_HORZ" > /dev/null 2>&1
		   then
			if xprop -id "$w" WM_STATE | grep -E "window state: Normal" > /dev/null 2>&1
			then
				MAX_FND=1
				break
			fi
		   fi
                fi
	done

	if [ $MAX_FND -eq 1 ] && [ $CURR -eq 0 ]
	then

        gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/${PANEL}/background/ color "rgba(${COL},$PANEL_ALPHA_MAXIMUM)"
		CURR=1
	elif [ $MAX_FND -eq 0 ] && [ $CURR -eq 1 ]
	then

gsettings set org.mate.panel.toplevel.background:/org/mate/panel/toplevels/${PANEL}/background/ color "rgba(${COL},$PANEL_ALPHA_REGULAR)"
		CURR=0
	fi
	

	sleep 1
done
exit 0