Bug 591047 - (7/7) Suppressing possible out-of-sync notifications; r=roc a=blocking-fennec

This commit is contained in:
Brad Lassey 2010-09-23 23:34:26 -04:00
parent 57e03bda68
commit e113ed383c
4 changed files with 45 additions and 0 deletions

View File

@ -89,6 +89,7 @@ NS_IMPL_ISUPPORTS4(TabParent, nsITabParent, nsIAuthPromptProvider, nsISSLStatusP
TabParent::TabParent()
: mSecurityState(0)
, mIMECompositionEnding(PR_FALSE)
, mIMEComposing(PR_FALSE)
{
}
@ -442,6 +443,16 @@ TabParent::HandleQueryContentEvent(nsQueryContentEvent& aEvent)
return true;
}
bool
TabParent::SendCompositionEvent(const nsCompositionEvent& event)
{
mIMEComposing = event.message == NS_COMPOSITION_START;
mIMECompositionStart = PR_MIN(mIMESelectionAnchor, mIMESelectionFocus);
if (mIMECompositionEnding)
return true;
return PBrowserParent::SendCompositionEvent(event);
}
/**
* During ResetInputState or CancelComposition, widget usually sends a
* NS_TEXT_TEXT event to finalize or clear the composition, respectively
@ -456,9 +467,26 @@ TabParent::SendTextEvent(const nsTextEvent& event)
mIMECompositionText = event.theText;
return true;
}
// We must be able to simulate the selection because
// we might not receive selection updates in time
if (!mIMEComposing) {
mIMECompositionStart = PR_MIN(mIMESelectionAnchor, mIMESelectionFocus);
}
mIMESelectionAnchor = mIMESelectionFocus =
mIMECompositionStart + event.theText.Length();
return PBrowserParent::SendTextEvent(event);
}
bool
TabParent::SendSelectionEvent(const nsSelectionEvent& event)
{
mIMESelectionAnchor = event.mOffset + (event.mReversed ? event.mLength : 0);
mIMESelectionFocus = event.mOffset + (!event.mReversed ? event.mLength : 0);
return PBrowserParent::SendSelectionEvent(event);
}
bool
TabParent::RecvEndIMEComposition(const PRBool& aCancel,
nsString* aComposition)

View File

@ -179,7 +179,9 @@ public:
static TabParent *GetIMETabParent() { return mIMETabParent; }
bool HandleQueryContentEvent(nsQueryContentEvent& aEvent);
bool SendCompositionEvent(const nsCompositionEvent& event);
bool SendTextEvent(const nsTextEvent& event);
bool SendSelectionEvent(const nsSelectionEvent& event);
protected:
bool ReceiveMessage(const nsString& aMessage,
PRBool aSync,
@ -224,10 +226,12 @@ protected:
nsString mIMECacheText;
PRUint32 mIMESelectionAnchor;
PRUint32 mIMESelectionFocus;
PRPackedBool mIMEComposing;
PRPackedBool mIMECompositionEnding;
// Buffer to store composition text during ResetInputState
// Compositions in almost all cases are small enough for nsAutoString
nsAutoString mIMECompositionText;
PRUint32 mIMECompositionStart;
private:
already_AddRefed<nsFrameLoader> GetFrameLoader() const;

View File

@ -111,6 +111,7 @@ PuppetWidget::Create(nsIWidget *aParent,
gfxASurface::ContentFromFormat(gfxASurface::ImageFormatARGB32));
mIMEComposing = PR_FALSE;
mIMESuppressNotifySel = PR_FALSE;
PuppetWidget* parent = static_cast<PuppetWidget*>(aParent);
if (parent) {
@ -276,11 +277,15 @@ PuppetWidget::DispatchEvent(nsGUIEvent* event, nsEventStatus& aStatus)
if (mEventCallback) {
if (event->message == NS_COMPOSITION_START) {
mIMEComposing = PR_TRUE;
} else if (event->message == NS_SELECTION_SET) {
mIMESuppressNotifySel = PR_TRUE;
}
aStatus = (*mEventCallback)(event);
if (event->message == NS_COMPOSITION_END) {
mIMEComposing = PR_FALSE;
} else if (event->message == NS_SELECTION_SET) {
mIMESuppressNotifySel = PR_FALSE;
}
} else if (mChild) {
event->widget = mChild;
@ -439,6 +444,13 @@ PuppetWidget::OnIMESelectionChange(void)
if (!mTabChild)
return NS_ERROR_FAILURE;
// When we send selection notifications during a composition or during a
// set selection event, there is a race condition where the notification
// arrives at chrome too late, which leads to chrome thinking the
// selection was elsewhere. Suppress notifications here to avoid that.
if (mIMEComposing || mIMESuppressNotifySel)
return NS_OK;
if (mIMEPreference.mWantUpdates) {
nsEventStatus status;
nsQueryContentEvent queryEvent(PR_TRUE, NS_QUERY_SELECTED_TEXT, this);

View File

@ -216,6 +216,7 @@ private:
// IME
nsIMEUpdatePreference mIMEPreference;
PRPackedBool mIMEComposing;
PRPackedBool mIMESuppressNotifySel;
};
} // namespace widget