Bug 1176955 part.2 NOTIFY_IME_OF_SELECTION should have a flag which indicates if it's caused by a selection event r=smaug

This commit is contained in:
Masayuki Nakano 2015-07-17 11:25:00 +09:00
parent b5b9eace4d
commit b2a38bd156
10 changed files with 78 additions and 15 deletions

View File

@ -95,6 +95,7 @@ IMEContentObserver::IMEContentObserver()
, mIsFocusEventPending(false)
, mIsSelectionChangeEventPending(false)
, mSelectionChangeCausedOnlyByComposition(false)
, mSelectionChangeCausedOnlyBySelectionEvent(false)
, mIsPositionChangeEventPending(false)
, mIsFlushingPendingNotifications(false)
{
@ -418,7 +419,9 @@ IMEContentObserver::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
nsresult rv = aSelection->GetRangeCount(&count);
NS_ENSURE_SUCCESS(rv, rv);
if (count > 0 && mWidget) {
MaybeNotifyIMEOfSelectionChange(causedByComposition);
bool causedBySelectionEvent = TextComposition::IsHandlingSelectionEvent();
MaybeNotifyIMEOfSelectionChange(causedByComposition,
causedBySelectionEvent);
}
return NS_OK;
}
@ -828,7 +831,9 @@ IMEContentObserver::PostTextChangeNotification(
}
void
IMEContentObserver::PostSelectionChangeNotification(bool aCausedByComposition)
IMEContentObserver::PostSelectionChangeNotification(
bool aCausedByComposition,
bool aCausedBySelectionEvent)
{
if (!mIsSelectionChangeEventPending) {
mSelectionChangeCausedOnlyByComposition = aCausedByComposition;
@ -836,6 +841,12 @@ IMEContentObserver::PostSelectionChangeNotification(bool aCausedByComposition)
mSelectionChangeCausedOnlyByComposition =
mSelectionChangeCausedOnlyByComposition && aCausedByComposition;
}
if (!mSelectionChangeCausedOnlyBySelectionEvent) {
mSelectionChangeCausedOnlyBySelectionEvent = aCausedBySelectionEvent;
} else {
mSelectionChangeCausedOnlyBySelectionEvent =
mSelectionChangeCausedOnlyBySelectionEvent && aCausedBySelectionEvent;
}
mIsSelectionChangeEventPending = true;
}
@ -939,7 +950,8 @@ IMEContentObserver::FlushMergeableNotifications()
if (mIsSelectionChangeEventPending) {
mIsSelectionChangeEventPending = false;
nsContentUtils::AddScriptRunner(
new SelectionChangeEvent(this, mSelectionChangeCausedOnlyByComposition));
new SelectionChangeEvent(this, mSelectionChangeCausedOnlyByComposition,
mSelectionChangeCausedOnlyBySelectionEvent));
}
if (mIsPositionChangeEventPending) {
@ -1041,7 +1053,8 @@ IMEContentObserver::SelectionChangeEvent::Run()
}
if (!IsSafeToNotifyIME()) {
mIMEContentObserver->PostSelectionChangeNotification(mCausedByComposition);
mIMEContentObserver->PostSelectionChangeNotification(
mCausedByComposition, mCausedBySelectionEvent);
return NS_OK;
}
@ -1070,6 +1083,8 @@ IMEContentObserver::SelectionChangeEvent::Run()
notification.mSelectionChangeData.mReversed = selection.mReply.mReversed;
notification.mSelectionChangeData.mCausedByComposition =
mCausedByComposition;
notification.mSelectionChangeData.mCausedBySelectionEvent =
mCausedBySelectionEvent;
IMEStateManager::NotifyIME(notification, mIMEContentObserver->mWidget);
return NS_OK;
}

View File

@ -132,10 +132,13 @@ private:
PostTextChangeNotification(aTextChangeData);
FlushMergeableNotifications();
}
void PostSelectionChangeNotification(bool aCausedByComposition);
void MaybeNotifyIMEOfSelectionChange(bool aCausedByComposition)
void PostSelectionChangeNotification(bool aCausedByComposition,
bool aCausedBySelectionEvent);
void MaybeNotifyIMEOfSelectionChange(bool aCausedByComposition,
bool aCausedBySelectionEvent)
{
PostSelectionChangeNotification(aCausedByComposition);
PostSelectionChangeNotification(aCausedByComposition,
aCausedBySelectionEvent);
FlushMergeableNotifications();
}
void PostPositionChangeNotification();
@ -239,6 +242,7 @@ private:
bool mIsFocusEventPending;
bool mIsSelectionChangeEventPending;
bool mSelectionChangeCausedOnlyByComposition;
bool mSelectionChangeCausedOnlyBySelectionEvent;
bool mIsPositionChangeEventPending;
bool mIsFlushingPendingNotifications;
@ -295,15 +299,20 @@ private:
{
public:
SelectionChangeEvent(IMEContentObserver* aIMEContentObserver,
bool aCausedByComposition)
bool aCausedByComposition,
bool aCausedBySelectionEvent)
: AChangeEvent(eChangeEventType_Selection, aIMEContentObserver)
, mCausedByComposition(aCausedByComposition)
, mCausedBySelectionEvent(aCausedBySelectionEvent)
{
aIMEContentObserver->mSelectionChangeCausedOnlyByComposition = false;
aIMEContentObserver->mSelectionChangeCausedOnlyBySelectionEvent = false;
}
NS_IMETHOD Run() override;
private:
bool mCausedByComposition;
bool mCausedBySelectionEvent;
};
class TextChangeEvent : public AChangeEvent

View File

@ -30,6 +30,8 @@ namespace mozilla {
* TextComposition
******************************************************************************/
bool TextComposition::sHandlingSelectionEvent = false;
TextComposition::TextComposition(nsPresContext* aPresContext,
nsINode* aNode,
TabParent* aTabParent,
@ -389,6 +391,12 @@ TextComposition::HandleSelectionEvent(nsPresContext* aPresContext,
}
ContentEventHandler handler(aPresContext);
AutoRestore<bool> saveHandlingSelectionEvent(sHandlingSelectionEvent);
sHandlingSelectionEvent = true;
// XXX During setting selection, a selection listener may change selection
// again. In such case, sHandlingSelectionEvent doesn't indicate if
// the selection change is caused by a selection event. However, it
// must be non-realistic scenario.
handler.OnSelectionEvent(aSelectionEvent);
}

View File

@ -41,6 +41,8 @@ class TextComposition final
public:
typedef dom::TabParent TabParent;
static bool IsHandlingSelectionEvent() { return sHandlingSelectionEvent; }
TextComposition(nsPresContext* aPresContext,
nsINode* aNode,
TabParent* aTabParent,
@ -171,6 +173,10 @@ private:
// WARNING: mPresContext may be destroying, so, be careful if you touch it.
}
// sHandlingSelectionEvent is true while TextComposition sends a selection
// event to ContentEventHandler.
static bool sHandlingSelectionEvent;
// This class holds nsPresContext weak. This instance shouldn't block
// destroying it. When the presContext is being destroyed, it's notified to
// IMEStateManager::OnDestroyPresContext(), and then, it destroy

View File

@ -222,9 +222,11 @@ parent:
*
* contentCache Cache of content
* causedByComposition true if the change is caused by composition
* causedBySelectionEvent true if the change is caused by selection event
*/
prio(urgent) async NotifyIMESelection(ContentCache contentCache,
bool causedByComposition);
bool causedByComposition,
bool causedBySelectionEvent);
/**
* Notifies chrome of updating its content cache.

View File

@ -2021,7 +2021,8 @@ TabParent::RecvNotifyIMESelectedCompositionRect(
bool
TabParent::RecvNotifyIMESelection(const ContentCache& aContentCache,
const bool& aCausedByComposition)
const bool& aCausedByComposition,
const bool& aCausedBySelectionEvent)
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
@ -2037,6 +2038,8 @@ TabParent::RecvNotifyIMESelection(const ContentCache& aContentCache,
!aCausedByComposition)) {
notification.mSelectionChangeData.mCausedByComposition =
aCausedByComposition;
notification.mSelectionChangeData.mCausedBySelectionEvent =
aCausedBySelectionEvent;
mContentCache.MaybeNotifyIME(widget, notification);
}
return true;

View File

@ -173,7 +173,8 @@ public:
const bool& aCausedByComposition) override;
virtual bool RecvNotifyIMESelectedCompositionRect(const ContentCache& aContentCache) override;
virtual bool RecvNotifyIMESelection(const ContentCache& aContentCache,
const bool& aCausedByComposition) override;
const bool& aCausedByComposition,
const bool& aCausedBySelectionEvent) override;
virtual bool RecvUpdateContentCache(const ContentCache& aContentCache) override;
virtual bool RecvNotifyIMEMouseButtonEvent(const widget::IMENotification& aEventMessage,
bool* aConsumedByIME) override;

View File

@ -795,7 +795,8 @@ PuppetWidget::NotifyIMEOfSelectionChange(
aIMENotification.mSelectionChangeData.GetWritingMode());
mTabChild->SendNotifyIMESelection(
mContentCache, aIMENotification.mSelectionChangeData.mCausedByComposition);
mContentCache, aIMENotification.mSelectionChangeData.mCausedByComposition,
aIMENotification.mSelectionChangeData.mCausedBySelectionEvent);
return NS_OK;
}

View File

@ -676,6 +676,7 @@ struct ParamTraits<mozilla::widget::IMENotification>
WriteParam(aMsg, aParam.mSelectionChangeData.mWritingMode);
WriteParam(aMsg, aParam.mSelectionChangeData.mReversed);
WriteParam(aMsg, aParam.mSelectionChangeData.mCausedByComposition);
WriteParam(aMsg, aParam.mSelectionChangeData.mCausedBySelectionEvent);
return;
case mozilla::widget::NOTIFY_IME_OF_TEXT_CHANGE:
WriteParam(aMsg, aParam.mTextChangeData.mStartOffset);
@ -719,7 +720,9 @@ struct ParamTraits<mozilla::widget::IMENotification>
ReadParam(aMsg, aIter,
&aResult->mSelectionChangeData.mReversed) &&
ReadParam(aMsg, aIter,
&aResult->mSelectionChangeData.mCausedByComposition);
&aResult->mSelectionChangeData.mCausedByComposition) &&
ReadParam(aMsg, aIter,
&aResult->mSelectionChangeData.mCausedBySelectionEvent);
case mozilla::widget::NOTIFY_IME_OF_TEXT_CHANGE:
return ReadParam(aMsg, aIter,
&aResult->mTextChangeData.mStartOffset) &&

View File

@ -615,6 +615,7 @@ struct IMENotification
mSelectionChangeData.mWritingMode = 0;
mSelectionChangeData.mReversed = false;
mSelectionChangeData.mCausedByComposition = false;
mSelectionChangeData.mCausedBySelectionEvent = false;
break;
case NOTIFY_IME_OF_TEXT_CHANGE:
mTextChangeData.Clear();
@ -659,9 +660,22 @@ struct IMENotification
aNotification.mSelectionChangeData.mWritingMode;
mSelectionChangeData.mReversed =
aNotification.mSelectionChangeData.mReversed;
mSelectionChangeData.mCausedByComposition =
mSelectionChangeData.mCausedByComposition &&
if (!mSelectionChangeData.mCausedByComposition) {
mSelectionChangeData.mCausedByComposition =
aNotification.mSelectionChangeData.mCausedByComposition;
} else {
mSelectionChangeData.mCausedByComposition =
mSelectionChangeData.mCausedByComposition &&
aNotification.mSelectionChangeData.mCausedByComposition;
}
if (!mSelectionChangeData.mCausedBySelectionEvent) {
mSelectionChangeData.mCausedBySelectionEvent =
aNotification.mSelectionChangeData.mCausedBySelectionEvent;
} else {
mSelectionChangeData.mCausedBySelectionEvent =
mSelectionChangeData.mCausedBySelectionEvent &&
aNotification.mSelectionChangeData.mCausedBySelectionEvent;
}
break;
case NOTIFY_IME_OF_TEXT_CHANGE:
MOZ_ASSERT(aNotification.mMessage == NOTIFY_IME_OF_TEXT_CHANGE);
@ -690,6 +704,7 @@ struct IMENotification
bool mReversed;
bool mCausedByComposition;
bool mCausedBySelectionEvent;
void SetWritingMode(const WritingMode& aWritingMode);
WritingMode GetWritingMode() const;