Bug 1433101 - part 1: Add new pref which disables keypress event for non-printable keys only for the default event group in web content r=smaug

UI Events declares that keypress event should be fired when the keypress event
causes some text input.  However, we're keeping our traditional behavior for
historical reasons because our internal event handlers (including event
handlers of Thunderbird) handles keypress events for any keys.  Therefore,
for minimizing the side effect, we should stop kicking keypress event handlers
in the default event group in web content.

This patch adds new pref for enabling the standard behavior in web content.

Additionally, creates WidgetKeyboardEvent::IsInputtingText() for sharing the
check logic between TextEventDispatcher and TextEditor/HTMLEditor.

MozReview-Commit-ID: 3rtXdLBPeVC

--HG--
extra : rebase_source : 2fc3c9a09840d0d03800c9a42bb83ca76a8db2d5
This commit is contained in:
Masayuki Nakano 2018-01-25 23:27:07 +09:00
parent 97a87e010b
commit 082c64aa0c
6 changed files with 36 additions and 10 deletions

View File

@ -679,11 +679,7 @@ HTMLEditor::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent)
return TypedText(EmptyString(), eTypedBreak);
}
// NOTE: On some keyboard layout, some characters are inputted with Control
// key or Alt key, but at that time, widget sets FALSE to these keys.
if (!aKeyboardEvent->mCharCode || aKeyboardEvent->IsControl() ||
aKeyboardEvent->IsAlt() || aKeyboardEvent->IsMeta() ||
aKeyboardEvent->IsOS()) {
if (!aKeyboardEvent->IsInputtingText()) {
// we don't PreventDefault() here or keybindings like control-x won't work
return NS_OK;
}

View File

@ -384,11 +384,7 @@ TextEditor::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent)
return TypedText(EmptyString(), eTypedBreak);
}
// NOTE: On some keyboard layout, some characters are inputted with Control
// key or Alt key, but at that time, widget sets FALSE to these keys.
if (!aKeyboardEvent->mCharCode || aKeyboardEvent->IsControl() ||
aKeyboardEvent->IsAlt() || aKeyboardEvent->IsMeta() ||
aKeyboardEvent->IsOS()) {
if (!aKeyboardEvent->IsInputtingText()) {
// we don't PreventDefault() here or keybindings like control-x won't work
return NS_OK;
}

View File

@ -206,6 +206,11 @@ pref("dom.gamepad.haptic_feedback.enabled", true);
// even if this is true).
pref("dom.keyboardevent.dispatch_during_composition", false);
// If this is true, TextEventDispatcher dispatches keypress event with setting
// WidgetEvent::mFlags::mOnlySystemGroupDispatchInContent to true if it won't
// cause inputting printable character.
pref("dom.keyboardevent.keypress.dispatch_non_printable_keys_only_system_group_in_content", false);
// Whether to run add-on code in different compartments from browser code. This
// causes a separate compartment for each (addon, global) combination, which may
// significantly increase the number of compartments in the system.

View File

@ -22,6 +22,8 @@ namespace widget {
*****************************************************************************/
bool TextEventDispatcher::sDispatchKeyEventsDuringComposition = false;
bool TextEventDispatcher::sDispatchKeyPressEventsOnlySystemGroupInContent =
false;
TextEventDispatcher::TextEventDispatcher(nsIWidget* aWidget)
: mWidget(aWidget)
@ -39,6 +41,11 @@ TextEventDispatcher::TextEventDispatcher(nsIWidget* aWidget)
&sDispatchKeyEventsDuringComposition,
"dom.keyboardevent.dispatch_during_composition",
false);
Preferences::AddBoolVarCache(
&sDispatchKeyPressEventsOnlySystemGroupInContent,
"dom.keyboardevent.keypress."
"dispatch_non_printable_keys_only_system_group_in_content",
false);
sInitialized = true;
}
@ -687,6 +694,12 @@ TextEventDispatcher::DispatchKeyboardEventInternal(
}
}
if (sDispatchKeyPressEventsOnlySystemGroupInContent &&
keyEvent.mMessage == eKeyPress &&
!keyEvent.IsInputtingText()) {
keyEvent.mFlags.mOnlySystemGroupDispatchInContent = true;
}
DispatchInputEvent(mWidget, keyEvent, aStatus);
return true;
}

View File

@ -454,6 +454,9 @@ private:
// If this is true, keydown and keyup events are dispatched even when there
// is a composition.
static bool sDispatchKeyEventsDuringComposition;
// If this is true, keypress events for non-printable keys are dispatched only
// for event listeners of the system event group in web content.
static bool sDispatchKeyPressEventsOnlySystemGroupInContent;
nsresult BeginInputTransactionInternal(
TextEventDispatcherListener* aListener,

View File

@ -228,6 +228,19 @@ public:
return IsKeyEventOnPlugin(mMessage);
}
bool IsInputtingText() const
{
// NOTE: On some keyboard layout, some characters are inputted with Control
// key or Alt key, but at that time, widget unset the modifier flag
// from eKeyPress event.
return mMessage == eKeyPress &&
mCharCode &&
!(mModifiers & (MODIFIER_ALT |
MODIFIER_CONTROL |
MODIFIER_META |
MODIFIER_OS));
}
virtual WidgetEvent* Duplicate() const override
{
MOZ_ASSERT(mClass == eKeyboardEventClass,