diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index 6a630cb1c4..130b033bd1 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -664,8 +664,7 @@ HTMLEditor::HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent) return TypedText(NS_LITERAL_STRING("\t"), eTypedText); } case NS_VK_RETURN: - if (nativeKeyEvent->IsControl() || nativeKeyEvent->IsAlt() || - nativeKeyEvent->IsMeta() || nativeKeyEvent->IsOS()) { + if (!nativeKeyEvent->IsInputtingLineBreak()) { return NS_OK; } aKeyEvent->AsEvent()->PreventDefault(); // consumed @@ -677,11 +676,7 @@ HTMLEditor::HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent) 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 (!nativeKeyEvent->mCharCode || nativeKeyEvent->IsControl() || - nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() || - nativeKeyEvent->IsOS()) { + if (!nativeKeyEvent->IsInputtingText()) { // we don't PreventDefault() here or keybindings like control-x won't work return NS_OK; } diff --git a/editor/libeditor/TextEditor.cpp b/editor/libeditor/TextEditor.cpp index 3bee7843ce..4b26eff9cd 100644 --- a/editor/libeditor/TextEditor.cpp +++ b/editor/libeditor/TextEditor.cpp @@ -397,20 +397,14 @@ TextEditor::HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent) return TypedText(NS_LITERAL_STRING("\t"), eTypedText); } case NS_VK_RETURN: - if (IsSingleLineEditor() || nativeKeyEvent->IsControl() || - nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() || - nativeKeyEvent->IsOS()) { + if (IsSingleLineEditor() || !nativeKeyEvent->IsInputtingLineBreak()) { return NS_OK; } aKeyEvent->AsEvent()->PreventDefault(); 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 (!nativeKeyEvent->mCharCode || nativeKeyEvent->IsControl() || - nativeKeyEvent->IsAlt() || nativeKeyEvent->IsMeta() || - nativeKeyEvent->IsOS()) { + if (!nativeKeyEvent->IsInputtingText()) { // we don't PreventDefault() here or keybindings like control-x won't work return NS_OK; } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index ec8e6d770f..ec30c9d4b2 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -231,6 +231,10 @@ pref("dom.keyboardevent.code.enabled", true); // even if this is true). pref("dom.keyboardevent.dispatch_during_composition", false); +// If this is true, TextEventDispatcher dispatches keypress events +// for the input of non-printable characters (content only). +pref("dom.keyboardevent.keypress.dispatch_non_printable_in_content", false); + // Whether URL,Location,Link::GetHash should be percent encoded // in setter and percent decoded in getter (old behaviour = true) pref("dom.url.encode_decode_hash", true); diff --git a/widget/TextEventDispatcher.cpp b/widget/TextEventDispatcher.cpp index 6c54376a48..2b058ba9c3 100644 --- a/widget/TextEventDispatcher.cpp +++ b/widget/TextEventDispatcher.cpp @@ -21,6 +21,7 @@ namespace widget { *****************************************************************************/ bool TextEventDispatcher::sDispatchKeyEventsDuringComposition = false; +bool TextEventDispatcher::sDispatchKeyPressEventNonPrintableInContent = false; TextEventDispatcher::TextEventDispatcher(nsIWidget* aWidget) : mWidget(aWidget) @@ -36,6 +37,10 @@ TextEventDispatcher::TextEventDispatcher(nsIWidget* aWidget) &sDispatchKeyEventsDuringComposition, "dom.keyboardevent.dispatch_during_composition", false); + Preferences::AddBoolVarCache( + &sDispatchKeyPressEventNonPrintableInContent, + "dom.keyboardevent.keypress.dispatch_non_printable_in_content", + false); sInitialized = true; } } @@ -531,6 +536,13 @@ TextEventDispatcher::DispatchKeyboardEventInternal( } } + if (!sDispatchKeyPressEventNonPrintableInContent && + keyEvent.mMessage == eKeyPress && + !keyEvent.IsInputtingText() && + !keyEvent.IsInputtingLineBreak()) { + keyEvent.mFlags.mOnlySystemGroupDispatchInContent = true; + } + DispatchInputEvent(mWidget, keyEvent, aStatus); return true; } diff --git a/widget/TextEventDispatcher.h b/widget/TextEventDispatcher.h index 1bed15a3bf..6d28200f5f 100644 --- a/widget/TextEventDispatcher.h +++ b/widget/TextEventDispatcher.h @@ -399,6 +399,10 @@ private: // is a composition. static bool sDispatchKeyEventsDuringComposition; + // If this is true, keypress events for non-printable keys are dispatched to + // event listeners of the system event group in web content. + static bool sDispatchKeyPressEventNonPrintableInContent; + nsresult BeginInputTransactionInternal( TextEventDispatcherListener* aListener, InputTransactionType aType); diff --git a/widget/TextEvents.h b/widget/TextEvents.h index 6c29341144..59aa91b2e0 100644 --- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -183,6 +183,30 @@ public: return IsKeyEventOnPlugin(mMessage); } + bool IsInputtingText() const + { + // NOTE: On some keyboard layouts, some characters are put in with Control + // or Alt keys, but at that time, widget unsets the modifier flag + // from the eKeyPress event, so it does not count as a modifier in + // this check. + return mMessage == eKeyPress && + mCharCode && + !(mModifiers & (MODIFIER_ALT | + MODIFIER_CONTROL | + MODIFIER_META | + MODIFIER_OS)); + } + + bool IsInputtingLineBreak() const + { + return mMessage == eKeyPress && + mKeyNameIndex == KEY_NAME_INDEX_Enter && + !(mModifiers & (MODIFIER_ALT | + MODIFIER_CONTROL | + MODIFIER_META | + MODIFIER_OS)); + } + virtual WidgetEvent* Duplicate() const override { MOZ_ASSERT(mClass == eKeyboardEventClass,