10.13. Plugs and Sockets

Plugs and Sockets cooperate to embed the user interface from one process into another process. This can also be accomplished using Bonobo.

10.13.1. Plugs

A Plug encapsulates a user interface provided by one application so that it can be embedded in another application's user interface. The "embedded" signal alerts the plug application that the plug has been embedded in the other application's user interface.

A Plug is created using the following function:

  plug = gtk.Plug(socket_id)

which creates a new Plug and embeds it in the Socket identified by socket_id. If socket_id is 0L, the plug is left "unplugged" and can later be plugged into a Socket using the Socket add_id() method.

The Plug method:

  id = plug.get_id()

returns the window ID of a Plug, that can be used to embed it inside a Socket using the Socket add_id() method.

The plug.py example program illustrates the use of a Plug:

    1	#!/usr/bin/python
    2	
    3	import pygtk
    4	pygtk.require('2.0')
    5	import gtk,sys
    6	
    7	Wid = 0L
    8	if len(sys.argv) == 2:
    9	    Wid = long(sys.argv[1])
   10	
   11	plug = gtk.Plug(Wid)
   12	print "Plug ID=", plug.get_id()
   13	
   14	def embed_event(widget):
   15	    print "I (",widget,") have just been embedded!"
   16	
   17	plug.connect("embedded", embed_event)
   18	
   19	entry = gtk.Entry()
   20	entry.set_text("hello")
   21	def entry_point(widget):
   22	    print "You've changed my text to '%s'" % widget.get_text()
   23	
   24	entry.connect("changed", entry_point)
   25	plug.connect("destroy", gtk.mainquit)
   26	
   27	plug.add(entry)
   28	plug.show_all()
   29	
   30	
   31	gtk.mainloop()

The program is invoked like:

  plug.py [windowID]

where windowID is the ID of a Socket to connect the Plug to.

10.13.2. Sockets

A Socket provides the widget to embed a Plug widget from another application into your GUI transparently. An application creates a Socket widget and, passes that widget's window ID to another application, which then creates a Plug using that window ID as a parameter. Any widgets contained in the Plug appear inside the first application's window.

The Socket window ID is obtained by using the Socket method get_id(). Before using this method, the Socket must be realized, and added to its parent.

Note

If you pass the window ID of the Socket to another process that will create a Plug in the Socket, you must make sure that the Socket widget is not destroyed until that Plug is created.

When GTK+ is notified that the embedded window has been destroyed, then it will destroy the Socket as well. You should always, therefore, be prepared for your sockets to be destroyed at any time when the main event loop is running. Destroying a Socket will cause an embedded Plug to be destroyed as well.

The communication between a Socket and a Plug follows the XEmbed protocol. This protocol has also been implemented in other toolkits, e.g. Qt, allowing the same level of integration when embedding a Qt widget in GTK or vice versa.

Create a new empty Socket:

  socket = gtk.Socket()

The Socket must be contained in a toplevel window before you invoke the add_id() method:

  socket.add_id(window_id)

which adds an XEMBED client, such as a Plug, to the Socket. The client may be in the same process or in a different process.

To embed a Plug in a Socket, you can either create the Plug with:

  plug = gtk.Plug(0L)

and then pass the number returned by the Plug get_id() method to the Socket add_id() method:

  socket.add_id(plug)

or you can invoke the Socket get_id() method:

    window_id = socket.get_id()

to get the window ID for the socket, and then create the plug with:

  plug = gtk.Plug(window_id)

The Socket must have already be added into a toplevel window before you can make this call.

The socket.py example program illustrates the use of a Socket:

    1	#!/usr/bin/python
    2	
    3	import string
    4	
    5	import pygtk
    6	pygtk.require('2.0')
    7	import gtk,sys
    8	
    9	window = gtk.Window()
   10	window.show()
   11	
   12	socket = gtk.Socket()
   13	socket.show()
   14	window.add(socket)
   15	
   16	print "Socket ID=", socket.get_id()
   17	window.connect("destroy", gtk.mainquit)
   18	
   19	def plugged_event(widget):
   20	    print "I (",widget,") have just had a plug inserted!"
   21	
   22	socket.connect("plug-added", plugged_event)
   23	
   24	if len(sys.argv) == 2:
   25	    socket.add_id(long(sys.argv[1]))
   26	
   27	gtk.mainloop()

To run the example you can either run plug.py first:

  $ python plug.py
  Plug ID= 20971522

and copy the output ID to the first arg of socket.py:

  $ python socket.py 20971522
  Socket ID= 48234523
  I ( <gtk.Plug object (GtkPlug) at 0x3008dd78> ) have just been embedded!
  I ( <gtk.Socket object (GtkSocket) at 0x3008ddf0> ) have just had a plug inserted!

Or you can run socket.py:

  $ python socket.py
  Socket ID= 20971547

and then run plug.py, copying across the window ID:

  $ python plug.py
  20971547
  I ( <gtk.Socket object (GtkSocket) at 0x3008ddf0> ) have just had a plug inserted!
  Plug ID= 48234498