Lets start by saying that there are lots and lots of ways.
You normally setup a token/identifier when the program starts, so later instances can look for the existence of that token.
I will describe one way which uses dbus.
Overview:
When starting a program, it can register itself on the session dbus under a unique name (e.g. "org.nicklemaire.myprogram"). Further instances of the program can check if such an accesspoint is already registered, and if so, tell the program what to do via this dbus access point (e.g. get focus, open a website, play a song). The last part is probably necessary when you want behaviour similar to "firefox askubuntu.com", which opens this page in a new tab in an already running instance.
Code:
#!/usr/bin/env python
import sys
import gtk
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
from multiprocessing import Process
class MyDBUSService(dbus.service.Object):
def __init__(self):
bus_name = dbus.service.BusName('org.nicklemaire.myprogram', bus=dbus.SessionBus())
dbus.service.Object.__init__(self, bus_name, '/org/nicklemaire/myprogram')
@dbus.service.method('org.nicklemaire.myprogram', in_signature='s')
def startup(self, arg):
print "got the following parameter from another instance:", arg
def call_instance():
try:
bus = dbus.SessionBus()
programinstance = bus.get_object('org.nicklemaire.myprogram', '/org/nicklemaire/myprogram')
bus = dbus.SessionBus()
programinstance = bus.get_object('org.nicklemaire.myprogram', '/org/nicklemaire/myprogram')
startup = programinstance.get_dbus_method('startup', 'org.nicklemaire.myprogram')
try:
arg = sys.argv[1]
except IndexError:
arg = ""
startup(arg)
print "Another instance was running and notified."
except dbus.exceptions.DBusException:
exit(-1) # process had an error
if __name__ == "__main__":
p = Process(target=call_instance)
p.start()
p.join()
if p.exitcode > 0: # process had an error
DBusGMainLoop(set_as_default=True)
myservice = MyDBUSService()
gtk.main()
Test:
Open a terminal and run the program: myprogram.py
. It will not terminate because we currently want to have it running and waiting for a second instance to start.
Now do this: open another terminal and run the program again, this time with an additional argument myprogram.py askubuntu.com
.
It should print: "Another instance was running and notified."
While in the first terminal, you should get an output similar to this: "got the following parameter from another instance: askubuntu.com"
The other part of your question: raising a program is described here: https://stackoverflow.com/questions/9054462/how-do-i-raise-a-window-that-is-minimized-or-covered-with-pygobject
Basically, you have to call mywindow.present()
in the startup
method.