зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
667279db0b
Коммит
d0c6c39489
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче