mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1137557 - Part 0: TextEventDispatcher shouldn't forward keyboard events coming from TextInputProcessor to the parent process. r=smaug
This commit is contained in:
parent
b775b4ff60
commit
e2804df573
@ -4,6 +4,7 @@
|
||||
* 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 "gfxPrefs.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/TextEventDispatcher.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
@ -772,6 +773,23 @@ TextInputProcessor::Keydown(nsIDOMKeyEvent* aDOMKeyEvent,
|
||||
return KeydownInternal(*originalKeyEvent, aKeyFlags, true, *aDoDefault);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -816,14 +834,15 @@ TextInputProcessor::KeydownInternal(const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
|
||||
nsEventStatus status = aDoDefault ? nsEventStatus_eIgnore :
|
||||
nsEventStatus_eConsumeNoDefault;
|
||||
if (!mDispatcher->DispatchKeyboardEvent(NS_KEY_DOWN, keyEvent, status)) {
|
||||
if (!mDispatcher->DispatchKeyboardEvent(NS_KEY_DOWN, keyEvent, status,
|
||||
GetDispatchTo())) {
|
||||
// If keydown event isn't dispatched, we don't need to dispatch keypress
|
||||
// events.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aAllowToDispatchKeypress) {
|
||||
mDispatcher->MaybeDispatchKeypressEvents(keyEvent, status);
|
||||
mDispatcher->MaybeDispatchKeypressEvents(keyEvent, status, GetDispatchTo());
|
||||
}
|
||||
|
||||
aDoDefault = (status != nsEventStatus_eConsumeNoDefault);
|
||||
@ -890,7 +909,8 @@ TextInputProcessor::KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
|
||||
nsEventStatus status = aDoDefault ? nsEventStatus_eIgnore :
|
||||
nsEventStatus_eConsumeNoDefault;
|
||||
mDispatcher->DispatchKeyboardEvent(NS_KEY_UP, keyEvent, status);
|
||||
mDispatcher->DispatchKeyboardEvent(NS_KEY_UP, keyEvent, status,
|
||||
GetDispatchTo());
|
||||
aDoDefault = (status != nsEventStatus_eConsumeNoDefault);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/TextEventDispatcher.h"
|
||||
#include "mozilla/TextEventDispatcherListener.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsITextInputProcessor.h"
|
||||
@ -17,10 +18,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace widget{
|
||||
class TextEventDispatcher;
|
||||
} // namespace widget
|
||||
|
||||
class TextInputProcessor final : public nsITextInputProcessor
|
||||
, public widget::TextEventDispatcherListener
|
||||
{
|
||||
@ -64,6 +61,7 @@ private:
|
||||
nsresult KeyupInternal(const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
uint32_t aKeyFlags,
|
||||
bool& aDoDefault);
|
||||
TextEventDispatcher::DispatchTo GetDispatchTo() const;
|
||||
nsresult IsValidStateForComposition();
|
||||
void UnlinkFromTextEventDispatcher();
|
||||
nsresult PrepareKeyboardEventToDispatch(WidgetKeyboardEvent& aKeyboardEvent,
|
||||
|
@ -140,16 +140,34 @@ nsresult
|
||||
TextEventDispatcher::DispatchEvent(nsIWidget* aWidget,
|
||||
WidgetGUIEvent& aEvent,
|
||||
nsEventStatus& aStatus)
|
||||
{
|
||||
MOZ_ASSERT(!aEvent.AsInputEvent(), "Use DispatchInputEvent()");
|
||||
|
||||
nsRefPtr<TextEventDispatcher> kungFuDeathGrip(this);
|
||||
nsCOMPtr<nsIWidget> widget(aWidget);
|
||||
mDispatchingEvent++;
|
||||
nsresult rv = widget->DispatchEvent(&aEvent, aStatus);
|
||||
mDispatchingEvent--;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
TextEventDispatcher::DispatchInputEvent(nsIWidget* aWidget,
|
||||
WidgetInputEvent& aEvent,
|
||||
nsEventStatus& aStatus,
|
||||
DispatchTo aDispatchTo)
|
||||
{
|
||||
nsRefPtr<TextEventDispatcher> kungFuDeathGrip(this);
|
||||
nsCOMPtr<nsIWidget> widget(aWidget);
|
||||
mDispatchingEvent++;
|
||||
|
||||
// If the event is dispatched via nsIWidget::DispatchInputEvent(), it
|
||||
// sends the event to the parent process first since APZ needs to handle it
|
||||
// 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 (aEvent.AsInputEvent() &&
|
||||
(!aEvent.mFlags.mIsSynthesizedForTests || gfxPrefs::TestEventsAsyncEnabled()))
|
||||
{
|
||||
aStatus = widget->DispatchInputEvent(aEvent.AsInputEvent());
|
||||
if (aDispatchTo == eDispatchToParentProcess) {
|
||||
aStatus = widget->DispatchInputEvent(&aEvent);
|
||||
} else {
|
||||
rv = widget->DispatchEvent(&aEvent, aStatus);
|
||||
}
|
||||
@ -286,9 +304,11 @@ bool
|
||||
TextEventDispatcher::DispatchKeyboardEvent(
|
||||
uint32_t aMessage,
|
||||
const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
nsEventStatus& aStatus)
|
||||
nsEventStatus& aStatus,
|
||||
DispatchTo aDispatchTo)
|
||||
{
|
||||
return DispatchKeyboardEventInternal(aMessage, aKeyboardEvent, aStatus);
|
||||
return DispatchKeyboardEventInternal(aMessage, aKeyboardEvent, aStatus,
|
||||
aDispatchTo);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -296,6 +316,7 @@ TextEventDispatcher::DispatchKeyboardEventInternal(
|
||||
uint32_t aMessage,
|
||||
const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
nsEventStatus& aStatus,
|
||||
DispatchTo aDispatchTo,
|
||||
uint32_t aIndexOfKeypress)
|
||||
{
|
||||
MOZ_ASSERT(aMessage == NS_KEY_DOWN || aMessage == NS_KEY_UP ||
|
||||
@ -374,14 +395,15 @@ TextEventDispatcher::DispatchKeyboardEventInternal(
|
||||
keyEvent.mPluginEvent.Clear();
|
||||
// TODO: Manage mUniqueId here.
|
||||
|
||||
DispatchEvent(mWidget, keyEvent, aStatus);
|
||||
DispatchInputEvent(mWidget, keyEvent, aStatus, aDispatchTo);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TextEventDispatcher::MaybeDispatchKeypressEvents(
|
||||
const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
nsEventStatus& aStatus)
|
||||
nsEventStatus& aStatus,
|
||||
DispatchTo aDispatchTo)
|
||||
{
|
||||
// If the key event was consumed, keypress event shouldn't be fired.
|
||||
if (aStatus == nsEventStatus_eConsumeNoDefault) {
|
||||
@ -401,7 +423,7 @@ TextEventDispatcher::MaybeDispatchKeypressEvents(
|
||||
for (size_t i = 0; i < keypressCount; i++) {
|
||||
aStatus = nsEventStatus_eIgnore;
|
||||
if (!DispatchKeyboardEventInternal(NS_KEY_PRESS, aKeyboardEvent,
|
||||
aStatus, i)) {
|
||||
aStatus, aDispatchTo, i)) {
|
||||
// The widget must have been gone.
|
||||
break;
|
||||
}
|
||||
|
@ -180,6 +180,26 @@ 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.
|
||||
*
|
||||
@ -192,11 +212,13 @@ 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(uint32_t aMessage,
|
||||
const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
nsEventStatus& aStatus);
|
||||
nsEventStatus& aStatus,
|
||||
DispatchTo aDispatchTo = eDispatchToParentProcess);
|
||||
|
||||
/**
|
||||
* MaybeDispatchKeypressEvents() maybe dispatches a keypress event which is
|
||||
@ -210,11 +232,14 @@ 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);
|
||||
nsEventStatus& aStatus,
|
||||
DispatchTo aDispatchTo =
|
||||
eDispatchToParentProcess);
|
||||
|
||||
private:
|
||||
// mWidget is owner of the instance. When this is created, this is set.
|
||||
@ -273,6 +298,7 @@ private:
|
||||
*/
|
||||
void InitEvent(WidgetGUIEvent& aEvent) const;
|
||||
|
||||
|
||||
/**
|
||||
* DispatchEvent() dispatches aEvent on aWidget.
|
||||
*/
|
||||
@ -280,6 +306,16 @@ private:
|
||||
WidgetGUIEvent& aEvent,
|
||||
nsEventStatus& aStatus);
|
||||
|
||||
/**
|
||||
* DispatchInputEvent() dispatches aEvent on aWidget.
|
||||
*
|
||||
* @param aDispatchTo See comments of DispatchTo.
|
||||
*/
|
||||
nsresult DispatchInputEvent(nsIWidget* aWidget,
|
||||
WidgetInputEvent& aEvent,
|
||||
nsEventStatus& aStatus,
|
||||
DispatchTo aDispatchTo);
|
||||
|
||||
/**
|
||||
* StartCompositionAutomaticallyIfNecessary() starts composition if it hasn't
|
||||
* been started it yet.
|
||||
@ -308,6 +344,7 @@ 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 NS_KEY_PRESS or
|
||||
* aKeyboard.mKeyNameIndex isn't
|
||||
* KEY_NAME_INDEX_USE_STRING. Otherwise, i.e.,
|
||||
@ -320,6 +357,8 @@ private:
|
||||
bool DispatchKeyboardEventInternal(uint32_t aMessage,
|
||||
const WidgetKeyboardEvent& aKeyboardEvent,
|
||||
nsEventStatus& aStatus,
|
||||
DispatchTo aDispatchTo =
|
||||
eDispatchToParentProcess,
|
||||
uint32_t aIndexOfKeypress = 0);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user