From e0a8ba4340b199cfe90534d977d4890bf02a4091 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 5 Aug 2011 12:45:47 -0400 Subject: Use an event filter to find new windows rather than a timeout --- modules/gtk2/Makefile.am | 4 ++++ modules/gtk2/vapi-fixes.vapi | 1 + modules/gtk3/Makefile.am | 4 ++++ modules/gtk3/caribou-gtk-module.vala | 38 +++++++++++++++++++----------------- modules/gtk3/vapi-fixes.vapi | 15 ++++++++++++++ 5 files changed, 44 insertions(+), 18 deletions(-) create mode 120000 modules/gtk2/vapi-fixes.vapi create mode 100644 modules/gtk3/vapi-fixes.vapi (limited to 'modules') diff --git a/modules/gtk2/Makefile.am b/modules/gtk2/Makefile.am index f59aabd..eaa03ca 100644 --- a/modules/gtk2/Makefile.am +++ b/modules/gtk2/Makefile.am @@ -9,6 +9,7 @@ libcaribou_gtk_module_la_SOURCES = \ libcaribou_gtk_module_la_VALAFLAGS = \ -h caribou-gtk-module.h \ --vapidir=. \ + --pkg vapi-fixes \ --pkg gdk-x11-2.0 \ --pkg gtk+-2.0 \ -D GTK2 \ @@ -28,3 +29,6 @@ libcaribou_gtk_module_la_LDFLAGS = \ -module \ $(NULL) +EXTRA_DIST = \ + vapi-fixes.vapi \ + $(NULL) diff --git a/modules/gtk2/vapi-fixes.vapi b/modules/gtk2/vapi-fixes.vapi new file mode 120000 index 0000000..cb1b309 --- /dev/null +++ b/modules/gtk2/vapi-fixes.vapi @@ -0,0 +1 @@ +../gtk3/vapi-fixes.vapi \ No newline at end of file diff --git a/modules/gtk3/Makefile.am b/modules/gtk3/Makefile.am index 0f5aa1b..a5a4fca 100644 --- a/modules/gtk3/Makefile.am +++ b/modules/gtk3/Makefile.am @@ -9,6 +9,7 @@ libcaribou_gtk_module_la_SOURCES = \ libcaribou_gtk_module_la_VALAFLAGS = \ -h caribou-gtk-module.h \ --vapidir=. \ + --pkg vapi-fixes \ --pkg gdk-x11-3.0 \ --pkg gtk+-3.0 \ $(VALAGLAFS) @@ -27,3 +28,6 @@ libcaribou_gtk_module_la_LDFLAGS = \ -module \ $(NULL) +EXTRA_DIST = \ + vapi-fixes.vapi \ + $(NULL) diff --git a/modules/gtk3/caribou-gtk-module.vala b/modules/gtk3/caribou-gtk-module.vala index 12429fb..283e361 100644 --- a/modules/gtk3/caribou-gtk-module.vala +++ b/modules/gtk3/caribou-gtk-module.vala @@ -22,31 +22,33 @@ namespace Caribou { keyboard = Bus.get_proxy_sync (BusType.SESSION, "org.gnome.Caribou.Keyboard", "/org/gnome/Caribou/Keyboard"); - add_tracker (); - - // Need to use a timeout because there is currently no other - // way to know whether a new window has been created - // https://bugzilla.gnome.org/show_bug.cgi?id=655828 - GLib.Timeout.add_seconds (10, () => { add_tracker (); - return true; }); + Gdk.window_add_filter (null, event_filter); } catch (Error e) { stderr.printf ("%s\n", e.message); } - } - private void add_tracker () { - GLib.List toplevels; + private Gdk.FilterReturn event_filter (Gdk.XEvent xevent, Gdk.Event evt) { + void* data; + Gtk.Window window; - toplevels = Gtk.Window.list_toplevels (); - foreach (Gtk.Window window in toplevels) { - if (!windows.lookup (window)) { - window.notify["has-toplevel-focus"].connect (toplevel_focus_changed); - window.set_focus.connect (window_focus_changed); - window.destroy.connect (() => { windows.remove (window); }); - windows.insert (window, true); - } + if (evt.any.window == null || + evt.any.window.get_window_type () != Gdk.WindowType.TOPLEVEL) + return Gdk.FilterReturn.CONTINUE; + + Gdk.window_get_user_data (evt.any.window, out data); + if (data == null || !(data is Gtk.Window)) + return Gdk.FilterReturn.CONTINUE; + + window = (Gtk.Window *) data; + if (!windows.lookup (window)) { + windows.insert (window, true); + window.notify["has-toplevel-focus"].connect (toplevel_focus_changed); + window.set_focus.connect (window_focus_changed); + window.destroy.connect (() => { windows.remove (window); }); } + + return Gdk.FilterReturn.CONTINUE; } private void toplevel_focus_changed (Object obj, ParamSpec prop) { diff --git a/modules/gtk3/vapi-fixes.vapi b/modules/gtk3/vapi-fixes.vapi new file mode 100644 index 0000000..42e7feb --- /dev/null +++ b/modules/gtk3/vapi-fixes.vapi @@ -0,0 +1,15 @@ +using Gdk; + +[CCode (cprefix = "Gdk", lower_case_cprefix = "gdk_", cheader_filename = "gdk/gdk.h")] + +namespace Gdk { + // Gdk.Window.add_filter() doesn't let you pass null for window + [CCode (cname = "gdk_window_add_filter")] + public void window_add_filter (Gdk.Window? window, + Gdk.FilterFunc function); + + // Official binding is missing the "out" + [CCode (cname = "gdk_window_get_user_data")] + public void window_get_user_data (Gdk.Window window, + out void* data); +} -- cgit v1.2.1