Embedding GTK applications via XEmbed

Together with GtkPlug, GtkSocket provides the ability to embed widgets from one process into another process in a fashion that is transparent to the user. One process creates a GtkSocket widget and passes that widget’s window ID to the other process, which then creates a GtkPlug with that window ID. Any widgets contained in the GtkPlug then will appear inside the first application’s window.

Here's an updated version of Embedding applications via XEmbed using GTK 3.0.

Reference

Here are commands for running some GTK applications in embedded mode:

gvim --servername %d --socketid %d #GVim server

gvim --servername %d --remote-send 'GoHello, World!<Esc><C-O>' #GVim client

cvlc --drawable-xid %d out.mp4     #VLC

xterm -into %lu    # Terminal emulator

mpv --wid=%lu url    # mpv video player

surf -e %lu   # Surf web browser from Suckless based on webkitgtk2


embed.c

#include <gtk/gtkx.h>

#define EXPR "'GoHello, World!<Esc><C-O>'"

void send_hello(GtkButton *btn, gint id)
{
    gchar *command = g_strdup_printf(
        "gvim --servername %d --remote-send " EXPR, id);
    g_spawn_command_line_async(command, NULL);
}

gint main(gint argc, gchar **argv)
{
    gtk_init(&argc, &argv);

    /* Create window */
    GtkWidget *win  = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkWidget *vbox = gtk_box_new(FALSE, 0);
    GtkWidget *sock = gtk_socket_new();
    GtkWidget *btn  = gtk_button_new_with_label("Hello, World!");
    g_signal_connect(sock, "plug-removed", gtk_main_quit, NULL);
    g_signal_connect(win,  "delete-event", gtk_main_quit, NULL);
    gtk_widget_set_size_request(sock, 200, 200);
    gtk_box_pack_start(GTK_BOX(vbox), sock, TRUE,  TRUE, 0);
    gtk_box_pack_start(GTK_BOX(vbox), btn,  FALSE, TRUE, 0);
    gtk_container_add(GTK_CONTAINER(win), vbox);
    gtk_widget_show_all(win);

    /* Embed vim */
    Window id = gtk_socket_get_id(GTK_SOCKET(sock));
    gchar *command = g_strdup_printf(
        "gvim --servername %d --socketid %d", id, id);
    g_spawn_command_line_async(command, NULL);
    g_signal_connect(btn, "clicked", G_CALLBACK(send_hello), (gpointer)id);

    /* Run */
    gtk_main();
    return 0;
}
 
 
Compile the file using following command to generate executable embed.

 gcc embed.c $(pkg-config --libs --cflags gtk+-3.0) -o embed  

Comments

Popular posts from this blog

GNU Emacs as a Comic Book Reader

Tinylisp and Multi-threaded Emacs

GNU Emacs as a Shopping App