How to create a custom splash screen for a program?
I am currently building a client for our users at work with Ubuntu MATE 15.10 and Plank as a dock. But when I click for example the Firefox icon in the dock nothing happens until it suddenly pops up after >10 seconds, no loading icon as a mouse pointer or something like that.
Now is there a way to make a custom splash screen like the one in LibreOffice? Or just create a window like "Firefox is being started..." which closes once the application is open?
Thanks!
Create a splash window
You can use GTK
's gtk_window_set_decorated()
to create a splash window without (any) decorations. Combined with gtk_window_set_position()
, you can pretty much create a custom splash screen.
An example
(script1, the splash window):
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, Pango
class Splash(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="splashtitle")
maingrid = Gtk.Grid()
self.add(maingrid)
maingrid.set_border_width(80)
# set text for the spash window
label = Gtk.Label("Eat bananas while you are waiting for Firefox")
label.modify_font(Pango.FontDescription('Ubuntu 22'))
maingrid.attach(label, 0, 0, 1, 1)
def splashwindow():
window = Splash()
window.set_decorated(False)
window.set_resizable(False)
window.set_position(Gtk.WindowPosition.CENTER)
window.show_all()
Gtk.main()
splashwindow()
which creates a splash screen like:
Of course, you can set any background colour, font and fontsize, images etc, depending on your taste, but this is the basic idea.
Make the splash screen disappear if the application's window appears
To kill the splash screen once the application's window appears, you'll need a script to wait for the application window, and (indeed) kill the process that runs the window.
(script2, the wrapper)
#!/usr/bin/env python3
import subprocess
import time
# set the application below
application = "firefox"
# set the path to the splash script below
path = "/path/to/splash_screen.py"
subprocess.Popen([application])
subprocess.Popen(["python3", path])
while True:
time.sleep(0.5)
try:
pid = subprocess.check_output(["pidof", application]).decode("utf-8").strip()
w_list = subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8")
if pid in w_list:
splashpid = [l.split()[2] for l in w_list.splitlines()\
if "splashtitle" in l][0]
subprocess.Popen(["kill", splashpid])
break
except subprocess.CalledProcessError:
pass
How to use
-
The script (2) needs
wmctrl
:sudo apt-get install wmctrl
-
Copy script1 (the splash screen) into an empty file, save it as
splash_screen.py
. Change if you want the text for the splash screen (but why would you :) )label = Gtk.Label("Eat more bananas while you wait for Firefox")
-
Copy script2 into an empty file, save it as
splash_wrapper.py
In the head section of the script, change the path in the line:path = "/path/to/splash_screen.py"
into the actual path (between quotes)
-
Now run the setup by the command:
python3 /path/to/splash_wrapper.py
and your splash screen will appear if you run the wrapper, it will disappear once Firefox actually starts.
Notes
As mentioned the example above is quite straightforward. Of course you can make it much smoother, pimp the splash screen in all possible ways, or even make it semi- transparent:
(code:)
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, Pango
class Splash(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="splashtitle")
maingrid = Gtk.Grid()
self.add(maingrid)
maingrid.set_border_width(80)
# set text for the spash window
label = Gtk.Label("Eat bananas while you are waiting for Firefox")
label.modify_font(Pango.FontDescription('Ubuntu 22'))
maingrid.attach(label, 0, 0, 1, 1)
def splashwindow():
window = Splash()
window.set_decorated(False)
window.set_resizable(False)
window.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0,0,0,1))
window.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse("grey"))
window.set_opacity(0.8)
window.set_position(Gtk.WindowPosition.CENTER)
window.show_all()
Gtk.main()
splashwindow()
or include an image:
(code:)
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, Pango
class Splash(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="splashtitle")
maingrid = Gtk.Grid()
self.add(maingrid)
image = Gtk.Image()
# set the path to the image below
image.set_from_file("/path/to/image.png")
maingrid.attach(image, 1, 0, 1, 1)
maingrid.set_border_width(40)
# set text for the spash window
label = Gtk.Label("Eat bananas while you are waiting for Firefox")
label.modify_font(Pango.FontDescription('Ubuntu 15'))
maingrid.attach(label, 0, 0, 1, 1)
def splashwindow():
window = Splash()
window.set_decorated(False)
window.set_resizable(False)
window.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0,0,0,1))
window.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse("grey"))
window.set_opacity(0.8)
window.set_position(Gtk.WindowPosition.CENTER)
window.show_all()
Gtk.main()
splashwindow()
and so on...
Furthermore, you can make the application and the text arguments of both scripts etc, but this is the basic idea.
No icon in Unity / tasklist?
If you do not want an icon to appear in Unity (or any other task manager, like Plank), you can simply add a line to the __init__
section:
self.set_skip_taskbar_hint(True)