diff --git a/widget/windows/IMMHandler.cpp b/widget/windows/IMMHandler.cpp index ccde4649400..0064cd29300 100644 --- a/widget/windows/IMMHandler.cpp +++ b/widget/windows/IMMHandler.cpp @@ -489,9 +489,15 @@ void IMMHandler::OnFocusChange(bool aFocus, nsWindow* aWindow) { MOZ_LOG(gIMMLog, LogLevel::Info, - ("IMM: OnFocusChange(aFocus=%s, aWindow=%p), sHasFocus=%s", - GetBoolName(aFocus), aWindow, GetBoolName(sHasFocus))); + ("IMM: OnFocusChange(aFocus=%s, aWindow=%p), sHasFocus=%s, " + "IsComposingWindow(aWindow)=%s, aWindow->Destroyed()=%s", + GetBoolName(aFocus), aWindow, GetBoolName(sHasFocus), + GetBoolName(IsComposingWindow(aWindow)), + GetBoolName(aWindow->Destroyed()))); + if (!aFocus && IsComposingWindow(aWindow) && aWindow->Destroyed()) { + CancelComposition(aWindow); + } if (gIMMHandler) { gIMMHandler->mSelection.Clear(); } @@ -1253,7 +1259,7 @@ IMMHandler::HandleStartComposition(nsWindow* aWindow, WidgetCompositionEvent event(true, eCompositionStart, aWindow); LayoutDeviceIntPoint point(0, 0); aWindow->InitEvent(event, &point); - aWindow->DispatchWindowEvent(&event); + DispatchEvent(aWindow, event); mIsComposing = true; mComposingWindow = aWindow; @@ -1532,7 +1538,7 @@ IMMHandler::HandleEndComposition(nsWindow* aWindow, if (aCommitString) { compositionCommitEvent.mData = *aCommitString; } - aWindow->DispatchWindowEvent(&compositionCommitEvent); + DispatchEvent(aWindow, compositionCommitEvent); mIsComposing = false; mComposingWindow = nullptr; } @@ -1656,7 +1662,7 @@ IMMHandler::HandleQueryCharPosition(nsWindow* aWindow, WidgetQueryContentEvent editorRect(true, eQueryEditorRect, aWindow); aWindow->InitEvent(editorRect); - aWindow->DispatchWindowEvent(&editorRect); + DispatchEvent(aWindow, editorRect); if (NS_WARN_IF(!editorRect.mSucceeded)) { MOZ_LOG(gIMMLog, LogLevel::Error, ("IMM: HandleQueryCharPosition, eQueryEditorRect failed")); @@ -1728,7 +1734,7 @@ IMMHandler::HandleDocumentFeed(nsWindow* aWindow, WidgetQueryContentEvent textContent(true, eQueryTextContent, aWindow); textContent.InitForQueryTextContent(0, UINT32_MAX); aWindow->InitEvent(textContent, &point); - aWindow->DispatchWindowEvent(&textContent); + DispatchEvent(aWindow, textContent); if (!textContent.mSucceeded) { MOZ_LOG(gIMMLog, LogLevel::Error, ("IMM: HandleDocumentFeed, FAILED, due to eQueryTextContent failure")); @@ -1876,6 +1882,22 @@ GetRangeTypeName(uint32_t aRangeType) } } +// static +void +IMMHandler::DispatchEvent(nsWindow* aWindow, WidgetGUIEvent& aEvent) +{ + MOZ_LOG(gIMMLog, LogLevel::Info, + ("IMM: DispatchEvent(aWindow=0x%p, aEvent={ mMessage=%s }, " + "aWindow->Destroyed()=%s", + aWindow, ToChar(aEvent.mMessage), GetBoolName(aWindow->Destroyed()))); + + if (aWindow->Destroyed()) { + return; + } + + aWindow->DispatchWindowEvent(&aEvent); +} + void IMMHandler::DispatchCompositionChangeEvent(nsWindow* aWindow, const IMEContext& aContext) @@ -1903,7 +1925,7 @@ IMMHandler::DispatchCompositionChangeEvent(nsWindow* aWindow, event.mRanges = CreateTextRangeArray(); event.mData = mCompositionString; - aWindow->DispatchWindowEvent(&event); + DispatchEvent(aWindow, event); // Calling SetIMERelatedWindowsPos will be failure on e10s at this point. // compositionchange event will notify NOTIFY_IME_OF_COMPOSITION_UPDATE, then @@ -2167,7 +2189,7 @@ IMMHandler::GetCharacterRectOfSelectedTextAt(nsWindow* aWindow, WidgetQueryContentEvent charRect(true, eQueryTextRect, aWindow); charRect.InitForQueryTextRect(offset, 1); aWindow->InitEvent(charRect, &point); - aWindow->DispatchWindowEvent(&charRect); + DispatchEvent(aWindow, charRect); if (charRect.mSucceeded) { aCharRect = charRect.mReply.mRect; if (aWritingMode) { @@ -2204,7 +2226,7 @@ IMMHandler::GetCaretRect(nsWindow* aWindow, WidgetQueryContentEvent caretRect(true, eQueryCaretRect, aWindow); caretRect.InitForQueryCaretRect(selection.mOffset); aWindow->InitEvent(caretRect, &point); - aWindow->DispatchWindowEvent(&caretRect); + DispatchEvent(aWindow, caretRect); if (!caretRect.mSucceeded) { MOZ_LOG(gIMMLog, LogLevel::Info, ("IMM: GetCaretRect, FAILED, due to eQueryCaretRect failure")); @@ -2377,7 +2399,7 @@ IMMHandler::SetIMERelatedWindowsPosOnPlugin(nsWindow* aWindow, { WidgetQueryContentEvent editorRectEvent(true, eQueryEditorRect, aWindow); aWindow->InitEvent(editorRectEvent); - aWindow->DispatchWindowEvent(&editorRectEvent); + DispatchEvent(aWindow, editorRectEvent); if (!editorRectEvent.mSucceeded) { MOZ_LOG(gIMMLog, LogLevel::Info, ("IMM: SetIMERelatedWindowsPosOnPlugin, " @@ -2754,7 +2776,7 @@ IMMHandler::Selection::Init(nsWindow* aWindow) WidgetQueryContentEvent selection(true, eQuerySelectedText, aWindow); LayoutDeviceIntPoint point(0, 0); aWindow->InitEvent(selection, &point); - aWindow->DispatchWindowEvent(&selection); + DispatchEvent(aWindow, selection); if (NS_WARN_IF(!selection.mSucceeded)) { MOZ_LOG(gIMMLog, LogLevel::Error, ("IMM: Selection::Init, FAILED, due to eQuerySelectedText failure")); diff --git a/widget/windows/IMMHandler.h b/widget/windows/IMMHandler.h index 1066cf8edc4..7b908ecfc74 100644 --- a/widget/windows/IMMHandler.h +++ b/widget/windows/IMMHandler.h @@ -352,6 +352,11 @@ protected: */ bool GetTargetClauseRange(uint32_t *aOffset, uint32_t *aLength = nullptr); + /** + * DispatchEvent() dispatches aEvent if aWidget hasn't been destroyed yet. + */ + static void DispatchEvent(nsWindow* aWindow, WidgetGUIEvent& aEvent); + /** * DispatchCompositionChangeEvent() dispatches eCompositionChange event * with clause information (it'll be retrieved by CreateTextRangeArray()).