Bug 875674 part.1 nsIMEUpdatePreference should store wanted updates per notification r=roc

This commit is contained in:
Masayuki Nakano 2013-07-11 16:46:34 +09:00
parent e757837a5c
commit da38d263f9
8 changed files with 56 additions and 38 deletions

View File

@ -51,7 +51,7 @@ class nsTextStateManager MOZ_FINAL : public nsISelectionListener,
{
public:
nsTextStateManager()
: mObserving(false)
: mObserving(nsIMEUpdatePreference::NOTIFY_NOTHING)
{
}
@ -79,7 +79,7 @@ private:
void NotifyContentAdded(nsINode* aContainer, int32_t aStart, int32_t aEnd);
void ObserveEditableNode();
bool mObserving;
nsIMEUpdatePreference::Notifications mObserving;
uint32_t mPreAttrChangeLength;
};
@ -736,9 +736,7 @@ nsTextStateManager::Init(nsIWidget* aWidget,
return;
}
if (mWidget->GetIMEUpdatePreference().mWantUpdates) {
ObserveEditableNode();
}
ObserveEditableNode();
}
void
@ -747,18 +745,19 @@ nsTextStateManager::ObserveEditableNode()
MOZ_ASSERT(mSel);
MOZ_ASSERT(mRootContent);
// add selection change listener
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(mSel));
NS_ENSURE_TRUE_VOID(selPrivate);
nsresult rv = selPrivate->AddSelectionListener(this);
NS_ENSURE_SUCCESS_VOID(rv);
rv = selPrivate->AddSelectionListener(this);
NS_ENSURE_SUCCESS_VOID(rv);
mObserving = mWidget->GetIMEUpdatePreference().mWantUpdates;
if (mObserving & nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE) {
// add selection change listener
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(mSel));
NS_ENSURE_TRUE_VOID(selPrivate);
nsresult rv = selPrivate->AddSelectionListener(this);
NS_ENSURE_SUCCESS_VOID(rv);
}
// add text change observer
mRootContent->AddMutationObserver(this);
mObserving = true;
if (mObserving & nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE) {
// add text change observer
mRootContent->AddMutationObserver(this);
}
}
void
@ -776,13 +775,13 @@ nsTextStateManager::Destroy(void)
}
// Even if there are some pending notification, it'll never notify the widget.
mWidget = nullptr;
if (mObserving && mSel) {
if ((mObserving & nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE) && mSel) {
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(mSel));
if (selPrivate)
selPrivate->RemoveSelectionListener(this);
}
mSel = nullptr;
if (mObserving && mRootContent) {
if ((mObserving & nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE) && mRootContent) {
mRootContent->RemoveMutationObserver(this);
}
mRootContent = nullptr;

View File

@ -748,7 +748,7 @@ TabParent::RecvNotifyIMEFocus(const bool& aFocus,
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
aPreference->mWantUpdates = false;
aPreference->mWantUpdates = nsIMEUpdatePreference::NOTIFY_NOTHING;
aPreference->mWantHints = false;
return true;
}

View File

@ -2367,7 +2367,9 @@ nsWindow::NotifyIMEOfTextChange(uint32_t aStart,
nsIMEUpdatePreference
nsWindow::GetIMEUpdatePreference()
{
return nsIMEUpdatePreference(true, true);
int8_t notifications = (nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE);
return nsIMEUpdatePreference(notifications, true);
}
void

View File

@ -191,13 +191,14 @@ enum nsTopLevelWidgetZPlacement { // for PlaceBehind()
/**
* Preference for receiving IME updates
*
* If mWantUpdates is true, nsTextStateManager will observe text change and
* selection change and call nsIWidget::NotifyIMEOfTextChange() and
* nsIWidget::NotifyIME(NOTIFY_IME_OF_SELECTION_CHANGE). The observing cost is
* very expensive.
* If mWantUpdates is not NOTIFY_NOTHING, nsTextStateManager will observe text
* change and/or selection change and call nsIWidget::NotifyIMEOfTextChange()
* and/or nsIWidget::NotifyIME(NOTIFY_IME_OF_SELECTION_CHANGE).
* Please note that the text change observing cost is very expensive especially
* on an HTML editor has focus.
* If the IME implementation on a particular platform doesn't care about
* NotifyIMEOfTextChange and NotifyIME(NOTIFY_IME_OF_SELECTION_CHANGE), they
* should set mWantUpdates to false to avoid the cost.
* NotifyIMEOfTextChange() and/or NotifyIME(NOTIFY_IME_OF_SELECTION_CHANGE),
* they should set mWantUpdates to NOTIFY_NOTHING to avoid the cost.
*
* If mWantHints is true, PuppetWidget will forward the content of text fields
* to the chrome process to be cached. This way we return the cached content
@ -208,15 +209,25 @@ enum nsTopLevelWidgetZPlacement { // for PlaceBehind()
*/
struct nsIMEUpdatePreference {
typedef int8_t Notifications;
enum
{
NOTIFY_NOTHING = 0x0000,
NOTIFY_SELECTION_CHANGE = 0x0001,
NOTIFY_TEXT_CHANGE = 0x0002
};
nsIMEUpdatePreference()
: mWantUpdates(false), mWantHints(false)
: mWantUpdates(NOTIFY_NOTHING), mWantHints(false)
{
}
nsIMEUpdatePreference(bool aWantUpdates, bool aWantHints)
nsIMEUpdatePreference(Notifications aWantUpdates, bool aWantHints)
: mWantUpdates(aWantUpdates), mWantHints(aWantHints)
{
}
bool mWantUpdates;
Notifications mWantUpdates;
bool mWantHints;
};

View File

@ -221,7 +221,7 @@ IMEHandler::GetUpdatePreference()
}
#endif //NS_ENABLE_TSF
return nsIMEUpdatePreference(false, false);
return nsIMEUpdatePreference();
}
// static

View File

@ -2920,13 +2920,16 @@ nsTextStore::OnFocusChange(bool aGotFocus,
nsIMEUpdatePreference
nsTextStore::GetIMEUpdatePreference()
{
bool hasFocus = false;
int8_t notifications = nsIMEUpdatePreference::NOTIFY_NOTHING;
if (sTsfThreadMgr && sTsfTextStore && sTsfTextStore->mDocumentMgr) {
nsRefPtr<ITfDocumentMgr> docMgr;
sTsfThreadMgr->GetFocus(getter_AddRefs(docMgr));
hasFocus = (docMgr == sTsfTextStore->mDocumentMgr);
if (docMgr == sTsfTextStore->mDocumentMgr) {
notifications = (nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE);
}
}
return nsIMEUpdatePreference(hasFocus, false);
return nsIMEUpdatePreference(notifications, false);
}
nsresult

View File

@ -456,13 +456,15 @@ PuppetWidget::NotifyIMEOfFocusChange(bool aFocus)
}
uint32_t chromeSeqno;
mIMEPreference.mWantUpdates = false;
mIMEPreference.mWantUpdates = nsIMEUpdatePreference::NOTIFY_NOTHING;
mIMEPreference.mWantHints = false;
if (!mTabChild->SendNotifyIMEFocus(aFocus, &mIMEPreference, &chromeSeqno))
return NS_ERROR_FAILURE;
if (aFocus) {
if (mIMEPreference.mWantUpdates && mIMEPreference.mWantHints) {
if ((mIMEPreference.mWantUpdates &
nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE) &&
mIMEPreference.mWantHints) {
NotifyIMEOfSelectionChange(); // Update selection
}
} else {
@ -500,7 +502,7 @@ PuppetWidget::NotifyIMEOfTextChange(uint32_t aStart,
mTabChild->SendNotifyIMETextHint(queryEvent.mReply.mString);
}
}
if (mIMEPreference.mWantUpdates) {
if (mIMEPreference.mWantUpdates & nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE) {
mTabChild->SendNotifyIMETextChange(aStart, aEnd, aNewEnd);
}
return NS_OK;
@ -516,7 +518,8 @@ PuppetWidget::NotifyIMEOfSelectionChange()
if (!mTabChild)
return NS_ERROR_FAILURE;
if (mIMEPreference.mWantUpdates) {
if (mIMEPreference.mWantUpdates &
nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE) {
nsEventStatus status;
nsQueryContentEvent queryEvent(true, NS_QUERY_SELECTED_TEXT, this);
InitEvent(queryEvent, nullptr);

View File

@ -181,7 +181,7 @@ public:
virtual bool ComputeShouldAccelerate(bool aDefault);
NS_IMETHOD GetToggledKeyState(uint32_t aKeyCode, bool* aLEDState) { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD NotifyIMEOfTextChange(uint32_t aStart, uint32_t aOldEnd, uint32_t aNewEnd) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
virtual nsIMEUpdatePreference GetIMEUpdatePreference() { return nsIMEUpdatePreference(false, false); }
virtual nsIMEUpdatePreference GetIMEUpdatePreference() MOZ_OVERRIDE { return nsIMEUpdatePreference(); }
NS_IMETHOD OnDefaultButtonLoaded(const nsIntRect &aButtonRect) { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD OverrideSystemMouseScrollSpeed(double aOriginalDeltaX,
double aOriginalDeltaY,