зеркало из https://github.com/mozilla/gecko-dev.git
Bug 966157 - Part 2. Child process should listen NOTIFY_IME_OF_POSITION_CHANGE. r=masayuki
This commit is contained in:
Родитель
62347a8f7b
Коммит
6bf9f859e7
|
@ -234,6 +234,16 @@ parent:
|
||||||
*/
|
*/
|
||||||
prio(urgent) async NotifyIMEEditorRect(nsIntRect rect);
|
prio(urgent) async NotifyIMEEditorRect(nsIntRect rect);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies chrome to position change
|
||||||
|
*
|
||||||
|
* editorRect Rect of current focused editor
|
||||||
|
* compositionRects Rects of current composition string
|
||||||
|
*/
|
||||||
|
prio(urgent) async NotifyIMEPositionChange(nsIntRect editorRect,
|
||||||
|
nsIntRect[] compositionRects,
|
||||||
|
nsIntRect caretRect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instructs chrome to end any pending composition
|
* Instructs chrome to end any pending composition
|
||||||
*
|
*
|
||||||
|
|
|
@ -1460,6 +1460,29 @@ TabParent::RecvNotifyIMEEditorRect(const nsIntRect& aRect)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TabParent::RecvNotifyIMEPositionChange(
|
||||||
|
const nsIntRect& aEditorRect,
|
||||||
|
const InfallibleTArray<nsIntRect>& aCompositionRects,
|
||||||
|
const nsIntRect& aCaretRect)
|
||||||
|
{
|
||||||
|
mIMEEditorRect = aEditorRect;
|
||||||
|
mIMECompositionRects = aCompositionRects;
|
||||||
|
mIMECaretRect = aCaretRect;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||||
|
if (!widget) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsIMEUpdatePreference updatePreference =
|
||||||
|
widget->GetIMEUpdatePreference();
|
||||||
|
if (updatePreference.WantPositionChanged()) {
|
||||||
|
widget->NotifyIME(IMENotification(NOTIFY_IME_OF_POSITION_CHANGE));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabParent::RecvRequestFocus(const bool& aCanRaise)
|
TabParent::RecvRequestFocus(const bool& aCanRaise)
|
||||||
{
|
{
|
||||||
|
|
|
@ -179,6 +179,10 @@ public:
|
||||||
virtual bool RecvNotifyIMEMouseButtonEvent(const widget::IMENotification& aEventMessage,
|
virtual bool RecvNotifyIMEMouseButtonEvent(const widget::IMENotification& aEventMessage,
|
||||||
bool* aConsumedByIME) MOZ_OVERRIDE;
|
bool* aConsumedByIME) MOZ_OVERRIDE;
|
||||||
virtual bool RecvNotifyIMEEditorRect(const nsIntRect& aRect) MOZ_OVERRIDE;
|
virtual bool RecvNotifyIMEEditorRect(const nsIntRect& aRect) MOZ_OVERRIDE;
|
||||||
|
virtual bool RecvNotifyIMEPositionChange(
|
||||||
|
const nsIntRect& aEditoRect,
|
||||||
|
const InfallibleTArray<nsIntRect>& aCompositionRects,
|
||||||
|
const nsIntRect& aCaretRect) MOZ_OVERRIDE;
|
||||||
virtual bool RecvEndIMEComposition(const bool& aCancel,
|
virtual bool RecvEndIMEComposition(const bool& aCancel,
|
||||||
nsString* aComposition) MOZ_OVERRIDE;
|
nsString* aComposition) MOZ_OVERRIDE;
|
||||||
virtual bool RecvGetInputContext(int32_t* aIMEEnabled,
|
virtual bool RecvGetInputContext(int32_t* aIMEEnabled,
|
||||||
|
|
|
@ -448,6 +448,8 @@ PuppetWidget::NotifyIME(const IMENotification& aIMENotification)
|
||||||
return NotifyIMEOfUpdateComposition();
|
return NotifyIMEOfUpdateComposition();
|
||||||
case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
|
case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
|
||||||
return NotifyIMEOfMouseButtonEvent(aIMENotification);
|
return NotifyIMEOfMouseButtonEvent(aIMENotification);
|
||||||
|
case NOTIFY_IME_OF_POSITION_CHANGE:
|
||||||
|
return NotifyIMEOfPositionChange();
|
||||||
default:
|
default:
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
@ -546,57 +548,110 @@ PuppetWidget::NotifyIMEOfUpdateComposition()
|
||||||
|
|
||||||
NS_ENSURE_TRUE(mTabChild, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(mTabChild, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
nsRefPtr<TextComposition> textComposition =
|
uint32_t startOffset;
|
||||||
IMEStateManager::GetTextCompositionFor(this);
|
uint32_t targetCauseOffset;
|
||||||
NS_ENSURE_TRUE(textComposition, NS_ERROR_FAILURE);
|
nsAutoTArray<nsIntRect, 16> textRectArray;
|
||||||
|
if (!GetCompositionRects(startOffset,
|
||||||
nsEventStatus status;
|
textRectArray,
|
||||||
nsTArray<nsIntRect> textRectArray(textComposition->String().Length());
|
targetCauseOffset)) {
|
||||||
uint32_t startOffset = textComposition->NativeOffsetOfStartComposition();
|
return NS_ERROR_FAILURE;
|
||||||
uint32_t endOffset = textComposition->String().Length() + startOffset;
|
|
||||||
for (uint32_t i = startOffset; i < endOffset; i++) {
|
|
||||||
WidgetQueryContentEvent textRect(true, NS_QUERY_TEXT_RECT, this);
|
|
||||||
InitEvent(textRect, nullptr);
|
|
||||||
textRect.InitForQueryTextRect(i, 1);
|
|
||||||
DispatchEvent(&textRect, status);
|
|
||||||
NS_ENSURE_TRUE(textRect.mSucceeded, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
textRectArray.AppendElement(textRect.mReply.mRect);
|
|
||||||
}
|
}
|
||||||
|
nsIntRect caretRect;
|
||||||
uint32_t targetCauseOffset = textComposition->OffsetOfTargetClause();
|
GetCaretRect(caretRect, targetCauseOffset);
|
||||||
WidgetQueryContentEvent caretRect(true, NS_QUERY_CARET_RECT, this);
|
|
||||||
InitEvent(caretRect, nullptr);
|
|
||||||
caretRect.InitForQueryCaretRect(targetCauseOffset);
|
|
||||||
DispatchEvent(&caretRect, status);
|
|
||||||
NS_ENSURE_TRUE(caretRect.mSucceeded, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
mTabChild->SendNotifyIMESelectedCompositionRect(startOffset,
|
mTabChild->SendNotifyIMESelectedCompositionRect(startOffset,
|
||||||
textRectArray,
|
textRectArray,
|
||||||
targetCauseOffset,
|
targetCauseOffset,
|
||||||
caretRect.mReply.mRect);
|
caretRect);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PuppetWidget::GetCompositionRects(uint32_t& aStartOffset,
|
||||||
|
nsTArray<nsIntRect>& aTextRectArray,
|
||||||
|
uint32_t& aTargetCauseOffset)
|
||||||
|
{
|
||||||
|
nsRefPtr<TextComposition> textComposition =
|
||||||
|
IMEStateManager::GetTextCompositionFor(this);
|
||||||
|
NS_ENSURE_TRUE(textComposition, false);
|
||||||
|
|
||||||
|
nsEventStatus status;
|
||||||
|
aTextRectArray.SetCapacity(textComposition->String().Length());
|
||||||
|
aStartOffset = textComposition->NativeOffsetOfStartComposition();
|
||||||
|
aTargetCauseOffset = textComposition->OffsetOfTargetClause();
|
||||||
|
uint32_t endOffset = textComposition->String().Length() + aStartOffset;
|
||||||
|
for (uint32_t i = aStartOffset; i < endOffset; i++) {
|
||||||
|
WidgetQueryContentEvent textRect(true, NS_QUERY_TEXT_RECT, this);
|
||||||
|
InitEvent(textRect, nullptr);
|
||||||
|
textRect.InitForQueryTextRect(i, 1);
|
||||||
|
DispatchEvent(&textRect, status);
|
||||||
|
NS_ENSURE_TRUE(textRect.mSucceeded, false);
|
||||||
|
|
||||||
|
aTextRectArray.AppendElement(textRect.mReply.mRect);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PuppetWidget::GetCaretOffset()
|
||||||
|
{
|
||||||
|
nsEventStatus status;
|
||||||
|
WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT, this);
|
||||||
|
InitEvent(selection, nullptr);
|
||||||
|
DispatchEvent(&selection, status);
|
||||||
|
NS_ENSURE_TRUE(selection.mSucceeded, 0);
|
||||||
|
|
||||||
|
return selection.mReply.mOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PuppetWidget::GetCaretRect(nsIntRect& aCaretRect, uint32_t aCaretOffset)
|
||||||
|
{
|
||||||
|
nsEventStatus status;
|
||||||
|
WidgetQueryContentEvent caretRect(true, NS_QUERY_CARET_RECT, this);
|
||||||
|
InitEvent(caretRect, nullptr);
|
||||||
|
caretRect.InitForQueryCaretRect(aCaretOffset);
|
||||||
|
DispatchEvent(&caretRect, status);
|
||||||
|
NS_ENSURE_TRUE(caretRect.mSucceeded, false);
|
||||||
|
|
||||||
|
aCaretRect = caretRect.mReply.mRect;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
PuppetWidget::NotifyIMEOfEditorRect()
|
PuppetWidget::NotifyIMEOfEditorRect()
|
||||||
{
|
{
|
||||||
#ifndef MOZ_CROSS_PROCESS_IME
|
#ifndef MOZ_CROSS_PROCESS_IME
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
#endif
|
#endif
|
||||||
|
if (NS_WARN_IF(!mTabChild)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIntRect rect;
|
||||||
|
if (!GetEditorRect(rect)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
mTabChild->SendNotifyIMEEditorRect(rect);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PuppetWidget::GetEditorRect(nsIntRect& aRect)
|
||||||
|
{
|
||||||
nsEventStatus status;
|
nsEventStatus status;
|
||||||
WidgetQueryContentEvent editorRectEvent(true, NS_QUERY_EDITOR_RECT, this);
|
WidgetQueryContentEvent editorRectEvent(true, NS_QUERY_EDITOR_RECT, this);
|
||||||
InitEvent(editorRectEvent);
|
InitEvent(editorRectEvent);
|
||||||
DispatchEvent(&editorRectEvent, status);
|
DispatchEvent(&editorRectEvent, status);
|
||||||
if (editorRectEvent.mSucceeded) {
|
if (NS_WARN_IF(!editorRectEvent.mSucceeded)) {
|
||||||
mTabChild->SendNotifyIMEEditorRect(editorRectEvent.mReply.mRect);
|
return false;
|
||||||
}
|
}
|
||||||
|
aRect = editorRectEvent.mReply.mRect;
|
||||||
|
|
||||||
return NS_OK;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nsIMEUpdatePreference
|
nsIMEUpdatePreference
|
||||||
PuppetWidget::GetIMEUpdatePreference()
|
PuppetWidget::GetIMEUpdatePreference()
|
||||||
{
|
{
|
||||||
|
@ -604,7 +659,8 @@ PuppetWidget::GetIMEUpdatePreference()
|
||||||
// e10s requires IME information cache into TabParent
|
// e10s requires IME information cache into TabParent
|
||||||
return nsIMEUpdatePreference(mIMEPreferenceOfParent.mWantUpdates |
|
return nsIMEUpdatePreference(mIMEPreferenceOfParent.mWantUpdates |
|
||||||
nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
|
nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
|
||||||
nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE);
|
nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE |
|
||||||
|
nsIMEUpdatePreference::NOTIFY_POSITION_CHANGE );
|
||||||
#else
|
#else
|
||||||
// B2G doesn't handle IME as widget-level.
|
// B2G doesn't handle IME as widget-level.
|
||||||
return nsIMEUpdatePreference();
|
return nsIMEUpdatePreference();
|
||||||
|
@ -695,6 +751,40 @@ PuppetWidget::NotifyIMEOfMouseButtonEvent(
|
||||||
return consumedByIME ? NS_SUCCESS_EVENT_CONSUMED : NS_OK;
|
return consumedByIME ? NS_SUCCESS_EVENT_CONSUMED : NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
PuppetWidget::NotifyIMEOfPositionChange()
|
||||||
|
{
|
||||||
|
#ifndef MOZ_CROSS_PROCESS_IME
|
||||||
|
return NS_OK;
|
||||||
|
#endif
|
||||||
|
if (NS_WARN_IF(!mTabChild)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIntRect editorRect;
|
||||||
|
if (!GetEditorRect(editorRect)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t startOffset;
|
||||||
|
uint32_t targetCauseOffset;
|
||||||
|
nsAutoTArray<nsIntRect, 16> textRectArray;
|
||||||
|
if (!GetCompositionRects(startOffset,
|
||||||
|
textRectArray,
|
||||||
|
targetCauseOffset)) {
|
||||||
|
// no composition string, get caret offset by NS_QUERY_SELECTED_TEXT
|
||||||
|
targetCauseOffset = GetCaretOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIntRect caretRect;
|
||||||
|
GetCaretRect(caretRect, targetCauseOffset);
|
||||||
|
if (!mTabChild->SendNotifyIMEPositionChange(editorRect, textRectArray,
|
||||||
|
caretRect)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
PuppetWidget::SetCursor(nsCursor aCursor)
|
PuppetWidget::SetCursor(nsCursor aCursor)
|
||||||
{
|
{
|
||||||
|
|
|
@ -217,6 +217,14 @@ private:
|
||||||
nsresult NotifyIMEOfTextChange(const IMENotification& aIMENotification);
|
nsresult NotifyIMEOfTextChange(const IMENotification& aIMENotification);
|
||||||
nsresult NotifyIMEOfMouseButtonEvent(const IMENotification& aIMENotification);
|
nsresult NotifyIMEOfMouseButtonEvent(const IMENotification& aIMENotification);
|
||||||
nsresult NotifyIMEOfEditorRect();
|
nsresult NotifyIMEOfEditorRect();
|
||||||
|
nsresult NotifyIMEOfPositionChange();
|
||||||
|
|
||||||
|
bool GetEditorRect(nsIntRect& aEditorRect);
|
||||||
|
bool GetCompositionRects(uint32_t& aStartOffset,
|
||||||
|
nsTArray<nsIntRect>& aRectArray,
|
||||||
|
uint32_t& aTargetCauseOffset);
|
||||||
|
bool GetCaretRect(nsIntRect& aCaretRect, uint32_t aCaretOffset);
|
||||||
|
uint32_t GetCaretOffset();
|
||||||
|
|
||||||
class PaintTask : public nsRunnable {
|
class PaintTask : public nsRunnable {
|
||||||
public:
|
public:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче