The Journalist's Cage

And this gray spirit yearning in desire to follow knowledge like a sinking star...

HomeBlogTagsArticles

Calendar

January 2007
SuMoTuWeThFrSa
 123456
78910111213
14151617181920
21222324252627
28293031

Recent Bookmarks

Tags

Archives


RSS

XEmbed with Ruby and Gtk::Socket

I recently discovered a Python IDE called PIDA that provides support for embedded Vim. I'm not a big fan of Python IDEs, but being able to use Vim as the editing component is definitely a killer feature. I haven't seen Vim embedded in a GNOME program since the unfortunate demise of the GVim Bonobo component and I had no idea it was even possible with current versions of Vim. A quick inspection of PIDA's source code revealed that it launches a new instance of GVim and then uses XEmbed to incorporate it into the user interface.

XEmbed experiment I had never heard of XEmbed before, but seeing it used in PIDA compelled me to pursue further investigation. Apparently, XEmbed makes it possible to embed virtually any X11 window inside of another application. GTK provides support for this with the Plug and Socket widgets, which are available in GTK's Python and Ruby bindings. XEmbed client support is also available in Qt with the QtXEmbedContainer object.

For the sake of experimentation, I wrote a simple Ruby script that uses my window management library and the Gtk::Socket object to facilitate window embedding. It provides two combo boxes which each contain a complete list of windows. The user selects a window in each one, and then clicks the Grab button to grab those windows and reparent them in Socket objects separated by a resizeable splitter. The source code for this experiment is relatively simple:

#!/usr/bin/env ruby

require "wmlib"
require "gtk2"

win = Gtk::Window.new("Embed Test")
win.signal_connect("destroy") {|w| Gtk.main_quit}

win.add vb = Gtk::VBox.new
vb.pack_start(hb = Gtk::HBox.new, false, false)

lst = Gtk::ListStore.new String, Integer

hb.pack_start(combo1 = Gtk::ComboBox.new)
hb.pack_start(combo2 = Gtk::ComboBox.new)
hb.pack_start(btnGrab = Gtk::Button.new("Grab"), false)

combo1.model = lst
combo2.model = lst

for w in WM::Window
  i = lst.append
  i[0], i[1] = w.title[0..30], w.id if w.title
end

vb.pack_start(pane = Gtk::HPaned.new)
pane.pack1 socket = Gtk::Socket.new, true, false
pane.pack2 socket2 = Gtk::Socket.new, true, false

## Use tabs instead of panes
#vb.pack_start(tabs = Gtk::Notebook.new)
#tabs.append_page(socket = Gtk::Socket.new)
#tabs.append_page(socket2 = Gtk::Socket.new)

win.show_all()

btnGrab.signal_connect("clicked") {|*a|
  socket.add_id combo1.active_iter[1]
  socket2.add_id combo2.active_iter[1]
}

Gtk.main

While experimenting with panes and XEmbed, one is reminded of tiling window managers like Ion. The ability to place arbitrary windows into tabs or panes is very compelling, and I'm certain I'll find some uses for the feature in the future.


Posted on 2007-01-060 comments



Comments

Add a Comment

Name:

E-mail: (Optional, Not shown)

Subject: (Optional)

Text in image:

Comment: