mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1065835 part.4 Destroy TextComposition instance after handling synthesized compositionend event when synthesized events for a request to commit or cancel is caused by PresShell discarding native compositionend event r=smaug
This commit is contained in:
parent
66be0a9376
commit
d5aafd2cdc
@ -945,7 +945,14 @@ IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode,
|
||||
// emulating a commit, the instance shouldn't be removed from the array
|
||||
// because IME may perform it later. Then, we need to ignore the
|
||||
// following commit events in TextComposition::DispatchEvent().
|
||||
if (!aIsSynthesized && aEvent->message == NS_COMPOSITION_END) {
|
||||
// However, if commit or cancel for a request is performed synchronously
|
||||
// during not safe to dispatch events, PresShell must have discarded
|
||||
// compositionend event. Then, the synthesized compositionend event is
|
||||
// the last event for the composition. In this case, we need to
|
||||
// destroy the TextComposition with synthesized compositionend event.
|
||||
if ((!aIsSynthesized ||
|
||||
composition->WasNativeCompositionEndEventDiscarded()) &&
|
||||
aEvent->message == NS_COMPOSITION_END) {
|
||||
TextCompositionArray::index_type i =
|
||||
sTextCompositions->IndexOf(GUIEvent->widget);
|
||||
if (i != TextCompositionArray::NoIndex) {
|
||||
@ -959,6 +966,38 @@ IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode,
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
IMEStateManager::OnCompositionEventDiscarded(WidgetEvent* aEvent)
|
||||
{
|
||||
// Note that this method is never called for synthesized events for emulating
|
||||
// commit or cancel composition.
|
||||
|
||||
PR_LOG(sISMLog, PR_LOG_ALWAYS,
|
||||
("ISM: IMEStateManager::OnCompositionEventDiscarded(aEvent={ mClass=%s, "
|
||||
"message=%s, mFlags={ mIsTrusted=%s } })",
|
||||
GetEventClassIDName(aEvent->mClass),
|
||||
GetEventMessageName(aEvent->message),
|
||||
GetBoolName(aEvent->mFlags.mIsTrusted)));
|
||||
|
||||
MOZ_ASSERT(aEvent->mClass == eCompositionEventClass ||
|
||||
aEvent->mClass == eTextEventClass);
|
||||
if (!aEvent->mFlags.mIsTrusted) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore compositionstart for now because sTextCompositions may not have
|
||||
// been created yet.
|
||||
if (aEvent->message == NS_COMPOSITION_START) {
|
||||
return;
|
||||
}
|
||||
|
||||
WidgetGUIEvent* GUIEvent = aEvent->AsGUIEvent();
|
||||
nsRefPtr<TextComposition> composition =
|
||||
sTextCompositions->GetCompositionFor(GUIEvent->widget);
|
||||
composition->OnCompositionEventDiscarded(GUIEvent);
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
IMEStateManager::NotifyIME(IMEMessage aMessage,
|
||||
|
@ -105,6 +105,12 @@ public:
|
||||
EventDispatchingCallback* aCallBack,
|
||||
bool aIsSynthesized = false);
|
||||
|
||||
/**
|
||||
* This is called when PresShell ignores composition event or text event due
|
||||
* to not safe to dispatch events.
|
||||
*/
|
||||
static void OnCompositionEventDiscarded(WidgetEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Get TextComposition from widget.
|
||||
*/
|
||||
|
@ -41,6 +41,7 @@ TextComposition::TextComposition(nsPresContext* aPresContext,
|
||||
, mIsRequestingCommit(false)
|
||||
, mIsRequestingCancel(false)
|
||||
, mRequestedToCommitOrCancel(false)
|
||||
, mWasNativeCompositionEndEventDiscarded(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -93,6 +94,28 @@ TextComposition::MaybeDispatchCompositionUpdate(const WidgetTextEvent* aEvent)
|
||||
return !Destroyed();
|
||||
}
|
||||
|
||||
void
|
||||
TextComposition::OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent)
|
||||
{
|
||||
// Note that this method is never called for synthesized events for emulating
|
||||
// commit or cancel composition.
|
||||
|
||||
MOZ_ASSERT(aEvent->mFlags.mIsTrusted,
|
||||
"Shouldn't be called with untrusted event");
|
||||
MOZ_ASSERT(aEvent->mClass == eCompositionEventClass ||
|
||||
aEvent->mClass == eTextEventClass);
|
||||
|
||||
// XXX If composition events are discarded, should we dispatch them with
|
||||
// runnable event? However, even if we do so, it might make native IME
|
||||
// confused due to async modification. Especially when native IME is
|
||||
// TSF.
|
||||
if (aEvent->message != NS_COMPOSITION_END) {
|
||||
return;
|
||||
}
|
||||
|
||||
mWasNativeCompositionEndEventDiscarded = true;
|
||||
}
|
||||
|
||||
void
|
||||
TextComposition::DispatchEvent(WidgetGUIEvent* aEvent,
|
||||
nsEventStatus* aStatus,
|
||||
|
@ -211,6 +211,11 @@ private:
|
||||
// mIsRequestingCancel are set false.
|
||||
bool mRequestedToCommitOrCancel;
|
||||
|
||||
// mWasNativeCompositionEndEventDiscarded is true if this composition was
|
||||
// requested commit or cancel itself but native compositionend event is
|
||||
// discarded by PresShell due to not safe to dispatch events.
|
||||
bool mWasNativeCompositionEndEventDiscarded;
|
||||
|
||||
// Hide the default constructor and copy constructor.
|
||||
TextComposition() {}
|
||||
TextComposition(const TextComposition& aOther);
|
||||
@ -255,6 +260,22 @@ private:
|
||||
*/
|
||||
bool MaybeDispatchCompositionUpdate(const WidgetTextEvent* aEvent);
|
||||
|
||||
/**
|
||||
* If IME has already dispatched compositionend event but it was discarded
|
||||
* by PresShell due to not safe to dispatch, this returns true.
|
||||
*/
|
||||
bool WasNativeCompositionEndEventDiscarded() const
|
||||
{
|
||||
return mWasNativeCompositionEndEventDiscarded;
|
||||
}
|
||||
|
||||
/**
|
||||
* OnCompositionEventDiscarded() is called when PresShell discards
|
||||
* compositionupdate, compositionend or text event due to not safe to
|
||||
* dispatch event.
|
||||
*/
|
||||
void OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Calculate composition offset then notify composition update to widget
|
||||
*/
|
||||
|
@ -6942,6 +6942,10 @@ PresShell::HandleEvent(nsIFrame* aFrame,
|
||||
|
||||
if (!nsContentUtils::IsSafeToRunScript() &&
|
||||
aEvent->IsAllowedToDispatchDOMEvent()) {
|
||||
if (aEvent->mClass == eCompositionEventClass ||
|
||||
aEvent->mClass == eTextEventClass) {
|
||||
IMEStateManager::OnCompositionEventDiscarded(aEvent);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (aEvent->IsIMERelatedEvent()) {
|
||||
nsPrintfCString warning("%d event is discarded", aEvent->message);
|
||||
|
Loading…
Reference in New Issue
Block a user