зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1166436 part.10 Optimize IME notification handling in PuppetWidget r=m_kato
This commit is contained in:
Родитель
496d6e76c8
Коммит
dcfea181de
|
@ -1179,6 +1179,9 @@ IMEContentObserver::FlushMergeableNotifications()
|
|||
nsContentUtils::AddScriptRunner(new TextChangeEvent(this, mTextChangeData));
|
||||
}
|
||||
|
||||
// Be aware, PuppetWidget depends on the order of this. A selection change
|
||||
// notification should not be sent before a text change notification because
|
||||
// PuppetWidget shouldn't query new text content every selection change.
|
||||
if (mIsSelectionChangeEventPending) {
|
||||
mIsSelectionChangeEventPending = false;
|
||||
nsContentUtils::AddScriptRunner(
|
||||
|
|
|
@ -215,11 +215,12 @@ parent:
|
|||
bool causedByComposition);
|
||||
|
||||
/**
|
||||
* Notifies chrome to refresh its text cache
|
||||
* Notifies chrome of updating its content cache.
|
||||
* This is useful if content is modified but we don't need to notify IME.
|
||||
*
|
||||
* contentCache Cache of content
|
||||
*/
|
||||
prio(urgent) async NotifyIMETextHint(ContentCache contentCache);
|
||||
prio(urgent) async UpdateContentCache(ContentCache contentCache);
|
||||
|
||||
/**
|
||||
* Notifies IME of mouse button event on a character in focused editor.
|
||||
|
@ -229,13 +230,6 @@ parent:
|
|||
prio(urgent) sync NotifyIMEMouseButtonEvent(IMENotification notification)
|
||||
returns (bool consumedByIME);
|
||||
|
||||
/**
|
||||
* Notifies chrome to currect editor rect
|
||||
*
|
||||
* contentCache Cache of content
|
||||
*/
|
||||
prio(urgent) async NotifyIMEEditorRect(ContentCache contentCache);
|
||||
|
||||
/**
|
||||
* Notifies chrome to position change
|
||||
*
|
||||
|
|
|
@ -1977,8 +1977,13 @@ TabParent::RecvNotifyIMESelection(const ContentCache& aContentCache,
|
|||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyIMETextHint(const ContentCache& aContentCache)
|
||||
TabParent::RecvUpdateContentCache(const ContentCache& aContentCache)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mContentCache.AssignContent(aContentCache);
|
||||
return true;
|
||||
}
|
||||
|
@ -1999,13 +2004,6 @@ TabParent::RecvNotifyIMEMouseButtonEvent(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyIMEEditorRect(const ContentCache& aContentCache)
|
||||
{
|
||||
mContentCache.AssignContent(aContentCache);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyIMEPositionChange(const ContentCache& aContentCache)
|
||||
{
|
||||
|
|
|
@ -172,10 +172,9 @@ public:
|
|||
virtual bool RecvNotifyIMESelectedCompositionRect(const ContentCache& aContentCache) override;
|
||||
virtual bool RecvNotifyIMESelection(const ContentCache& aContentCache,
|
||||
const bool& aCausedByComposition) override;
|
||||
virtual bool RecvNotifyIMETextHint(const ContentCache& aContentCache) override;
|
||||
virtual bool RecvUpdateContentCache(const ContentCache& aContentCache) override;
|
||||
virtual bool RecvNotifyIMEMouseButtonEvent(const widget::IMENotification& aEventMessage,
|
||||
bool* aConsumedByIME) override;
|
||||
virtual bool RecvNotifyIMEEditorRect(const ContentCache& aContentCache) override;
|
||||
virtual bool RecvNotifyIMEPositionChange(const ContentCache& aContentCache) override;
|
||||
virtual bool RecvEndIMEComposition(const bool& aCancel,
|
||||
bool* aNoCompositionEvent,
|
||||
|
|
|
@ -25,6 +25,7 @@ ContentCache::ContentCache()
|
|||
, mCompositionEventsDuringRequest(0)
|
||||
, mIsComposing(false)
|
||||
, mRequestedToCommitOrCancelComposition(false)
|
||||
, mIsChrome(XRE_GetProcessType() == GeckoProcessType_Default)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -32,6 +33,10 @@ void
|
|||
ContentCache::Clear()
|
||||
{
|
||||
mText.Truncate();
|
||||
mSelection.Clear();
|
||||
mCaret.Clear();
|
||||
mTextRectArray.Clear();
|
||||
mEditorRect.SetEmpty();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -111,6 +116,11 @@ ContentCache::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent,
|
|||
bool
|
||||
ContentCache::CacheAll(nsIWidget* aWidget)
|
||||
{
|
||||
// CacheAll() must be called in content process.
|
||||
if (NS_WARN_IF(mIsChrome)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!CacheText(aWidget)) ||
|
||||
NS_WARN_IF(!CacheSelection(aWidget)) ||
|
||||
NS_WARN_IF(!CacheTextRects(aWidget)) ||
|
||||
|
@ -123,6 +133,11 @@ ContentCache::CacheAll(nsIWidget* aWidget)
|
|||
bool
|
||||
ContentCache::CacheSelection(nsIWidget* aWidget)
|
||||
{
|
||||
// CacheSelection() must be called in content process.
|
||||
if (NS_WARN_IF(mIsChrome)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mCaret.Clear();
|
||||
mSelection.Clear();
|
||||
|
||||
|
@ -166,6 +181,11 @@ ContentCache::CacheSelection(nsIWidget* aWidget)
|
|||
bool
|
||||
ContentCache::CacheEditorRect(nsIWidget* aWidget)
|
||||
{
|
||||
// CacheEditorRect() must be called in content process.
|
||||
if (NS_WARN_IF(mIsChrome)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
WidgetQueryContentEvent editorRectEvent(true, NS_QUERY_EDITOR_RECT, aWidget);
|
||||
aWidget->DispatchEvent(&editorRectEvent, status);
|
||||
|
@ -179,6 +199,11 @@ ContentCache::CacheEditorRect(nsIWidget* aWidget)
|
|||
bool
|
||||
ContentCache::CacheText(nsIWidget* aWidget)
|
||||
{
|
||||
// CacheText() must be called in content process.
|
||||
if (NS_WARN_IF(mIsChrome)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
WidgetQueryContentEvent queryText(true, NS_QUERY_TEXT_CONTENT, aWidget);
|
||||
queryText.InitForQueryTextContent(0, UINT32_MAX);
|
||||
|
@ -194,6 +219,11 @@ ContentCache::CacheText(nsIWidget* aWidget)
|
|||
bool
|
||||
ContentCache::CacheTextRects(nsIWidget* aWidget)
|
||||
{
|
||||
// CacheTextRects() must be called in content process.
|
||||
if (NS_WARN_IF(mIsChrome)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mTextRectArray.Clear();
|
||||
|
||||
nsRefPtr<TextComposition> textComposition =
|
||||
|
|
|
@ -278,6 +278,7 @@ private:
|
|||
|
||||
bool mIsComposing;
|
||||
bool mRequestedToCommitOrCancelComposition;
|
||||
bool mIsChrome;
|
||||
|
||||
friend struct IPC::ParamTraits<ContentCache>;
|
||||
};
|
||||
|
|
|
@ -674,11 +674,12 @@ PuppetWidget::NotifyIMEOfFocusChange(bool aFocus)
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (aFocus) {
|
||||
if (NS_WARN_IF(!mContentCache.CacheText(this))) {
|
||||
// When IME gets focus, we should initalize all information of the content.
|
||||
if (NS_WARN_IF(!mContentCache.CacheAll(this))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mTabChild->SendNotifyIMETextHint(mContentCache);
|
||||
} else {
|
||||
// When IME loses focus, we don't need to store anything.
|
||||
mContentCache.Clear();
|
||||
}
|
||||
|
||||
|
@ -687,14 +688,6 @@ PuppetWidget::NotifyIMEOfFocusChange(bool aFocus)
|
|||
&mIMEPreferenceOfParent)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// TODO: Optimize this later.
|
||||
if (aFocus) {
|
||||
IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
|
||||
notification.mSelectionChangeData.mCausedByComposition = false;
|
||||
NotifyIMEOfSelectionChange(notification); // Update selection
|
||||
NotifyIMEOfEditorRect();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -715,23 +708,6 @@ PuppetWidget::NotifyIMEOfUpdateComposition()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PuppetWidget::NotifyIMEOfEditorRect()
|
||||
{
|
||||
#ifndef MOZ_CROSS_PROCESS_IME
|
||||
return NS_OK;
|
||||
#endif
|
||||
if (NS_WARN_IF(!mTabChild)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!mContentCache.CacheEditorRect(this))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mTabChild->SendNotifyIMEEditorRect(mContentCache);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIMEUpdatePreference
|
||||
PuppetWidget::GetIMEUpdatePreference()
|
||||
{
|
||||
|
@ -760,10 +736,16 @@ PuppetWidget::NotifyIMEOfTextChange(const IMENotification& aIMENotification)
|
|||
if (!mTabChild)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (NS_WARN_IF(!mContentCache.CacheText(this))) {
|
||||
// FYI: text change notification is the first notification after
|
||||
// a user operation changes the content. So, we need to modify
|
||||
// the cache as far as possible here.
|
||||
|
||||
// When text is changed, selection and text rects must be changed too.
|
||||
if (NS_WARN_IF(!mContentCache.CacheText(this)) ||
|
||||
NS_WARN_IF(!mContentCache.CacheTextRects(this)) ||
|
||||
NS_WARN_IF(!mContentCache.CacheSelection(this))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mTabChild->SendNotifyIMETextHint(mContentCache);
|
||||
|
||||
// TabParent doesn't this this to cache. we don't send the notification
|
||||
// if parent process doesn't request NOTIFY_TEXT_CHANGE.
|
||||
|
@ -776,6 +758,8 @@ PuppetWidget::NotifyIMEOfTextChange(const IMENotification& aIMENotification)
|
|||
aIMENotification.mTextChangeData.mOldEndOffset,
|
||||
aIMENotification.mTextChangeData.mNewEndOffset,
|
||||
aIMENotification.mTextChangeData.mCausedByComposition);
|
||||
} else {
|
||||
mTabChild->SendUpdateContentCache(mContentCache);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -794,6 +778,8 @@ PuppetWidget::NotifyIMEOfSelectionChange(
|
|||
if (!mTabChild)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Note that selection change must be notified after text change if it occurs.
|
||||
// Therefore, we don't need to query text content again here.
|
||||
mContentCache.SetSelection(
|
||||
aIMENotification.mSelectionChangeData.mOffset,
|
||||
aIMENotification.mSelectionChangeData.mLength,
|
||||
|
|
|
@ -262,7 +262,6 @@ private:
|
|||
nsresult NotifyIMEOfUpdateComposition();
|
||||
nsresult NotifyIMEOfTextChange(const IMENotification& aIMENotification);
|
||||
nsresult NotifyIMEOfMouseButtonEvent(const IMENotification& aIMENotification);
|
||||
nsresult NotifyIMEOfEditorRect();
|
||||
nsresult NotifyIMEOfPositionChange();
|
||||
|
||||
bool CacheEditorRect();
|
||||
|
|
Загрузка…
Ссылка в новой задаче