Bug 961704 part.2 Add an option to nsIMEUpdatePreference which prevents to be notified selection/text changes caused by composition r=smaug

This commit is contained in:
Masayuki Nakano 2014-02-26 09:48:02 +09:00
parent 814a2aa932
commit 9f4af3ce4f
11 changed files with 224 additions and 56 deletions

View File

@ -26,12 +26,15 @@ namespace mozilla {
TextComposition::TextComposition(nsPresContext* aPresContext,
nsINode* aNode,
WidgetGUIEvent* aEvent) :
mPresContext(aPresContext), mNode(aNode),
mNativeContext(aEvent->widget->GetInputContext().mNativeIMEContext),
mCompositionStartOffset(0), mCompositionTargetOffset(0),
mIsSynthesizedForTests(aEvent->mFlags.mIsSynthesizedForTests),
mIsComposing(false)
WidgetGUIEvent* aEvent)
: mPresContext(aPresContext)
, mNode(aNode)
, mNativeContext(aEvent->widget->GetInputContext().mNativeIMEContext)
, mCompositionStartOffset(0)
, mCompositionTargetOffset(0)
, mIsSynthesizedForTests(aEvent->mFlags.mIsSynthesizedForTests)
, mIsComposing(false)
, mIsEditorHandlingEvent(false)
{
}
@ -158,6 +161,7 @@ void
TextComposition::EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent)
{
mIsComposing = aTextEvent->IsComposing();
mIsEditorHandlingEvent = true;
MOZ_ASSERT(mLastData == aTextEvent->theText,
"The text of a text event must be same as previous data attribute value "
@ -168,6 +172,7 @@ void
TextComposition::EditorDidHandleTextEvent()
{
mString = mLastData;
mIsEditorHandlingEvent = false;
}
void

View File

@ -93,6 +93,15 @@ public:
*/
bool IsComposing() const { return mIsComposing; }
/**
* Returns true while editor is handling an event which is modifying the
* composition string.
*/
bool IsEditorHandlingEvent() const
{
return mIsEditorHandlingEvent;
}
/**
* StartHandlingComposition() and EndHandlingComposition() are called by
* editor when it holds a TextComposition instance and release it.
@ -161,6 +170,10 @@ private:
// See the comment for IsComposing().
bool mIsComposing;
// mIsEditorHandlingEvent is true while editor is modifying the composition
// string.
bool mIsEditorHandlingEvent;
// Hide the default constructor and copy constructor.
TextComposition() {}
TextComposition(const TextComposition& aOther);

View File

@ -67,6 +67,7 @@ public:
nsIContent* aContent);
void Destroy(void);
bool IsManaging(nsPresContext* aPresContext, nsIContent* aContent);
bool IsEditorHandlingEventForComposition() const;
bool KeepAliveDuringDeactive() const
{
return mUpdatePreference.WantDuringDeactive();
@ -818,6 +819,20 @@ nsTextStateManager::IsManaging(nsPresContext* aPresContext,
aContent);
}
bool
nsTextStateManager::IsEditorHandlingEventForComposition() const
{
if (!mWidget) {
return false;
}
nsRefPtr<TextComposition> composition =
nsIMEStateManager::GetTextCompositionFor(mWidget);
if (!composition) {
return false;
}
return composition->IsEditorHandlingEvent();
}
NS_IMPL_ISUPPORTS2(nsTextStateManager,
nsIMutationObserver,
nsISelectionListener)
@ -825,22 +840,27 @@ NS_IMPL_ISUPPORTS2(nsTextStateManager,
// Helper class, used for selection change notification
class SelectionChangeEvent : public nsRunnable {
public:
SelectionChangeEvent(nsTextStateManager *aDispatcher)
SelectionChangeEvent(nsTextStateManager *aDispatcher,
bool aCausedByComposition)
: mDispatcher(aDispatcher)
, mCausedByComposition(aCausedByComposition)
{
MOZ_ASSERT(mDispatcher);
}
NS_IMETHOD Run() {
if (mDispatcher->mWidget) {
mDispatcher->mWidget->NotifyIME(
IMENotification(NOTIFY_IME_OF_SELECTION_CHANGE));
IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
notification.mSelectionChangeData.mCausedByComposition =
mCausedByComposition;
mDispatcher->mWidget->NotifyIME(notification);
}
return NS_OK;
}
private:
nsRefPtr<nsTextStateManager> mDispatcher;
bool mCausedByComposition;
};
nsresult
@ -848,11 +868,18 @@ nsTextStateManager::NotifySelectionChanged(nsIDOMDocument* aDoc,
nsISelection* aSel,
int16_t aReason)
{
bool causedByComposition = IsEditorHandlingEventForComposition();
if (causedByComposition &&
!mUpdatePreference.WantChangesCausedByComposition()) {
return NS_OK;
}
int32_t count = 0;
nsresult rv = aSel->GetRangeCount(&count);
NS_ENSURE_SUCCESS(rv, rv);
if (count > 0 && mWidget) {
nsContentUtils::AddScriptRunner(new SelectionChangeEvent(this));
nsContentUtils::AddScriptRunner(
new SelectionChangeEvent(this, causedByComposition));
}
return NS_OK;
}
@ -861,11 +888,13 @@ nsTextStateManager::NotifySelectionChanged(nsIDOMDocument* aDoc,
class TextChangeEvent : public nsRunnable {
public:
TextChangeEvent(nsTextStateManager* aDispatcher,
uint32_t start, uint32_t oldEnd, uint32_t newEnd)
uint32_t aStart, uint32_t aOldEnd, uint32_t aNewEnd,
bool aCausedByComposition)
: mDispatcher(aDispatcher)
, mStart(start)
, mOldEnd(oldEnd)
, mNewEnd(newEnd)
, mStart(aStart)
, mOldEnd(aOldEnd)
, mNewEnd(aNewEnd)
, mCausedByComposition(aCausedByComposition)
{
MOZ_ASSERT(mDispatcher);
}
@ -876,6 +905,7 @@ public:
notification.mTextChangeData.mStartOffset = mStart;
notification.mTextChangeData.mOldEndOffset = mOldEnd;
notification.mTextChangeData.mNewEndOffset = mNewEnd;
notification.mTextChangeData.mCausedByComposition = mCausedByComposition;
mDispatcher->mWidget->NotifyIME(notification);
}
return NS_OK;
@ -884,6 +914,7 @@ public:
private:
nsRefPtr<nsTextStateManager> mDispatcher;
uint32_t mStart, mOldEnd, mNewEnd;
bool mCausedByComposition;
};
void
@ -894,6 +925,12 @@ nsTextStateManager::CharacterDataChanged(nsIDocument* aDocument,
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
"character data changed for non-text node");
bool causedByComposition = IsEditorHandlingEventForComposition();
if (causedByComposition &&
!mUpdatePreference.WantChangesCausedByComposition()) {
return;
}
uint32_t offset = 0;
// get offsets of change and fire notification
if (NS_FAILED(nsContentEventHandler::GetFlatTextOffsetOfRange(
@ -904,7 +941,7 @@ nsTextStateManager::CharacterDataChanged(nsIDocument* aDocument,
uint32_t newEnd = offset + aInfo->mReplaceLength;
nsContentUtils::AddScriptRunner(
new TextChangeEvent(this, offset, oldEnd, newEnd));
new TextChangeEvent(this, offset, oldEnd, newEnd, causedByComposition));
}
void
@ -912,6 +949,12 @@ nsTextStateManager::NotifyContentAdded(nsINode* aContainer,
int32_t aStartIndex,
int32_t aEndIndex)
{
bool causedByComposition = IsEditorHandlingEventForComposition();
if (causedByComposition &&
!mUpdatePreference.WantChangesCausedByComposition()) {
return;
}
uint32_t offset = 0, newOffset = 0;
if (NS_FAILED(nsContentEventHandler::GetFlatTextOffsetOfRange(
mRootContent, aContainer, aStartIndex, &offset)))
@ -924,9 +967,11 @@ nsTextStateManager::NotifyContentAdded(nsINode* aContainer,
return;
// fire notification
if (newOffset)
if (newOffset) {
nsContentUtils::AddScriptRunner(
new TextChangeEvent(this, offset, offset, offset + newOffset));
new TextChangeEvent(this, offset, offset, offset + newOffset,
causedByComposition));
}
}
void
@ -956,6 +1001,12 @@ nsTextStateManager::ContentRemoved(nsIDocument* aDocument,
int32_t aIndexInContainer,
nsIContent* aPreviousSibling)
{
bool causedByComposition = IsEditorHandlingEventForComposition();
if (causedByComposition &&
!mUpdatePreference.WantChangesCausedByComposition()) {
return;
}
uint32_t offset = 0, childOffset = 1;
if (NS_FAILED(nsContentEventHandler::GetFlatTextOffsetOfRange(
mRootContent, NODE_FROM(aContainer, aDocument),
@ -973,9 +1024,11 @@ nsTextStateManager::ContentRemoved(nsIDocument* aDocument,
return;
// fire notification
if (childOffset)
if (childOffset) {
nsContentUtils::AddScriptRunner(
new TextChangeEvent(this, offset, offset + childOffset, offset));
new TextChangeEvent(this, offset, offset + childOffset, offset,
causedByComposition));
}
}
static nsIContent*
@ -1006,6 +1059,12 @@ nsTextStateManager::AttributeChanged(nsIDocument* aDocument,
nsIAtom* aAttribute,
int32_t aModType)
{
bool causedByComposition = IsEditorHandlingEventForComposition();
if (causedByComposition &&
!mUpdatePreference.WantChangesCausedByComposition()) {
return;
}
nsIContent *content = GetContentBR(aElement);
if (!content) {
return;
@ -1017,7 +1076,8 @@ nsTextStateManager::AttributeChanged(nsIDocument* aDocument,
if (NS_SUCCEEDED(nsContentEventHandler::GetFlatTextOffsetOfRange(
mRootContent, content, 0, &start))) {
nsContentUtils::AddScriptRunner(new TextChangeEvent(this, start,
start + mPreAttrChangeLength, start + postAttrChangeLength));
start + mPreAttrChangeLength, start + postAttrChangeLength,
causedByComposition));
}
}
}

View File

@ -130,11 +130,13 @@ parent:
* offset Starting offset of the change
* end Ending offset of the range deleted
* newEnd New ending offset after insertion
* causedByComposition true if the change is caused by composition
*
* for insertion, offset == end
* for deletion, offset == newEnd
*/
NotifyIMETextChange(uint32_t offset, uint32_t end, uint32_t newEnd);
NotifyIMETextChange(uint32_t offset, uint32_t end, uint32_t newEnd,
bool causedByComposition);
/**
* Notifies chrome that there is a IME compostion rect updated
@ -152,8 +154,10 @@ parent:
* seqno Current seqno value on the content side
* anchor Offset where the selection started
* focus Offset where the caret is
* causedByComposition true if the change is caused by composition
*/
NotifyIMESelection(uint32_t seqno, uint32_t anchor, uint32_t focus);
NotifyIMESelection(uint32_t seqno, uint32_t anchor, uint32_t focus,
bool causedByComposition);
/**
* Notifies chrome to refresh its text cache

View File

@ -1051,7 +1051,7 @@ TabParent::RecvNotifyIMEFocus(const bool& aFocus,
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
aPreference->mWantUpdates = nsIMEUpdatePreference::NOTIFY_NOTHING;
*aPreference = nsIMEUpdatePreference();
return true;
}
@ -1073,19 +1073,27 @@ TabParent::RecvNotifyIMEFocus(const bool& aFocus,
bool
TabParent::RecvNotifyIMETextChange(const uint32_t& aStart,
const uint32_t& aEnd,
const uint32_t& aNewEnd)
const uint32_t& aNewEnd,
const bool& aCausedByComposition)
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return true;
NS_ASSERTION(widget->GetIMEUpdatePreference().WantTextChange(),
#ifdef DEBUG
nsIMEUpdatePreference updatePreference = widget->GetIMEUpdatePreference();
NS_ASSERTION(updatePreference.WantTextChange(),
"Don't call Send/RecvNotifyIMETextChange without NOTIFY_TEXT_CHANGE");
MOZ_ASSERT(!aCausedByComposition ||
updatePreference.WantChangesCausedByComposition(),
"The widget doesn't want text change notification caused by composition");
#endif
IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE);
notification.mTextChangeData.mStartOffset = aStart;
notification.mTextChangeData.mOldEndOffset = aEnd;
notification.mTextChangeData.mNewEndOffset = aNewEnd;
notification.mTextChangeData.mCausedByComposition = aCausedByComposition;
widget->NotifyIME(notification);
return true;
}
@ -1111,7 +1119,8 @@ TabParent::RecvNotifyIMESelectedCompositionRect(const uint32_t& aOffset,
bool
TabParent::RecvNotifyIMESelection(const uint32_t& aSeqno,
const uint32_t& aAnchor,
const uint32_t& aFocus)
const uint32_t& aFocus,
const bool& aCausedByComposition)
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
@ -1120,8 +1129,15 @@ TabParent::RecvNotifyIMESelection(const uint32_t& aSeqno,
if (aSeqno == mIMESeqno) {
mIMESelectionAnchor = aAnchor;
mIMESelectionFocus = aFocus;
if (widget->GetIMEUpdatePreference().WantSelectionChange()) {
widget->NotifyIME(IMENotification(NOTIFY_IME_OF_SELECTION_CHANGE));
const nsIMEUpdatePreference updatePreference =
widget->GetIMEUpdatePreference();
if (updatePreference.WantSelectionChange() &&
(updatePreference.WantChangesCausedByComposition() ||
!aCausedByComposition)) {
IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
notification.mSelectionChangeData.mCausedByComposition =
aCausedByComposition;
widget->NotifyIME(notification);
}
}
return true;

View File

@ -149,13 +149,15 @@ public:
uint32_t* aSeqno) MOZ_OVERRIDE;
virtual bool RecvNotifyIMETextChange(const uint32_t& aStart,
const uint32_t& aEnd,
const uint32_t& aNewEnd) MOZ_OVERRIDE;
const uint32_t& aNewEnd,
const bool& aCausedByComposition) MOZ_OVERRIDE;
virtual bool RecvNotifyIMESelectedCompositionRect(const uint32_t& aOffset,
const nsIntRect& aRect,
const nsIntRect& aCaretRect) MOZ_OVERRIDE;
virtual bool RecvNotifyIMESelection(const uint32_t& aSeqno,
const uint32_t& aAnchor,
const uint32_t& aFocus) MOZ_OVERRIDE;
const uint32_t& aFocus,
const bool& aCausedByComposition) MOZ_OVERRIDE;
virtual bool RecvNotifyIMETextHint(const nsString& aText) MOZ_OVERRIDE;
virtual bool RecvEndIMEComposition(const bool& aCancel,
nsString* aComposition) MOZ_OVERRIDE;

View File

@ -2379,9 +2379,9 @@ nsWindow::NotifyIMEOfTextChange(const IMENotification& aIMENotification)
nsIMEUpdatePreference
nsWindow::GetIMEUpdatePreference()
{
int8_t notifications = (nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
return nsIMEUpdatePreference(
nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE);
return nsIMEUpdatePreference(notifications);
}
void

View File

@ -221,23 +221,39 @@ struct nsIMEUpdatePreference {
typedef uint8_t Notifications;
enum
enum MOZ_ENUM_TYPE(Notifications)
{
NOTIFY_NOTHING = 0x00,
NOTIFY_SELECTION_CHANGE = 0x01,
NOTIFY_TEXT_CHANGE = 0x02,
NOTIFY_DURING_DEACTIVE = 0x80
NOTIFY_NOTHING = 0,
NOTIFY_SELECTION_CHANGE = 1 << 0,
NOTIFY_TEXT_CHANGE = 1 << 1,
// Following values indicate when widget needs or doesn't need notification.
NOTIFY_CHANGES_CAUSED_BY_COMPOSITION = 1 << 6,
// NOTE: NOTIFY_DURING_DEACTIVE isn't supported in environments where two
// or more compositions are possible. E.g., Mac and Linux (GTK).
NOTIFY_DURING_DEACTIVE = 1 << 7,
// Changes are notified in following conditions if the instance is
// just constructed. If some platforms don't need change notifications
// in some of following conditions, the platform should remove following
// flags before returing the instance from nsIWidget::GetUpdatePreference().
DEFAULT_CONDITIONS_OF_NOTIFYING_CHANGES =
NOTIFY_CHANGES_CAUSED_BY_COMPOSITION
};
nsIMEUpdatePreference()
: mWantUpdates(NOTIFY_NOTHING)
: mWantUpdates(DEFAULT_CONDITIONS_OF_NOTIFYING_CHANGES)
{
}
nsIMEUpdatePreference(Notifications aWantUpdates)
: mWantUpdates(aWantUpdates)
: mWantUpdates(aWantUpdates | DEFAULT_CONDITIONS_OF_NOTIFYING_CHANGES)
{
}
void DontNotifyChangesCausedByComposition()
{
mWantUpdates &= ~DEFAULT_CONDITIONS_OF_NOTIFYING_CHANGES;
}
bool WantSelectionChange() const
{
return !!(mWantUpdates & NOTIFY_SELECTION_CHANGE);
@ -248,6 +264,17 @@ struct nsIMEUpdatePreference {
return !!(mWantUpdates & NOTIFY_TEXT_CHANGE);
}
bool WantChanges() const
{
return WantSelectionChange() || WantTextChange();
}
bool WantChangesCausedByComposition() const
{
return WantChanges() &&
!!(mWantUpdates & NOTIFY_CHANGES_CAUSED_BY_COMPOSITION);
}
bool WantDuringDeactive() const
{
return !!(mWantUpdates & NOTIFY_DURING_DEACTIVE);
@ -479,10 +506,14 @@ struct IMENotification
: mMessage(aMessage)
{
switch (aMessage) {
case NOTIFY_IME_OF_SELECTION_CHANGE:
mSelectionChangeData.mCausedByComposition = false;
break;
case NOTIFY_IME_OF_TEXT_CHANGE:
mTextChangeData.mStartOffset = 0;
mTextChangeData.mOldEndOffset = 0;
mTextChangeData.mNewEndOffset = 0;
mTextChangeData.mCausedByComposition = false;
break;
default:
break;
@ -493,6 +524,12 @@ struct IMENotification
union
{
// NOTIFY_IME_OF_SELECTION_CHANGE specific data
struct
{
bool mCausedByComposition;
} mSelectionChangeData;
// NOTIFY_IME_OF_TEXT_CHANGE specific data
struct
{
@ -500,6 +537,8 @@ struct IMENotification
uint32_t mOldEndOffset;
uint32_t mNewEndOffset;
bool mCausedByComposition;
uint32_t OldLength() const { return mOldEndOffset - mStartOffset; }
uint32_t NewLength() const { return mNewEndOffset - mStartOffset; }
int32_t AdditionalLength() const
@ -515,6 +554,18 @@ struct IMENotification
} mTextChangeData;
};
bool IsCausedByComposition() const
{
switch (mMessage) {
case NOTIFY_IME_OF_SELECTION_CHANGE:
return mSelectionChangeData.mCausedByComposition;
case NOTIFY_IME_OF_TEXT_CHANGE:
return mTextChangeData.mCausedByComposition;
default:
return false;
}
}
private:
IMENotification();
};

View File

@ -3171,18 +3171,21 @@ nsTextStore::OnFocusChange(bool aGotFocus,
nsIMEUpdatePreference
nsTextStore::GetIMEUpdatePreference()
{
nsIMEUpdatePreference::Notifications notifications =
nsIMEUpdatePreference::NOTIFY_NOTHING;
if (sTsfThreadMgr && sTsfTextStore && sTsfTextStore->mDocumentMgr) {
nsRefPtr<ITfDocumentMgr> docMgr;
sTsfThreadMgr->GetFocus(getter_AddRefs(docMgr));
if (docMgr == sTsfTextStore->mDocumentMgr) {
notifications = (nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
nsIMEUpdatePreference updatePreference(
nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE |
nsIMEUpdatePreference::NOTIFY_DURING_DEACTIVE);
// nsTextStore shouldn't notify TSF of selection change and text change
// which are caused by composition.
updatePreference.DontNotifyChangesCausedByComposition();
return updatePreference;
}
}
return nsIMEUpdatePreference(notifications);
return nsIMEUpdatePreference();
}
nsresult

View File

@ -390,7 +390,7 @@ PuppetWidget::NotifyIME(const IMENotification& aIMENotification)
case NOTIFY_IME_OF_BLUR:
return NotifyIMEOfFocusChange(false);
case NOTIFY_IME_OF_SELECTION_CHANGE:
return NotifyIMEOfSelectionChange();
return NotifyIMEOfSelectionChange(aIMENotification);
case NOTIFY_IME_OF_TEXT_CHANGE:
return NotifyIMEOfTextChange(aIMENotification);
case NOTIFY_IME_OF_COMPOSITION_UPDATE:
@ -467,14 +467,16 @@ PuppetWidget::NotifyIMEOfFocusChange(bool aFocus)
}
uint32_t chromeSeqno;
mIMEPreferenceOfParent.mWantUpdates = nsIMEUpdatePreference::NOTIFY_NOTHING;
mIMEPreferenceOfParent = nsIMEUpdatePreference();
if (!mTabChild->SendNotifyIMEFocus(aFocus, &mIMEPreferenceOfParent,
&chromeSeqno)) {
return NS_ERROR_FAILURE;
}
if (aFocus) {
NotifyIMEOfSelectionChange(); // Update selection
IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
notification.mSelectionChangeData.mCausedByComposition = false;
NotifyIMEOfSelectionChange(notification); // Update selection
} else {
mIMELastBlurSeqno = chromeSeqno;
}
@ -531,6 +533,9 @@ PuppetWidget::GetIMEUpdatePreference()
nsresult
PuppetWidget::NotifyIMEOfTextChange(const IMENotification& aIMENotification)
{
MOZ_ASSERT(aIMENotification.mMessage == NOTIFY_IME_OF_TEXT_CHANGE,
"Passed wrong notification");
#ifndef MOZ_CROSS_PROCESS_IME
return NS_OK;
#endif
@ -550,18 +555,25 @@ PuppetWidget::NotifyIMEOfTextChange(const IMENotification& aIMENotification)
// TabParent doesn't this this to cache. we don't send the notification
// if parent process doesn't request NOTIFY_TEXT_CHANGE.
if (mIMEPreferenceOfParent.WantTextChange()) {
if (mIMEPreferenceOfParent.WantTextChange() &&
(mIMEPreferenceOfParent.WantChangesCausedByComposition() ||
!aIMENotification.mTextChangeData.mCausedByComposition)) {
mTabChild->SendNotifyIMETextChange(
aIMENotification.mTextChangeData.mStartOffset,
aIMENotification.mTextChangeData.mOldEndOffset,
aIMENotification.mTextChangeData.mNewEndOffset);
aIMENotification.mTextChangeData.mNewEndOffset,
aIMENotification.mTextChangeData.mCausedByComposition);
}
return NS_OK;
}
nsresult
PuppetWidget::NotifyIMEOfSelectionChange()
PuppetWidget::NotifyIMEOfSelectionChange(
const IMENotification& aIMENotification)
{
MOZ_ASSERT(aIMENotification.mMessage == NOTIFY_IME_OF_SELECTION_CHANGE,
"Passed wrong notification");
#ifndef MOZ_CROSS_PROCESS_IME
return NS_OK;
#endif
@ -575,9 +587,11 @@ PuppetWidget::NotifyIMEOfSelectionChange()
DispatchEvent(&queryEvent, status);
if (queryEvent.mSucceeded) {
mTabChild->SendNotifyIMESelection(mIMELastReceivedSeqno,
mTabChild->SendNotifyIMESelection(
mIMELastReceivedSeqno,
queryEvent.GetSelectionStart(),
queryEvent.GetSelectionEnd());
queryEvent.GetSelectionEnd(),
aIMENotification.mSelectionChangeData.mCausedByComposition);
}
return NS_OK;
}

View File

@ -180,7 +180,7 @@ private:
nsresult IMEEndComposition(bool aCancel);
nsresult NotifyIMEOfFocusChange(bool aFocus);
nsresult NotifyIMEOfSelectionChange();
nsresult NotifyIMEOfSelectionChange(const IMENotification& aIMENotification);
nsresult NotifyIMEOfUpdateComposition();
nsresult NotifyIMEOfTextChange(const IMENotification& aIMENotification);