mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 960871 part.10 Some methods which took both WidgetCompositionEvent and WidgetTextEvent should take only WidgetCompositionEvent r=smaug
This commit is contained in:
parent
d028544b2b
commit
2be456d529
@ -870,38 +870,37 @@ IMEStateManager::EnsureTextCompositionArray()
|
||||
|
||||
// static
|
||||
void
|
||||
IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode,
|
||||
IMEStateManager::DispatchCompositionEvent(
|
||||
nsINode* aEventTargetNode,
|
||||
nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
WidgetCompositionEvent* aCompositionEvent,
|
||||
nsEventStatus* aStatus,
|
||||
EventDispatchingCallback* aCallBack,
|
||||
bool aIsSynthesized)
|
||||
{
|
||||
PR_LOG(sISMLog, PR_LOG_ALWAYS,
|
||||
("ISM: IMEStateManager::DispatchCompositionEvent(aNode=0x%p, "
|
||||
"aPresContext=0x%p, aEvent={ message=%s, "
|
||||
"aPresContext=0x%p, aCompositionEvent={ message=%s, "
|
||||
"mFlags={ mIsTrusted=%s, mPropagationStopped=%s } }, "
|
||||
"aIsSynthesized=%s)",
|
||||
aEventTargetNode, aPresContext,
|
||||
GetEventMessageName(aEvent->message),
|
||||
GetBoolName(aEvent->mFlags.mIsTrusted),
|
||||
GetBoolName(aEvent->mFlags.mPropagationStopped),
|
||||
GetEventMessageName(aCompositionEvent->message),
|
||||
GetBoolName(aCompositionEvent->mFlags.mIsTrusted),
|
||||
GetBoolName(aCompositionEvent->mFlags.mPropagationStopped),
|
||||
GetBoolName(aIsSynthesized)));
|
||||
|
||||
MOZ_ASSERT(aEvent->mClass == eCompositionEventClass);
|
||||
if (!aEvent->mFlags.mIsTrusted || aEvent->mFlags.mPropagationStopped) {
|
||||
if (!aCompositionEvent->mFlags.mIsTrusted ||
|
||||
aCompositionEvent->mFlags.mPropagationStopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aEvent->message != NS_COMPOSITION_UPDATE,
|
||||
MOZ_ASSERT(aCompositionEvent->message != NS_COMPOSITION_UPDATE,
|
||||
"compositionupdate event shouldn't be dispatched manually");
|
||||
|
||||
EnsureTextCompositionArray();
|
||||
|
||||
WidgetGUIEvent* GUIEvent = aEvent->AsGUIEvent();
|
||||
|
||||
nsRefPtr<TextComposition> composition =
|
||||
sTextCompositions->GetCompositionFor(GUIEvent->widget);
|
||||
sTextCompositions->GetCompositionFor(aCompositionEvent->widget);
|
||||
if (!composition) {
|
||||
// If synthesized event comes after delayed native composition events
|
||||
// for request of commit or cancel, we should ignore it.
|
||||
@ -911,18 +910,20 @@ IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode,
|
||||
PR_LOG(sISMLog, PR_LOG_DEBUG,
|
||||
("ISM: IMEStateManager::DispatchCompositionEvent(), "
|
||||
"adding new TextComposition to the array"));
|
||||
MOZ_ASSERT(GUIEvent->message == NS_COMPOSITION_START);
|
||||
composition = new TextComposition(aPresContext, aEventTargetNode, GUIEvent);
|
||||
MOZ_ASSERT(aCompositionEvent->message == NS_COMPOSITION_START);
|
||||
composition =
|
||||
new TextComposition(aPresContext, aEventTargetNode, aCompositionEvent);
|
||||
sTextCompositions->AppendElement(composition);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
MOZ_ASSERT(GUIEvent->message != NS_COMPOSITION_START);
|
||||
MOZ_ASSERT(aCompositionEvent->message != NS_COMPOSITION_START);
|
||||
}
|
||||
#endif // #ifdef DEBUG
|
||||
|
||||
// Dispatch the event on composing target.
|
||||
composition->DispatchEvent(GUIEvent, aStatus, aCallBack, aIsSynthesized);
|
||||
composition->DispatchCompositionEvent(aCompositionEvent, aStatus, aCallBack,
|
||||
aIsSynthesized);
|
||||
|
||||
// WARNING: the |composition| might have been destroyed already.
|
||||
|
||||
@ -938,9 +939,9 @@ IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode,
|
||||
// destroy the TextComposition with synthesized compositionend event.
|
||||
if ((!aIsSynthesized ||
|
||||
composition->WasNativeCompositionEndEventDiscarded()) &&
|
||||
aEvent->message == NS_COMPOSITION_END) {
|
||||
aCompositionEvent->message == NS_COMPOSITION_END) {
|
||||
TextCompositionArray::index_type i =
|
||||
sTextCompositions->IndexOf(GUIEvent->widget);
|
||||
sTextCompositions->IndexOf(aCompositionEvent->widget);
|
||||
if (i != TextCompositionArray::NoIndex) {
|
||||
PR_LOG(sISMLog, PR_LOG_DEBUG,
|
||||
("ISM: IMEStateManager::DispatchCompositionEvent(), "
|
||||
@ -954,32 +955,31 @@ IMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode,
|
||||
|
||||
// static
|
||||
void
|
||||
IMEStateManager::OnCompositionEventDiscarded(WidgetEvent* aEvent)
|
||||
IMEStateManager::OnCompositionEventDiscarded(
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
{
|
||||
// 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={ "
|
||||
("ISM: IMEStateManager::OnCompositionEventDiscarded(aCompositionEvent={ "
|
||||
"message=%s, mFlags={ mIsTrusted=%s } })",
|
||||
GetEventMessageName(aEvent->message),
|
||||
GetBoolName(aEvent->mFlags.mIsTrusted)));
|
||||
GetEventMessageName(aCompositionEvent->message),
|
||||
GetBoolName(aCompositionEvent->mFlags.mIsTrusted)));
|
||||
|
||||
MOZ_ASSERT(aEvent->mClass == eCompositionEventClass);
|
||||
if (!aEvent->mFlags.mIsTrusted) {
|
||||
if (!aCompositionEvent->mFlags.mIsTrusted) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore compositionstart for now because sTextCompositions may not have
|
||||
// been created yet.
|
||||
if (aEvent->message == NS_COMPOSITION_START) {
|
||||
if (aCompositionEvent->message == NS_COMPOSITION_START) {
|
||||
return;
|
||||
}
|
||||
|
||||
WidgetGUIEvent* GUIEvent = aEvent->AsGUIEvent();
|
||||
nsRefPtr<TextComposition> composition =
|
||||
sTextCompositions->GetCompositionFor(GUIEvent->widget);
|
||||
composition->OnCompositionEventDiscarded(GUIEvent);
|
||||
sTextCompositions->GetCompositionFor(aCompositionEvent->widget);
|
||||
composition->OnCompositionEventDiscarded(aCompositionEvent);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -1214,11 +1214,11 @@ IMEStateManager::GetTextCompositionFor(nsIWidget* aWidget)
|
||||
|
||||
// static
|
||||
already_AddRefed<TextComposition>
|
||||
IMEStateManager::GetTextCompositionFor(WidgetGUIEvent* aEvent)
|
||||
IMEStateManager::GetTextCompositionFor(WidgetGUIEvent* aGUIEvent)
|
||||
{
|
||||
MOZ_ASSERT(aEvent->AsCompositionEvent() || aEvent->AsKeyboardEvent(),
|
||||
"aEvent has to be WidgetCompositionEvent or WidgetKeyboardEvent");
|
||||
return GetTextCompositionFor(aEvent->widget);
|
||||
MOZ_ASSERT(aGUIEvent->AsCompositionEvent() || aGUIEvent->AsKeyboardEvent(),
|
||||
"aGUIEvent has to be WidgetCompositionEvent or WidgetKeyboardEvent");
|
||||
return GetTextCompositionFor(aGUIEvent->widget);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -97,9 +97,10 @@ public:
|
||||
* events must be fired the stored target. If the stored composition event
|
||||
* target is destroying, this removes the stored composition automatically.
|
||||
*/
|
||||
static void DispatchCompositionEvent(nsINode* aEventTargetNode,
|
||||
static void DispatchCompositionEvent(
|
||||
nsINode* aEventTargetNode,
|
||||
nsPresContext* aPresContext,
|
||||
WidgetEvent* aEvent,
|
||||
WidgetCompositionEvent* aCompositionEvent,
|
||||
nsEventStatus* aStatus,
|
||||
EventDispatchingCallback* aCallBack,
|
||||
bool aIsSynthesized = false);
|
||||
@ -108,7 +109,8 @@ public:
|
||||
* This is called when PresShell ignores a composition event due to not safe
|
||||
* to dispatch events.
|
||||
*/
|
||||
static void OnCompositionEventDiscarded(WidgetEvent* aEvent);
|
||||
static void OnCompositionEventDiscarded(
|
||||
const WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
/**
|
||||
* Get TextComposition from widget.
|
||||
@ -119,10 +121,10 @@ public:
|
||||
/**
|
||||
* Returns TextComposition instance for the event.
|
||||
*
|
||||
* @param aEvent Should be a composition event which is being dispatched.
|
||||
* @param aGUIEvent Should be a composition event which is being dispatched.
|
||||
*/
|
||||
static already_AddRefed<TextComposition>
|
||||
GetTextCompositionFor(WidgetGUIEvent* aEvent);
|
||||
GetTextCompositionFor(WidgetGUIEvent* aGUIEvent);
|
||||
|
||||
/**
|
||||
* Send a notification to IME. It depends on the IME or platform spec what
|
||||
|
@ -29,13 +29,14 @@ namespace mozilla {
|
||||
|
||||
TextComposition::TextComposition(nsPresContext* aPresContext,
|
||||
nsINode* aNode,
|
||||
WidgetGUIEvent* aEvent)
|
||||
WidgetCompositionEvent* aCompositionEvent)
|
||||
: mPresContext(aPresContext)
|
||||
, mNode(aNode)
|
||||
, mNativeContext(aEvent->widget->GetInputContext().mNativeIMEContext)
|
||||
, mNativeContext(
|
||||
aCompositionEvent->widget->GetInputContext().mNativeIMEContext)
|
||||
, mCompositionStartOffset(0)
|
||||
, mCompositionTargetOffset(0)
|
||||
, mIsSynthesizedForTests(aEvent->mFlags.mIsSynthesizedForTests)
|
||||
, mIsSynthesizedForTests(aCompositionEvent->mFlags.mIsSynthesizedForTests)
|
||||
, mIsComposing(false)
|
||||
, mIsEditorHandlingEvent(false)
|
||||
, mIsRequestingCommit(false)
|
||||
@ -62,24 +63,24 @@ TextComposition::MatchesNativeContext(nsIWidget* aWidget) const
|
||||
|
||||
bool
|
||||
TextComposition::MaybeDispatchCompositionUpdate(
|
||||
const WidgetCompositionEvent* aEvent)
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
{
|
||||
if (Destroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mLastData == aEvent->mData) {
|
||||
if (mLastData == aCompositionEvent->mData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
WidgetCompositionEvent compositionUpdate(aEvent->mFlags.mIsTrusted,
|
||||
WidgetCompositionEvent compositionUpdate(aCompositionEvent->mFlags.mIsTrusted,
|
||||
NS_COMPOSITION_UPDATE,
|
||||
aEvent->widget);
|
||||
compositionUpdate.time = aEvent->time;
|
||||
compositionUpdate.timeStamp = aEvent->timeStamp;
|
||||
compositionUpdate.mData = aEvent->mData;
|
||||
aCompositionEvent->widget);
|
||||
compositionUpdate.time = aCompositionEvent->time;
|
||||
compositionUpdate.timeStamp = aCompositionEvent->timeStamp;
|
||||
compositionUpdate.mData = aCompositionEvent->mData;
|
||||
compositionUpdate.mFlags.mIsSynthesizedForTests =
|
||||
aEvent->mFlags.mIsSynthesizedForTests;
|
||||
aCompositionEvent->mFlags.mIsSynthesizedForTests;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eConsumeNoDefault;
|
||||
mLastData = compositionUpdate.mData;
|
||||
@ -89,20 +90,20 @@ TextComposition::MaybeDispatchCompositionUpdate(
|
||||
}
|
||||
|
||||
void
|
||||
TextComposition::OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent)
|
||||
TextComposition::OnCompositionEventDiscarded(
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
{
|
||||
// Note that this method is never called for synthesized events for emulating
|
||||
// commit or cancel composition.
|
||||
|
||||
MOZ_ASSERT(aEvent->mFlags.mIsTrusted,
|
||||
MOZ_ASSERT(aCompositionEvent->mFlags.mIsTrusted,
|
||||
"Shouldn't be called with untrusted event");
|
||||
MOZ_ASSERT(aEvent->mClass == eCompositionEventClass);
|
||||
|
||||
// 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) {
|
||||
if (aCompositionEvent->message != NS_COMPOSITION_END) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -110,7 +111,8 @@ TextComposition::OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent)
|
||||
}
|
||||
|
||||
void
|
||||
TextComposition::DispatchEvent(WidgetGUIEvent* aEvent,
|
||||
TextComposition::DispatchCompositionEvent(
|
||||
WidgetCompositionEvent* aCompositionEvent,
|
||||
nsEventStatus* aStatus,
|
||||
EventDispatchingCallback* aCallBack,
|
||||
bool aIsSynthesized)
|
||||
@ -144,10 +146,10 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent,
|
||||
// 2. non-empty string is committed at requesting cancel.
|
||||
if (!aIsSynthesized && (mIsRequestingCommit || mIsRequestingCancel)) {
|
||||
nsString* committingData = nullptr;
|
||||
switch (aEvent->message) {
|
||||
switch (aCompositionEvent->message) {
|
||||
case NS_COMPOSITION_END:
|
||||
case NS_COMPOSITION_CHANGE:
|
||||
committingData = &aEvent->AsCompositionEvent()->mData;
|
||||
committingData = &aCompositionEvent->mData;
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Unexpected event comes during committing or "
|
||||
@ -164,14 +166,14 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent,
|
||||
}
|
||||
}
|
||||
|
||||
if (aEvent->message == NS_COMPOSITION_CHANGE) {
|
||||
if (!MaybeDispatchCompositionUpdate(aEvent->AsCompositionEvent())) {
|
||||
if (aCompositionEvent->message == NS_COMPOSITION_CHANGE) {
|
||||
if (!MaybeDispatchCompositionUpdate(aCompositionEvent)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EventDispatcher::Dispatch(mNode, mPresContext,
|
||||
aEvent, nullptr, aStatus, aCallBack);
|
||||
aCompositionEvent, nullptr, aStatus, aCallBack);
|
||||
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return;
|
||||
@ -179,31 +181,32 @@ TextComposition::DispatchEvent(WidgetGUIEvent* aEvent,
|
||||
|
||||
// Emulate editor behavior of compositionchange event (DOM text event) handler
|
||||
// if no editor handles composition events.
|
||||
if (aEvent->message == NS_COMPOSITION_CHANGE && !HasEditor()) {
|
||||
EditorWillHandleCompositionChangeEvent(aEvent->AsCompositionEvent());
|
||||
if (aCompositionEvent->message == NS_COMPOSITION_CHANGE && !HasEditor()) {
|
||||
EditorWillHandleCompositionChangeEvent(aCompositionEvent);
|
||||
EditorDidHandleCompositionChangeEvent();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
else if (aEvent->message == NS_COMPOSITION_END) {
|
||||
else if (aCompositionEvent->message == NS_COMPOSITION_END) {
|
||||
MOZ_ASSERT(!mIsComposing, "Why is the editor still composing?");
|
||||
MOZ_ASSERT(!HasEditor(), "Why does the editor still keep to hold this?");
|
||||
}
|
||||
#endif // #ifdef DEBUG
|
||||
|
||||
// Notify composition update to widget if possible
|
||||
NotityUpdateComposition(aEvent);
|
||||
NotityUpdateComposition(aCompositionEvent);
|
||||
}
|
||||
|
||||
void
|
||||
TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent)
|
||||
TextComposition::NotityUpdateComposition(
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
{
|
||||
nsEventStatus status;
|
||||
|
||||
// When compositon start, notify the rect of first offset character.
|
||||
// When not compositon start, notify the rect of selected composition
|
||||
// string if compositionchange event.
|
||||
if (aEvent->message == NS_COMPOSITION_START) {
|
||||
if (aCompositionEvent->message == NS_COMPOSITION_START) {
|
||||
nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget();
|
||||
// Update composition start offset
|
||||
WidgetQueryContentEvent selectedTextEvent(true,
|
||||
@ -218,10 +221,9 @@ TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent)
|
||||
mCompositionStartOffset = 0;
|
||||
}
|
||||
mCompositionTargetOffset = mCompositionStartOffset;
|
||||
} else if (aEvent->message == NS_COMPOSITION_CHANGE) {
|
||||
} else if (aCompositionEvent->message == NS_COMPOSITION_CHANGE) {
|
||||
mCompositionTargetOffset =
|
||||
mCompositionStartOffset +
|
||||
aEvent->AsCompositionEvent()->TargetClauseOffset();
|
||||
mCompositionStartOffset + aCompositionEvent->TargetClauseOffset();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ class TextComposition MOZ_FINAL
|
||||
public:
|
||||
TextComposition(nsPresContext* aPresContext,
|
||||
nsINode* aNode,
|
||||
WidgetGUIEvent* aEvent);
|
||||
WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
bool Destroyed() const { return !mPresContext; }
|
||||
nsPresContext* GetPresContext() const { return mPresContext; }
|
||||
@ -250,21 +250,22 @@ private:
|
||||
void EditorDidHandleCompositionChangeEvent();
|
||||
|
||||
/**
|
||||
* DispatchEvent() dispatches the aEvent to the mContent synchronously.
|
||||
* The caller must ensure that it's safe to dispatch the event.
|
||||
* DispatchCompositionEvent() dispatches the aCompositionEvent to the mContent
|
||||
* synchronously. The caller must ensure that it's safe to dispatch the event.
|
||||
*/
|
||||
void DispatchEvent(WidgetGUIEvent* aEvent,
|
||||
void DispatchCompositionEvent(WidgetCompositionEvent* aCompositionEvent,
|
||||
nsEventStatus* aStatus,
|
||||
EventDispatchingCallback* aCallBack,
|
||||
bool aIsSynthesized);
|
||||
|
||||
/**
|
||||
* MaybeDispatchCompositionUpdate() may dispatch a compositionupdate event
|
||||
* if aEvent changes composition string.
|
||||
* if aCompositionEvent changes composition string.
|
||||
* @return Returns false if dispatching the compositionupdate event caused
|
||||
* destroying this composition.
|
||||
*/
|
||||
bool MaybeDispatchCompositionUpdate(const WidgetCompositionEvent* aEvent);
|
||||
bool MaybeDispatchCompositionUpdate(
|
||||
const WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
/**
|
||||
* If IME has already dispatched compositionend event but it was discarded
|
||||
@ -280,12 +281,13 @@ private:
|
||||
* compositionupdate, compositionend or compositionchange event due to not
|
||||
* safe to dispatch event.
|
||||
*/
|
||||
void OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent);
|
||||
void OnCompositionEventDiscarded(
|
||||
const WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
/**
|
||||
* Calculate composition offset then notify composition update to widget
|
||||
*/
|
||||
void NotityUpdateComposition(WidgetGUIEvent* aEvent);
|
||||
void NotityUpdateComposition(const WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
/**
|
||||
* CompositionEventDispatcher dispatches the specified composition (or text)
|
||||
|
@ -6943,7 +6943,8 @@ PresShell::HandleEvent(nsIFrame* aFrame,
|
||||
if (!nsContentUtils::IsSafeToRunScript() &&
|
||||
aEvent->IsAllowedToDispatchDOMEvent()) {
|
||||
if (aEvent->mClass == eCompositionEventClass) {
|
||||
IMEStateManager::OnCompositionEventDiscarded(aEvent);
|
||||
IMEStateManager::OnCompositionEventDiscarded(
|
||||
aEvent->AsCompositionEvent());
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (aEvent->IsIMERelatedEvent()) {
|
||||
@ -7860,7 +7861,8 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, nsEventStatus* aStatus)
|
||||
if (eventTarget) {
|
||||
if (aEvent->mClass == eCompositionEventClass) {
|
||||
IMEStateManager::DispatchCompositionEvent(eventTarget,
|
||||
mPresContext, aEvent, aStatus, eventCBPtr);
|
||||
mPresContext, aEvent->AsCompositionEvent(), aStatus,
|
||||
eventCBPtr);
|
||||
} else {
|
||||
EventDispatcher::Dispatch(eventTarget, mPresContext,
|
||||
aEvent, nullptr, aStatus, eventCBPtr);
|
||||
|
Loading…
Reference in New Issue
Block a user