Plugs and Sockets

Overview
From time to time, it may be useful to be able to embed a widget from another application within your application. gtkmm allows you to do this with the Gtk::Socket and Gtk::Plug classes. It is not anticipated that very many applications will need this functionality, but in the rare case that you need to display a widget that is running in a completely different process, these classes can be very helpful.
The communication between a Socket and a Plug follows the XEmbed protocol. This protocol has also been implemented in other toolkits (e.g. Qt), which allows the same level of integration when embedding a Qt widget in GTK+ or vice versa.
The way that Sockets and Plugs work together is through their window ids. Both a Socket and a Plug have IDs that can be retrieved with their get_id() member functions. The use of these IDs will be explained below in Connecting Plugs and Sockets.

Sockets
A Socket is a special kind of container widget that provides the ability to embed widgets from one process into another process in a way that is transparent to the user.

Plugs
A Plug is a special kind of Window that can be plugged into a Socket. Besides the normal properties and methods of Gtk::Window, a Plug provides a constructor that takes the ID of a Socket, which will automatically embed the Plug into the Socket that matches that ID.
Since a Plug is just a special type of Gtk::Window class, you can add containers or widgets to it like you would to any other window.

Connecting Plugs and Sockets
After a Socket or Plug object is realized, you can obtain its ID with its get_id() function. This ID can then be shared with other processes so that other processes know how to connect to each other.
There are two basic strategies that can be used:
Create a Socket object in one process and pass the ID of that Socket to another process so that it can create a Plug object by specifying the given Socket ID in its constructor. There is no way to assign a Plug to a particular Socket after creation, so you must pass the Socket ID to the Plug's constructor.
Create a Plug independantly from any particular Socket and pass the ID of the Plug to other processes that need to use it. The ID of the Plug can be associated with a particular Socket object using the Socket::add_id() function. This is the approach used in the example below.

Plugs and Sockets Example
The following is a simple example of using sockets and plugs. The method of communication between processes is deliberately kept very simple: The Plug writes its ID out to a text file named plug.id and the process with the socket reads the ID from this file. In a real program, you may want to use a more sophisticated method of inter-process communication.
Source Code
File: plug.cc (For use with gtkmm 3, not gtkmm 2)

#include <iostream>
#include <fstream>
#include <gtkmm.h>
#include <gtkmm/plug.h>
#include <glib/gstdio.h>

using namespace std;

const char* id_filename = "plug.id";

void on_embed()
{
  cout << "I've been embedded." << endl;
}

class MyPlug : public Gtk::Plug
{
  public:
    MyPlug() :
      m_label("I am the plug")
  {
    set_size_request(150, 100);
    add(m_label);
    signal_embedded().connect(sigc::ptr_fun(on_embed));
    show_all_children();
  }

  private:
    Gtk::Label m_label;
};


int main(int argc, char** argv)
{
  // The plug and the socket have different application ids, so they can run
  // simultaneously.
  Glib::RefPtr<Gtk::Application> app =
    Gtk::Application::create(argc, argv, "org.gtkmm.example.plug");
  MyPlug plug;
  plug.show();

  ofstream out(id_filename);
  out << plug.get_id();
  out.close();
  cout << "The window ID is: " << plug.get_id() << endl;

  app->run(plug);

  // remove the ID file when the program exits
  g_remove(id_filename);
  return 0;
}

File: socket.cc (For use with gtkmm 3, not gtkmm 2)

#include <iostream>
#include <fstream>
#include <gtkmm.h>
#include <gtkmm/socket.h>

using namespace std;

const char* id_filename = "plug.id";

void plug_added()
{
  cout << "A plug was added" << endl;
}

bool plug_removed()
{
  cout << "A Plug was removed" << endl;
  return true;
}

class MySocketWindow : public Gtk::Window
{
  public:
    MySocketWindow()
    {
      ifstream infile(id_filename);
      if (infile)
      {
        Gtk::Socket* socket = Gtk::manage(new Gtk::Socket());
        add(*socket);
        socket->signal_plug_added().connect(sigc::ptr_fun(plug_added));
        socket->signal_plug_removed().connect(sigc::ptr_fun(plug_removed));
        ::Window plug_id = 0;
        infile >> plug_id;
        infile.close();
        socket->add_id(plug_id);
      }
      else
      {
        Gtk::Label* label = Gtk::manage(
            new Gtk::Label(
              "Plug id file not found.\n Make sure plug is running."));
        add(*label);
        set_size_request(150, 50);
      }
      show_all();
    }
};

int main(int argc, char** argv)
{
  // The plug and the socket have different application ids, so they can run
  // simultaneously.
  Glib::RefPtr<Gtk::Application> app =
    Gtk::Application::create(argc, argv, "org.gtkmm.example.socket");
  MySocketWindow win;
  app->run(win);
  return 0;
}

This example creates two executable programs: socket and plug. The idea is that socket has an application window that will embed a widget from the plug program. The way this example is designed, plug must be running first before starting socket. To see the example in action, execute the following commands in order from within the example directory:
Start the plug program and send it to the background (or just use a different terminal).

$ ./plug &

After which you should see something like the following:

The window ID is: 69206019

Then start the socket program:

$ ./socket

After starting socket, you should see the following output in the terminal:

I've been embedded.
A plug was added

The first line of output is from plug, after it has been notified that it has been embedded inside of a Socket. The second line was emitted by socket in response to its plug_added signal. If everything was done as described above, the socket window should look roughly like the following:
If for some reason the Socket couldn't attach the Plug, the window would look something like this: