bug 1074869 - make atk deal with proxied focus events r=davidb
authorTrevor Saunders <trev.saunders@gmail.com>
Tue, 30 Sep 2014 10:00:26 -0400
changeset 215261 f991f366f66e8d0938e292b1fd57e495d6503f37
parent 215260 4c04203003c22c9b725bb9ecbe2b5731f5fc601f
child 215262 c617a998c23944cc2111a7dbb0e1581cd366b94a
push id51729
push usertrev.saunders@gmail.com
push dateWed, 12 Nov 2014 20:45:14 +0000
treeherdermozilla-inbound@f991f366f66e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdavidb
bugs1074869
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1074869 - make atk deal with proxied focus events r=davidb
accessible/atk/AccessibleWrap.cpp
accessible/base/EventQueue.cpp
accessible/base/EventQueue.h
accessible/base/Platform.h
accessible/ipc/DocAccessibleParent.cpp
accessible/ipc/DocAccessibleParent.h
accessible/ipc/PDocAccessible.ipdl
accessible/mac/Platform.mm
accessible/other/Platform.cpp
accessible/windows/msaa/Platform.cpp
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -1302,16 +1302,26 @@ AccessibleWrap::HandleAccEvent(AccEvent*
         atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, false);
         atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, false);
         break;
     }
 
     return NS_OK;
 }
 
+void
+a11y::ProxyEvent(ProxyAccessible* aTarget, uint32_t aEventType)
+{
+  AtkObject* wrapper = GetWrapperFor(aTarget);
+  if (aEventType == nsIAccessibleEvent::EVENT_FOCUS) {
+    atk_focus_tracker_notify(wrapper);
+    atk_object_notify_state_change(wrapper, ATK_STATE_FOCUSED, true);
+  }
+}
+
 nsresult
 AccessibleWrap::FireAtkStateChangeEvent(AccEvent* aEvent,
                                         AtkObject* aObject)
 {
     AccStateChangeEvent* event = downcast_accEvent(aEvent);
     NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
 
     bool isEnabled = event->IsStateEnabled();
--- a/accessible/base/EventQueue.cpp
+++ b/accessible/base/EventQueue.cpp
@@ -475,16 +475,43 @@ EventQueue::CreateTextChangeEventFor(Acc
   if (text.IsEmpty())
     return;
 
   aEvent->mTextChangeEvent =
     new AccTextChangeEvent(textAccessible, offset, text, aEvent->IsShow(),
                            aEvent->mIsFromUserInput ? eFromUserInput : eNoUserInput);
 }
 
+void
+EventQueue::SendIPCEvent(AccEvent* aEvent) const
+{
+  DocAccessibleChild* ipcDoc = mDocument->IPCDoc();
+  uint64_t id = aEvent->GetAccessible()->IsDoc() ? 0 :
+    reinterpret_cast<uintptr_t>(aEvent->GetAccessible());
+
+  switch(aEvent->GetEventType()) {
+    case nsIAccessibleEvent::EVENT_SHOW:
+      ipcDoc->ShowEvent(downcast_accEvent(aEvent));
+      break;
+
+    case nsIAccessibleEvent::EVENT_HIDE:
+      ipcDoc->SendHideEvent(id);
+      break;
+
+    case nsIAccessibleEvent::EVENT_REORDER:
+      // reorder events on the application acc aren't necessary to tell the parent
+      // about new top level documents.
+      if (!aEvent->GetAccessible()->IsApplication())
+        ipcDoc->SendEvent(id, aEvent->GetEventType());
+      break;
+    default:
+      ipcDoc->SendEvent(id, aEvent->GetEventType());
+  }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // EventQueue: event queue
 
 void
 EventQueue::ProcessEventQueue()
 {
   // Process only currently queued events.
   nsTArray<nsRefPtr<AccEvent> > events;
@@ -552,19 +579,12 @@ EventQueue::ProcessEventQueue()
     }
 
     if (event->mEventType == nsIAccessibleEvent::EVENT_HIDE)
       mDocument->ShutdownChildrenInSubtree(event->mAccessible);
 
     if (!mDocument)
       return;
 
-    if (IPCAccessibilityActive()) {
-    DocAccessibleChild* ipcDoc = mDocument->IPCDoc();
-      if (event->mEventType == nsIAccessibleEvent::EVENT_SHOW)
-        ipcDoc->ShowEvent(downcast_accEvent(event));
-      else if (event->mEventType == nsIAccessibleEvent::EVENT_HIDE)
-        ipcDoc->SendHideEvent(reinterpret_cast<uintptr_t>(event->GetAccessible()));
-      else
-        ipcDoc->SendEvent(event->GetEventType());
-    }
+    if (IPCAccessibilityActive())
+      SendIPCEvent(event);
   }
 }
--- a/accessible/base/EventQueue.h
+++ b/accessible/base/EventQueue.h
@@ -49,16 +49,21 @@ private:
   /**
    * Coalesce two selection change events within the same select control.
    */
   void CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
                                AccSelChangeEvent* aThisEvent,
                                uint32_t aThisIndex);
 
   /**
+   * Notify the parent process of events being fired by this event queue.
+   */
+  void SendIPCEvent(AccEvent* aEvent) const;
+
+  /**
    * Coalesce text change events caused by sibling hide events.
    */
   void CoalesceTextChangeEventsFor(AccHideEvent* aTailEvent,
                                    AccHideEvent* aThisEvent);
   void CoalesceTextChangeEventsFor(AccShowEvent* aTailEvent,
                                    AccShowEvent* aThisEvent);
 
   /**
--- a/accessible/base/Platform.h
+++ b/accessible/base/Platform.h
@@ -1,14 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include <stdint.h>
+
 namespace mozilla {
 namespace a11y {
 
 class ProxyAccessible;
 
 enum EPlatformDisabledState {
   ePlatformIsForceEnabled = -1,
   ePlatformIsEnabled = 0,
@@ -55,11 +57,16 @@ void PlatformShutdown();
  */
 void ProxyCreated(ProxyAccessible*);
 
 /**
  * Called just before a ProxyAccessible is destroyed so its wrapper can be
  * disposed of and other action taken.
  */
 void ProxyDestroyed(ProxyAccessible*);
+
+/**
+ * Callied when an event is fired on a proxied accessible.
+ */
+void ProxyEvent(ProxyAccessible* aTarget, uint32_t aEventType);
 } // namespace a11y
 } // namespace mozilla
 
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -107,10 +107,28 @@ DocAccessibleParent::RecvHideEvent(const
   }
 
   ProxyAccessible* parent = root->Parent();
   parent->RemoveChild(root);
   root->Shutdown();
 
   return true;
 }
+
+bool
+DocAccessibleParent::RecvEvent(const uint64_t& aID, const uint32_t& aEventType)
+{
+  if (!aID) {
+    ProxyEvent(this, aEventType);
+    return true;
+  }
+
+  ProxyEntry* e = mAccessibles.GetEntry(aID);
+  if (!e) {
+    NS_ERROR("no proxy for event!");
+    return true;
+  }
+
+  ProxyEvent(e->mProxy, aEventType);
+  return true;
 }
 }
+}
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -34,20 +34,18 @@ public:
     MOZ_ASSERT(mChildDocs.Length() == 0);
     MOZ_ASSERT(!mParentDoc);
   }
 
   /*
    * Called when a message from a document in a child process notifies the main
    * process it is firing an event.
    */
-  virtual bool RecvEvent(const uint32_t& aType) MOZ_OVERRIDE
-  {
-    return true;
-  }
+  virtual bool RecvEvent(const uint64_t& aID, const uint32_t& aType)
+    MOZ_OVERRIDE;
 
   virtual bool RecvShowEvent(const ShowEventData& aData) MOZ_OVERRIDE;
   virtual bool RecvHideEvent(const uint64_t& aRootID) MOZ_OVERRIDE;
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE
   {
     MOZ_ASSERT(mChildDocs.IsEmpty(),
                "why wheren't the child docs destroyed already?");
--- a/accessible/ipc/PDocAccessible.ipdl
+++ b/accessible/ipc/PDocAccessible.ipdl
@@ -35,17 +35,17 @@ prio(normal upto high) sync protocol PDo
 
 parent:
   __delete__();
 
   /*
    * Notify the parent process the document in the child process is firing an
    * event.
    */
-  Event(uint32_t type);
+  Event(uint64_t aID, uint32_t type);
   ShowEvent(ShowEventData data);
   HideEvent(uint64_t aRootID);
 
 child:
   prio(high) sync State(uint64_t aID) returns(uint64_t states);
   prio(high) sync Name(uint64_t aID) returns(nsString name);
   prio(high) sync Description(uint64_t aID) returns(nsString desc);
   prio(high) sync Attributes(uint64_t aID) returns(Attribute[] attributes);
--- a/accessible/mac/Platform.mm
+++ b/accessible/mac/Platform.mm
@@ -37,16 +37,21 @@ void
 ProxyCreated(ProxyAccessible*)
 {
 }
 
 void
 ProxyDestroyed(ProxyAccessible*)
 {
 }
+
+void
+ProxyEvent(ProxyAccessible*, uint32_t)
+{
+}
 }
 }
 
 @interface GeckoNSApplication(a11y)
 -(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
 @end
 
 @implementation GeckoNSApplication(a11y)
--- a/accessible/other/Platform.cpp
+++ b/accessible/other/Platform.cpp
@@ -23,8 +23,13 @@ void
 a11y::ProxyCreated(ProxyAccessible*)
 {
 }
 
 void
 a11y::ProxyDestroyed(ProxyAccessible*)
 {
 }
+
+void
+a11y::ProxyEvent(ProxyAccessible*, uint32_t)
+{
+}
--- a/accessible/windows/msaa/Platform.cpp
+++ b/accessible/windows/msaa/Platform.cpp
@@ -38,8 +38,13 @@ void
 a11y::ProxyCreated(ProxyAccessible*)
 {
 }
 
 void
 a11y::ProxyDestroyed(ProxyAccessible*)
 {
 }
+
+void
+a11y::ProxyEvent(ProxyAccessible*, uint32_t)
+{
+}