mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1130937 part.2 nsGtkIMModule should set candidiate window position to bottom left of the target clause in vertical writing mode r=m_kato
This commit is contained in:
parent
8d0ec572a9
commit
518ed96e43
@ -410,6 +410,15 @@ public:
|
||||
return mRanges ? mRanges->TargetClauseOffset() : 0;
|
||||
}
|
||||
|
||||
uint32_t TargetClauseLength() const
|
||||
{
|
||||
uint32_t length = UINT32_MAX;
|
||||
if (mRanges) {
|
||||
length = mRanges->TargetClauseLength();
|
||||
}
|
||||
return length == UINT32_MAX ? mData.Length() : length;
|
||||
}
|
||||
|
||||
uint32_t RangeCount() const
|
||||
{
|
||||
return mRanges ? mRanges->Length() : 0;
|
||||
|
@ -195,6 +195,18 @@ class TextRangeArray final : public nsAutoTArray<TextRange, 10>
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(TextRangeArray)
|
||||
|
||||
const TextRange* GetTargetClause() const
|
||||
{
|
||||
for (uint32_t i = 0; i < Length(); ++i) {
|
||||
const TextRange& range = ElementAt(i);
|
||||
if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT ||
|
||||
range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) {
|
||||
return ⦥
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
bool IsComposing() const
|
||||
{
|
||||
@ -206,18 +218,20 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns target clase offset. If there are selected clauses, this returns
|
||||
// Returns target clause offset. If there are selected clauses, this returns
|
||||
// the first selected clause offset. Otherwise, 0.
|
||||
uint32_t TargetClauseOffset() const
|
||||
{
|
||||
for (uint32_t i = 0; i < Length(); ++i) {
|
||||
const TextRange& range = ElementAt(i);
|
||||
if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT ||
|
||||
range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) {
|
||||
return range.mStartOffset;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
const TextRange* range = GetTargetClause();
|
||||
return range ? range->mStartOffset : 0;
|
||||
}
|
||||
|
||||
// Returns target clause length. If there are selected clauses, this returns
|
||||
// the first selected clause length. Otherwise, UINT32_MAX.
|
||||
uint32_t TargetClauseLength() const
|
||||
{
|
||||
const TextRange* range = GetTargetClause();
|
||||
return range ? range->Length() : UINT32_MAX;
|
||||
}
|
||||
|
||||
bool Equals(const TextRangeArray& aOther) const
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "mozilla/MiscEvents.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "WritingModes.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
@ -111,7 +112,6 @@ nsGtkIMModule::nsGtkIMModule(nsWindow* aOwnerWindow)
|
||||
, mComposingContext(nullptr)
|
||||
, mCompositionStart(UINT32_MAX)
|
||||
, mProcessingKeyEvent(nullptr)
|
||||
, mCompositionTargetOffset(UINT32_MAX)
|
||||
, mCompositionState(eCompositionState_NotComposing)
|
||||
, mIsIMFocused(false)
|
||||
, mIsDeletingSurrounding(false)
|
||||
@ -535,7 +535,7 @@ nsGtkIMModule::OnUpdateComposition()
|
||||
return;
|
||||
}
|
||||
|
||||
SetCursorPosition(GetActiveContext(), mCompositionTargetOffset);
|
||||
SetCursorPosition(GetActiveContext());
|
||||
}
|
||||
|
||||
void
|
||||
@ -819,7 +819,8 @@ nsGtkIMModule::OnStartCompositionNative(GtkIMContext *aContext)
|
||||
if (!DispatchCompositionStart(aContext)) {
|
||||
return;
|
||||
}
|
||||
mCompositionTargetOffset = mCompositionStart;
|
||||
mCompositionTargetRange.mOffset = mCompositionStart;
|
||||
mCompositionTargetRange.mLength = 0;
|
||||
}
|
||||
|
||||
/* static */
|
||||
@ -1195,7 +1196,9 @@ nsGtkIMModule::DispatchCompositionChangeEvent(
|
||||
// We cannot call SetCursorPosition for e10s-aware.
|
||||
// DispatchEvent is async on e10s, so composition rect isn't updated now
|
||||
// on tab parent.
|
||||
mCompositionTargetOffset = targetOffset;
|
||||
mCompositionTargetRange.mOffset = targetOffset;
|
||||
mCompositionTargetRange.mLength =
|
||||
compositionChangeEvent.mRanges->TargetClauseLength();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1238,7 +1241,7 @@ nsGtkIMModule::DispatchCompositionCommitEvent(
|
||||
NS_COMPOSITION_COMMIT_AS_IS;
|
||||
mCompositionState = eCompositionState_NotComposing;
|
||||
mCompositionStart = UINT32_MAX;
|
||||
mCompositionTargetOffset = UINT32_MAX;
|
||||
mCompositionTargetRange.Clear();
|
||||
mDispatchedCompositionString.Truncate();
|
||||
|
||||
WidgetCompositionEvent compositionCommitEvent(true, message,
|
||||
@ -1393,16 +1396,19 @@ nsGtkIMModule::CreateTextRangeArray(GtkIMContext* aContext,
|
||||
}
|
||||
|
||||
void
|
||||
nsGtkIMModule::SetCursorPosition(GtkIMContext* aContext,
|
||||
uint32_t aTargetOffset)
|
||||
nsGtkIMModule::SetCursorPosition(GtkIMContext* aContext)
|
||||
{
|
||||
MOZ_LOG(gGtkIMLog, LogLevel::Info,
|
||||
("GtkIMModule(%p): SetCursorPosition, aContext=%p, aTargetOffset=%u",
|
||||
this, aContext, aTargetOffset));
|
||||
("GtkIMModule(%p): SetCursorPosition, aContext=%p, "
|
||||
"mCompositionTargetRange={ mOffset=%u, mLength=%u }"
|
||||
"mSelection.mWritingMode=%s",
|
||||
this, aContext, mCompositionTargetRange.mOffset,
|
||||
mCompositionTargetRange.mLength,
|
||||
GetWritingModeName(mSelection.mWritingMode).get()));
|
||||
|
||||
if (aTargetOffset == UINT32_MAX) {
|
||||
if (!mCompositionTargetRange.IsValid()) {
|
||||
MOZ_LOG(gGtkIMLog, LogLevel::Info,
|
||||
(" FAILED, aTargetOffset is wrong offset"));
|
||||
(" FAILED, mCompositionTargetRange is invalid"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1420,7 +1426,15 @@ nsGtkIMModule::SetCursorPosition(GtkIMContext* aContext,
|
||||
|
||||
WidgetQueryContentEvent charRect(true, NS_QUERY_TEXT_RECT,
|
||||
mLastFocusedWindow);
|
||||
charRect.InitForQueryTextRect(aTargetOffset, 1);
|
||||
if (mSelection.mWritingMode.IsVertical()) {
|
||||
// For preventing the candidate window to overlap the target clause,
|
||||
// we should set fake (typically, very tall) caret rect.
|
||||
uint32_t length = mCompositionTargetRange.mLength ?
|
||||
mCompositionTargetRange.mLength : 1;
|
||||
charRect.InitForQueryTextRect(mCompositionTargetRange.mOffset, length);
|
||||
} else {
|
||||
charRect.InitForQueryTextRect(mCompositionTargetRange.mOffset, 1);
|
||||
}
|
||||
InitEvent(charRect);
|
||||
nsEventStatus status;
|
||||
mLastFocusedWindow->DispatchEvent(&charRect, status);
|
||||
@ -1429,6 +1443,7 @@ nsGtkIMModule::SetCursorPosition(GtkIMContext* aContext,
|
||||
(" FAILED, NS_QUERY_TEXT_RECT was failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
nsWindow* rootWindow =
|
||||
static_cast<nsWindow*>(mLastFocusedWindow->GetTopLevelWidget());
|
||||
|
||||
|
@ -125,8 +125,27 @@ protected:
|
||||
// event.
|
||||
GdkEventKey* mProcessingKeyEvent;
|
||||
|
||||
// current target offset of IME composition
|
||||
uint32_t mCompositionTargetOffset;
|
||||
struct Range
|
||||
{
|
||||
uint32_t mOffset;
|
||||
uint32_t mLength;
|
||||
|
||||
Range()
|
||||
: mOffset(UINT32_MAX)
|
||||
, mLength(UINT32_MAX)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsValid() const { return mOffset != UINT32_MAX; }
|
||||
void Clear()
|
||||
{
|
||||
mOffset = UINT32_MAX;
|
||||
mLength = UINT32_MAX;
|
||||
}
|
||||
};
|
||||
|
||||
// current target offset and length of IME composition
|
||||
Range mCompositionTargetRange;
|
||||
|
||||
// mCompositionState indicates current status of composition.
|
||||
enum eCompositionState {
|
||||
@ -327,14 +346,11 @@ protected:
|
||||
const nsAString& aLastDispatchedData);
|
||||
|
||||
/**
|
||||
* Sets the offset's cursor position to IME.
|
||||
* Move the candidate window with "fake" cursor position.
|
||||
*
|
||||
* @param aContext A GtkIMContext which is being handled.
|
||||
* @param aTargetOffset Offset of a character which is anchor of
|
||||
* a candidate window. This is offset in
|
||||
* UTF-16 string.
|
||||
*/
|
||||
void SetCursorPosition(GtkIMContext* aContext, uint32_t aTargetOffset);
|
||||
void SetCursorPosition(GtkIMContext* aContext);
|
||||
|
||||
// Queries the current selection offset of the window.
|
||||
uint32_t GetSelectionOffset(nsWindow* aWindow);
|
||||
|
Loading…
Reference in New Issue
Block a user