Launcher icon (to start a script) keeps blinking and is unresponsive for seven seconds, how can I solve it?

I have a script, which I start from the Unity Launcher. When I click on the icon, my script starts successfully.

While the script only takes a split second to run, the launcher icon blinks for about 7-8 sec., during which the launcher is occupied and doesn't respond to additional clicks.

Can I customize my bash script in such a way that the blinking icon doesn't block the script for seven seconds?

I use Ubuntu 15.10.


Solution 1:

Not a dupe

Very much related this one, but slightly different, since the blinking, non-responsive icon is a different problem, not solved by adding:

StartupNotify=false

to the launcher; the icon will still keep blinking for appr. seven seconds. Although the issues in both questions have the same background, both the symptoms and the possible solution are slightly different.

The cause

After starting GUI applications from the Unity Launcher (by clicking on the icon), the launcher waits for a window to appear. While waiting, the cursor blinks. It takes the launcher a while before it comes to the conclusion that its "date" (the window) won't show up. While waiting however, the launcher does not accept new clicks to execute the script (again).

The solution in the above linked question, adding

StartupNotify=false

does solve the spinning wheel of the mouse cursor, but does not make the icon responsive again.

Then what does work?

The other solution in the linked answer however (opening a fake, invisible window when starting a non- GUI script from the Unity launcher) will also solve the issue of the blinking icon.

From the linked answer:

  1. Create, if it does not exist yet, the directory ~/bin
  2. Copy the script below into an empty file, save it as fake_window (no extension) in ~/bin and make it executable

    #!/usr/bin/env python3
    from gi.repository import Gtk
    from threading import Thread
    import time
    import subprocess
    
    """
    This is a self-destroying window, to "feed" Unity a fake-window, preventing
    the launcher to show a spinning wheel, waiting for a window to appear.
    Include the command to run this script at the end of the (your) script.
    """
    
    class FakeWin(Gtk.Window):
    
        def __init__(self):
            Gtk.Window.__init__(self, title="1526closeme")
            Thread(target = self.close).start()
    
        def close(self):
            t = 0
            while t < 150:
                time.sleep(0.2)
                try:
                    pid = subprocess.check_output(["pgrep", "-f", "fake_window"])\
                          .decode("utf-8").strip()
                    subprocess.Popen(["kill", pid])
                    break
                except subprocess.CalledProcessError:
                    pass
                t += 1
    
    def fakewindow():
        window = FakeWin()
        # make our window transparent
        window.set_opacity(0)
        window.set_default_size(0,0)
        window.show_all()
        Gtk.main()
    
    fakewindow()
    
  3. Add to the very end of your script the command:

    fake_window
    
  4. Log out and back in (or run source ~/.profile)

Now the icon will not blink for seven seconds if you run your script from the Unity Launcher.