зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1003934 - Forward NS_MOUSE_EXIT events to content processes so they know the mouse has exited their frame. r=smaug
This commit is contained in:
Родитель
472ffc6a96
Коммит
2ee59969dc
|
@ -1144,6 +1144,7 @@ CrossProcessSafeEvent(const WidgetEvent& aEvent)
|
|||
case NS_MOUSE_BUTTON_UP:
|
||||
case NS_MOUSE_MOVE:
|
||||
case NS_CONTEXTMENU:
|
||||
case NS_MOUSE_EXIT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -1165,7 +1166,6 @@ CrossProcessSafeEvent(const WidgetEvent& aEvent)
|
|||
|
||||
bool
|
||||
EventStateManager::HandleCrossProcessEvent(WidgetEvent* aEvent,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStatus *aStatus) {
|
||||
if (*aStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
aEvent->mFlags.mNoCrossProcessBoundaryForwarding ||
|
||||
|
@ -2655,7 +2655,6 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
NS_ENSURE_ARG_POINTER(aStatus);
|
||||
|
||||
bool dispatchedToContentProcess = HandleCrossProcessEvent(aEvent,
|
||||
aTargetFrame,
|
||||
aStatus);
|
||||
|
||||
mCurrentTarget = aTargetFrame;
|
||||
|
@ -3542,6 +3541,44 @@ EventStateManager::IsHandlingUserInput()
|
|||
(TimeStamp::Now() - sHandlingInputStart) <= timeout;
|
||||
}
|
||||
|
||||
static void
|
||||
CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent,
|
||||
uint32_t aMessage,
|
||||
nsIContent* aRelatedContent,
|
||||
nsAutoPtr<WidgetMouseEvent>& aNewEvent)
|
||||
{
|
||||
WidgetPointerEvent* sourcePointer = aMouseEvent->AsPointerEvent();
|
||||
if (sourcePointer) {
|
||||
PROFILER_LABEL("Input", "DispatchPointerEvent");
|
||||
nsAutoPtr<WidgetPointerEvent> newPointerEvent;
|
||||
newPointerEvent =
|
||||
new WidgetPointerEvent(aMouseEvent->mFlags.mIsTrusted, aMessage,
|
||||
aMouseEvent->widget);
|
||||
newPointerEvent->isPrimary = sourcePointer->isPrimary;
|
||||
newPointerEvent->pointerId = sourcePointer->pointerId;
|
||||
newPointerEvent->width = sourcePointer->width;
|
||||
newPointerEvent->height = sourcePointer->height;
|
||||
newPointerEvent->inputSource = sourcePointer->inputSource;
|
||||
newPointerEvent->relatedTarget =
|
||||
nsIPresShell::GetPointerCapturingContent(sourcePointer->pointerId)
|
||||
? nullptr
|
||||
: aRelatedContent;
|
||||
aNewEvent = newPointerEvent.forget();
|
||||
} else {
|
||||
aNewEvent =
|
||||
new WidgetMouseEvent(aMouseEvent->mFlags.mIsTrusted, aMessage,
|
||||
aMouseEvent->widget, WidgetMouseEvent::eReal);
|
||||
aNewEvent->relatedTarget = aRelatedContent;
|
||||
}
|
||||
aNewEvent->refPoint = aMouseEvent->refPoint;
|
||||
aNewEvent->modifiers = aMouseEvent->modifiers;
|
||||
aNewEvent->button = aMouseEvent->button;
|
||||
aNewEvent->buttons = aMouseEvent->buttons;
|
||||
aNewEvent->pressure = aMouseEvent->pressure;
|
||||
aNewEvent->pluginEvent = aMouseEvent->pluginEvent;
|
||||
aNewEvent->inputSource = aMouseEvent->inputSource;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
|
||||
uint32_t aMessage,
|
||||
|
@ -3567,54 +3604,49 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
|
|||
return mPresContext->GetPrimaryFrameFor(content);
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsAutoPtr<WidgetMouseEvent> event;
|
||||
WidgetPointerEvent* sourcePointer = aMouseEvent->AsPointerEvent();
|
||||
if (sourcePointer) {
|
||||
PROFILER_LABEL("Input", "DispatchPointerEvent");
|
||||
nsAutoPtr<WidgetPointerEvent> newPointerEvent;
|
||||
newPointerEvent =
|
||||
new WidgetPointerEvent(aMouseEvent->mFlags.mIsTrusted, aMessage,
|
||||
aMouseEvent->widget);
|
||||
newPointerEvent->isPrimary = sourcePointer->isPrimary;
|
||||
newPointerEvent->pointerId = sourcePointer->pointerId;
|
||||
newPointerEvent->width = sourcePointer->width;
|
||||
newPointerEvent->height = sourcePointer->height;
|
||||
newPointerEvent->inputSource = sourcePointer->inputSource;
|
||||
newPointerEvent->relatedTarget = nsIPresShell::GetPointerCapturingContent(sourcePointer->pointerId)
|
||||
? nullptr
|
||||
: aRelatedContent;
|
||||
event = newPointerEvent.forget();
|
||||
} else {
|
||||
PROFILER_LABEL("Input", "DispatchMouseEvent");
|
||||
event =
|
||||
new WidgetMouseEvent(aMouseEvent->mFlags.mIsTrusted, aMessage,
|
||||
aMouseEvent->widget, WidgetMouseEvent::eReal);
|
||||
event->relatedTarget = aRelatedContent;
|
||||
mCurrentTargetContent = nullptr;
|
||||
|
||||
if (!aTargetContent) {
|
||||
return nullptr;
|
||||
}
|
||||
event->refPoint = aMouseEvent->refPoint;
|
||||
event->modifiers = aMouseEvent->modifiers;
|
||||
event->button = aMouseEvent->button;
|
||||
event->buttons = aMouseEvent->buttons;
|
||||
event->pressure = aMouseEvent->pressure;
|
||||
event->pluginEvent = aMouseEvent->pluginEvent;
|
||||
event->inputSource = aMouseEvent->inputSource;
|
||||
|
||||
nsAutoPtr<WidgetMouseEvent> dispatchEvent;
|
||||
CreateMouseOrPointerWidgetEvent(aMouseEvent, aMessage,
|
||||
aRelatedContent, dispatchEvent);
|
||||
|
||||
nsWeakFrame previousTarget = mCurrentTarget;
|
||||
|
||||
mCurrentTargetContent = aTargetContent;
|
||||
|
||||
nsIFrame* targetFrame = nullptr;
|
||||
if (aTargetContent) {
|
||||
ESMEventCB callback(aTargetContent);
|
||||
EventDispatcher::Dispatch(aTargetContent, mPresContext, event, nullptr,
|
||||
&status, &callback);
|
||||
|
||||
// Although the primary frame was checked in event callback,
|
||||
// it may not be the same object after event dispatching and handling.
|
||||
// So we need to refetch it.
|
||||
if (mPresContext) {
|
||||
targetFrame = mPresContext->GetPrimaryFrameFor(aTargetContent);
|
||||
if (aMouseEvent->AsMouseEvent()) {
|
||||
PROFILER_LABEL("Input", "DispatchMouseEvent");
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
ESMEventCB callback(aTargetContent);
|
||||
EventDispatcher::Dispatch(aTargetContent, mPresContext, dispatchEvent, nullptr,
|
||||
&status, &callback);
|
||||
|
||||
if (mPresContext) {
|
||||
// Although the primary frame was checked in event callback, it may not be
|
||||
// the same object after event dispatch and handling, so refetch it.
|
||||
targetFrame = mPresContext->GetPrimaryFrameFor(aTargetContent);
|
||||
|
||||
// If we are leaving remote content, dispatch a mouse exit event to the
|
||||
// remote frame.
|
||||
if (aMessage == NS_MOUSE_EXIT_SYNTH && IsRemoteTarget(aTargetContent)) {
|
||||
// For remote content, send a normal widget mouse exit event.
|
||||
nsAutoPtr<WidgetMouseEvent> remoteEvent;
|
||||
CreateMouseOrPointerWidgetEvent(aMouseEvent, NS_MOUSE_EXIT,
|
||||
aRelatedContent, remoteEvent);
|
||||
|
||||
// mCurrentTarget is set to the new target, so we must reset it to the
|
||||
// old target and then dispatch a cross-process event. (mCurrentTarget
|
||||
// will be set back below.) HandleCrossProcessEvent will query for the
|
||||
// proper target via GetEventTarget which will return mCurrentTarget.
|
||||
mCurrentTarget = targetFrame;
|
||||
HandleCrossProcessEvent(remoteEvent, &status);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -783,7 +783,6 @@ protected:
|
|||
nsFrameLoader* aRemote,
|
||||
nsEventStatus *aStatus);
|
||||
bool HandleCrossProcessEvent(WidgetEvent* aEvent,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStatus* aStatus);
|
||||
|
||||
void ReleaseCurrentIMEContentObserver();
|
||||
|
|
Загрузка…
Ссылка в новой задаче