Bug 1370496 - Hide on screen keyboard when input lose focus r?:surkov draft
authorJan Horak <jhorak@redhat.com>
Thu, 05 Oct 2017 12:20:26 +0200
changeset 675504 9895e681ddeae4e89d194bd335a707259c724b49
parent 660738 37b95547f0d27565452136d16b2df2857be840f6
child 734612 b0ba3dad591e6107edcae2f70a33461e29da1adc
push id83140
push userbmo:jhorak@redhat.com
push dateThu, 05 Oct 2017 10:20:47 +0000
bugs1370496
milestone57.0a1
Bug 1370496 - Hide on screen keyboard when input lose focus r?:surkov The focus event now is sending atk_object_notify_state_change to the previously focused atkobject when focus is changed. This leads to hiding on screen keyboard when newly focused element does not support input. MozReview-Commit-ID: 2bGVxXBQX5t
accessible/atk/AccessibleWrap.cpp
accessible/base/AccEvent.h
accessible/base/FocusManager.cpp
accessible/base/FocusManager.h
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -1238,16 +1238,24 @@ AccessibleWrap::HandleAccEvent(AccEvent*
                                                      event->IsTextInserted(),
                                                      event->IsFromUserInput());
 
         return NS_OK;
       }
 
     case nsIAccessibleEvent::EVENT_FOCUS:
       {
+        AccFocusEvent* event = downcast_accEvent(aEvent);
+        if (event->GetLastFocusedAccessible()) {
+            AtkObject* oldAtkObj = AccessibleWrap::GetAtkObject(event->GetLastFocusedAccessible());
+            if (oldAtkObj) {
+                atk_object_notify_state_change(oldAtkObj, ATK_STATE_FOCUSED, false);
+            }
+        }
+
         a11y::RootAccessible* rootAccWrap = accWrap->RootAccessible();
         if (rootAccWrap && rootAccWrap->mActivated) {
             atk_focus_tracker_notify(atkObj);
             // Fire state change event for focus
             atk_object_notify_state_change(atkObj, ATK_STATE_FOCUSED, true);
             return NS_OK;
         }
       } break;
--- a/accessible/base/AccEvent.h
+++ b/accessible/base/AccEvent.h
@@ -165,16 +165,34 @@ public:
 
 private:
   uint64_t mState;
   bool mIsEnabled;
 
   friend class EventQueue;
 };
 
+class AccFocusEvent: public AccEvent
+{
+public:
+  AccFocusEvent(Accessible* aAccessible,
+                EIsFromUserInput aIsFromUserInput,
+                Accessible* aPrevAccessible) :
+    AccEvent(nsIAccessibleEvent::EVENT_FOCUS, aAccessible,
+             aIsFromUserInput, eCoalesceOfSameType),
+              mLastFocusedAccessible(aPrevAccessible)  { }
+  Accessible* GetLastFocusedAccessible() {
+    return mLastFocusedAccessible;
+  }
+private:
+  RefPtr<Accessible> mLastFocusedAccessible;
+
+  friend class EventQueue;
+};
+
 
 /**
  * Accessible text change event.
  */
 class AccTextChangeEvent: public AccEvent
 {
 public:
   AccTextChangeEvent(Accessible* aAccessible, int32_t aStart,
--- a/accessible/base/FocusManager.cpp
+++ b/accessible/base/FocusManager.cpp
@@ -17,16 +17,17 @@
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/TabParent.h"
 
 namespace mozilla {
 namespace a11y {
 
 FocusManager::FocusManager()
 {
+  mLastFocusedItem = nullptr;
 }
 
 FocusManager::~FocusManager()
 {
 }
 
 Accessible*
 FocusManager::FocusedAccessible() const
@@ -369,18 +370,20 @@ FocusManager::ProcessFocusEvent(AccEvent
 #endif
 
   // Reset cached caret value. The cache will be updated upon processing the
   // next caret move event. This ensures that we will return the correct caret
   // offset before the caret move event is handled.
   SelectionMgr()->ResetCaretOffset();
 
   RefPtr<AccEvent> focusEvent =
-    new AccEvent(nsIAccessibleEvent::EVENT_FOCUS, target, aEvent->FromUserInput());
+    new AccFocusEvent(target, aEvent->FromUserInput(), mLastFocusedItem);
   nsEventShell::FireEvent(focusEvent);
+  // Store last focused item for later bluring
+  mLastFocusedItem = target;
 
   // Fire scrolling_start event when the document receives the focus if it has
   // an anchor jump. If an accessible within the document receive the focus
   // then null out the anchor jump because it no longer applies.
   DocAccessible* targetDocument = target->Document();
   Accessible* anchorJump = targetDocument->AnchorJump();
   if (anchorJump) {
     if (target == targetDocument) {
--- a/accessible/base/FocusManager.h
+++ b/accessible/base/FocusManager.h
@@ -119,14 +119,15 @@ private:
   /**
    * Return DOM document having DOM focus.
    */
   nsIDocument* FocusedDOMDocument() const;
 
 private:
   RefPtr<Accessible> mActiveItem;
   RefPtr<Accessible> mActiveARIAMenubar;
+  RefPtr<Accessible> mLastFocusedItem;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif