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
--- 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