Bug 1137572 part.4 TextEventDispatcher::DispatchInputEvent() should decide if dispatches events with nsIWidget::DispatchInputEvent() with input transaction type r=smaug

This commit is contained in:
Masayuki Nakano 2016-03-16 13:47:48 +09:00
parent e65433cc66
commit e7fa655b11
4 changed files with 70 additions and 81 deletions

View File

@ -197,7 +197,8 @@ TextInputProcessor::BeginInputTransactionInternal(
}
if (aForTests) {
rv = dispatcher->BeginTestInputTransaction(this);
bool isAPZAware = gfxPrefs::TestEventsAsyncEnabled();
rv = dispatcher->BeginTestInputTransaction(this, isAPZAware);
} else {
rv = dispatcher->BeginInputTransaction(this);
}
@ -779,23 +780,6 @@ TextInputProcessor::Keydown(nsIDOMKeyEvent* aDOMKeyEvent,
return KeydownInternal(*originalKeyEvent, aKeyFlags, true, *aConsumedFlags);
}
TextEventDispatcher::DispatchTo
TextInputProcessor::GetDispatchTo() const
{
// Support asynchronous tests.
if (mForTests) {
return gfxPrefs::TestEventsAsyncEnabled() ?
TextEventDispatcher::eDispatchToParentProcess :
TextEventDispatcher::eDispatchToCurrentProcess;
}
// Otherwise, TextInputProcessor supports only keyboard apps on B2G.
// Keyboard apps on B2G doesn't want to dispatch keyboard events to
// chrome process. Therefore, this should dispatch key events only in
// the current process.
return TextEventDispatcher::eDispatchToCurrentProcess;
}
nsresult
TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
uint32_t aKeyFlags,
@ -841,8 +825,7 @@ TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
nsEventStatus status = aConsumedFlags ? nsEventStatus_eConsumeNoDefault :
nsEventStatus_eIgnore;
if (!mDispatcher->DispatchKeyboardEvent(eKeyDown, keyEvent, status,
GetDispatchTo())) {
if (!mDispatcher->DispatchKeyboardEvent(eKeyDown, keyEvent, status)) {
// If keydown event isn't dispatched, we don't need to dispatch keypress
// events.
return NS_OK;
@ -853,8 +836,7 @@ TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
KEYEVENT_NOT_CONSUMED;
if (aAllowToDispatchKeypress &&
mDispatcher->MaybeDispatchKeypressEvents(keyEvent, status,
GetDispatchTo())) {
mDispatcher->MaybeDispatchKeypressEvents(keyEvent, status)) {
aConsumedFlags |=
(status == nsEventStatus_eConsumeNoDefault) ? KEYPRESS_IS_CONSUMED :
KEYEVENT_NOT_CONSUMED;
@ -923,7 +905,7 @@ TextInputProcessor::KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
nsEventStatus status = aDoDefault ? nsEventStatus_eIgnore :
nsEventStatus_eConsumeNoDefault;
mDispatcher->DispatchKeyboardEvent(eKeyUp, keyEvent, status, GetDispatchTo());
mDispatcher->DispatchKeyboardEvent(eKeyUp, keyEvent, status);
aDoDefault = (status != nsEventStatus_eConsumeNoDefault);
return NS_OK;
}

View File

@ -61,7 +61,6 @@ private:
nsresult KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
uint32_t aKeyFlags,
bool& aDoDefault);
TextEventDispatcher::DispatchTo GetDispatchTo() const;
nsresult IsValidStateForComposition();
void UnlinkFromTextEventDispatcher();
nsresult PrepareKeyboardEventToDispatch(WidgetKeyboardEvent& aKeyboardEvent,

View File

@ -44,14 +44,18 @@ nsresult
TextEventDispatcher::BeginInputTransaction(
TextEventDispatcherListener* aListener)
{
return BeginInputTransactionInternal(aListener, eOtherInputTransaction);
return BeginInputTransactionInternal(aListener,
eSameProcessSyncInputTransaction);
}
nsresult
TextEventDispatcher::BeginTestInputTransaction(
TextEventDispatcherListener* aListener)
TextEventDispatcherListener* aListener,
bool aIsAPZAware)
{
return BeginInputTransactionInternal(aListener, eTestInputTransaction);
return BeginInputTransactionInternal(aListener,
aIsAPZAware ? eAsyncTestInputTransaction :
eSameProcessSyncTestInputTransaction);
}
nsresult
@ -150,8 +154,7 @@ TextEventDispatcher::InitEvent(WidgetGUIEvent& aEvent) const
{
aEvent.time = PR_IntervalNow();
aEvent.refPoint = LayoutDeviceIntPoint(0, 0);
aEvent.mFlags.mIsSynthesizedForTests =
mInputTransactionType == eTestInputTransaction;
aEvent.mFlags.mIsSynthesizedForTests = IsForTests();
if (aEvent.mClass != eCompositionEventClass) {
return;
}
@ -188,8 +191,7 @@ TextEventDispatcher::DispatchEvent(nsIWidget* aWidget,
nsresult
TextEventDispatcher::DispatchInputEvent(nsIWidget* aWidget,
WidgetInputEvent& aEvent,
nsEventStatus& aStatus,
DispatchTo aDispatchTo)
nsEventStatus& aStatus)
{
RefPtr<TextEventDispatcher> kungFuDeathGrip(this);
nsCOMPtr<nsIWidget> widget(aWidget);
@ -200,7 +202,7 @@ TextEventDispatcher::DispatchInputEvent(nsIWidget* aWidget,
// first. However, some callers (e.g., keyboard apps on B2G and tests
// expecting synchronous dispatch) don't want this to do that.
nsresult rv = NS_OK;
if (aDispatchTo == eDispatchToParentProcess) {
if (ShouldSendInputEventToAPZ()) {
aStatus = widget->DispatchInputEvent(&aEvent);
} else {
rv = widget->DispatchEvent(&aEvent, aStatus);
@ -370,11 +372,9 @@ bool
TextEventDispatcher::DispatchKeyboardEvent(
EventMessage aMessage,
const WidgetKeyboardEvent& aKeyboardEvent,
nsEventStatus& aStatus,
DispatchTo aDispatchTo)
nsEventStatus& aStatus)
{
return DispatchKeyboardEventInternal(aMessage, aKeyboardEvent, aStatus,
aDispatchTo);
return DispatchKeyboardEventInternal(aMessage, aKeyboardEvent, aStatus);
}
bool
@ -382,7 +382,6 @@ TextEventDispatcher::DispatchKeyboardEventInternal(
EventMessage aMessage,
const WidgetKeyboardEvent& aKeyboardEvent,
nsEventStatus& aStatus,
DispatchTo aDispatchTo,
uint32_t aIndexOfKeypress)
{
MOZ_ASSERT(aMessage == eKeyDown || aMessage == eKeyUp ||
@ -461,15 +460,14 @@ TextEventDispatcher::DispatchKeyboardEventInternal(
keyEvent.mPluginEvent.Clear();
// TODO: Manage mUniqueId here.
DispatchInputEvent(mWidget, keyEvent, aStatus, aDispatchTo);
DispatchInputEvent(mWidget, keyEvent, aStatus);
return true;
}
bool
TextEventDispatcher::MaybeDispatchKeypressEvents(
const WidgetKeyboardEvent& aKeyboardEvent,
nsEventStatus& aStatus,
DispatchTo aDispatchTo)
nsEventStatus& aStatus)
{
// If the key event was consumed, keypress event shouldn't be fired.
if (aStatus == nsEventStatus_eConsumeNoDefault) {
@ -489,7 +487,7 @@ TextEventDispatcher::MaybeDispatchKeypressEvents(
for (size_t i = 0; i < keypressCount; i++) {
aStatus = nsEventStatus_eIgnore;
if (!DispatchKeyboardEventInternal(eKeyPress, aKeyboardEvent,
aStatus, aDispatchTo, i)) {
aStatus, i)) {
// The widget must have been gone.
break;
}

View File

@ -56,7 +56,8 @@ public:
* definition below.
*/
nsresult BeginInputTransaction(TextEventDispatcherListener* aListener);
nsresult BeginTestInputTransaction(TextEventDispatcherListener* aListener);
nsresult BeginTestInputTransaction(TextEventDispatcherListener* aListener,
bool aIsAPZAware);
nsresult BeginNativeInputTransaction();
/**
@ -196,26 +197,6 @@ public:
*/
nsresult NotifyIME(const IMENotification& aIMENotification);
/**
* DispatchTo indicates whether the event may be dispatched to its parent
* process first (if there is) or not. If the event is dispatched to the
* parent process, APZ will handle it first. Otherwise, the event won't be
* handled by APZ if it's in a child process.
*/
enum DispatchTo
{
// The event may be dispatched to its parent process if there is a parent.
// In such case, the event will be handled asynchronously. Additionally,
// the event may be sent to its child process if a child process (including
// the dispatching process) has focus.
eDispatchToParentProcess = 0,
// The event must be dispatched in the current process. But of course,
// the event may be sent to a child process when it has focus. If there is
// no child process, the event may be handled synchronously.
eDispatchToCurrentProcess = 1
};
/**
* DispatchKeyboardEvent() maybe dispatches aKeyboardEvent.
*
@ -228,13 +209,11 @@ public:
* set nsEventStatus_eIgnore. After dispatching
* a event and it's consumed this returns
* nsEventStatus_eConsumeNoDefault.
* @param aDispatchTo See comments of DispatchTo.
* @return true if an event is dispatched. Otherwise, false.
*/
bool DispatchKeyboardEvent(EventMessage aMessage,
const WidgetKeyboardEvent& aKeyboardEvent,
nsEventStatus& aStatus,
DispatchTo aDispatchTo = eDispatchToParentProcess);
nsEventStatus& aStatus);
/**
* MaybeDispatchKeypressEvents() maybe dispatches a keypress event which is
@ -248,14 +227,11 @@ public:
* When this method dispatches one or more keypress
* events and one of them is consumed, this returns
* nsEventStatus_eConsumeNoDefault.
* @param aDispatchTo See comments of DispatchTo.
* @return true if one or more events are dispatched.
* Otherwise, false.
*/
bool MaybeDispatchKeypressEvents(const WidgetKeyboardEvent& aKeyboardEvent,
nsEventStatus& aStatus,
DispatchTo aDispatchTo =
eDispatchToParentProcess);
nsEventStatus& aStatus);
private:
// mWidget is owner of the instance. When this is created, this is set.
@ -300,16 +276,56 @@ private:
{
// No input transaction has been started.
eNoInputTransaction,
// Input transaction for native IME or keyboard event handler.
// Input transaction for native IME or keyboard event handler. Note that
// keyboard events may be dispatched via parent process if there is.
eNativeInputTransaction,
// Input transaction for automated tests.
eTestInputTransaction,
// Input transaction for Others (must be IME on B2G).
eOtherInputTransaction
// Input transaction for automated tests which are APZ-aware. Note that
// keyboard events may be dispatched via parent process if there is.
eAsyncTestInputTransaction,
// Input transaction for automated tests which assume events are fired
// synchronously. I.e., keyboard events are always dispatched in the
// current process.
eSameProcessSyncTestInputTransaction,
// Input transaction for Others (must be IME on B2G). Events are fired
// synchronously because TextInputProcessor which is the only user of
// this input transaction type supports only keyboard apps on B2G.
// Keyboard apps on B2G doesn't want to dispatch keyboard events to
// chrome process. Therefore, this should dispatch key events only in
// the current process.
eSameProcessSyncInputTransaction
};
InputTransactionType mInputTransactionType;
bool IsForTests() const
{
return mInputTransactionType == eAsyncTestInputTransaction ||
mInputTransactionType == eSameProcessSyncTestInputTransaction;
}
// ShouldSendInputEventToAPZ() returns true when WidgetInputEvent should
// be dispatched via its parent process (if there is) for APZ. Otherwise,
// when the input transaction is for IME of B2G or automated tests which
// isn't APZ-aware, WidgetInputEvent should be dispatched form current
// process directly.
bool ShouldSendInputEventToAPZ() const
{
switch (mInputTransactionType) {
case eNativeInputTransaction:
case eAsyncTestInputTransaction:
return true;
case eSameProcessSyncTestInputTransaction:
case eSameProcessSyncInputTransaction:
return false;
case eNoInputTransaction:
NS_WARNING("Why does the caller need to dispatch an event when "
"there is no input transaction?");
return true;
default:
MOZ_CRASH("Define the behavior of new InputTransactionType");
}
}
// See IsComposing().
bool mIsComposing;
@ -337,13 +353,10 @@ private:
/**
* DispatchInputEvent() dispatches aEvent on aWidget.
*
* @param aDispatchTo See comments of DispatchTo.
*/
nsresult DispatchInputEvent(nsIWidget* aWidget,
WidgetInputEvent& aEvent,
nsEventStatus& aStatus,
DispatchTo aDispatchTo);
nsEventStatus& aStatus);
/**
* StartCompositionAutomaticallyIfNecessary() starts composition if it hasn't
@ -373,7 +386,6 @@ private:
* set nsEventStatus_eIgnore. After dispatching
* a event and it's consumed this returns
* nsEventStatus_eConsumeNoDefault.
* @param aDispatchTo See comments of DispatchTo.
* @param aIndexOfKeypress This must be 0 if aMessage isn't eKeyPress or
* aKeyboard.mKeyNameIndex isn't
* KEY_NAME_INDEX_USE_STRING. Otherwise, i.e.,
@ -386,8 +398,6 @@ private:
bool DispatchKeyboardEventInternal(EventMessage aMessage,
const WidgetKeyboardEvent& aKeyboardEvent,
nsEventStatus& aStatus,
DispatchTo aDispatchTo =
eDispatchToParentProcess,
uint32_t aIndexOfKeypress = 0);
};