mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 966157 - Part 2. Child process should listen NOTIFY_IME_OF_POSITION_CHANGE. r=masayuki
This commit is contained in:
parent
327fa03357
commit
846f5a8420
@ -234,6 +234,16 @@ parent:
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
@ -1495,6 +1495,29 @@ TabParent::RecvNotifyIMEEditorRect(const nsIntRect& aRect)
|
||||
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
|
||||
TabParent::RecvRequestFocus(const bool& aCanRaise)
|
||||
{
|
||||
|
@ -179,6 +179,10 @@ public:
|
||||
virtual bool RecvNotifyIMEMouseButtonEvent(const widget::IMENotification& aEventMessage,
|
||||
bool* aConsumedByIME) 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,
|
||||
nsString* aComposition) MOZ_OVERRIDE;
|
||||
virtual bool RecvGetInputContext(int32_t* aIMEEnabled,
|
||||
|
@ -448,6 +448,8 @@ PuppetWidget::NotifyIME(const IMENotification& aIMENotification)
|
||||
return NotifyIMEOfUpdateComposition();
|
||||
case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
|
||||
return NotifyIMEOfMouseButtonEvent(aIMENotification);
|
||||
case NOTIFY_IME_OF_POSITION_CHANGE:
|
||||
return NotifyIMEOfPositionChange();
|
||||
default:
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
@ -546,57 +548,110 @@ PuppetWidget::NotifyIMEOfUpdateComposition()
|
||||
|
||||
NS_ENSURE_TRUE(mTabChild, NS_ERROR_FAILURE);
|
||||
|
||||
nsRefPtr<TextComposition> textComposition =
|
||||
IMEStateManager::GetTextCompositionFor(this);
|
||||
NS_ENSURE_TRUE(textComposition, NS_ERROR_FAILURE);
|
||||
|
||||
nsEventStatus status;
|
||||
nsTArray<nsIntRect> textRectArray(textComposition->String().Length());
|
||||
uint32_t startOffset = textComposition->NativeOffsetOfStartComposition();
|
||||
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);
|
||||
uint32_t startOffset;
|
||||
uint32_t targetCauseOffset;
|
||||
nsAutoTArray<nsIntRect, 16> textRectArray;
|
||||
if (!GetCompositionRects(startOffset,
|
||||
textRectArray,
|
||||
targetCauseOffset)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uint32_t targetCauseOffset = textComposition->OffsetOfTargetClause();
|
||||
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);
|
||||
nsIntRect caretRect;
|
||||
GetCaretRect(caretRect, targetCauseOffset);
|
||||
|
||||
mTabChild->SendNotifyIMESelectedCompositionRect(startOffset,
|
||||
textRectArray,
|
||||
targetCauseOffset,
|
||||
caretRect.mReply.mRect);
|
||||
caretRect);
|
||||
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
|
||||
PuppetWidget::NotifyIMEOfEditorRect()
|
||||
{
|
||||
#ifndef MOZ_CROSS_PROCESS_IME
|
||||
return NS_OK;
|
||||
#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;
|
||||
WidgetQueryContentEvent editorRectEvent(true, NS_QUERY_EDITOR_RECT, this);
|
||||
InitEvent(editorRectEvent);
|
||||
DispatchEvent(&editorRectEvent, status);
|
||||
if (editorRectEvent.mSucceeded) {
|
||||
mTabChild->SendNotifyIMEEditorRect(editorRectEvent.mReply.mRect);
|
||||
if (NS_WARN_IF(!editorRectEvent.mSucceeded)) {
|
||||
return false;
|
||||
}
|
||||
aRect = editorRectEvent.mReply.mRect;
|
||||
|
||||
return NS_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
nsIMEUpdatePreference
|
||||
PuppetWidget::GetIMEUpdatePreference()
|
||||
{
|
||||
@ -604,7 +659,8 @@ PuppetWidget::GetIMEUpdatePreference()
|
||||
// e10s requires IME information cache into TabParent
|
||||
return nsIMEUpdatePreference(mIMEPreferenceOfParent.mWantUpdates |
|
||||
nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE |
|
||||
nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE);
|
||||
nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE |
|
||||
nsIMEUpdatePreference::NOTIFY_POSITION_CHANGE );
|
||||
#else
|
||||
// B2G doesn't handle IME as widget-level.
|
||||
return nsIMEUpdatePreference();
|
||||
@ -695,6 +751,40 @@ PuppetWidget::NotifyIMEOfMouseButtonEvent(
|
||||
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
|
||||
PuppetWidget::SetCursor(nsCursor aCursor)
|
||||
{
|
||||
|
@ -217,6 +217,14 @@ private:
|
||||
nsresult NotifyIMEOfTextChange(const IMENotification& aIMENotification);
|
||||
nsresult NotifyIMEOfMouseButtonEvent(const IMENotification& aIMENotification);
|
||||
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 {
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user