diff options
author | David Robillard <d@drobilla.net> | 2013-02-22 21:22:01 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2013-02-22 21:22:01 +0000 |
commit | 28cf00ed548bd658039b2ee52e35829b1e6dc821 (patch) | |
tree | 32fd1c70198a57b8d1218f70c633945038b99a3f | |
parent | 61a8166c4fda5e3486ae9d19ff102e36a14bfcb0 (diff) | |
download | suil-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-- | AUTHORS | 1 | ||||
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | src/x11_in_gtk2.c | 97 | ||||
-rw-r--r-- | wscript | 7 |
4 files changed, 57 insertions, 51 deletions
@@ -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 @@ -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)); @@ -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('') |