зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1179122 TextComposition should manage a composition which is even in a child process r=smaug
This commit is contained in:
Родитель
b9aee98f59
Коммит
b577b3a7ed
|
@ -842,21 +842,6 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
NS_ASSERTION(selectedText.mSucceeded, "Failed to get selected text");
|
||||
compositionEvent->mData = selectedText.mReply.mString;
|
||||
}
|
||||
// through to compositionend handling
|
||||
case NS_COMPOSITION_END:
|
||||
case NS_COMPOSITION_CHANGE:
|
||||
case NS_COMPOSITION_COMMIT_AS_IS:
|
||||
case NS_COMPOSITION_COMMIT:
|
||||
{
|
||||
WidgetCompositionEvent* compositionEvent = aEvent->AsCompositionEvent();
|
||||
if (IsTargetCrossProcess(compositionEvent)) {
|
||||
// Will not be handled locally, remote the event
|
||||
if (GetCrossProcessTarget()->SendCompositionEvent(*compositionEvent)) {
|
||||
// Cancel local dispatching
|
||||
aEvent->mFlags.mPropagationStopped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
@ -1125,16 +1125,20 @@ IMEStateManager::DispatchCompositionEvent(
|
|||
EventDispatchingCallback* aCallBack,
|
||||
bool aIsSynthesized)
|
||||
{
|
||||
nsRefPtr<TabParent> tabParent =
|
||||
aEventTargetNode->IsContent() ?
|
||||
TabParent::GetFrom(aEventTargetNode->AsContent()) : nullptr;
|
||||
|
||||
MOZ_LOG(sISMLog, LogLevel::Info,
|
||||
("ISM: IMEStateManager::DispatchCompositionEvent(aNode=0x%p, "
|
||||
"aPresContext=0x%p, aCompositionEvent={ message=%s, "
|
||||
"mFlags={ mIsTrusted=%s, mPropagationStopped=%s } }, "
|
||||
"aIsSynthesized=%s)",
|
||||
"aIsSynthesized=%s), tabParent=%p",
|
||||
aEventTargetNode, aPresContext,
|
||||
GetEventMessageName(aCompositionEvent->message),
|
||||
GetBoolName(aCompositionEvent->mFlags.mIsTrusted),
|
||||
GetBoolName(aCompositionEvent->mFlags.mPropagationStopped),
|
||||
GetBoolName(aIsSynthesized)));
|
||||
GetBoolName(aIsSynthesized), tabParent.get()));
|
||||
|
||||
if (!aCompositionEvent->mFlags.mIsTrusted ||
|
||||
aCompositionEvent->mFlags.mPropagationStopped) {
|
||||
|
@ -1159,7 +1163,8 @@ IMEStateManager::DispatchCompositionEvent(
|
|||
"adding new TextComposition to the array"));
|
||||
MOZ_ASSERT(aCompositionEvent->message == NS_COMPOSITION_START);
|
||||
composition =
|
||||
new TextComposition(aPresContext, aEventTargetNode, aCompositionEvent);
|
||||
new TextComposition(aPresContext, aEventTargetNode, tabParent,
|
||||
aCompositionEvent);
|
||||
sTextCompositions->AppendElement(composition);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
|
@ -1203,7 +1208,7 @@ IMEStateManager::DispatchCompositionEvent(
|
|||
// static
|
||||
void
|
||||
IMEStateManager::OnCompositionEventDiscarded(
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
WidgetCompositionEvent* aCompositionEvent)
|
||||
{
|
||||
// Note that this method is never called for synthesized events for emulating
|
||||
// commit or cancel composition.
|
||||
|
|
|
@ -157,7 +157,7 @@ public:
|
|||
* to dispatch events.
|
||||
*/
|
||||
static void OnCompositionEventDiscarded(
|
||||
const WidgetCompositionEvent* aCompositionEvent);
|
||||
WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
/**
|
||||
* Get TextComposition from widget.
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/TextComposition.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
|
||||
using namespace mozilla::widget;
|
||||
|
||||
|
@ -30,9 +32,11 @@ namespace mozilla {
|
|||
|
||||
TextComposition::TextComposition(nsPresContext* aPresContext,
|
||||
nsINode* aNode,
|
||||
TabParent* aTabParent,
|
||||
WidgetCompositionEvent* aCompositionEvent)
|
||||
: mPresContext(aPresContext)
|
||||
, mNode(aNode)
|
||||
, mTabParent(aTabParent)
|
||||
, mNativeContext(
|
||||
aCompositionEvent->widget->GetInputContext().mNativeIMEContext)
|
||||
, mCompositionStartOffset(0)
|
||||
|
@ -55,6 +59,7 @@ TextComposition::Destroy()
|
|||
{
|
||||
mPresContext = nullptr;
|
||||
mNode = nullptr;
|
||||
mTabParent = nullptr;
|
||||
// TODO: If the editor is still alive and this is held by it, we should tell
|
||||
// this being destroyed for cleaning up the stuff.
|
||||
}
|
||||
|
@ -77,6 +82,8 @@ bool
|
|||
TextComposition::MaybeDispatchCompositionUpdate(
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mTabParent);
|
||||
|
||||
if (!IsValidStateForComposition(aCompositionEvent->widget)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -95,6 +102,8 @@ TextComposition::CloneAndDispatchAs(
|
|||
nsEventStatus* aStatus,
|
||||
EventDispatchingCallback* aCallBack)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mTabParent);
|
||||
|
||||
MOZ_ASSERT(IsValidStateForComposition(aCompositionEvent->widget),
|
||||
"Should be called only when it's safe to dispatch an event");
|
||||
|
||||
|
@ -118,7 +127,7 @@ TextComposition::CloneAndDispatchAs(
|
|||
|
||||
void
|
||||
TextComposition::OnCompositionEventDiscarded(
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
WidgetCompositionEvent* aCompositionEvent)
|
||||
{
|
||||
// Note that this method is never called for synthesized events for emulating
|
||||
// commit or cancel composition.
|
||||
|
@ -126,6 +135,11 @@ TextComposition::OnCompositionEventDiscarded(
|
|||
MOZ_ASSERT(aCompositionEvent->mFlags.mIsTrusted,
|
||||
"Shouldn't be called with untrusted event");
|
||||
|
||||
if (mTabParent) {
|
||||
// The composition event should be discarded in the child process too.
|
||||
unused << mTabParent->SendCompositionEvent(*aCompositionEvent);
|
||||
}
|
||||
|
||||
// XXX If composition events are discarded, should we dispatch them with
|
||||
// runnable event? However, even if we do so, it might make native IME
|
||||
// confused due to async modification. Especially when native IME is
|
||||
|
@ -198,6 +212,21 @@ TextComposition::DispatchCompositionEvent(
|
|||
EventDispatchingCallback* aCallBack,
|
||||
bool aIsSynthesized)
|
||||
{
|
||||
// If the content is a container of TabParent, composition should be in the
|
||||
// remote process.
|
||||
if (mTabParent) {
|
||||
unused << mTabParent->SendCompositionEvent(*aCompositionEvent);
|
||||
aCompositionEvent->mFlags.mPropagationStopped = true;
|
||||
if (aCompositionEvent->CausesDOMTextEvent()) {
|
||||
mLastData = aCompositionEvent->mData;
|
||||
// Although, the composition event hasn't been actually handled yet,
|
||||
// emulate an editor to be handling the composition event.
|
||||
EditorWillHandleCompositionChangeEvent(aCompositionEvent);
|
||||
EditorDidHandleCompositionChangeEvent();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mAllowControlCharacters) {
|
||||
RemoveControlCharactersFrom(aCompositionEvent->mData,
|
||||
aCompositionEvent->mRanges);
|
||||
|
@ -349,6 +378,8 @@ void
|
|||
TextComposition::NotityUpdateComposition(
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mTabParent);
|
||||
|
||||
nsEventStatus status;
|
||||
|
||||
// When compositon start, notify the rect of first offset character.
|
||||
|
@ -465,6 +496,8 @@ TextComposition::EditorWillHandleCompositionChangeEvent(
|
|||
void
|
||||
TextComposition::OnEditorDestroyed()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mTabParent);
|
||||
|
||||
MOZ_ASSERT(!mIsEditorHandlingEvent,
|
||||
"The editor should have stopped listening events");
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
|
@ -487,6 +520,8 @@ TextComposition::EditorDidHandleCompositionChangeEvent()
|
|||
void
|
||||
TextComposition::StartHandlingComposition(nsIEditor* aEditor)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mTabParent);
|
||||
|
||||
MOZ_ASSERT(!HasEditor(), "There is a handling editor already");
|
||||
mEditorWeak = do_GetWeakReference(aEditor);
|
||||
}
|
||||
|
@ -494,6 +529,8 @@ TextComposition::StartHandlingComposition(nsIEditor* aEditor)
|
|||
void
|
||||
TextComposition::EndHandlingComposition(nsIEditor* aEditor)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mTabParent);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
MOZ_ASSERT(editor == aEditor, "Another editor handled the composition?");
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/TextRange.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
|
||||
class nsIEditor;
|
||||
|
||||
|
@ -38,8 +39,11 @@ class TextComposition final
|
|||
NS_INLINE_DECL_REFCOUNTING(TextComposition)
|
||||
|
||||
public:
|
||||
typedef dom::TabParent TabParent;
|
||||
|
||||
TextComposition(nsPresContext* aPresContext,
|
||||
nsINode* aNode,
|
||||
TabParent* aTabParent,
|
||||
WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
bool Destroyed() const { return !mPresContext; }
|
||||
|
@ -173,6 +177,7 @@ private:
|
|||
// this instance.
|
||||
nsPresContext* mPresContext;
|
||||
nsCOMPtr<nsINode> mNode;
|
||||
nsRefPtr<TabParent> mTabParent;
|
||||
|
||||
// This is the clause and caret range information which is managed by
|
||||
// the focused editor. This may be null if there is no clauses or caret.
|
||||
|
@ -314,8 +319,7 @@ private:
|
|||
* compositionupdate, compositionend or compositionchange event due to not
|
||||
* safe to dispatch event.
|
||||
*/
|
||||
void OnCompositionEventDiscarded(
|
||||
const WidgetCompositionEvent* aCompositionEvent);
|
||||
void OnCompositionEventDiscarded(WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
/**
|
||||
* Calculate composition offset then notify composition update to widget
|
||||
|
|
Загрузка…
Ссылка в новой задаче