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,