Skip to content

Instantly share code, notes, and snippets.

Created August 26, 2014 20:04
Show Gist options
  • Save anonymous/f179ff891f7c8029faf8 to your computer and use it in GitHub Desktop.
Save anonymous/f179ff891f7c8029faf8 to your computer and use it in GitHub Desktop.
sockfoc: sockfoc.cc window_ext.h
g++ -ggdb sockfoc.cc -o sockfoc `pkg-config gtkmm-3.0 --cflags --libs` -lX11
#include <gtkmm.h>
#include <gtkmm/socket.h>
#include "window_ext.h"
#define XEMBED_FOCUS_IN 4
#define XEMBED_FOCUS_CURRENT 0
class TheWindow : public WindowExt
{
Gtk::Box* box;
Gtk::Socket* socket;
Gtk::Button* button_close;
public:
TheWindow() : WindowExt(Gtk::WINDOW_POPUP)
{
signal_realize().connect( sigc::mem_fun(*this,&TheWindow::add_term) );
button_close = Gtk::manage( new Gtk::Button("Close Window.") );
box = Gtk::manage( new Gtk::Box(Gtk::ORIENTATION_VERTICAL) );
box->pack_start( *button_close );
add(*box);
button_close->signal_clicked().connect(
sigc::mem_fun(*this,&Window::hide)
);
show_all();
grab_keyboard(this->get_window());
}
void add_term()
{
socket = Gtk::manage( new Gtk::Socket );
box->pack_start( *socket );
int xid = socket->get_id();
char buffer[50];
//sprintf(buffer, "xterm -into %d &", xid);
sprintf(buffer, "urxvt -embed %d &", xid);
system(buffer);
box->show_all();
socket->signal_plug_added().connect(
sigc::mem_fun(*this, &TheWindow::send_focus_in)
);
socket->signal_plug_removed().connect(
sigc::mem_fun(*this, &TheWindow::on_plug_removed)
);
}
bool on_plug_removed()
{
hide();
return false;
}
void send_focus_in()
{
GdkWindow* plug = socket->get_plug_window()->gobj();
GdkDisplay *display = gdk_window_get_display(plug);
XClientMessageEvent xclient;
memset(&xclient, 0, sizeof (xclient));
xclient.window = GDK_WINDOW_XID(plug);
xclient.type = ClientMessage;
xclient.message_type =
gdk_x11_get_xatom_by_name_for_display(display, "_XEMBED");
xclient.format = 32;
xclient.data.l[0] = gtk_get_current_event_time();
xclient.data.l[1] = XEMBED_FOCUS_IN;
xclient.data.l[2] = XEMBED_FOCUS_CURRENT;
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
XSendEvent(
GDK_WINDOW_XDISPLAY(plug),
GDK_WINDOW_XID(plug), False, NoEventMask, (XEvent *)&xclient
);
}
};
int main(int argc, char** argv)
{
Glib::RefPtr<Gtk::Application> app;
app = Gtk::Application::create(argc, argv, "socket.focustest");
TheWindow win;
return app->run(win);
}
#ifndef WINDOW_EXT_H
#define WINDOW_EXT_H
#include <gtkmm.h>
#include <iostream>
class Overlay;
class WindowExt : public Gtk::Window
{
private:
Cairo::RefPtr<Cairo::Region> shape;
public:
void grab_keyboard(Glib::RefPtr<Gdk::Window> dest)
{
Glib::RefPtr<Gdk::Display> display = get_display();
Glib::RefPtr<Gdk::DeviceManager> deviceM = display->get_device_manager();
std::vector< Glib::RefPtr<Gdk::Device> >devices =
deviceM->list_devices( Gdk::DEVICE_TYPE_MASTER );
std::vector< Glib::RefPtr<Gdk::Device> >::iterator it;
for(it = devices.begin(); it != devices.end(); ++it)
{
for(int grab = Gdk::GRAB_NOT_VIEWABLE; grab == Gdk::GRAB_NOT_VIEWABLE;)
{
grab = (*it)->grab(
dest, Gdk::OWNERSHIP_NONE, true,
Gdk::ALL_EVENTS_MASK, GDK_CURRENT_TIME
);
}
}
}
WindowExt(Gtk::WindowType type=Gtk::WINDOW_TOPLEVEL) : Window(type) {}
virtual ~WindowExt(){}
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment