зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1176955 part.1 TextComposition should guarantee that WidgetSelectionEvent should be handled by same content as the target of composition events when there is a composition r=smaug
This commit is contained in:
Родитель
3b86e653ba
Коммит
6a5c380903
|
@ -805,18 +805,8 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
break;
|
||||
case NS_SELECTION_SET:
|
||||
{
|
||||
WidgetSelectionEvent* selectionEvent = aEvent->AsSelectionEvent();
|
||||
if (IsTargetCrossProcess(selectionEvent)) {
|
||||
// Will not be handled locally, remote the event
|
||||
if (GetCrossProcessTarget()->SendSelectionEvent(*selectionEvent)) {
|
||||
selectionEvent->mSucceeded = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ContentEventHandler handler(mPresContext);
|
||||
handler.OnSelectionEvent(selectionEvent);
|
||||
}
|
||||
IMEStateManager::HandleSelectionEvent(aPresContext, GetFocusedContent(),
|
||||
aEvent->AsSelectionEvent());
|
||||
break;
|
||||
case NS_CONTENT_COMMAND_CUT:
|
||||
case NS_CONTENT_COMMAND_COPY:
|
||||
|
|
|
@ -149,6 +149,8 @@ GetEventMessageName(uint32_t aMessage)
|
|||
return "NS_COMPOSITION_COMMIT_AS_IS";
|
||||
case NS_COMPOSITION_COMMIT:
|
||||
return "NS_COMPOSITION_COMMIT";
|
||||
case NS_SELECTION_SET:
|
||||
return "NS_SELECTION_SET";
|
||||
default:
|
||||
return "unacceptable event message";
|
||||
}
|
||||
|
@ -1205,6 +1207,56 @@ IMEStateManager::DispatchCompositionEvent(
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
nsIContent*
|
||||
IMEStateManager::GetRootContent(nsPresContext* aPresContext)
|
||||
{
|
||||
nsIDocument* doc = aPresContext->Document();
|
||||
if (NS_WARN_IF(!doc)) {
|
||||
return nullptr;
|
||||
}
|
||||
return doc->GetRootElement();
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
IMEStateManager::HandleSelectionEvent(nsPresContext* aPresContext,
|
||||
nsIContent* aEventTargetContent,
|
||||
WidgetSelectionEvent* aSelectionEvent)
|
||||
{
|
||||
nsIContent* eventTargetContent =
|
||||
aEventTargetContent ? aEventTargetContent :
|
||||
GetRootContent(aPresContext);
|
||||
nsRefPtr<TabParent> tabParent =
|
||||
eventTargetContent ? TabParent::GetFrom(eventTargetContent) : nullptr;
|
||||
|
||||
MOZ_LOG(sISMLog, LogLevel::Info,
|
||||
("ISM: IMEStateManager::HandleSelectionEvent(aPresContext=0x%p, "
|
||||
"aEventTargetContent=0x%p, aSelectionEvent={ message=%s, "
|
||||
"mFlags={ mIsTrusted=%s } }), tabParent=%p",
|
||||
aPresContext, aEventTargetContent,
|
||||
GetEventMessageName(aSelectionEvent->message),
|
||||
GetBoolName(aSelectionEvent->mFlags.mIsTrusted),
|
||||
tabParent.get()));
|
||||
|
||||
if (!aSelectionEvent->mFlags.mIsTrusted) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<TextComposition> composition = sTextCompositions ?
|
||||
sTextCompositions->GetCompositionFor(aSelectionEvent->widget) : nullptr;
|
||||
if (composition) {
|
||||
// When there is a composition, TextComposition should guarantee that the
|
||||
// selection event will be handled in same target as composition events.
|
||||
composition->HandleSelectionEvent(aSelectionEvent);
|
||||
} else {
|
||||
// When there is no composition, the selection event should be handled
|
||||
// in the aPresContext or tabParent.
|
||||
TextComposition::HandleSelectionEvent(aPresContext, tabParent,
|
||||
aSelectionEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
IMEStateManager::OnCompositionEventDiscarded(
|
||||
|
|
|
@ -152,6 +152,15 @@ public:
|
|||
EventDispatchingCallback* aCallBack,
|
||||
bool aIsSynthesized = false);
|
||||
|
||||
/**
|
||||
* All selection events must be handled via HandleSelectionEvent()
|
||||
* because they must be handled by same target as composition events when
|
||||
* there is a composition.
|
||||
*/
|
||||
static void HandleSelectionEvent(nsPresContext* aPresContext,
|
||||
nsIContent* aEventTargetContent,
|
||||
WidgetSelectionEvent* aSelectionEvent);
|
||||
|
||||
/**
|
||||
* This is called when PresShell ignores a composition event due to not safe
|
||||
* to dispatch events.
|
||||
|
@ -212,6 +221,8 @@ protected:
|
|||
|
||||
static bool IsIMEObserverNeeded(const IMEState& aState);
|
||||
|
||||
static nsIContent* GetRootContent(nsPresContext* aPresContext);
|
||||
|
||||
static StaticRefPtr<nsIContent> sContent;
|
||||
static nsPresContext* sPresContext;
|
||||
static StaticRefPtr<nsIWidget> sFocusedIMEWidget;
|
||||
|
|
|
@ -374,6 +374,24 @@ TextComposition::DispatchCompositionEvent(
|
|||
NotityUpdateComposition(aCompositionEvent);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
TextComposition::HandleSelectionEvent(nsPresContext* aPresContext,
|
||||
TabParent* aTabParent,
|
||||
WidgetSelectionEvent* aSelectionEvent)
|
||||
{
|
||||
// If the content is a container of TabParent, composition should be in the
|
||||
// remote process.
|
||||
if (aTabParent) {
|
||||
unused << aTabParent->SendSelectionEvent(*aSelectionEvent);
|
||||
aSelectionEvent->mFlags.mPropagationStopped = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ContentEventHandler handler(aPresContext);
|
||||
handler.OnSelectionEvent(aSelectionEvent);
|
||||
}
|
||||
|
||||
void
|
||||
TextComposition::NotityUpdateComposition(
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
|
|
|
@ -284,6 +284,18 @@ private:
|
|||
EventDispatchingCallback* aCallBack,
|
||||
bool aIsSynthesized);
|
||||
|
||||
/**
|
||||
* HandleSelectionEvent() sends the selection event to ContentEventHandler
|
||||
* or dispatches it to the focused child process.
|
||||
*/
|
||||
void HandleSelectionEvent(WidgetSelectionEvent* aSelectionEvent)
|
||||
{
|
||||
HandleSelectionEvent(mPresContext, mTabParent, aSelectionEvent);
|
||||
}
|
||||
static void HandleSelectionEvent(nsPresContext* aPresContext,
|
||||
TabParent* aTabParent,
|
||||
WidgetSelectionEvent* aSelectionEvent);
|
||||
|
||||
/**
|
||||
* MaybeDispatchCompositionUpdate() may dispatch a compositionupdate event
|
||||
* if aCompositionEvent changes composition string.
|
||||
|
|
|
@ -2298,7 +2298,11 @@ TabParent::SendSelectionEvent(WidgetSelectionEvent& event)
|
|||
return true;
|
||||
}
|
||||
mContentCache.OnSelectionEvent(event);
|
||||
return PBrowserParent::SendSelectionEvent(event);
|
||||
if (NS_WARN_IF(!PBrowserParent::SendSelectionEvent(event))) {
|
||||
return false;
|
||||
}
|
||||
event.mSucceeded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*static*/ TabParent*
|
||||
|
|
Загрузка…
Ссылка в новой задаче