mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 20:22:00 +00:00
Bug 583976. Part 3 - Automatically forward mouse and key input events to out-of-process content, and add cursor support in PuppetWidget. r=smaug,stechz
This commit is contained in:
parent
00693c144c
commit
9628013f99
@ -240,6 +240,24 @@ interface nsIFrameLoader : nsISupports
|
||||
const unsigned long RENDER_MODE_ASYNC_SCROLL = 0x00000001;
|
||||
|
||||
attribute unsigned long renderMode;
|
||||
|
||||
/**
|
||||
* The default event mode automatically forwards the events
|
||||
* handled in nsEventStateManager::HandleCrossProcessEvent to
|
||||
* the child content process when these events are targeted to
|
||||
* the remote browser element.
|
||||
*
|
||||
* Used primarly for input events (mouse, keyboard)
|
||||
*/
|
||||
const unsigned long EVENT_MODE_NORMAL_DISPATCH = 0x00000000;
|
||||
|
||||
/**
|
||||
* With this event mode, it's the application's responsability to
|
||||
* convert and forward events to the content process
|
||||
*/
|
||||
const unsigned long EVENT_MODE_DONT_FORWARD_TO_CHILD = 0x00000001;
|
||||
|
||||
attribute unsigned long eventMode;
|
||||
};
|
||||
|
||||
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
|
||||
|
@ -327,6 +327,7 @@ nsFrameLoader::nsFrameLoader(nsIContent *aOwner, PRBool aNetworkCreated)
|
||||
, mCurrentRemoteFrame(nsnull)
|
||||
, mRemoteBrowser(nsnull)
|
||||
, mRenderMode(RENDER_MODE_DEFAULT)
|
||||
, mEventMode(EVENT_MODE_NORMAL_DISPATCH)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1660,6 +1661,20 @@ nsFrameLoader::SetRenderMode(PRUint32 aRenderMode)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::GetEventMode(PRUint32* aEventMode)
|
||||
{
|
||||
*aEventMode = mEventMode;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::SetEventMode(PRUint32 aEventMode)
|
||||
{
|
||||
mEventMode = aEventMode;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIntSize
|
||||
nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
|
||||
{
|
||||
|
@ -342,6 +342,10 @@ private:
|
||||
// RENDER_MODE_ASYNC_SCROLL), all the fields below are ignored in
|
||||
// favor of what content tells.
|
||||
PRUint32 mRenderMode;
|
||||
|
||||
// See nsIFrameLoader.idl. EVENT_MODE_NORMAL_DISPATCH automatically
|
||||
// forwards some input events to out-of-process content.
|
||||
PRUint32 mEventMode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1657,6 +1657,93 @@ nsEventStateManager::HandleAccessKey(nsPresContext* aPresContext,
|
||||
}// if end. bubble up process
|
||||
}// end of HandleAccessKey
|
||||
|
||||
void
|
||||
nsEventStateManager::DispatchCrossProcessEvent(nsEvent* aEvent, nsIFrameLoader* frameLoader) {
|
||||
nsFrameLoader* fml = static_cast<nsFrameLoader*>(frameLoader);
|
||||
PBrowserParent* remoteBrowser = fml->GetRemoteBrowser();
|
||||
TabParent* remote = static_cast<TabParent*>(remoteBrowser);
|
||||
if (!remote) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aEvent->eventStructType == NS_MOUSE_EVENT) {
|
||||
nsMouseEvent* mouseEvent = static_cast<nsMouseEvent*>(aEvent);
|
||||
remote->SendRealMouseEvent(*mouseEvent);
|
||||
}
|
||||
|
||||
if (aEvent->eventStructType == NS_KEY_EVENT) {
|
||||
nsKeyEvent* keyEvent = static_cast<nsKeyEvent*>(aEvent);
|
||||
remote->SendRealKeyEvent(*keyEvent);
|
||||
}
|
||||
|
||||
if (aEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
|
||||
nsMouseScrollEvent* scrollEvent = static_cast<nsMouseScrollEvent*>(aEvent);
|
||||
remote->SendMouseScrollEvent(*scrollEvent);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEventStateManager::IsRemoteTarget(nsIContent* target) {
|
||||
return target &&
|
||||
target->Tag() == nsGkAtoms::browser &&
|
||||
target->IsXUL() &&
|
||||
target->AttrValueIs(kNameSpaceID_None, nsGkAtoms::Remote,
|
||||
nsGkAtoms::_true, eIgnoreCase);
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsEventStateManager::HandleCrossProcessEvent(nsEvent *aEvent,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStatus *aStatus) {
|
||||
|
||||
switch (aEvent->eventStructType) {
|
||||
case NS_KEY_EVENT:
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
break;
|
||||
case NS_MOUSE_EVENT:
|
||||
if (aEvent->message == NS_MOUSE_BUTTON_DOWN ||
|
||||
aEvent->message == NS_MOUSE_BUTTON_UP ||
|
||||
aEvent->message == NS_MOUSE_MOVE) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIContent* target = mCurrentTargetContent;
|
||||
if (!target && aTargetFrame) {
|
||||
target = aTargetFrame->GetContent();
|
||||
}
|
||||
|
||||
if (*aStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
!target ||
|
||||
!IsRemoteTarget(target)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(target);
|
||||
if (!loaderOwner) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsRefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
|
||||
if (!frameLoader) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRUint32 eventMode;
|
||||
frameLoader->GetEventMode(&eventMode);
|
||||
if (eventMode == nsIFrameLoader::EVENT_MODE_DONT_FORWARD_TO_CHILD) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, aTargetFrame);
|
||||
aEvent->refPoint = pt.ToNearestPixels(mPresContext->AppUnitsPerDevPixel());
|
||||
|
||||
DispatchCrossProcessEvent(aEvent, frameLoader);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// CreateClickHoldTimer
|
||||
@ -2905,6 +2992,8 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
NS_ENSURE_ARG(aPresContext);
|
||||
NS_ENSURE_ARG_POINTER(aStatus);
|
||||
|
||||
HandleCrossProcessEvent(aEvent, aTargetFrame, aStatus);
|
||||
|
||||
mCurrentTarget = aTargetFrame;
|
||||
mCurrentTargetContent = nsnull;
|
||||
|
||||
@ -3420,6 +3509,10 @@ nsEventStateManager::UpdateCursor(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIFrame* aTargetFrame,
|
||||
nsEventStatus* aStatus)
|
||||
{
|
||||
if (aTargetFrame && IsRemoteTarget(aTargetFrame->GetContent())) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRInt32 cursor = NS_STYLE_CURSOR_DEFAULT;
|
||||
imgIContainer* container = nsnull;
|
||||
PRBool haveHotspot = PR_FALSE;
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIFrameLoader.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIMarkupDocumentViewer.h"
|
||||
@ -427,6 +428,12 @@ protected:
|
||||
mozilla::dom::TabParent *GetCrossProcessTarget();
|
||||
PRBool IsTargetCrossProcess(nsGUIEvent *aEvent);
|
||||
|
||||
void DispatchCrossProcessEvent(nsEvent* aEvent, nsIFrameLoader* remote);
|
||||
PRBool IsRemoteTarget(nsIContent* target);
|
||||
PRBool HandleCrossProcessEvent(nsEvent *aEvent,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsEventStatus *aStatus);
|
||||
|
||||
private:
|
||||
static inline void DoStateChange(mozilla::dom::Element* aElement,
|
||||
nsEventStates aState, PRBool aAddState);
|
||||
|
@ -58,6 +58,9 @@ using nsQueryContentEvent;
|
||||
using nsRect;
|
||||
using nsSelectionEvent;
|
||||
using nsTextEvent;
|
||||
using nsMouseEvent;
|
||||
using nsMouseScrollEvent;
|
||||
using nsKeyEvent;
|
||||
using RemoteDOMEvent;
|
||||
|
||||
namespace mozilla {
|
||||
@ -180,6 +183,8 @@ parent:
|
||||
*/
|
||||
sync GetDPI() returns (float value);
|
||||
|
||||
SetCursor(PRUint32 value);
|
||||
|
||||
PContentPermissionRequest(nsCString aType, URI uri);
|
||||
|
||||
PContentDialog(PRUint32 aType, nsCString aName, nsCString aFeatures,
|
||||
@ -254,6 +259,10 @@ child:
|
||||
PRInt32 aModifiers,
|
||||
bool aIgnoreRootScrollFrame);
|
||||
|
||||
RealMouseEvent(nsMouseEvent event);
|
||||
RealKeyEvent(nsKeyEvent event);
|
||||
MouseScrollEvent(nsMouseScrollEvent event);
|
||||
|
||||
/**
|
||||
* @see nsIDOMWindowUtils sendKeyEvent.
|
||||
*/
|
||||
|
@ -580,6 +580,31 @@ TabChild::RecvMouseEvent(const nsString& aType,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvRealMouseEvent(const nsMouseEvent& event)
|
||||
{
|
||||
nsMouseEvent localEvent(event);
|
||||
DispatchWidgetEvent(localEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvMouseScrollEvent(const nsMouseScrollEvent& event)
|
||||
{
|
||||
nsMouseScrollEvent localEvent(event);
|
||||
DispatchWidgetEvent(localEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TabChild::RecvRealKeyEvent(const nsKeyEvent& event)
|
||||
{
|
||||
nsKeyEvent localEvent(event);
|
||||
DispatchWidgetEvent(localEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvKeyEvent(const nsString& aType,
|
||||
const PRInt32& aKeyCode,
|
||||
|
@ -188,6 +188,9 @@ public:
|
||||
const PRInt32& aClickCount,
|
||||
const PRInt32& aModifiers,
|
||||
const bool& aIgnoreRootScrollFrame);
|
||||
virtual bool RecvRealMouseEvent(const nsMouseEvent& event);
|
||||
virtual bool RecvRealKeyEvent(const nsKeyEvent& event);
|
||||
virtual bool RecvMouseScrollEvent(const nsMouseScrollEvent& event);
|
||||
virtual bool RecvKeyEvent(const nsString& aType,
|
||||
const PRInt32& aKeyCode,
|
||||
const PRInt32& aCharCode,
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include "nsSerializationHelper.h"
|
||||
#include "nsIPromptFactory.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
@ -299,6 +300,21 @@ TabParent::SendKeyEvent(const nsAString& aType,
|
||||
aModifiers, aPreventDefault);
|
||||
}
|
||||
|
||||
bool TabParent::SendRealMouseEvent(nsMouseEvent& event)
|
||||
{
|
||||
return PBrowserParent::SendRealMouseEvent(event);
|
||||
}
|
||||
|
||||
bool TabParent::SendMouseScrollEvent(nsMouseScrollEvent& event)
|
||||
{
|
||||
return PBrowserParent::SendMouseScrollEvent(event);
|
||||
}
|
||||
|
||||
bool TabParent::SendRealKeyEvent(nsKeyEvent& event)
|
||||
{
|
||||
return PBrowserParent::SendRealKeyEvent(event);
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvSyncMessage(const nsString& aMessage,
|
||||
const nsString& aJSON,
|
||||
@ -314,6 +330,16 @@ TabParent::RecvAsyncMessage(const nsString& aMessage,
|
||||
return ReceiveMessage(aMessage, PR_FALSE, aJSON, nsnull);
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvSetCursor(const PRUint32& aCursor)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
widget->SetCursor((nsCursor) aCursor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyIMEFocus(const PRBool& aFocus,
|
||||
nsIMEUpdatePreference* aPreference,
|
||||
|
@ -107,6 +107,7 @@ public:
|
||||
virtual bool RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction, const PRUint32& aReason);
|
||||
virtual bool RecvGetIMEOpenState(PRBool* aValue);
|
||||
virtual bool RecvSetIMEOpenState(const PRBool& aValue);
|
||||
virtual bool RecvSetCursor(const PRUint32& aValue);
|
||||
virtual bool RecvGetDPI(float* aValue);
|
||||
virtual PContentDialogParent* AllocPContentDialog(const PRUint32& aType,
|
||||
const nsCString& aName,
|
||||
@ -134,6 +135,9 @@ public:
|
||||
void SendKeyEvent(const nsAString& aType, PRInt32 aKeyCode,
|
||||
PRInt32 aCharCode, PRInt32 aModifiers,
|
||||
PRBool aPreventDefault);
|
||||
bool SendRealMouseEvent(nsMouseEvent& event);
|
||||
bool SendMouseScrollEvent(nsMouseScrollEvent& event);
|
||||
bool SendRealKeyEvent(nsKeyEvent& event);
|
||||
|
||||
virtual PDocumentRendererParent*
|
||||
AllocPDocumentRenderer(const nsRect& documentRect, const gfxMatrix& transform,
|
||||
|
@ -2845,6 +2845,7 @@ Tab.prototype = {
|
||||
|
||||
let fl = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
|
||||
fl.renderMode = Ci.nsIFrameLoader.RENDER_MODE_ASYNC_SCROLL;
|
||||
fl.eventMode = Ci.nsIFrameLoader.EVENT_MODE_DONT_FORWARD_TO_CHILD;
|
||||
|
||||
return browser;
|
||||
},
|
||||
|
@ -821,7 +821,16 @@ public:
|
||||
|
||||
class nsMouseEvent_base : public nsInputEvent
|
||||
{
|
||||
private:
|
||||
friend class mozilla::dom::PBrowserParent;
|
||||
friend class mozilla::dom::PBrowserChild;
|
||||
|
||||
public:
|
||||
|
||||
nsMouseEvent_base()
|
||||
{
|
||||
}
|
||||
|
||||
nsMouseEvent_base(PRBool isTrusted, PRUint32 msg, nsIWidget *w, PRUint8 type)
|
||||
: nsInputEvent(isTrusted, msg, w, type), button(0), pressure(0),
|
||||
inputSource(nsIDOMNSMouseEvent::MOZ_SOURCE_MOUSE) {}
|
||||
@ -841,12 +850,20 @@ public:
|
||||
|
||||
class nsMouseEvent : public nsMouseEvent_base
|
||||
{
|
||||
private:
|
||||
friend class mozilla::dom::PBrowserParent;
|
||||
friend class mozilla::dom::PBrowserChild;
|
||||
|
||||
public:
|
||||
enum buttonType { eLeftButton = 0, eMiddleButton = 1, eRightButton = 2 };
|
||||
enum reasonType { eReal, eSynthesized };
|
||||
enum contextType { eNormal, eContextMenuKey };
|
||||
enum exitType { eChild, eTopLevel };
|
||||
|
||||
nsMouseEvent()
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
nsMouseEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w,
|
||||
PRUint8 structType, reasonType aReason)
|
||||
@ -953,7 +970,15 @@ struct nsAlternativeCharCode {
|
||||
|
||||
class nsKeyEvent : public nsInputEvent
|
||||
{
|
||||
private:
|
||||
friend class mozilla::dom::PBrowserParent;
|
||||
friend class mozilla::dom::PBrowserChild;
|
||||
|
||||
public:
|
||||
nsKeyEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsKeyEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w)
|
||||
: nsInputEvent(isTrusted, msg, w, NS_KEY_EVENT),
|
||||
keyCode(0), charCode(0), isChar(0)
|
||||
@ -1180,6 +1205,14 @@ public:
|
||||
|
||||
class nsMouseScrollEvent : public nsMouseEvent_base
|
||||
{
|
||||
private:
|
||||
friend class mozilla::dom::PBrowserParent;
|
||||
friend class mozilla::dom::PBrowserChild;
|
||||
|
||||
nsMouseScrollEvent()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
enum nsMouseScrollFlags {
|
||||
kIsFullPage = 1 << 0,
|
||||
|
@ -153,6 +153,61 @@ struct ParamTraits<nsMouseScrollEvent>
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct ParamTraits<nsMouseEvent>
|
||||
{
|
||||
typedef nsMouseEvent paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, static_cast<nsMouseEvent_base>(aParam));
|
||||
WriteParam(aMsg, aParam.ignoreRootScrollFrame);
|
||||
WriteParam(aMsg, (PRUint8) aParam.reason);
|
||||
WriteParam(aMsg, (PRUint8) aParam.context);
|
||||
WriteParam(aMsg, (PRUint8) aParam.exit);
|
||||
WriteParam(aMsg, aParam.clickCount);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
bool rv;
|
||||
PRUint8 reason, context, exit;
|
||||
rv = ReadParam(aMsg, aIter, static_cast<nsMouseEvent_base*>(aResult)) &&
|
||||
ReadParam(aMsg, aIter, &aResult->ignoreRootScrollFrame) &&
|
||||
ReadParam(aMsg, aIter, &reason) &&
|
||||
ReadParam(aMsg, aIter, &context) &&
|
||||
ReadParam(aMsg, aIter, &exit) &&
|
||||
ReadParam(aMsg, aIter, &aResult->clickCount);
|
||||
aResult->reason = static_cast<nsMouseEvent::reasonType>(reason);
|
||||
aResult->context = static_cast<nsMouseEvent::contextType>(context);
|
||||
aResult->exit = static_cast<nsMouseEvent::exitType>(exit);
|
||||
return rv;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<nsKeyEvent>
|
||||
{
|
||||
typedef nsKeyEvent paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, static_cast<nsInputEvent>(aParam));
|
||||
WriteParam(aMsg, aParam.keyCode);
|
||||
WriteParam(aMsg, aParam.charCode);
|
||||
WriteParam(aMsg, aParam.isChar);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
return ReadParam(aMsg, aIter, static_cast<nsInputEvent*>(aResult)) &&
|
||||
ReadParam(aMsg, aIter, &aResult->keyCode) &&
|
||||
ReadParam(aMsg, aIter, &aResult->charCode) &&
|
||||
ReadParam(aMsg, aIter, &aResult->isChar);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<nsTextRangeStyle>
|
||||
{
|
||||
|
@ -505,6 +505,16 @@ PuppetWidget::OnIMESelectionChange(void)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PuppetWidget::SetCursor(nsCursor aCursor)
|
||||
{
|
||||
if (!mTabChild ||
|
||||
!mTabChild->SendSetCursor(aCursor)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PuppetWidget::DispatchPaintEvent()
|
||||
{
|
||||
|
@ -180,6 +180,8 @@ public:
|
||||
PRUint32 aNewEnd);
|
||||
NS_IMETHOD OnIMESelectionChange(void);
|
||||
|
||||
NS_IMETHOD SetCursor(nsCursor aCursor);
|
||||
|
||||
// Gets the DPI of the screen corresponding to this widget.
|
||||
// Contacts the parent process which gets the DPI from the
|
||||
// proper widget there. TODO: Handle DPI changes that happen
|
||||
|
Loading…
x
Reference in New Issue
Block a user