2003-12-03 Padraig O'Briain <padraig.obriain@sun.com>
authorpadraigo <padraigo@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Wed, 3 Dec 2003 15:00:33 +0000 (15:00 +0000)
committerpadraigo <padraigo@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Wed, 3 Dec 2003 15:00:33 +0000 (15:00 +0000)
*registryd/deviceeventcontroller.c: Add an idle handler which polls
the keyboard on a timeout intil the key state goes from pressed to
released. Fixes bug #111429.

git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@567 e2bd861d-eb25-0410-b326-f6ed22b6b98c

ChangeLog
registryd/deviceeventcontroller.c

index 715cc25..2703274 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,12 @@
 2003-12-03  Padraig O'Briain <padraig.obriain@sun.com>
 
-       * atk-bridge.c: (atk_bridge_init): Create accessible application 
+       *registryd/deviceeventcontroller.c: Add an idle handler which polls
+       the keyboard on a timeout intil the key state goes from pressed to
+       released. Fixes bug #111429.
+
+2003-12-03  Padraig O'Briain <padraig.obriain@sun.com>
+
+       * atk-bridge/bridge.c: (atk_bridge_init): Create accessible application 
        root object so that it is present when a context menu in an 
        out-of-process applet is popped up.
        (spi_atk_bridge_do_registration): Create acceessible application root
index 07fd059..dc080f7 100644 (file)
 #include "../libspi/spi-private.h"
 #include "deviceeventcontroller.h"
 
+#define CHECK_RELEASE_DELAY 20
+#define BIT(c, x)       (c[x/8]&(1<<(x%8)))
+static guint check_release_handler = 0;
+static Accessibility_DeviceEvent pressed_event;
+static SpiDEController *saved_controller; 
+static void wait_for_release_event (GdkEvent *event, SpiDEController *controller);
+
 /* Our parent Gtk object type */
 #define PARENT_TYPE BONOBO_TYPE_OBJECT
 
@@ -1011,7 +1018,10 @@ global_filter_fn (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
           if (is_consumed)
             XAllowEvents (spi_get_display (), AsyncKeyboard, CurrentTime);
           else
-            XAllowEvents (spi_get_display (), ReplayKeyboard, CurrentTime);
+            {
+              wait_for_release_event (event, controller);
+              XAllowEvents (spi_get_display (), ReplayKeyboard, CurrentTime);
+            }
         }
 
       return GDK_FILTER_CONTINUE;
@@ -2381,6 +2391,46 @@ spi_device_event_controller_new (SpiRegistry *registry)
   return retval;
 }
 
+static gboolean
+is_key_released (KeyCode code)
+{
+  char keys[32];
+  int down;
+  int i;
+
+  XQueryKeymap (spi_get_display (), keys);
+  down = BIT (keys, code);
+  return (down == 0);
+}
+
+static gboolean
+check_release (gpointer data)
+{
+  gboolean released;
+  Accessibility_DeviceEvent *event = (Accessibility_DeviceEvent *)data;
+  KeyCode code = event->hw_code;
+  CORBA_Environment ev;
+
+  released = is_key_released (code);
+
+  if (released)
+    {
+      check_release_handler = 0;
+      event->type = Accessibility_KEY_RELEASED_EVENT;
+      ev._major = CORBA_NO_EXCEPTION;
+      spi_controller_notify_keylisteners (saved_controller, event, CORBA_TRUE, &ev);
+    }
+  return (released == 0);
+}
+
+static void wait_for_release_event (GdkEvent        *event,
+                                    SpiDEController *controller)
+{
+  pressed_event = spi_keystroke_from_x_key_event ((XKeyEvent *) event);
+  saved_controller = controller;
+  check_release_handler = g_timeout_add (CHECK_RELEASE_DELAY, check_release, &pressed_event);
+}
+
 BONOBO_TYPE_FUNC_FULL (SpiDEController,
                       Accessibility_DeviceEventController,
                       PARENT_TYPE,