Back out bug 20022. a=chofmann

This commit is contained in:
dbaron%dbaron.org 2004-02-14 20:29:19 +00:00
parent 20faa7f7e1
commit d97dedc812
8 changed files with 61 additions and 157 deletions

View File

@ -1581,6 +1581,11 @@ nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext,
nsIScrollableView* sv = nsnull;
nsIFrame* focusFrame = nsnull;
// Create a mouseout event that we fire to the content before
// scrolling, to allow tooltips to disappear, etc.
nsMouseEvent mouseOutEvent(NS_MOUSE_EXIT, aMSEvent->widget);
nsIPresShell *presShell = aPresContext->PresShell();
// Otherwise, check for a focused content element
@ -1622,6 +1627,8 @@ nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext,
PRBool passToParent;
if (sv) {
GenerateMouseEnterExit(aPresContext, &mouseOutEvent);
// If we're already at the scroll limit for this view, scroll the
// parent view instead.

View File

@ -4872,8 +4872,6 @@ PresShell::UnsuppressAndInvalidate()
if (focusController) // Unsuppress now that we've shown the new window and focused it.
focusController->SetSuppressFocus(PR_FALSE, "PresShell suppression on Web page loads");
mViewManager->SynthesizeMouseMove(PR_FALSE);
}
NS_IMETHODIMP
@ -6047,13 +6045,6 @@ PresShell::HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, nsIContent*
return NS_OK;
}
inline PRBool
IsSynthesizedMouseMove(nsEvent* aEvent)
{
return aEvent->eventStructType == NS_MOUSE_EVENT &&
NS_STATIC_CAST(nsMouseEvent*, aEvent)->reason != nsMouseEvent::eReal;
}
nsresult
PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
PRUint32 aFlags, nsEventStatus* aStatus)
@ -6092,10 +6083,7 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
aStatus, aView);
// 2. Give event to the DOM for third party and JS use.
if ((GetCurrentEventFrame()) && NS_SUCCEEDED(rv) &&
// We want synthesized mouse moves to cause mouseover and mouseout
// DOM events (PreHandleEvent above), but not mousemove DOM events.
!IsSynthesizedMouseMove(aEvent)) {
if ((GetCurrentEventFrame()) && NS_SUCCEEDED(rv)) {
if (mCurrentEventContent) {
rv = mCurrentEventContent->HandleDOMEvent(mPresContext, aEvent, nsnull,
aFlags, aStatus);
@ -6345,8 +6333,6 @@ PresShell::DidDoReflow()
HandlePostedDOMEvents();
HandlePostedAttributeChanges();
HandlePostedReflowCallbacks();
if (!mPaintingSuppressed)
mViewManager->SynthesizeMouseMove(PR_FALSE);
}
nsresult

View File

@ -4872,8 +4872,6 @@ PresShell::UnsuppressAndInvalidate()
if (focusController) // Unsuppress now that we've shown the new window and focused it.
focusController->SetSuppressFocus(PR_FALSE, "PresShell suppression on Web page loads");
mViewManager->SynthesizeMouseMove(PR_FALSE);
}
NS_IMETHODIMP
@ -6047,13 +6045,6 @@ PresShell::HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, nsIContent*
return NS_OK;
}
inline PRBool
IsSynthesizedMouseMove(nsEvent* aEvent)
{
return aEvent->eventStructType == NS_MOUSE_EVENT &&
NS_STATIC_CAST(nsMouseEvent*, aEvent)->reason != nsMouseEvent::eReal;
}
nsresult
PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
PRUint32 aFlags, nsEventStatus* aStatus)
@ -6092,10 +6083,7 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
aStatus, aView);
// 2. Give event to the DOM for third party and JS use.
if ((GetCurrentEventFrame()) && NS_SUCCEEDED(rv) &&
// We want synthesized mouse moves to cause mouseover and mouseout
// DOM events (PreHandleEvent above), but not mousemove DOM events.
!IsSynthesizedMouseMove(aEvent)) {
if ((GetCurrentEventFrame()) && NS_SUCCEEDED(rv)) {
if (mCurrentEventContent) {
rv = mCurrentEventContent->HandleDOMEvent(mPresContext, aEvent, nsnull,
aFlags, aStatus);
@ -6345,8 +6333,6 @@ PresShell::DidDoReflow()
HandlePostedDOMEvents();
HandlePostedAttributeChanges();
HandlePostedReflowCallbacks();
if (!mPaintingSuppressed)
mViewManager->SynthesizeMouseMove(PR_FALSE);
}
nsresult

View File

@ -520,12 +520,6 @@ public:
PRUint16 aMinTwips,
nsRectVisibility *aRectVisibility)=0;
/**
* Dispatch a mouse move event based on the most recent mouse
* position. This is used when the contents of the page moved
* (aFromScroll is false) or scrolled (aFromScroll is true).
*/
NS_IMETHOD SynthesizeMouseMove(PRBool aFromScroll)=0;
};
//update view now?

View File

@ -646,8 +646,6 @@ NS_IMETHODIMP nsScrollPortView::ScrollToImpl(nscoord aX, nscoord aY, PRUint32 aU
mOffsetY = aY;
Scroll(scrolledView, dxPx, dyPx, t2p, 0);
mViewManager->SynthesizeMouseMove(PR_TRUE);
// notify the listeners.
if (nsnull != mListeners) {

View File

@ -317,23 +317,43 @@ static void PrintZTreeNode(DisplayZTreeNode* aNode, PRInt32 aIndent)
//-------------- Begin Invalidate Event Definition ------------------------
struct nsViewManagerEvent : public PLEvent {
nsViewManagerEvent(nsViewManager* aViewManager);
~nsViewManagerEvent() { }
struct nsInvalidateEvent : public PLEvent {
nsInvalidateEvent(nsViewManager* aViewManager);
~nsInvalidateEvent() { }
virtual void HandleEvent() = 0;
void HandleEvent() {
NS_ASSERTION(nsnull != mViewManager,"ViewManager is null");
// Search for valid view manager before trying to access it
// This is just a safety check. We should never have a circumstance
// where the view manager has been destroyed and the invalidate event
// which it owns is still around. The invalidate event should be destroyed
// by the RevokeEvent in the viewmanager's destructor.
PRBool found = PR_FALSE;
PRInt32 index;
PRInt32 count = nsViewManager::GetViewManagerCount();
const nsVoidArray* viewManagers = nsViewManager::GetViewManagerArray();
for (index = 0; index < count; index++) {
nsViewManager* vm = (nsViewManager*)viewManagers->ElementAt(index);
if (vm == mViewManager) {
found = PR_TRUE;
}
}
nsViewManager* ViewManager() {
// |owner| is a weak pointer, but the view manager will destroy any
// pending invalidate events in it's destructor.
return NS_STATIC_CAST(nsViewManager*, owner);
}
if (found) {
mViewManager->ProcessInvalidateEvent();
} else {
NS_ASSERTION(PR_FALSE, "bad view manager asked to process invalidate event");
}
};
nsViewManager* mViewManager; // Weak Reference. The viewmanager will destroy any pending
// invalidate events in it's destructor.
};
static void* PR_CALLBACK HandlePLEvent(PLEvent* aEvent)
{
NS_ASSERTION(nsnull != aEvent,"Event is null");
nsViewManagerEvent *event = NS_STATIC_CAST(nsViewManagerEvent*, aEvent);
nsInvalidateEvent *event = NS_STATIC_CAST(nsInvalidateEvent*, aEvent);
event->HandleEvent();
return nsnull;
}
@ -341,25 +361,17 @@ static void* PR_CALLBACK HandlePLEvent(PLEvent* aEvent)
static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent)
{
NS_ASSERTION(nsnull != aEvent,"Event is null");
nsViewManagerEvent *event = NS_STATIC_CAST(nsViewManagerEvent*, aEvent);
nsInvalidateEvent *event = NS_STATIC_CAST(nsInvalidateEvent*, aEvent);
delete event;
}
nsViewManagerEvent::nsViewManagerEvent(nsViewManager* aViewManager)
nsInvalidateEvent::nsInvalidateEvent(nsViewManager* aViewManager)
{
NS_ASSERTION(aViewManager, "null parameter");
mViewManager = aViewManager; // Assign weak reference
PL_InitEvent(this, aViewManager, ::HandlePLEvent, ::DestroyPLEvent);
}
struct nsInvalidateEvent : public nsViewManagerEvent {
nsInvalidateEvent(nsViewManager *aViewManager)
: nsViewManagerEvent(aViewManager) { }
virtual void HandleEvent() {
ViewManager()->ProcessInvalidateEvent();
}
};
//-------------- End Invalidate Event Definition ---------------------------
// Compare two Z-index values taking into account topmost and
@ -405,10 +417,7 @@ nsIRenderingContext* nsViewManager::gCleanupContext = nsnull;
nsVoidArray* nsViewManager::gViewManagers = nsnull;
PRUint32 nsViewManager::gLastUserEventTime = 0;
#define NOT_IN_WINDOW PR_INT32_MIN
nsViewManager::nsViewManager()
: mMouseLocation(NOT_IN_WINDOW, NOT_IN_WINDOW)
{
if (gViewManagers == nsnull) {
NS_ASSERTION(mVMCount == 0, "View Manager count is incorrect");
@ -451,7 +460,6 @@ nsViewManager::~nsViewManager()
NS_ASSERTION(nsnull != eventQueue, "Event queue is null");
eventQueue->RevokeEvents(this);
mInvalidateEventQueue = nsnull;
mSynthMouseMoveEventQueue = nsnull;
NS_IF_RELEASE(mRootWindow);
@ -1963,34 +1971,27 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS
}
if (nsnull != view) {
float t2p;
t2p = mContext->AppUnitsToDevUnits();
float p2t;
p2t = mContext->DevUnitsToAppUnits();
//Calculate the proper offset for the view we're going to
offset.x = offset.y = 0;
if (baseView != view) {
//Get offset from root of baseView
nsView *parent;
//Get offset from root of baseView
nsView *parent;
for (parent = baseView; parent != mRootView;
parent = parent->GetParent())
parent->ConvertToParentCoords(&offset.x, &offset.y);
parent = baseView;
while (mRootView != parent) {
parent->ConvertToParentCoords(&offset.x, &offset.y);
parent = parent->GetParent();
}
if (aEvent->message == NS_MOUSE_MOVE) {
mMouseLocation.MoveTo(NSTwipsToIntPixels(offset.x, t2p) +
aEvent->point.x,
NSTwipsToIntPixels(offset.y, t2p) +
aEvent->point.y);
} else if (aEvent->message == NS_MOUSE_EXIT && view == mRootView) {
mMouseLocation.MoveTo(NOT_IN_WINDOW, NOT_IN_WINDOW);
//Subtract back offset from root of view
parent = view;
while (mRootView != parent) {
parent->ConvertFromParentCoords(&offset.x, &offset.y);
parent = parent->GetParent();
}
}
//Subtract back offset from root of view
for (parent = view; parent != mRootView;
parent = parent->GetParent())
parent->ConvertFromParentCoords(&offset.x, &offset.y);
//Dispatch the event
//Before we start mucking with coords, make sure we know our baseline
aEvent->refPoint.x = aEvent->point.x;
@ -2001,6 +2002,9 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS
baseView->GetDimensions(baseViewDimensions);
}
float t2p = mContext->AppUnitsToDevUnits();
float p2t = mContext->DevUnitsToAppUnits();
aEvent->point.x = baseViewDimensions.x + NSIntPixelsToTwips(aEvent->point.x, p2t);
aEvent->point.y = baseViewDimensions.y + NSIntPixelsToTwips(aEvent->point.y, p2t);
@ -4071,64 +4075,3 @@ nsViewManager::GetLastUserEventTime(PRUint32& aTime)
aTime = gLastUserEventTime;
return NS_OK;
}
struct nsSynthMouseMoveEvent : public nsViewManagerEvent {
nsSynthMouseMoveEvent(nsViewManager *aViewManager, PRBool aFromScroll)
: nsViewManagerEvent(aViewManager),
mFromScroll(aFromScroll)
{
}
virtual void HandleEvent() {
ViewManager()->ProcessSynthMouseMoveEvent(mFromScroll);
}
PRBool mFromScroll;
};
NS_IMETHODIMP
nsViewManager::SynthesizeMouseMove(PRBool aFromScroll)
{
if (mMouseLocation == nsPoint(NOT_IN_WINDOW, NOT_IN_WINDOW))
return NS_OK;
nsCOMPtr<nsIEventQueue> eventQueue;
mEventQueueService->GetSpecialEventQueue(
nsIEventQueueService::UI_THREAD_EVENT_QUEUE, getter_AddRefs(eventQueue));
NS_ASSERTION(nsnull != eventQueue, "Event queue is null");
if (eventQueue != mSynthMouseMoveEventQueue) {
nsSynthMouseMoveEvent *ev = new nsSynthMouseMoveEvent(this, aFromScroll);
eventQueue->PostEvent(ev);
mSynthMouseMoveEventQueue = eventQueue;
}
return NS_OK;
}
void
nsViewManager::ProcessSynthMouseMoveEvent(PRBool aFromScroll)
{
// allow new event to be posted while handling this one only if the
// source of the event is a scroll (to prevent infinite reflow loops)
if (aFromScroll)
mSynthMouseMoveEventQueue = nsnull;
if (mMouseLocation == nsPoint(NOT_IN_WINDOW, NOT_IN_WINDOW)) {
mSynthMouseMoveEventQueue = nsnull;
return;
}
nsMouseEvent event(NS_MOUSE_MOVE, mRootView->GetWidget(),
nsMouseEvent::eSynthesized);
event.point = mMouseLocation;
event.time = PR_IntervalNow();
// XXX set event.isShift, event.isControl, event.isAlt, event.isMeta ?
nsEventStatus status;
DispatchEvent(&event, &status);
if (!aFromScroll)
mSynthMouseMoveEventQueue = nsnull;
}

View File

@ -61,7 +61,6 @@ class nsISupportsArray;
struct DisplayListElement2;
struct DisplayZTreeNode;
class BlendingBuffers;
struct nsViewManagerEvent;
//Uncomment the following line to enable generation of viewmanager performance data.
#ifdef MOZ_PERF_METRICS
@ -233,9 +232,6 @@ public:
PRUint16 aMinTwips,
nsRectVisibility *aRectVisibility);
NS_IMETHOD SynthesizeMouseMove(PRBool aFromScroll);
void ProcessSynthMouseMoveEvent(PRBool aFromScroll);
protected:
virtual ~nsViewManager();
void ProcessPendingUpdates(nsView *aView);
@ -393,7 +389,6 @@ private:
nsIScrollableView *mRootScrollable;
PRInt32 mCachingWidgetChanges;
nscolor mDefaultBackgroundColor;
nsPoint mMouseLocation; // device units, relative to mRootView
nsHashtable mMapPlaceholderViewToZTreeNode;
@ -420,7 +415,6 @@ protected:
PRBool mHasPendingInvalidates;
nsCOMPtr<nsIEventQueueService> mEventQueueService;
nsCOMPtr<nsIEventQueue> mInvalidateEventQueue;
nsCOMPtr<nsIEventQueue> mSynthMouseMoveEventQueue;
void PostInvalidateEvent();
#ifdef NS_VM_PERF_METRICS

View File

@ -363,14 +363,11 @@ struct nsInputEvent : public nsGUIEvent
struct nsMouseEvent : public nsInputEvent
{
enum reasonType { eReal, eSynthesized };
nsMouseEvent(PRUint32 msg = 0,
nsIWidget *w = nsnull,
reasonType aReason = eReal,
PRUint8 structType = NS_MOUSE_EVENT)
: nsInputEvent(msg, w, structType),
clickCount(0), acceptActivation(PR_FALSE), reason(aReason)
clickCount(0), acceptActivation(PR_FALSE)
{
}
@ -379,7 +376,6 @@ struct nsMouseEvent : public nsInputEvent
/// Special return code for MOUSE_ACTIVATE to signal
/// if the target accepts activation (1), or denies it (0)
PRBool acceptActivation;
reasonType reason;
};
/**