author | Masayuki Nakano <masayuki@d-toybox.com> |
Sat, 02 Dec 2017 10:46:31 +0900 | |
changeset 394977 | f5039cf4ead7e14b067052ab1ecff2277ecbeace |
parent 394976 | 525f2f1623850d9de7f0b1995f0c68fe1a14e0cc |
child 394978 | afc17c7465c2371b7ba0f50c92ec065c099e9fd3 |
push id | 97987 |
push user | nerli@mozilla.com |
push date | Tue, 05 Dec 2017 13:52:50 +0000 |
treeherder | mozilla-inbound@8842dba7396b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | m_kato |
bugs | 1403759 |
milestone | 59.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/widget/CommandList.h +++ b/widget/CommandList.h @@ -17,16 +17,18 @@ NS_DEFINE_COMMAND(Cut, NS_DEFINE_COMMAND(Delete, cmd_delete) NS_DEFINE_COMMAND(DeleteCharBackward, cmd_deleteCharBackward) NS_DEFINE_COMMAND(DeleteCharForward, cmd_deleteCharForward) NS_DEFINE_COMMAND(DeleteToBeginningOfLine, cmd_deleteToBeginningOfLine) NS_DEFINE_COMMAND(DeleteToEndOfLine, cmd_deleteToEndOfLine) NS_DEFINE_COMMAND(DeleteWordBackward, cmd_deleteWordBackward) NS_DEFINE_COMMAND(DeleteWordForward, cmd_deleteWordForward) NS_DEFINE_COMMAND(EndLine, cmd_endLine) +NS_DEFINE_COMMAND(InsertParagraph, cmd_insertParagraph) +NS_DEFINE_COMMAND(InsertLineBreak, cmd_insertLineBreak) NS_DEFINE_COMMAND(LineNext, cmd_lineNext) NS_DEFINE_COMMAND(LinePrevious, cmd_linePrevious) NS_DEFINE_COMMAND(MoveBottom, cmd_moveBottom) NS_DEFINE_COMMAND(MovePageDown, cmd_movePageDown) NS_DEFINE_COMMAND(MovePageUp, cmd_movePageUp) NS_DEFINE_COMMAND(MoveTop, cmd_moveTop) NS_DEFINE_COMMAND(Paste, cmd_paste) NS_DEFINE_COMMAND(ScrollBottom, cmd_scrollBottom)
--- a/widget/EventForwards.h +++ b/widget/EventForwards.h @@ -119,16 +119,18 @@ typedef int8_t CommandInt; enum Command : CommandInt { CommandDoNothing #include "mozilla/CommandList.h" }; #undef NS_DEFINE_COMMAND +const char* ToChar(Command aCommand); + } // namespace mozilla /** * All header files should include this header instead of *Events.h. */ namespace mozilla {
--- a/widget/WidgetEventImpl.cpp +++ b/widget/WidgetEventImpl.cpp @@ -80,16 +80,38 @@ ToString(CodeNameIndex aCodeNameIndex) if (aCodeNameIndex == CODE_NAME_INDEX_USE_STRING) { return NS_LITERAL_CSTRING("USE_STRING"); } nsAutoString codeName; WidgetKeyboardEvent::GetDOMCodeName(aCodeNameIndex, codeName); return NS_ConvertUTF16toUTF8(codeName); } +const char* +ToChar(Command aCommand) +{ + if (aCommand == CommandDoNothing) { + return "CommandDoNothing"; + } + + switch (aCommand) { + +#define NS_DEFINE_COMMAND(aName, aCommandStr) \ + case Command##aName: \ + return "Command" #aName; + +#include "mozilla/CommandList.h" + +#undef NS_DEFINE_COMMAND + + default: + return "illegal command value"; + } +} + const nsCString GetDOMKeyCodeName(uint32_t aKeyCode) { switch (aKeyCode) { #define NS_DISALLOW_SAME_KEYCODE #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) \ case aDOMKeyCode: \ return NS_LITERAL_CSTRING(#aDOMKeyName);
--- a/widget/cocoa/TextInputHandler.h +++ b/widget/cocoa/TextInputHandler.h @@ -1155,23 +1155,19 @@ public: * @param aAttrString An inserted string. * @param aReplacementRange The range which will be replaced with the * aAttrString instead of current selection. */ void InsertText(NSAttributedString *aAttrString, NSRange* aReplacementRange = nullptr); /** - * Handles "insertNewline:" command. Due to bug 1350541, this always - * dispatches a keypress event of Enter key unless there is composition. - * If it's handling Enter key event, this dispatches "actual" Enter - * keypress event. Otherwise, dispatches "fake" Enter keypress event - * whose code value is unidentified. + * Handles aCommand. This may cause dispatching an eKeyPress event. */ - void InsertNewline(); + void HandleCommand(Command aCommand); /** * doCommandBySelector event handler. * * @param aSelector A selector of the command. * @return TRUE if the command is consumed. Otherwise, * FALSE. */
--- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -2346,110 +2346,132 @@ TextInputHandler::InsertText(NSAttribute currentKeyEvent->mKeyPressHandled = keyPressHandled; currentKeyEvent->mKeyPressDispatched = keyPressDispatched; } NS_OBJC_END_TRY_ABORT_BLOCK; } void -TextInputHandler::InsertNewline() +TextInputHandler::HandleCommand(Command aCommand) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK; if (Destroyed()) { return; } KeyEventState* currentKeyEvent = GetCurrentKeyEvent(); MOZ_LOG(gLog, LogLevel::Info, - ("%p TextInputHandler::InsertNewline, " - "IsIMEComposing()=%s, " + ("%p TextInputHandler::HandleCommand, " + "aCommand=%s, IsIMEComposing()=%s, " "keyevent=%p, keydownHandled=%s, keypressDispatched=%s, " "causedOtherKeyEvents=%s, compositionDispatched=%s", - this, TrueOrFalse(IsIMEComposing()), + this, ToChar(aCommand), TrueOrFalse(IsIMEComposing()), currentKeyEvent ? currentKeyEvent->mKeyEvent : nullptr, currentKeyEvent ? TrueOrFalse(currentKeyEvent->mKeyDownHandled) : "N/A", currentKeyEvent ? TrueOrFalse(currentKeyEvent->mKeyPressDispatched) : "N/A", currentKeyEvent ? TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents) : "N/A", currentKeyEvent ? TrueOrFalse(currentKeyEvent->mCompositionDispatched) : "N/A")); // If "insertNewline:" command shouldn't be handled, let's ignore it. if (currentKeyEvent && !currentKeyEvent->CanHandleCommand()) { return; } // If it's in composition, we cannot dispatch keypress event. - // Therefore, we should insert '\n' as committing composition. + // Therefore, we should use different approach or give up to handle + // the command. if (IsIMEComposing()) { - NSAttributedString* lineBreaker = - [[NSAttributedString alloc] initWithString:@"\n"]; - InsertTextAsCommittingComposition(lineBreaker, nullptr); - if (currentKeyEvent) { - currentKeyEvent->mCompositionDispatched = true; + switch (aCommand) { + case CommandInsertLineBreak: + case CommandInsertParagraph: { + // Insert '\n' as committing composition. + // Otherwise, we need to dispatch keypress event because HTMLEditor + // doesn't treat "\n" in composition string as a line break unless + // the whitespace is treated as pre (see bug 1350541). In strictly + // speaking, we should dispatch keypress event as-is if it's handling + // NSKeyDown event or should insert it with committing composition. + NSAttributedString* lineBreaker = + [[NSAttributedString alloc] initWithString:@"\n"]; + InsertTextAsCommittingComposition(lineBreaker, nullptr); + if (currentKeyEvent) { + currentKeyEvent->mCompositionDispatched = true; + } + [lineBreaker release]; + return; + } + default: + break; } - [lineBreaker release]; - return; } - // Otherwise, we need to dispatch keypress event because HTMLEditor doesn't - // treat "\n" in composition string as a line break unless the whitespace is - // treated as pre (see bug 1350541). In strictly speaking, we should - // dispatch keypress event as-is if it's handling NSKeyDown event or - // should insert it with committing composition. - RefPtr<nsChildView> widget(mWidget); nsresult rv = mDispatcher->BeginNativeInputTransaction(); if (NS_WARN_IF(NS_FAILED(rv))) { MOZ_LOG(gLog, LogLevel::Error, - ("%p, IMEInputHandler::InsertNewline, " + ("%p, IMEInputHandler::HandleCommand, " "FAILED, due to BeginNativeInputTransaction() failure", this)); return; } - // TODO: If it's not Enter keypress but user customized the OS settings - // to insert a line breaker with other key, we should just set + // TODO: If it's not appropriate keypress but user customized the OS + // settings to do the command with other key, we should just set // command to the keypress event and it should be handled as - // Enter key press in editor. - - // If it's handling actual Enter key event and hasn't cause any composition + // the key press in editor. + + // If it's handling actual key event and hasn't cause any composition // events nor other key events, we should expose actual modifier state. - // Otherwise, we should remove Control, Option and Command state since - // editor may behave differently if some of them are active. Although, - // Shift+Enter and Enter are work differently in HTML editor, we should - // expose actual Shift state if it's caused by Enter key for compatibility - // with Chromium. Chromium breaks line in HTML editor with default pargraph - // separator when Enter is pressed, with <br> element when Shift+Enter. - // Safari breaks line in HTML editor with default paragraph separator when - // Enter, Shift+Enter or Option+Enter. So, we should not change Shift+Enter - // meaning when there was composition string or not. + // Otherwise, we should adjust Control, Option and Command state since + // editor may behave differently if some of them are active. bool dispatchFakeKeyPress = !(currentKeyEvent && currentKeyEvent->IsEnterKeyEvent() && currentKeyEvent->CanDispatchKeyPressEvent()); WidgetKeyboardEvent keypressEvent(true, eKeyPress, widget); if (!dispatchFakeKeyPress) { - // If we're acutally handling an Enter key press, we should dispatch - // Enter keypress event as-is. + // If we're acutally handling a key press, we should dispatch + // the keypress event as-is. currentKeyEvent->InitKeyEvent(this, keypressEvent); } else { - // Otherwise, we should dispatch "fake" Enter keypress event. - // In this case, we shouldn't set code value to "Enter". - NSEvent* keyEvent = currentKeyEvent ? currentKeyEvent->mKeyEvent : nullptr; - nsCocoaUtils::InitInputEvent(keypressEvent, keyEvent); - keypressEvent.mKeyCode = NS_VK_RETURN; - keypressEvent.mKeyNameIndex = KEY_NAME_INDEX_Enter; - keypressEvent.mModifiers &= ~(MODIFIER_CONTROL | - MODIFIER_ALT | - MODIFIER_META); + // Otherwise, we should dispatch "fake" keypress event. + switch (aCommand) { + case CommandInsertLineBreak: + case CommandInsertParagraph: { + // Although, Shift+Enter and Enter are work differently in HTML + // editor, we should expose actual Shift state if it's caused by + // Enter key for compatibility with Chromium. Chromium breaks + // line in HTML editor with default pargraph separator when Enter + // is pressed, with <br> element when Shift+Enter. Safari breaks + // line in HTML editor with default paragraph separator when + // Enter, Shift+Enter or Option+Enter. So, we should not change + // Shift+Enter meaning when there was composition string or not. + NSEvent* keyEvent = + currentKeyEvent ? currentKeyEvent->mKeyEvent : nullptr; + nsCocoaUtils::InitInputEvent(keypressEvent, keyEvent); + keypressEvent.mKeyCode = NS_VK_RETURN; + keypressEvent.mKeyNameIndex = KEY_NAME_INDEX_Enter; + keypressEvent.mModifiers &= ~(MODIFIER_CONTROL | + MODIFIER_ALT | + MODIFIER_META); + if (aCommand == CommandInsertLineBreak) { + // In default settings, Ctrl + Enter causes insertLineBreak command. + // So, let's make Ctrl state active of the keypress event. + keypressEvent.mModifiers |= MODIFIER_CONTROL; + } + break; + } + default: + return; + } } nsEventStatus status = nsEventStatus_eIgnore; bool keyPressDispatched = mDispatcher->MaybeDispatchKeypressEvents(keypressEvent, status, currentKeyEvent); bool keyPressHandled = (status == nsEventStatus_eConsumeNoDefault);
--- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -5582,17 +5582,25 @@ GetIntegerDeltaForEvent(NSEvent* aEvent) mTextInputHandler->HandleKeyUpEvent(theEvent); NS_OBJC_END_TRY_ABORT_BLOCK; } - (void)insertNewline:(id)sender { if (mTextInputHandler) { - mTextInputHandler->InsertNewline(); + mTextInputHandler->HandleCommand(CommandInsertParagraph); + } +} + +- (void)insertLineBreak:(id)sender +{ + // Ctrl + Enter in the default settings. + if (mTextInputHandler) { + mTextInputHandler->HandleCommand(CommandInsertLineBreak); } } - (void)flagsChanged:(NSEvent*)theEvent { NS_OBJC_BEGIN_TRY_ABORT_BLOCK; NS_ENSURE_TRUE(mGeckoChild, );