зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1083067 part.1 Create nsGtkIMModule::DispatchCompositionEventsForCommit() r=m_kato
This commit is contained in:
Родитель
024559acd7
Коммит
1c506a8eb6
|
@ -751,7 +751,7 @@ nsGtkIMModule::OnEndCompositionNative(GtkIMContext *aContext)
|
|||
}
|
||||
|
||||
// Be aware, widget can be gone
|
||||
DispatchCompositionEnd();
|
||||
DispatchCompositionEventsForCommit(mDispatchedCompositionString);
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -933,12 +933,8 @@ nsGtkIMModule::CommitCompositionBy(const nsAString& aString)
|
|||
this, NS_ConvertUTF16toUTF8(aString).get(),
|
||||
NS_ConvertUTF16toUTF8(mDispatchedCompositionString).get()));
|
||||
|
||||
if (!DispatchCompositionChangeEvent(aString, true)) {
|
||||
return false;
|
||||
}
|
||||
// We should dispatch the compositionend event here because some IMEs
|
||||
// might not fire "preedit_end" native event.
|
||||
return DispatchCompositionEnd(); // Be aware, widget can be gone
|
||||
// Be aware, widget can be gone
|
||||
return DispatchCompositionEventsForCommit(aString);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1037,48 +1033,6 @@ nsGtkIMModule::DispatchCompositionStart()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsGtkIMModule::DispatchCompositionEnd()
|
||||
{
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
("GtkIMModule(%p): DispatchCompositionEnd, "
|
||||
"mDispatchedCompositionString=\"%s\"",
|
||||
this, NS_ConvertUTF16toUTF8(mDispatchedCompositionString).get()));
|
||||
|
||||
if (!IsComposing()) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" WARNING, we have alrady finished the composition"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mLastFocusedWindow) {
|
||||
mDispatchedCompositionString.Truncate();
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" FAILED, there are no focused window in this module"));
|
||||
return false;
|
||||
}
|
||||
|
||||
WidgetCompositionEvent compEvent(true, NS_COMPOSITION_END,
|
||||
mLastFocusedWindow);
|
||||
InitEvent(compEvent);
|
||||
compEvent.mData = mDispatchedCompositionString;
|
||||
nsEventStatus status;
|
||||
nsCOMPtr<nsIWidget> kungFuDeathGrip = mLastFocusedWindow;
|
||||
mLastFocusedWindow->DispatchEvent(&compEvent, status);
|
||||
mCompositionState = eCompositionState_NotComposing;
|
||||
mCompositionStart = UINT32_MAX;
|
||||
mCompositionTargetOffset = UINT32_MAX;
|
||||
mDispatchedCompositionString.Truncate();
|
||||
if (static_cast<nsWindow*>(kungFuDeathGrip.get())->IsDestroyed() ||
|
||||
kungFuDeathGrip != mLastFocusedWindow) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" NOTE, the focused widget was destroyed/changed by compositionend event"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsGtkIMModule::DispatchCompositionChangeEvent(
|
||||
const nsAString &aCompositionString,
|
||||
|
@ -1158,6 +1112,85 @@ nsGtkIMModule::DispatchCompositionChangeEvent(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsGtkIMModule::DispatchCompositionEventsForCommit(
|
||||
const nsAString& aCommitString)
|
||||
{
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
("GtkIMModule(%p): DispatchCompositionEventsForCommit, "
|
||||
"aCommitString=\"%s\"",
|
||||
this, NS_ConvertUTF16toUTF8(aCommitString).get()));
|
||||
|
||||
if (!mLastFocusedWindow) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" FAILED, there are no focused window in this module"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsComposing()) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" FAILED, there is no composition"));
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<nsWindow> lastFocusedWindow(mLastFocusedWindow);
|
||||
|
||||
// First, dispatch a compositionchange event for committing with
|
||||
// aCommitString.
|
||||
mCompositionState =
|
||||
eCompositionState_CommitCompositionChangeEventDispatched;
|
||||
|
||||
WidgetCompositionEvent compositionChangeEvent(true, NS_COMPOSITION_CHANGE,
|
||||
mLastFocusedWindow);
|
||||
InitEvent(compositionChangeEvent);
|
||||
compositionChangeEvent.mData = aCommitString;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
mLastFocusedWindow->DispatchEvent(&compositionChangeEvent, status);
|
||||
|
||||
if (!IsComposing()) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" FAILED, there is no composition during dispatching "
|
||||
"a compositionchange event for committing the composition"));
|
||||
if (lastFocusedWindow->IsDestroyed() ||
|
||||
lastFocusedWindow != mLastFocusedWindow) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" NOTE, the focused widget was destroyed/changed by "
|
||||
"compositionchange event"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Next, forget current composition before dispatching a composionend event.
|
||||
mCompositionState = eCompositionState_NotComposing;
|
||||
mCompositionStart = UINT32_MAX;
|
||||
mCompositionTargetOffset = UINT32_MAX;
|
||||
mDispatchedCompositionString.Truncate();
|
||||
|
||||
// Finally, dispatch a compositionend event if it's possible.
|
||||
if (!lastFocusedWindow->IsDestroyed() &&
|
||||
lastFocusedWindow == mLastFocusedWindow) {
|
||||
WidgetCompositionEvent compositionEndEvent(true, NS_COMPOSITION_END,
|
||||
mLastFocusedWindow);
|
||||
InitEvent(compositionEndEvent);
|
||||
compositionEndEvent.mData = aCommitString;
|
||||
|
||||
status = nsEventStatus_eIgnore;
|
||||
mLastFocusedWindow->DispatchEvent(&compositionEndEvent, status);
|
||||
}
|
||||
|
||||
if (lastFocusedWindow->IsDestroyed() ||
|
||||
lastFocusedWindow != mLastFocusedWindow) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" NOTE, the focused widget was destroyed/changed by "
|
||||
"compositionend event"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<TextRangeArray>
|
||||
nsGtkIMModule::CreateTextRangeArray()
|
||||
{
|
||||
|
@ -1461,13 +1494,7 @@ nsGtkIMModule::DeleteText(const int32_t aOffset, const uint32_t aNChars)
|
|||
bool editorHadCompositionString = EditorHasCompositionString();
|
||||
if (wasComposing) {
|
||||
selOffset = mCompositionStart;
|
||||
if (editorHadCompositionString &&
|
||||
!DispatchCompositionChangeEvent(mSelectedString, true)) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" FAILED, quitting from DeletText"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!DispatchCompositionEnd()) {
|
||||
if (!DispatchCompositionEventsForCommit(mSelectedString)) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" FAILED, quitting from DeletText"));
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
@ -305,16 +305,20 @@ protected:
|
|||
* FALSE, callers cannot continue the composition.
|
||||
* - CommitCompositionBy
|
||||
* - DispatchCompositionStart
|
||||
* - DispatchCompositionEnd
|
||||
* - DispatchCompositionChangeEvent
|
||||
* - DispatchCompositionEventsForCommit
|
||||
*/
|
||||
|
||||
// Commits the current composition by the aString.
|
||||
bool CommitCompositionBy(const nsAString& aString);
|
||||
|
||||
// Dispatches a composition start event or a composition end event.
|
||||
/**
|
||||
* Dispatches a composition start event.
|
||||
*
|
||||
* @return true if the focused widget is neither
|
||||
* destroyed nor changed. Otherwise, false.
|
||||
*/
|
||||
bool DispatchCompositionStart();
|
||||
bool DispatchCompositionEnd();
|
||||
|
||||
// Dispatches a compositionchange event. If aIsCommit is TRUE, dispatches
|
||||
// a committed compositionchange event. Otherwise, dispatches a composing
|
||||
|
@ -322,6 +326,16 @@ protected:
|
|||
bool DispatchCompositionChangeEvent(const nsAString& aCompositionString,
|
||||
bool aIsCommit);
|
||||
|
||||
/**
|
||||
* Dispatches a compositionchange event for committing the composition
|
||||
* string and a compositionend event.
|
||||
*
|
||||
* @param aCommitString The string which the composition is
|
||||
* committed with.
|
||||
* @return true if the focused widget is neither
|
||||
* destroyed nor changed. Otherwise, false.
|
||||
*/
|
||||
bool DispatchCompositionEventsForCommit(const nsAString& aCommitString);
|
||||
};
|
||||
|
||||
#endif // __nsGtkIMModule_h__
|
||||
|
|
Загрузка…
Ссылка в новой задаче