Updated NEWS; fixed bug causing multiple event emission if
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Sun, 24 Nov 2002 14:49:51 +0000 (14:49 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Sun, 24 Nov 2002 14:49:51 +0000 (14:49 +0000)
registry dies and is restarted; workaround for GOK bug 98420.

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

ChangeLog
NEWS
atk-bridge/bridge.c
registryd/deviceeventcontroller.c

index 860fcbc..d792845 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2002-11-24  Bill Haneman  <bill.haneman@sun.com>
+
+        * NEWS: 
+       Updated NEWS (accidentally didn't make it into 1.1.5 tarball,
+       retagged).
+       
+       * atk-bridge/bridge.c:
+       (spi_atk_register_event_listeners):
+       Don't re-register for ATK events if the registry has died
+       and the app needs to re-register; the ATK listeners are in
+       process and doing so will cause duplicate emission.
+
+       * registryd/deviceeventcontroller.c:
+       (spi_poll_mouse_moved):
+       Reformat the source, detect and emit multiple button-change
+       events (i.e. if multiple buttons have changed between poll
+       intervals).
+       Add code to detect mouse-down events even when the pointer
+       is grabbed; workaround for GOK bug 98420.
+       (spi_controller_register_with_devices):
+       Call XTestGrabControl with 'impervious' flag set to True,
+       allows us to synthesize events and query the pointer even during
+       an active grab by another client.
+       (spi_device_event_controller_forward_mouse_event):
+       Set the mouse_mask_state to the mouse_button_state from
+       the intercepted event, to synchronize the grab listener with
+       the poll state.
+       
 2002-11-20  Bill Haneman  <bill.haneman@sun.com>
 
        * cspi/spi_accessible.c:
diff --git a/NEWS b/NEWS
index d06a90c..324472a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,43 @@
 (top)
 in HEAD:
 
-* bugfixes for: 84856
+What's new in at-spi-1.1.5:
+
+* event struct in libspi is bigger, increased unimplemented
+  slot count for sufficient future bincompatible expansion. 
+ (WARNING: breaks bincompat for direct CORBA clients. CSPI clients
+  not affected.)
+
+* New accessor methods allow state-coherent query of many
+  event types.
+
+* API Frozen for GNOME 2.2.
+
+* New role types: APPLICATION, HEADER, FOOTER, PARAGRAPH, RULER.
+
+* New relations, FLOWS_FROM, FLOWS_TO, EMBEDS, EMBEDDED_BY,
+       SUBWINDOW_OF.
+
+* New state, MANAGES_DESCENDANTS.  New event, "active-descendant-changed".
+
+* reduced debug output, unless you set AT_SPI_DEBUG environment
+  variable to string which parses to an integer value > 0.
+
+* added definitions for SPI_KEYMASK_BUTTON1, etc.
+
+* added SPI_LAYER_WINDOW.
+
+* Added ability to register 'device event listeners' which can
+  consume device events, such as mouse events.
+
+* Added support for mouse and key-modifier event notification.
+
+* deprecated KeyEventType in favor of EventType.
+
+* bugfixes for >50 bugs including: 98836, 98842, 97916, 95828, 
+       93592, 95940, 95517, 93658, 95055, 94555, 84856.
+
+* updated copyrights to include Ximian.
 
 What's new in at-spi-1.1.0:
 
index e1befea..86bbaa5 100644 (file)
@@ -46,6 +46,7 @@ static CORBA_Environment ev;
 static Accessibility_Registry registry = NULL;
 static SpiApplication *this_app = NULL;
 static gboolean registry_died = FALSE;
+static gboolean atk_listeners_registered = FALSE;
 static guint toplevel_handler;
 
 /* NOT YET USED
@@ -274,7 +275,12 @@ spi_atk_register_event_listeners (void)
   guint      id;
   GObject   *ao = g_object_new (ATK_TYPE_OBJECT, NULL);
   AtkObject *bo = atk_no_op_object_new (ao);
-  
+
+
+  if (atk_listeners_registered) return;
+
+  atk_listeners_registered = TRUE;
+
   /* Register for focus event notifications, and register app with central registry  */
 
   listener_ids = g_array_sized_new (FALSE, TRUE, sizeof (guint), 16);
index 8fe64e4..df24cde 100644 (file)
@@ -1,5 +1,5 @@
-/*
- * AT-SPI - Assistive Technology Service Provider Interface
+/* AT-SPI - Assistive Technology Service Provider Interface
+ *
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
  * Copyright 2001, 2002 Sun Microsystems Inc.,
@@ -199,106 +199,170 @@ spi_dec_poll_mouse_moved (gpointer data)
   Display *display = spi_get_display ();
 
   if (display != NULL)
-         XQueryPointer(display, DefaultRootWindow (display),
-               &root_return, &child_return,
-               &x, &y,
-               &win_x_return, &win_y_return, &mask_return);
-
-  if (mask_return != mouse_mask_state) {
-         if ((mask_return & mouse_button_mask) !=
-             (mouse_mask_state & mouse_button_mask)) {
-                 int button_number = 0;
-                 if (!(mask_return & Button1Mask) &&
-                     (mouse_mask_state & Button1Mask)) {
-                         button_number = 1;
-                 } else if (!(mask_return & Button2Mask) &&
-                            (mouse_mask_state & Button2Mask)) {
-                         button_number = 2;
-                 } else if (!(mask_return & Button3Mask) &&
-                            (mouse_mask_state & Button3Mask)) {
-                         button_number = 3;
-                 } else if (!(mask_return & Button4Mask) &&
-                            (mouse_mask_state & Button1Mask)) {
-                         button_number = 4;
-                 } else if (!(mask_return & Button5Mask) &&
-                            (mouse_mask_state & Button5Mask)) {
-                         button_number = 5;
-                 }
-                 if (button_number) {
+    XQueryPointer(display, DefaultRootWindow (display),
+                 &root_return, &child_return,
+                 &x, &y,
+                 &win_x_return, &win_y_return, &mask_return);
+  
+  /* 
+   * Since many clients grab the pointer, and X goes an automatic
+   * pointer grab on mouse-down, we often must detect mouse button events
+   * by polling rather than via a button grab. 
+   * The while loop (rather than if) is used since it's possible that 
+   * multiple buttons have changed state since we last checked.
+   */
+  if (mask_return != mouse_mask_state) 
+    {
+      while ((mask_return & mouse_button_mask) !=
+            (mouse_mask_state & mouse_button_mask)) 
+       {
+         int button_number = 0;
+         gboolean is_down = False;
+
+         if (!(mask_return & Button1Mask) &&
+             (mouse_mask_state & Button1Mask)) 
+           {
+             mouse_mask_state &= ~Button1Mask;
+             button_number = 1;
+           } 
+         else if ((mask_return & Button1Mask) &&
+             !(mouse_mask_state & Button1Mask)) 
+           {
+             mouse_mask_state |= Button1Mask;
+             button_number = 1;
+             is_down = True;
+           } 
+         else if (!(mask_return & Button2Mask) &&
+                      (mouse_mask_state & Button2Mask)) 
+           {
+             mouse_mask_state &= ~Button2Mask;
+             button_number = 2;
+           } 
+         else if ((mask_return & Button2Mask) &&
+                      !(mouse_mask_state & Button2Mask)) 
+           {
+             mouse_mask_state |= Button2Mask;
+             button_number = 2;
+             is_down = True;
+           } 
+         else if (!(mask_return & Button3Mask) &&
+                  (mouse_mask_state & Button3Mask)) 
+           {
+             mouse_mask_state &= ~Button3Mask;
+             button_number = 3;
+           } 
+         else if ((mask_return & Button3Mask) &&
+                  !(mouse_mask_state & Button3Mask)) 
+           {
+             mouse_mask_state |= Button3Mask;
+             button_number = 3;
+             is_down = True;
+           } 
+         else if (!(mask_return & Button4Mask) &&
+                  (mouse_mask_state & Button1Mask)) 
+           {
+             mouse_mask_state &= ~Button4Mask;
+             button_number = 4;
+           } 
+         else if ((mask_return & Button4Mask) &&
+                  !(mouse_mask_state & Button1Mask)) 
+           {
+             mouse_mask_state |= Button4Mask;
+             button_number = 4;
+             is_down = True;
+           } 
+         else if (!(mask_return & Button5Mask) &&
+                  (mouse_mask_state & Button5Mask)) 
+           {
+             mouse_mask_state &= ~Button5Mask;
+             button_number = 5;
+           }
+         else if ((mask_return & Button5Mask) &&
+                  !(mouse_mask_state & Button5Mask)) 
+           {
+             mouse_mask_state |= Button5Mask;
+             button_number = 5;
+             is_down = True;
+           }
+         if (button_number) {
 #ifdef SPI_DEBUG                 
-                         fprintf (stderr, "Button %d Released\n",
-                                  button_number);
+           fprintf (stderr, "Button %d %s\n",
+                    button_number, (is_down) ? "Pressed" : "Released");
 #endif
-                         snprintf (event_name, 22, "mouse:button:%dr", button_number);
-                         /* TODO: distinguish between physical and 
-                          * logical buttons 
-                          */
-                         mouse_e.type      = Accessibility_BUTTON_RELEASED_EVENT;
-                         mouse_e.id        = button_number;
-                         mouse_e.hw_code   = button_number;
-                          mouse_e.modifiers = (CORBA_unsigned_short) 
-                                              mouse_mask_state; 
-                         mouse_e.timestamp = 0;
-                         mouse_e.event_string = "";
-                         mouse_e.is_text   = CORBA_FALSE;
-                         is_consumed = 
-                           spi_controller_notify_mouselisteners (controller, 
-                                                                 &mouse_e, 
-                                                                 &ev);
-                         e.type = event_name;
-                         e.source = BONOBO_OBJREF (registry->desktop);
-                         e.detail1 = last_mouse_pos->x;
-                         e.detail2 = last_mouse_pos->y;
-                         spi_init_any_nil (&e.any_data);
-                         CORBA_exception_init (&ev);
-                         if (!is_consumed)
-                           Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
-                                                               &e,
-                                                               &ev);  
-                 }
+           snprintf (event_name, 22, "mouse:button:%d%c", button_number,
+                     (is_down) ? 'p' : 'r');
+           /* TODO: distinguish between physical and 
+            * logical buttons 
+            */
+           mouse_e.type      = (is_down) ? 
+             Accessibility_BUTTON_PRESSED_EVENT :
+             Accessibility_BUTTON_RELEASED_EVENT;
+           mouse_e.id        = button_number;
+           mouse_e.hw_code   = button_number;
+           mouse_e.modifiers = (CORBA_unsigned_short) mouse_mask_state; 
+           mouse_e.timestamp = 0;
+           mouse_e.event_string = "";
+           mouse_e.is_text   = CORBA_FALSE;
+           is_consumed = 
+             spi_controller_notify_mouselisteners (controller, 
+                                                   &mouse_e, 
+                                                   &ev);
+           e.type = event_name;
+           e.source = BONOBO_OBJREF (registry->desktop);
+           e.detail1 = last_mouse_pos->x;
+           e.detail2 = last_mouse_pos->y;
+           spi_init_any_nil (&e.any_data);
+           CORBA_exception_init (&ev);
+           if (!is_consumed)
+             Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
+                                                 &e,
+                                                 &ev);  
          }
-         if ((mask_return & key_modifier_mask) !=
-             (mouse_mask_state & key_modifier_mask)) {
+       }
+      
+      if ((mask_return & key_modifier_mask) !=
+      (mouse_mask_state & key_modifier_mask)) {
 #ifdef SPI_DEBUG
-                 fprintf (stderr, "MODIFIER CHANGE EVENT!\n");
+       fprintf (stderr, "MODIFIER CHANGE EVENT!\n");
 #endif
-                 e.type = "keyboard:modifiers";  
-                 e.source = BONOBO_OBJREF (registry->desktop);
-                 e.detail1 = mouse_mask_state;
-                 e.detail2 = mask_return;
-                 spi_init_any_nil (&e.any_data);
-                 CORBA_exception_init (&ev);
-                 Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
-                                                     &e,
-                                                     &ev);
-         }
-         mouse_mask_state = mask_return;
-  }
+       e.type = "keyboard:modifiers";  
+       e.source = BONOBO_OBJREF (registry->desktop);
+       e.detail1 = mouse_mask_state;
+       e.detail2 = mask_return;
+       spi_init_any_nil (&e.any_data);
+       CORBA_exception_init (&ev);
+       Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
+                                           &e,
+                                           &ev);
+      }
+      mouse_mask_state = mask_return;
+    }  
+  
   if (poll_count++ == poll_count_modulus) {
-         poll_count = 0;
-         e.type = "mouse:abs";  
-         e.source = BONOBO_OBJREF (registry->desktop);
-         e.detail1 = x;
-         e.detail2 = y;
-         spi_init_any_nil (&e.any_data);
-         CORBA_exception_init (&ev);
-         Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
-                                             &e,
-                                             &ev);
+    poll_count = 0;
+    e.type = "mouse:abs";  
+    e.source = BONOBO_OBJREF (registry->desktop);
+    e.detail1 = x;
+    e.detail2 = y;
+    spi_init_any_nil (&e.any_data);
+    CORBA_exception_init (&ev);
+    Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
+                                       &e,
+                                       &ev);
   }
   if (x != last_mouse_pos->x || y != last_mouse_pos->y) {
-         e.type = "mouse:rel";  
-         e.source = BONOBO_OBJREF (registry->desktop);
-         e.detail1 = x - last_mouse_pos->x;
-         e.detail2 = y - last_mouse_pos->y;
-         spi_init_any_nil (&e.any_data);
-         CORBA_exception_init (&ev);
-         last_mouse_pos->x = x;
-         last_mouse_pos->y = y;
-         Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
-                                             &e,
-                                             &ev);
-         return TRUE;
+    e.type = "mouse:rel";  
+    e.source = BONOBO_OBJREF (registry->desktop);
+    e.detail1 = x - last_mouse_pos->x;
+    e.detail2 = y - last_mouse_pos->y;
+    spi_init_any_nil (&e.any_data);
+    CORBA_exception_init (&ev);
+    last_mouse_pos->x = x;
+    last_mouse_pos->y = y;
+    Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
+                                       &e,
+                                       &ev);
+    return TRUE;
   }
   return FALSE;
 }
@@ -691,7 +755,7 @@ spi_device_event_controller_forward_mouse_event (SpiDEController *controller,
   int button = xbutton_event->button;
   
   unsigned int mouse_button_state = xbutton_event->state;
-
+  
   switch (button)
     {
     case 1:
@@ -732,22 +796,26 @@ spi_device_event_controller_forward_mouse_event (SpiDEController *controller,
   mouse_e.timestamp = (CORBA_unsigned_long) xbutton_event->time;
   mouse_e.event_string = "";
   mouse_e.is_text   = CORBA_FALSE;
-  is_consumed = spi_controller_notify_mouselisteners (controller, &mouse_e, &ev);
-
-  e.type = CORBA_string_dup (event_name);
-  e.source = BONOBO_OBJREF (controller->registry->desktop);
-  e.detail1 = last_mouse_pos->x;
-  e.detail2 = last_mouse_pos->y;
-  spi_init_any_nil (&e.any_data);
-  CORBA_exception_init (&ev);
-  
-  Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry),
-                                     &e,
-                                     &ev);
-
+  if ((mouse_button_state & mouse_button_mask) != 
+      (mouse_mask_state & mouse_button_mask)) 
+    { 
+      mouse_mask_state = mouse_button_state;
+      is_consumed = 
+       spi_controller_notify_mouselisteners (controller, &mouse_e, &ev);
+      e.type = CORBA_string_dup (event_name);
+      e.source = BONOBO_OBJREF (controller->registry->desktop);
+      e.detail1 = last_mouse_pos->x;
+      e.detail2 = last_mouse_pos->y;
+      spi_init_any_nil (&e.any_data);
+      CORBA_exception_init (&ev);
+      
+      Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry),
+                                         &e,
+                                         &ev);
+    }
   xkb_mod_unlatch_occurred = (xevent->type == ButtonPress ||
                              xevent->type == ButtonRelease);
-  
+      
   /* if client wants to consume this event, and XKB latch state was
    *   unset by this button event, we reset it
    */
@@ -856,7 +924,8 @@ spi_controller_register_with_devices (SpiDEController *controller)
 {
   DEControllerPrivateData *priv = (DEControllerPrivateData *) 
          g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);     
-
+  /* FIXME: should check for extension first! */
+  XTestGrabControl (spi_get_display (), True);
   priv->xkb_desc = XkbGetMap (spi_get_display (), 0, XkbUseCoreKbd);
 
   /* calls to device-specific implementations and routines go here */