Bug 1018639 - Maintain separate cursors in chrome and client processes. r=roc

The TabChild now maintains a concept of the current cursor for the child
process.  This value is asynchronously cached in the TabParent.  The
chrome process now establishes cursor on its own - consulting the
TabParent when the cursor enters/exits the tab.  While the cursor is
over tab content, changes to the TabParent's cached cursor are
immediately forwarded to the widget.
This commit is contained in:
David Parks 2015-04-14 16:29:10 -07:00
Родитель 667279db0b
Коммит d0c6c39489
3 изменённых файлов: 57 добавлений и 15 удалений

Просмотреть файл

@ -1180,7 +1180,9 @@ CrossProcessSafeEvent(const WidgetEvent& aEvent)
case NS_MOUSE_BUTTON_UP:
case NS_MOUSE_MOVE:
case NS_CONTEXTMENU:
case NS_MOUSE_ENTER:
case NS_MOUSE_EXIT:
case NS_MOUSE_ENTER_SYNTH:
return true;
default:
return false;
@ -3787,20 +3789,27 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
// 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);
// If we are entering/leaving remote content, dispatch a mouse enter/exit
// event to the remote frame.
if (IsRemoteTarget(aTargetContent)) {
if (aMessage == NS_MOUSE_EXIT_SYNTH) {
// 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);
// 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);
} else if (aMessage == NS_MOUSE_ENTER_SYNTH) {
nsAutoPtr<WidgetMouseEvent> remoteEvent;
CreateMouseOrPointerWidgetEvent(aMouseEvent, NS_MOUSE_ENTER,
aRelatedContent, remoteEvent);
HandleCrossProcessEvent(remoteEvent, &status);
}
}
}

Просмотреть файл

@ -283,6 +283,8 @@ TabParent::TabParent(nsIContentParent* aManager,
, mTabId(aTabId)
, mCreatingWindow(false)
, mNeedLayerTreeReadyNotification(false)
, mCursor(nsCursor(-1))
, mTabSetsCursor(false)
{
MOZ_ASSERT(aManager);
}
@ -1168,6 +1170,25 @@ bool TabParent::SendRealMouseEvent(WidgetMouseEvent& event)
return false;
}
event.refPoint += GetChildProcessOffset();
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
// When we mouseenter the tab, the tab's cursor should become the current
// cursor. When we mouseexit, we stop.
if (event.message == NS_MOUSE_ENTER ||
event.message == NS_MOUSE_ENTER_SYNTH) {
mTabSetsCursor = true;
if (mCursor != nsCursor(-1)) {
widget->SetCursor(mCursor);
}
// We don't actually want to forward NS_MOUSE_ENTER messages.
return true;
} else if (event.message == NS_MOUSE_EXIT ||
event.message == NS_MOUSE_EXIT_SYNTH) {
mTabSetsCursor = false;
}
}
if (event.message == NS_MOUSE_MOVE) {
return SendRealMouseMoveEvent(event);
}
@ -1636,12 +1657,16 @@ TabParent::RecvAsyncMessage(const nsString& aMessage,
bool
TabParent::RecvSetCursor(const uint32_t& aCursor, const bool& aForce)
{
mCursor = static_cast<nsCursor>(aCursor);
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
if (aForce) {
widget->ClearCachedCursor();
}
widget->SetCursor((nsCursor) aCursor);
if (mTabSetsCursor) {
widget->SetCursor(mCursor);
}
}
return true;
}

Просмотреть файл

@ -25,13 +25,13 @@
#include "nsIXULBrowserWindow.h"
#include "nsWeakReference.h"
#include "Units.h"
#include "nsIWidget.h"
class nsFrameLoader;
class nsIFrameLoader;
class nsIContent;
class nsIPrincipal;
class nsIURI;
class nsIWidget;
class nsILoadContext;
class nsIDocShell;
@ -587,6 +587,14 @@ private:
// again once the RenderFrameParent arrives.
bool mNeedLayerTreeReadyNotification;
// Cached cursor setting from TabChild. When the cursor is over the tab,
// it should take this appearance.
nsCursor mCursor;
// True if the cursor changes from the TabChild should change the widget
// cursor. This happens whenever the cursor is in the tab's region.
bool mTabSetsCursor;
private:
// This is used when APZ needs to find the TabParent associated with a layer
// to dispatch events.