summaryrefslogtreecommitdiffstats
path: root/src/x11_in_gtk2.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2013-02-22 21:22:01 +0000
committerDavid Robillard <d@drobilla.net>2013-02-22 21:22:01 +0000
commit28cf00ed548bd658039b2ee52e35829b1e6dc821 (patch)
tree32fd1c70198a57b8d1218f70c633945038b99a3f /src/x11_in_gtk2.c
parent61a8166c4fda5e3486ae9d19ff102e36a14bfcb0 (diff)
downloadsuil-28cf00ed548bd658039b2ee52e35829b1e6dc821.tar.gz
suil-28cf00ed548bd658039b2ee52e35829b1e6dc821.tar.bz2
suil-28cf00ed548bd658039b2ee52e35829b1e6dc821.zip
Fix key events for X11 in Gtk.
git-svn-id: http://svn.drobilla.net/lad/trunk/suil@5064 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/x11_in_gtk2.c')
-rw-r--r--src/x11_in_gtk2.c97
1 files changed, 56 insertions, 41 deletions
diff --git a/src/x11_in_gtk2.c b/src/x11_in_gtk2.c
index 0adc408..9d79541 100644
--- a/src/x11_in_gtk2.c
+++ b/src/x11_in_gtk2.c
@@ -42,33 +42,49 @@ GType suil_x11_wrapper_get_type(void); // Accessor for SUIL_TYPE_X11_WRAPPER
G_DEFINE_TYPE(SuilX11Wrapper, suil_x11_wrapper, GTK_TYPE_SOCKET)
-#ifdef SUIL_FORWARD_KEYS
-static GdkFilterReturn
-event_filter(GdkXEvent* xevent, GdkEvent* event, gpointer data)
+static void
+forward_key_event(SuilX11Wrapper* socket,
+ GdkEvent* gdk_event)
{
- SuilX11Wrapper* wrap = (SuilX11Wrapper*)data;
- XEvent* ev = (XEvent*)xevent;
- if (wrap->instance &&
- wrap->instance->handle &&
- (ev->type == KeyPress || ev->type == KeyRelease)) {
- // Forward keyboard events to UI window
- XSendEvent(ev->xkey.display, (Window)wrap->instance->ui_widget, 1, 0, ev);
- XSync(ev->xkey.display, TRUE);
+ GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(socket->plug));
+ GdkScreen* screen = gdk_window_get_screen(window);
+
+ XKeyEvent xev;
+ memset(&xev, 0, sizeof(xev));
+ xev.type = (gdk_event->type == GDK_KEY_PRESS) ? KeyPress : KeyRelease;
+ xev.root = GDK_WINDOW_XID(gdk_screen_get_root_window(screen));
+ xev.window = GDK_WINDOW_XID(window);
+ xev.subwindow = None;
+ xev.time = gdk_event->key.time;
+ xev.state = gdk_event->key.state;
+ xev.keycode = gdk_event->key.hardware_keycode;
+
+ XSendEvent (GDK_WINDOW_XDISPLAY(window),
+ (Window)socket->instance->ui_widget,
+ False,
+ NoEventMask,
+ (XEvent*)&xev);
+}
+
+static gboolean
+suil_x11_wrapper_key_event(GtkWidget* widget,
+ GdkEventKey* event)
+{
+ SuilX11Wrapper* const self = SUIL_X11_WRAPPER(widget);
+
+ if (self->plug) {
+ forward_key_event(self, (GdkEvent*)event);
+ return TRUE;
}
- return GDK_FILTER_CONTINUE;
+
+ return FALSE;
}
-#endif
static gboolean
on_plug_removed(GtkSocket* sock, gpointer data)
{
SuilX11Wrapper* const self = SUIL_X11_WRAPPER(sock);
-#ifdef SUIL_FORWARD_KEYS
- GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(self));
- gdk_window_remove_filter(window, event_filter, self);
-#endif
-
if (self->instance->handle) {
self->instance->descriptor->cleanup(self->instance->handle);
self->instance->handle = NULL;
@@ -89,28 +105,36 @@ suil_x11_wrapper_finalize(GObject* gobject)
}
static void
-suil_x11_wrapper_class_init(SuilX11WrapperClass* klass)
+suil_x11_wrapper_realize(GtkWidget* w)
{
- GObjectClass* const gobject_class = G_OBJECT_CLASS(klass);
+ SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(w);
+ GtkSocket* const socket = GTK_SOCKET(w);
- gobject_class->finalize = suil_x11_wrapper_finalize;
+ if (GTK_WIDGET_CLASS(suil_x11_wrapper_parent_class)->realize) {
+ GTK_WIDGET_CLASS(suil_x11_wrapper_parent_class)->realize(w);
+ }
+
+ gtk_socket_add_id(socket, gtk_plug_get_id(wrap->plug));
+ gtk_widget_show(GTK_WIDGET(wrap->plug));
}
static void
-suil_x11_wrapper_init(SuilX11Wrapper* self)
+suil_x11_wrapper_class_init(SuilX11WrapperClass* klass)
{
- self->instance = NULL;
- self->plug = GTK_PLUG(gtk_plug_new(0));
+ GObjectClass* const gobject_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass* const widget_class = GTK_WIDGET_CLASS(klass);
+
+ gobject_class->finalize = suil_x11_wrapper_finalize;
+ widget_class->realize = suil_x11_wrapper_realize;
+ widget_class->key_press_event = suil_x11_wrapper_key_event;
}
static void
-suil_x11_wrapper_realize(GtkWidget* w, gpointer data)
+suil_x11_wrapper_init(SuilX11Wrapper* self)
{
- SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(w);
- GtkSocket* const socket = GTK_SOCKET(w);
-
- gtk_socket_add_id(socket, gtk_plug_get_id(wrap->plug));
- gtk_widget_show_all(GTK_WIDGET(wrap->plug));
+ self->plug = GTK_PLUG(gtk_plug_new(0));
+ self->wrapper = NULL;
+ self->instance = NULL;
}
static int
@@ -130,11 +154,6 @@ wrapper_wrap(SuilWrapper* wrapper,
wrap->wrapper = wrapper;
wrap->instance = instance;
- g_signal_connect_after(G_OBJECT(wrap),
- "realize",
- G_CALLBACK(suil_x11_wrapper_realize),
- NULL);
-
g_signal_connect(G_OBJECT(wrap),
"plug-removed",
G_CALLBACK(on_plug_removed),
@@ -167,16 +186,12 @@ suil_wrapper_new(SuilHost* host,
SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(
g_object_new(SUIL_TYPE_X11_WRAPPER, NULL));
- wrap->wrapper = NULL;
-
wrapper->impl = wrap;
wrapper->resize.handle = wrap;
wrapper->resize.ui_resize = wrapper_resize;
-#ifdef SUIL_FORWARD_KEYS
- GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(wrap));
- gdk_window_add_filter(window, event_filter, wrap);
-#endif
+ gtk_widget_set_sensitive(GTK_WIDGET(wrap), TRUE);
+ gtk_widget_set_can_focus(GTK_WIDGET(wrap), TRUE);
suil_add_feature(features, &n_features, LV2_UI__parent,
(void*)(intptr_t)gtk_plug_get_id(wrap->plug));