mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1690827 - part 1: Number each composition for native IME or synthesized in the parent process r=smaug
For handling (ignoring) "too late" composition commit request from content process, we need to distinguish a request is for which composition. Therefore, we need to number each composition originated in the parent process. This patch makes `TextComposition` instance which is created at first composition event for a composition consider a composition ID in the parent process and set it to composition events which are dispatched into the DOM tree in the parent or sent to a remote process. And also this patch adds the composition ID param to the request method of committing composition and reply methods to notify the parent process of ending a composition event handling. The last patch handle them in `ContentCacheInParent` to consider whether a request/reply should be ignored or handled. Differential Revision: https://phabricator.services.mozilla.com/D179310
This commit is contained in:
parent
765a840831
commit
cb321ed332
@ -306,7 +306,7 @@ void IMEStateManager::MaybeStartOffsetUpdatedInChild(nsIWidget* aWidget,
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<TextComposition> composition = GetTextCompositionFor(aWidget);
|
||||
TextComposition* const composition = GetTextCompositionFor(aWidget);
|
||||
if (NS_WARN_IF(!composition)) {
|
||||
MOZ_LOG(sISMLog, LogLevel::Warning,
|
||||
("MaybeStartOffsetUpdatedInChild(aWidget=0x%p, aStartOffset=%u), "
|
||||
@ -2328,36 +2328,24 @@ nsresult IMEStateManager::GetFocusSelectionAndRootElement(
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<TextComposition> IMEStateManager::GetTextCompositionFor(
|
||||
nsIWidget* aWidget) {
|
||||
if (!sTextCompositions) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<TextComposition> textComposition =
|
||||
sTextCompositions->GetCompositionFor(aWidget);
|
||||
return textComposition.forget();
|
||||
TextComposition* IMEStateManager::GetTextCompositionFor(nsIWidget* aWidget) {
|
||||
return sTextCompositions ? sTextCompositions->GetCompositionFor(aWidget)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<TextComposition> IMEStateManager::GetTextCompositionFor(
|
||||
TextComposition* IMEStateManager::GetTextCompositionFor(
|
||||
const WidgetCompositionEvent* aCompositionEvent) {
|
||||
if (!sTextCompositions) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<TextComposition> textComposition =
|
||||
sTextCompositions->GetCompositionFor(aCompositionEvent);
|
||||
return textComposition.forget();
|
||||
return sTextCompositions
|
||||
? sTextCompositions->GetCompositionFor(aCompositionEvent)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<TextComposition> IMEStateManager::GetTextCompositionFor(
|
||||
TextComposition* IMEStateManager::GetTextCompositionFor(
|
||||
nsPresContext* aPresContext) {
|
||||
if (!sTextCompositions) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<TextComposition> textComposition =
|
||||
sTextCompositions->GetCompositionFor(aPresContext);
|
||||
return textComposition.forget();
|
||||
return sTextCompositions ? sTextCompositions->GetCompositionFor(aPresContext)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -277,13 +277,12 @@ class IMEStateManager {
|
||||
/**
|
||||
* Get TextComposition from widget.
|
||||
*/
|
||||
static already_AddRefed<TextComposition> GetTextCompositionFor(
|
||||
nsIWidget* aWidget);
|
||||
static TextComposition* GetTextCompositionFor(nsIWidget* aWidget);
|
||||
|
||||
/**
|
||||
* Returns TextComposition instance for the event.
|
||||
*/
|
||||
static already_AddRefed<TextComposition> GetTextCompositionFor(
|
||||
static TextComposition* GetTextCompositionFor(
|
||||
const WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
/**
|
||||
@ -291,8 +290,7 @@ class IMEStateManager {
|
||||
* Be aware, even if another pres context which shares native IME context with
|
||||
* specified pres context has composition, this returns nullptr.
|
||||
*/
|
||||
static already_AddRefed<TextComposition> GetTextCompositionFor(
|
||||
nsPresContext* aPresContext);
|
||||
static TextComposition* GetTextCompositionFor(nsPresContext* aPresContext);
|
||||
|
||||
/**
|
||||
* Send a notification to IME. It depends on the IME or platform spec what
|
||||
|
@ -45,6 +45,26 @@ namespace mozilla {
|
||||
|
||||
#define IDEOGRAPHIC_SPACE (u"\x3000"_ns)
|
||||
|
||||
static uint32_t GetOrCreateCompositionId(WidgetCompositionEvent* aEvent) {
|
||||
// If we're in the parent process, return new composition ID.
|
||||
if (XRE_IsParentProcess()) {
|
||||
static uint32_t sNextCompositionId = 1u;
|
||||
if (MOZ_UNLIKELY(sNextCompositionId == UINT32_MAX)) {
|
||||
sNextCompositionId = 1u;
|
||||
}
|
||||
// FYI: When we send the event to a remote process, TextComposition will
|
||||
// set aEvent->mCompositionId to this value. Therefore, we don't need to
|
||||
// set it here.
|
||||
return sNextCompositionId++;
|
||||
}
|
||||
// If aEvent comes from the parent process, the event has composition ID
|
||||
// considered by the parent process. Then, we should use it.
|
||||
// Otherwise, aEvent is synthesized in this process, it won't cross the
|
||||
// process boundary between this process and the parent process. Therefore,
|
||||
// we don't need to set meaningful composition ID for the text composition.
|
||||
return aEvent->mCompositionId;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* TextComposition
|
||||
******************************************************************************/
|
||||
@ -58,6 +78,7 @@ TextComposition::TextComposition(nsPresContext* aPresContext, nsINode* aNode,
|
||||
mNode(aNode),
|
||||
mBrowserParent(aBrowserParent),
|
||||
mNativeContext(aCompositionEvent->mNativeIMEContext),
|
||||
mCompositionId(GetOrCreateCompositionId(aCompositionEvent)),
|
||||
mCompositionStartOffset(0),
|
||||
mTargetClauseOffsetInComposition(0),
|
||||
mCompositionStartOffsetInTextNode(UINT32_MAX),
|
||||
@ -244,8 +265,8 @@ void TextComposition::OnCompositionEventDiscarded(
|
||||
"Shouldn't be called with untrusted event");
|
||||
|
||||
if (mBrowserParent) {
|
||||
// The composition event should be discarded in the child process too.
|
||||
Unused << mBrowserParent->SendCompositionEvent(*aCompositionEvent);
|
||||
Unused << mBrowserParent->SendCompositionEvent(*aCompositionEvent,
|
||||
mCompositionId);
|
||||
}
|
||||
|
||||
// XXX If composition events are discarded, should we dispatch them with
|
||||
@ -343,7 +364,8 @@ void TextComposition::DispatchCompositionEvent(
|
||||
// If the content is a container of BrowserParent, composition should be in
|
||||
// the remote process.
|
||||
if (mBrowserParent) {
|
||||
Unused << mBrowserParent->SendCompositionEvent(*aCompositionEvent);
|
||||
Unused << mBrowserParent->SendCompositionEvent(*aCompositionEvent,
|
||||
mCompositionId);
|
||||
aCompositionEvent->StopPropagation();
|
||||
if (aCompositionEvent->CausesDOMTextEvent()) {
|
||||
mLastData = aCompositionEvent->mData;
|
||||
@ -644,6 +666,7 @@ void TextComposition::DispatchCompositionEventRunnable(
|
||||
}
|
||||
|
||||
nsresult TextComposition::RequestToCommit(nsIWidget* aWidget, bool aDiscard) {
|
||||
MOZ_ASSERT(this == IMEStateManager::GetTextCompositionFor(aWidget));
|
||||
// If this composition is already requested to be committed or canceled,
|
||||
// or has already finished in IME, we don't need to request it again because
|
||||
// request from this instance shouldn't cause committing nor canceling current
|
||||
|
@ -51,6 +51,8 @@ class TextComposition final {
|
||||
TextComposition(nsPresContext* aPresContext, nsINode* aNode,
|
||||
BrowserParent* aBrowserParent,
|
||||
WidgetCompositionEvent* aCompositionEvent);
|
||||
TextComposition() = delete;
|
||||
TextComposition(const TextComposition& aOther) = delete;
|
||||
|
||||
bool Destroyed() const { return !mPresContext; }
|
||||
nsPresContext* GetPresContext() const { return mPresContext; }
|
||||
@ -92,6 +94,10 @@ class TextComposition final {
|
||||
// came from nsDOMWindowUtils.
|
||||
bool IsSynthesizedForTests() const { return mIsSynthesizedForTests; }
|
||||
|
||||
// Returns the composition ID. It must be 0 if the composition is synthesized
|
||||
// in a content process. Otherwise, returns 1 or larger value.
|
||||
uint32_t Id() const { return mCompositionId; }
|
||||
|
||||
const widget::NativeIMEContext& GetNativeIMEContext() const {
|
||||
return mNativeContext;
|
||||
}
|
||||
@ -323,6 +329,11 @@ class TextComposition final {
|
||||
// editor.
|
||||
nsString mString;
|
||||
|
||||
// Composition ID of this composition. If this is in a parent process,
|
||||
// this is 1 or larger. If the composition is created for managing a
|
||||
// composition synthesized in a content process, this is 0.
|
||||
const uint32_t mCompositionId = 0;
|
||||
|
||||
// Offset of the composition string from start of the editor
|
||||
uint32_t mCompositionStartOffset;
|
||||
// Offset of the selected clause of the composition string from
|
||||
@ -387,26 +398,6 @@ class TextComposition final {
|
||||
// when DispatchCompositionEvent() is called.
|
||||
bool mWasCompositionStringEmpty;
|
||||
|
||||
// Hide the default constructor and copy constructor.
|
||||
TextComposition()
|
||||
: mPresContext(nullptr),
|
||||
mNativeContext(nullptr),
|
||||
mCompositionStartOffset(0),
|
||||
mTargetClauseOffsetInComposition(0),
|
||||
mCompositionStartOffsetInTextNode(UINT32_MAX),
|
||||
mCompositionLengthInTextNode(UINT32_MAX),
|
||||
mIsSynthesizedForTests(false),
|
||||
mIsComposing(false),
|
||||
mIsEditorHandlingEvent(false),
|
||||
mIsRequestingCommit(false),
|
||||
mIsRequestingCancel(false),
|
||||
mRequestedToCommitOrCancel(false),
|
||||
mHasReceivedCommitEvent(false),
|
||||
mWasNativeCompositionEndEventDiscarded(false),
|
||||
mAllowControlCharacters(false),
|
||||
mWasCompositionStringEmpty(true) {}
|
||||
TextComposition(const TextComposition& aOther);
|
||||
|
||||
/**
|
||||
* If we're requesting IME to commit or cancel composition, or we've already
|
||||
* requested it, or we've already known this composition has been ended in
|
||||
|
@ -2088,7 +2088,8 @@ mozilla::ipc::IPCResult BrowserChild::RecvCompositionEvent(
|
||||
WidgetCompositionEvent localEvent(aEvent);
|
||||
localEvent.mWidget = mPuppetWidget;
|
||||
DispatchWidgetEventViaAPZ(localEvent);
|
||||
Unused << SendOnEventNeedingAckHandled(aEvent.mMessage);
|
||||
Unused << SendOnEventNeedingAckHandled(aEvent.mMessage,
|
||||
localEvent.mCompositionId);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
@ -2102,7 +2103,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvSelectionEvent(
|
||||
WidgetSelectionEvent localEvent(aEvent);
|
||||
localEvent.mWidget = mPuppetWidget;
|
||||
DispatchWidgetEventViaAPZ(localEvent);
|
||||
Unused << SendOnEventNeedingAckHandled(aEvent.mMessage);
|
||||
Unused << SendOnEventNeedingAckHandled(aEvent.mMessage, 0u);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -2404,7 +2404,7 @@ mozilla::ipc::IPCResult BrowserParent::RecvNotifyIMEPositionChange(
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserParent::RecvOnEventNeedingAckHandled(
|
||||
const EventMessage& aMessage) {
|
||||
const EventMessage& aMessage, const uint32_t& aCompositionId) {
|
||||
// This is called when the child process receives WidgetCompositionEvent or
|
||||
// WidgetSelectionEvent.
|
||||
// FYI: Don't check if widget is nullptr here because it's more important to
|
||||
@ -2414,7 +2414,7 @@ mozilla::ipc::IPCResult BrowserParent::RecvOnEventNeedingAckHandled(
|
||||
// While calling OnEventNeedingAckHandled(), BrowserParent *might* be
|
||||
// destroyed since it may send notifications to IME.
|
||||
RefPtr<BrowserParent> kungFuDeathGrip(this);
|
||||
mContentCache.OnEventNeedingAckHandled(widget, aMessage);
|
||||
mContentCache.OnEventNeedingAckHandled(widget, aMessage, aCompositionId);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
@ -3057,11 +3057,19 @@ bool BrowserParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BrowserParent::SendCompositionEvent(WidgetCompositionEvent& aEvent) {
|
||||
bool BrowserParent::SendCompositionEvent(WidgetCompositionEvent& aEvent,
|
||||
uint32_t aCompositionId) {
|
||||
if (mIsDestroyed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// When the composition is handled in a remote process, we need to handle
|
||||
// commit/cancel result for composition with the composition ID to avoid
|
||||
// to abort newer composition. Therefore, we need to let the remote process
|
||||
// know the composition ID.
|
||||
MOZ_ASSERT(aCompositionId != 0);
|
||||
aEvent.mCompositionId = aCompositionId;
|
||||
|
||||
if (!mContentCache.OnCompositionEvent(aEvent)) {
|
||||
return true;
|
||||
}
|
||||
@ -3215,7 +3223,8 @@ void BrowserParent::UnsetLastMouseRemoteTarget(BrowserParent* aBrowserParent) {
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserParent::RecvRequestIMEToCommitComposition(
|
||||
const bool& aCancel, bool* aIsCommitted, nsString* aCommittedString) {
|
||||
const bool& aCancel, const uint32_t& aCompositionId, bool* aIsCommitted,
|
||||
nsString* aCommittedString) {
|
||||
nsCOMPtr<nsIWidget> widget = GetTextInputHandlingWidget();
|
||||
if (!widget) {
|
||||
*aIsCommitted = false;
|
||||
@ -3223,7 +3232,7 @@ mozilla::ipc::IPCResult BrowserParent::RecvRequestIMEToCommitComposition(
|
||||
}
|
||||
|
||||
*aIsCommitted = mContentCache.RequestIMEToCommitComposition(
|
||||
widget, aCancel, *aCommittedString);
|
||||
widget, aCancel, aCompositionId, *aCommittedString);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -353,10 +353,11 @@ class BrowserParent final : public PBrowserParent,
|
||||
const widget::IMENotification& aEventMessage);
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnEventNeedingAckHandled(
|
||||
const EventMessage& aMessage);
|
||||
const EventMessage& aMessage, const uint32_t& aCompositionId);
|
||||
|
||||
mozilla::ipc::IPCResult RecvRequestIMEToCommitComposition(
|
||||
const bool& aCancel, bool* aIsCommitted, nsString* aCommittedString);
|
||||
const bool& aCancel, const uint32_t& aCompositionId, bool* aIsCommitted,
|
||||
nsString* aCommittedString);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetInputContext(widget::IMEState* aIMEState);
|
||||
|
||||
@ -580,7 +581,8 @@ class BrowserParent final : public PBrowserParent,
|
||||
* If you need to check if it's actually posted to the remote process,
|
||||
* you can refer aEvent.HasBeenPostedToRemoteProcess().
|
||||
*/
|
||||
bool SendCompositionEvent(mozilla::WidgetCompositionEvent& aEvent);
|
||||
bool SendCompositionEvent(mozilla::WidgetCompositionEvent& aEvent,
|
||||
uint32_t aCompositionId);
|
||||
|
||||
bool SendSelectionEvent(mozilla::WidgetSelectionEvent& aEvent);
|
||||
|
||||
|
@ -318,6 +318,8 @@ parent:
|
||||
* Requests chrome to commit or cancel composition of IME.
|
||||
*
|
||||
* cancel Set true if composition should be cancelled.
|
||||
* compositionId Set the composition ID to requesting commit
|
||||
* (stored in TextComposition).
|
||||
*
|
||||
* isCommitted Returns true if the request causes composition
|
||||
* being committed synchronously.
|
||||
@ -326,7 +328,8 @@ parent:
|
||||
* try to restore selected string which was
|
||||
* replaced with the composition.
|
||||
*/
|
||||
[Nested=inside_cpow] sync RequestIMEToCommitComposition(bool cancel)
|
||||
[Nested=inside_cpow] sync RequestIMEToCommitComposition(bool cancel,
|
||||
uint32_t aCompositionId)
|
||||
returns (bool isCommitted, nsString committedString);
|
||||
|
||||
/**
|
||||
@ -334,9 +337,13 @@ parent:
|
||||
* composition event or a selection event which is sent from the parent
|
||||
* process.
|
||||
*
|
||||
* message The message value of the handled event.
|
||||
* message The message value of the handled event.
|
||||
* compositionId The composition ID of handled composition event if
|
||||
* the message is a composition event message. Otherwise,
|
||||
* 0.
|
||||
*/
|
||||
[Nested=inside_cpow] async OnEventNeedingAckHandled(EventMessage message);
|
||||
[Nested=inside_cpow] async OnEventNeedingAckHandled(EventMessage message,
|
||||
uint32_t compositionId);
|
||||
|
||||
/**
|
||||
* Request that the parent process move focus to the browser's frame. If
|
||||
|
@ -1389,19 +1389,21 @@ void ContentCacheInParent::OnSelectionEvent(
|
||||
}
|
||||
|
||||
void ContentCacheInParent::OnEventNeedingAckHandled(nsIWidget* aWidget,
|
||||
EventMessage aMessage) {
|
||||
EventMessage aMessage,
|
||||
uint32_t aCompositionId) {
|
||||
// This is called when the child process receives WidgetCompositionEvent or
|
||||
// WidgetSelectionEvent.
|
||||
|
||||
MOZ_LOG(
|
||||
sContentCacheLog, LogLevel::Info,
|
||||
("0x%p OnEventNeedingAckHandled(aWidget=0x%p, "
|
||||
"aMessage=%s), mPendingEventsNeedingAck=%u, "
|
||||
"aMessage=%s, aCompositionId=%" PRIu32 "), mPendingEventsNeedingAck=%u, "
|
||||
"mWidgetHasComposition=%s, mPendingCompositionCount=%" PRIu8 ", "
|
||||
"mPendingCommitCount=%" PRIu8 ", mIsChildIgnoringCompositionEvents=%s",
|
||||
this, aWidget, ToChar(aMessage), mPendingEventsNeedingAck,
|
||||
GetBoolName(mWidgetHasComposition), mPendingCompositionCount,
|
||||
mPendingCommitCount, GetBoolName(mIsChildIgnoringCompositionEvents)));
|
||||
this, aWidget, ToChar(aMessage), aCompositionId,
|
||||
mPendingEventsNeedingAck, GetBoolName(mWidgetHasComposition),
|
||||
mPendingCompositionCount, mPendingCommitCount,
|
||||
GetBoolName(mIsChildIgnoringCompositionEvents)));
|
||||
|
||||
#if MOZ_DIAGNOSTIC_ASSERT_ENABLED && !defined(FUZZING_SNAPSHOT)
|
||||
mReceivedEventMessages.AppendElement(aMessage);
|
||||
@ -1513,16 +1515,19 @@ void ContentCacheInParent::OnEventNeedingAckHandled(nsIWidget* aWidget,
|
||||
}
|
||||
|
||||
bool ContentCacheInParent::RequestIMEToCommitComposition(
|
||||
nsIWidget* aWidget, bool aCancel, nsAString& aCommittedString) {
|
||||
nsIWidget* aWidget, bool aCancel, uint32_t aCompositionId,
|
||||
nsAString& aCommittedString) {
|
||||
MOZ_LOG(
|
||||
sContentCacheLog, LogLevel::Info,
|
||||
("0x%p RequestToCommitComposition(aWidget=%p, "
|
||||
"aCancel=%s), mPendingCompositionCount=%" PRIu8 ", "
|
||||
"mPendingCommitCount=%" PRIu8 ", mIsChildIgnoringCompositionEvents=%s, "
|
||||
"aCancel=%s, aCompositionId=%" PRIu32
|
||||
"), mPendingCompositionCount=%" PRIu8 ", mPendingCommitCount=%" PRIu8
|
||||
", mIsChildIgnoringCompositionEvents=%s, "
|
||||
"IMEStateManager::DoesBrowserParentHaveIMEFocus(&mBrowserParent)=%s, "
|
||||
"mWidgetHasComposition=%s, mCommitStringByRequest=%p",
|
||||
this, aWidget, GetBoolName(aCancel), mPendingCompositionCount,
|
||||
mPendingCommitCount, GetBoolName(mIsChildIgnoringCompositionEvents),
|
||||
this, aWidget, GetBoolName(aCancel), aCompositionId,
|
||||
mPendingCompositionCount, mPendingCommitCount,
|
||||
GetBoolName(mIsChildIgnoringCompositionEvents),
|
||||
GetBoolName(
|
||||
IMEStateManager::DoesBrowserParentHaveIMEFocus(&mBrowserParent)),
|
||||
GetBoolName(mWidgetHasComposition), mCommitStringByRequest));
|
||||
|
@ -426,7 +426,8 @@ class ContentCacheInParent final : public ContentCache {
|
||||
* BrowserParent or aWidget. Therefore, the caller must not destroy
|
||||
* this instance during a call of this method.
|
||||
*/
|
||||
void OnEventNeedingAckHandled(nsIWidget* aWidget, EventMessage aMessage);
|
||||
void OnEventNeedingAckHandled(nsIWidget* aWidget, EventMessage aMessage,
|
||||
uint32_t aCompositionId);
|
||||
|
||||
/**
|
||||
* RequestIMEToCommitComposition() requests aWidget to commit or cancel
|
||||
@ -436,6 +437,9 @@ class ContentCacheInParent final : public ContentCache {
|
||||
* the composition.
|
||||
* @param aCancel When the caller tries to cancel the composition, true.
|
||||
* Otherwise, i.e., tries to commit the composition, false.
|
||||
* @param aCompositionId
|
||||
* The composition ID which should be committed or
|
||||
* canceled.
|
||||
* @param aCommittedString The committed string (i.e., the last data of
|
||||
* dispatched composition events during requesting
|
||||
* IME to commit composition.
|
||||
@ -443,6 +447,7 @@ class ContentCacheInParent final : public ContentCache {
|
||||
* synchronously.
|
||||
*/
|
||||
bool RequestIMEToCommitComposition(nsIWidget* aWidget, bool aCancel,
|
||||
uint32_t aCompositionId,
|
||||
nsAString& aCommittedString);
|
||||
|
||||
/**
|
||||
|
@ -371,6 +371,9 @@ struct NativeIMEContext final {
|
||||
// See also NS_ONLY_ONE_NATIVE_IME_CONTEXT.
|
||||
uintptr_t mRawNativeIMEContext;
|
||||
// Process ID of the origin of mNativeIMEContext.
|
||||
// static_cast<uint64_t>(-1) if the instance is not initialized properly.
|
||||
// 0 if the instance is originated in the parent process.
|
||||
// 1 or greater if the instance is originated in a content process.
|
||||
uint64_t mOriginProcessID;
|
||||
|
||||
NativeIMEContext() : mRawNativeIMEContext(0), mOriginProcessID(0) {
|
||||
@ -384,7 +387,12 @@ struct NativeIMEContext final {
|
||||
|
||||
bool IsValid() const {
|
||||
return mRawNativeIMEContext &&
|
||||
mOriginProcessID != static_cast<uintptr_t>(-1);
|
||||
mOriginProcessID != static_cast<uint64_t>(-1);
|
||||
}
|
||||
|
||||
bool IsOriginatedInParentProcess() const {
|
||||
return mOriginProcessID != 0 &&
|
||||
mOriginProcessID != static_cast<uint64_t>(-1);
|
||||
}
|
||||
|
||||
void Init(nsIWidget* aWidget);
|
||||
|
@ -645,7 +645,7 @@ nsresult PuppetWidget::RequestIMEToCommitComposition(bool aCancel) {
|
||||
bool isCommitted = false;
|
||||
nsAutoString committedString;
|
||||
if (NS_WARN_IF(!mBrowserChild->SendRequestIMEToCommitComposition(
|
||||
aCancel, &isCommitted, &committedString))) {
|
||||
aCancel, composition->Id(), &isCommitted, &committedString))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -673,7 +673,7 @@ nsresult PuppetWidget::RequestIMEToCommitComposition(bool aCancel) {
|
||||
mIgnoreCompositionEvents = true;
|
||||
|
||||
Unused << mBrowserChild->SendOnEventNeedingAckHandled(
|
||||
eCompositionCommitRequestHandled);
|
||||
eCompositionCommitRequestHandled, composition->Id());
|
||||
|
||||
// NOTE: PuppetWidget might be destroyed already.
|
||||
return NS_OK;
|
||||
|
@ -885,6 +885,11 @@ class WidgetCompositionEvent : public WidgetGUIEvent {
|
||||
// the another event's mMessage.
|
||||
EventMessage mOriginalMessage;
|
||||
|
||||
// Composition ID considered by TextComposition. If the event has not been
|
||||
// handled by TextComposition yet, this is 0. And also if the event is for
|
||||
// a composition synthesized in a content process, this is always 0.
|
||||
uint32_t mCompositionId = 0;
|
||||
|
||||
void AssignCompositionEventData(const WidgetCompositionEvent& aEvent,
|
||||
bool aCopyTargets) {
|
||||
AssignGUIEventData(aEvent, aCopyTargets);
|
||||
|
@ -551,6 +551,7 @@ struct ParamTraits<mozilla::WidgetCompositionEvent> {
|
||||
WriteParam(aWriter, static_cast<const mozilla::WidgetGUIEvent&>(aParam));
|
||||
WriteParam(aWriter, aParam.mData);
|
||||
WriteParam(aWriter, aParam.mNativeIMEContext);
|
||||
WriteParam(aWriter, aParam.mCompositionId);
|
||||
bool hasRanges = !!aParam.mRanges;
|
||||
WriteParam(aWriter, hasRanges);
|
||||
if (hasRanges) {
|
||||
@ -563,6 +564,7 @@ struct ParamTraits<mozilla::WidgetCompositionEvent> {
|
||||
if (!ReadParam(aReader, static_cast<mozilla::WidgetGUIEvent*>(aResult)) ||
|
||||
!ReadParam(aReader, &aResult->mData) ||
|
||||
!ReadParam(aReader, &aResult->mNativeIMEContext) ||
|
||||
!ReadParam(aReader, &aResult->mCompositionId) ||
|
||||
!ReadParam(aReader, &hasRanges)) {
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user