summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--AUTHORS1
-rw-r--r--NEWS3
-rw-r--r--src/x11_in_gtk2.c97
-rw-r--r--wscript7
4 files changed, 57 insertions, 51 deletions
diff --git a/AUTHORS b/AUTHORS
index 2a82a14..70cccdb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -6,4 +6,3 @@ Contributors:
* Fix reparenting of Gtk UIs in Qt
* Peter Nelson <peter@fuzzle.org>
* Fix crash when a broken UI returns a NULL descriptor
- * Fix crash on close caused by key filter for X11 in Gtk
diff --git a/NEWS b/NEWS
index 4df90a0..ba44fee 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,6 @@
suil (0.6.11) unstable;
- * Add compile time option to disable explicit Gtk to X11 key forwarding
- * Fix crash on close caused by key filter for X11 in Gtk
+ * Fix key events for X11 in Gtk
* Fix crash when a broken UI returns a NULL descriptor
* Fix compilation on BSD
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));
diff --git a/wscript b/wscript
index 9a64f3f..00313e2 100644
--- a/wscript
+++ b/wscript
@@ -26,8 +26,6 @@ def options(opt):
help="Build static library")
opt.add_option('--no-shared', action='store_true', dest='no_shared',
help='Do not build shared library')
- opt.add_option('--no-forward-keys', action='store_true', dest='no_forward_keys',
- help='Do not explicitly forward key events for X11 in Gtk')
opt.add_option('--gtk2-lib-name', type='string', dest='gtk2_lib_name',
default="libgtk-x11-2.0.so.0",
help="Gtk2 library name [Default: libgtk-x11-2.0.so.0]")
@@ -92,9 +90,6 @@ def configure(conf):
autowaf.define(conf, 'SUIL_MODULE_PREFIX', module_prefix)
autowaf.define(conf, 'SUIL_MODULE_EXT', module_ext)
- if not Options.options.no_forward_keys:
- autowaf.define(conf, 'SUIL_FORWARD_KEYS', 1)
-
autowaf.set_lib_env(conf, 'suil', SUIL_VERSION)
conf.write_config_header('suil_config.h', remove=False)
@@ -102,8 +97,6 @@ def configure(conf):
conf.is_defined('HAVE_GTK2'))
autowaf.display_msg(conf, "Gtk2 Library Name",
conf.env.SUIL_GTK2_LIB_NAME)
- autowaf.display_msg(conf, "Forward Gtk keys to X11 UI",
- conf.is_defined('SUIL_FORWARD_KEYS'))
autowaf.display_msg(conf, "Qt4 Support",
conf.is_defined('HAVE_QT4'))
print('')