Add Change Icon to Ubuntu Panel

What would be the easiest way to add and change an icon in an Ubuntu (Gnome) panel? I'm looking for something as simple as a shell script, but I'm not limited to that. They will write a program for him if this is a better or simpler approach.

The idea is to create a script / program to monitor certain conditions (for example, mount point availability, Internet connection availability) and change the state of the icon to display the current state.

+4
source share
3 answers

One easy way is to do it in Python. See a blog post , for example.

+2
source

I found YAD (another dialog) to provide the simplest solution. See brief description of webupd8 . However, integration in Unity seems to be a bit broken right now. I mention this below, but if you really care about Unity, you should probably look at other answers.

Note. Although I am convinced that YAD works in a wide variety of environments, I only tested the instructions below using Lubuntu 15.10 (LXDE desktop) and Ubuntu 14.04 (Unity desktop).

Installation

I got a working installation with:

sudo apt-add-repository ppa:webupd8team/y-ppa-manager sudo apt-get update sudo apt-get install yad 

(Actually, I don't need the first two lines in Lubuntu 15.10, but that could be a coincidence.)
LXDE is called

 yad --notification --listen 

then raised the tray icon, which I could change by typing (for example): icon:gtk-help . Unity didn’t appear, so I needed the following ...

Work for Unity: The following instructions are again taken from webupd8 . The problem is that the "system tray" no longer exists officially in Unity. One of the possible solutions for launching programs such as YAD, which did not catch up with this change, is to install an "emulator in the system tray":

 sudo apt-add-repository ppa:fixnix/indicator-systemtray-unity sudo apt-get update sudo apt-get install indicator-systemtray-unity 

To get the icons directly in the Unity panel, I used the following settings:

 gsettings set net.launchpad.indicator.systemtray tray-is-static true gsettings set net.launchpad.indicator.systemtray show-background-static false 

As soon as I yad --notification out and yad --notification again, yad --notification worked as expected. (Moreover, "systemtray" displayed some additional icons that I previously searched in vain.) The position of the icons on the panel can be adjusted using:

 gsettings set net.launchpad.indicator.systemtray static-x 1500 

(where 1500 can be replaced with any reasonable value). I do not know how to get the icons that will be displayed right-to-right. If you ever wanted to remove the system tray emulator, webupd8 is recommended:

 sudo apt-get purge indicator-systemtray-unity 

Demo

Here is a simplified demo that can help illustrate how to use YAD in real-world scenarios. I assume that YAD itself is already installed as described above. Suppose we would like to monitor the output of a program running on the command line and update the tray icon accordingly. For the purposes of this demonstration, let's just take this "program" into the following script "dummyprogram.sh":

 #! /bin/bash i=1 while [ $i -ne 3 ] do let "i=((i+1)%2)" echo $i sleep 1 done 

Copying the above lines to the file "dummyprogram.sh", which makes it executable using "chmod + x dummyprogram.sh", and calling "./dummyprogram.sh" should lead to the following output:

 0 1 0 1 ... 

(one line every second). Now for the real problem. To get the "designated" version of the above output in the tray area, we use the following script "demo.sh":

 #! /bin/bash while read x do if [ $x -eq 0 ] then echo icon:gtk-home else echo icon:gtk-help fi done 

Copy the lines again to the file "demo.sh" and make it executable. Call

 ./dummyprogram.sh | ./demo.sh | yad --notification --listen 

Now it should lead to the desired result: the icon in the tray area, which changes back and forth between two different icons every second.

You can end the demo by typing Ctrl-C in the terminal.

+1
source

For those who care about Unity, a simple solution does not currently exist. So perhaps there is a way to write a custom Python script that uses the Unity AppIndicator-API. There are already many examples of this on the Internet, but it still took a lot of effort to achieve a script that implements approximately the same functionality as the solution using the YAD described in my other answer : a script that will listen to the program output and update the icon accordingly tray. Here is my solution:

 #!/usr/bin/python import os, threading, signal from subprocess import Popen, PIPE, STDOUT from gi.repository import Gtk from gi.repository import AppIndicator3 as AppIndicator class my_indicator: ICON_0 = "gtk-home" ICON_1 = "gtk-help" def __init__(self, wrapper): self.ind = AppIndicator.Indicator.new("my-app-indicator", Gtk.STOCK_INFO, AppIndicator.IndicatorCategory.SYSTEM_SERVICES) self.ind.set_status(AppIndicator.IndicatorStatus.ACTIVE) self.wrapper = wrapper self.build_menu() def build_menu(self): item_quit = Gtk.MenuItem('Quit') item_quit.connect('activate', self.wrapper.quit) menu = Gtk.Menu() self.ind.set_menu(menu) menu.append(item_quit) menu.show_all() def update_icon(self,icon): self.ind.set_icon(icon) class dummy_wrapper: PROGRAM = "./dummyprogram.sh" def __init__(self): self.indicator = my_indicator(self) def main(self): self.process = Popen(self.PROGRAM, stdout=PIPE, stderr=STDOUT, close_fds=True, shell=True, preexec_fn=os.setsid) self.thread = threading.Thread(target=self.watch_pipe, args=(self.process.stdout,self.indicator)) self.thread.daemon = True self.thread.start() Gtk.main() def quit(self, source): if self.process: os.killpg(self.process.pid, signal.SIGTERM) if self.thread: self.thread.join() Gtk.main_quit() @staticmethod def watch_pipe(pipe, indicator): while 1: line = pipe.readline().strip() # The thread waits here until a line appears in the pipe. if not line: # This happens exactly once, namely when the process ends. break else: print line if line=="0": indicator.update_icon(my_indicator.ICON_0) else: indicator.update_icon(my_indicator.ICON_1) dummy_wrapper().main() 

Some quick notes about the code:

  • The syntax of the lines that call and close the program I want to listen to ( ./dummyprogram.sh ), i.e. the lines self.process = Popen(... and os.killpg(... are taken from this answer . This seems to be the only reliable way to terminate the shell process (sub).
  • the script cannot be completed with Ctrl-C - use the Quit menu item instead). It should be possible to add an event handler for Ctrl-C using a signal library, but this seems to be broken due to a bug in Gtk. See this answer for possible work.

Demo Paste the above code into the my-indicator.py file and make it executable with chmod +x my-indicator.py . Do the same for the dummy-programm.sh file described in my answer suggesting YAD . Call ./my-indicator.py and you will see an icon in the Unity panel that changes between two different icons every second. (This should also work on gnome and KDE tables if the Ubuntu application indicator library is installed.)

0
source

All Articles