[caribou: 16/23] Use an event filter to find new windows rather than a timeout



commit e0a8ba4340b199cfe90534d977d4890bf02a4091
Author: Dan Winship <danw gnome org>
Date:   Fri Aug 5 12:45:47 2011 -0400

    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(-)
---
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<weak Gtk.Window> 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);
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]