From 1b13b0f841cfce77a987a3a978161be381e167c6 Mon Sep 17 00:00:00 2001 From: "joki%netscape.com" Date: Tue, 15 Jun 1999 03:14:28 +0000 Subject: [PATCH] Fixes for event going to frames which have changes as a result of other event handlers. (loosely bug 1283) git-svn-id: svn://10.0.0.236/trunk@35325 18797224-902f-48f8-a5cc-f745e15eee43 --- .../events/public/nsIEventStateManager.h | 3 +- mozilla/content/events/src/nsDOMEvent.cpp | 6 ++-- .../events/src/nsEventStateManager.cpp | 35 ++++++++++++++++++- .../content/events/src/nsEventStateManager.h | 4 ++- mozilla/layout/base/nsPresShell.cpp | 27 +++++++++++--- .../events/public/nsIEventStateManager.h | 3 +- mozilla/layout/events/src/nsDOMEvent.cpp | 6 ++-- .../layout/events/src/nsEventStateManager.cpp | 35 ++++++++++++++++++- .../layout/events/src/nsEventStateManager.h | 4 ++- mozilla/layout/html/base/src/nsPresShell.cpp | 27 +++++++++++--- 10 files changed, 126 insertions(+), 24 deletions(-) diff --git a/mozilla/content/events/public/nsIEventStateManager.h b/mozilla/content/events/public/nsIEventStateManager.h index 7f81f16ceb0..8146107f36d 100644 --- a/mozilla/content/events/public/nsIEventStateManager.h +++ b/mozilla/content/events/public/nsIEventStateManager.h @@ -44,7 +44,8 @@ public: NS_IMETHOD PreHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, nsIFrame* aTargetFrame, - nsEventStatus& aStatus) = 0; + nsEventStatus& aStatus, + nsIView* aView) = 0; NS_IMETHOD PostHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, diff --git a/mozilla/content/events/src/nsDOMEvent.cpp b/mozilla/content/events/src/nsDOMEvent.cpp index 6fa5128ea37..28a4963fc8c 100644 --- a/mozilla/content/events/src/nsDOMEvent.cpp +++ b/mozilla/content/events/src/nsDOMEvent.cpp @@ -337,14 +337,12 @@ NS_METHOD nsDOMEvent::GetButton(PRUint32* aButton) // nsINSEventInterface NS_METHOD nsDOMEvent::GetLayerX(PRInt32* aLayerX) { - *aLayerX = 0; - return NS_OK; + return GetClientX(aLayerX); } NS_METHOD nsDOMEvent::GetLayerY(PRInt32* aLayerY) { - *aLayerY = 0; - return NS_OK; + return GetClientY(aLayerY); } NS_METHOD nsDOMEvent::GetPageX(PRInt32* aPageX) diff --git a/mozilla/content/events/src/nsEventStateManager.cpp b/mozilla/content/events/src/nsEventStateManager.cpp index f9f3160c6b1..5a241e36519 100644 --- a/mozilla/content/events/src/nsEventStateManager.cpp +++ b/mozilla/content/events/src/nsEventStateManager.cpp @@ -58,6 +58,7 @@ nsEventStateManager::nsEventStateManager() { mLastMouseOverFrame = nsnull; mLastDragOverFrame = nsnull; mCurrentTarget = nsnull; + mCurrentTargetContent = nsnull; mLastLeftMouseDownContent = nsnull; mLastMiddleMouseDownContent = nsnull; mLastRightMouseDownContent = nsnull; @@ -73,6 +74,7 @@ nsEventStateManager::nsEventStateManager() { } nsEventStateManager::~nsEventStateManager() { + NS_IF_RELEASE(mCurrentTargetContent); NS_IF_RELEASE(mActiveContent); NS_IF_RELEASE(mHoverContent); NS_IF_RELEASE(mDragOverContent); @@ -91,9 +93,11 @@ NS_IMETHODIMP nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, nsIFrame* aTargetFrame, - nsEventStatus& aStatus) + nsEventStatus& aStatus, + nsIView* aView) { mCurrentTarget = aTargetFrame; + NS_IF_RELEASE(mCurrentTargetContent); nsFrameState state; mCurrentTarget->GetFrameState(&state); @@ -111,6 +115,20 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, GenerateMouseEnterExit(aPresContext, aEvent); break; case NS_GOTFOCUS: +#if 0 + nsIViewManager* viewMgr; + if (NS_SUCCEEDED(aView->GetViewManager(viewMgr)) && viewMgr) { + nsIView* rootView; + viewMgr->GetRootView(rootView); + if (rootView == aView) { + printf("send focus\n"); + } + else { + printf("don't send focus\n"); + } + NS_RELEASE(viewMgr); + } +#endif //XXX Do we need window related focus change stuff here? break; case NS_LOSTFOCUS: @@ -128,6 +146,7 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext, nsIView* aView) { mCurrentTarget = aTargetFrame; + NS_IF_RELEASE(mCurrentTargetContent); nsresult ret = NS_OK; nsFrameState state; @@ -251,6 +270,9 @@ nsEventStateManager::ClearFrameRefs(nsIFrame* aFrame) mLastMouseOverFrame = nsnull; } if (aFrame == mCurrentTarget) { + if (aFrame) { + aFrame->GetContent(&mCurrentTargetContent); + } mCurrentTarget = nsnull; } return NS_OK; @@ -881,7 +903,18 @@ nsEventStateManager::GetNextTabIndex(nsIContent* aParent, PRBool forward) NS_IMETHODIMP nsEventStateManager::GetEventTarget(nsIFrame **aFrame) { + if (!mCurrentTarget && mCurrentTargetContent) { + nsCOMPtr shell; + if (mPresContext) { + nsresult rv = mPresContext->GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv) && shell){ + shell->GetPrimaryFrameFor(mCurrentTargetContent, &mCurrentTarget); + } + } + } + *aFrame = mCurrentTarget; + return NS_OK; } diff --git a/mozilla/content/events/src/nsEventStateManager.h b/mozilla/content/events/src/nsEventStateManager.h index ebd15e44fe2..f00cc6d880a 100644 --- a/mozilla/content/events/src/nsEventStateManager.h +++ b/mozilla/content/events/src/nsEventStateManager.h @@ -39,7 +39,8 @@ public: NS_IMETHOD PreHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, nsIFrame* aTargetFrame, - nsEventStatus& aStatus); + nsEventStatus& aStatus, + nsIView* aView); NS_IMETHOD PostHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, @@ -70,6 +71,7 @@ protected: //Any frames here must be checked for validity in ClearFrameRefs nsIFrame* mCurrentTarget; + nsIContent* mCurrentTargetContent; nsIFrame* mLastMouseOverFrame; nsIFrame* mLastDragOverFrame; diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index bd7c9f16326..450d8c9ee48 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -382,6 +382,7 @@ protected: PRUint32 mReflowLockCount; PRBool mIsDestroying; nsIFrame* mCurrentEventFrame; + nsIContent* mCurrentEventContent; nsCOMPtr mSelection; nsCOMPtr mCaret; @@ -393,6 +394,7 @@ private: void DisableScrolling(){mScrollingEnabled = PR_FALSE;} void EnableScrolling(){mScrollingEnabled = PR_TRUE;} PRBool IsScrollingEnabled(){return mScrollingEnabled;} + nsIFrame* GetCurrentEventFrame(); }; #ifdef NS_DEBUG @@ -459,6 +461,7 @@ PresShell::PresShell() mIsDestroying = PR_FALSE; mCaretEnabled = PR_FALSE; mDisplayNonTextSelection = PR_FALSE; + mCurrentEventContent = nsnull; EnableScrolling(); } @@ -540,6 +543,8 @@ PresShell::~PresShell() mRefCnt = 99;/* XXX hack! get around re-entrancy bugs */ mIsDestroying = PR_TRUE; + + NS_IF_RELEASE(mCurrentEventContent); if (mViewManager) { // Disable paints during tear down of the frame tree mViewManager->DisableRefresh(); @@ -1285,6 +1290,7 @@ PresShell::ClearFrameRefs(nsIFrame* aFrame) } if (aFrame == mCurrentEventFrame) { + mCurrentEventFrame->GetContent(&mCurrentEventContent); mCurrentEventFrame = nsnull; } return NS_OK; @@ -1965,6 +1971,16 @@ PresShell::Paint(nsIView *aView, return rv; } +nsIFrame* +PresShell::GetCurrentEventFrame() +{ + if (!mCurrentEventFrame && mCurrentEventContent) { + GetPrimaryFrameFor(mCurrentEventContent, &mCurrentEventFrame); + } + + return mCurrentEventFrame; +} + NS_IMETHODIMP PresShell::HandleEvent(nsIView *aView, nsGUIEvent* aEvent, @@ -2003,15 +2019,16 @@ PresShell::HandleEvent(nsIView *aView, //we are a listener now. } frame->GetFrameForPoint(aEvent->point, &mCurrentEventFrame); - if (nsnull != mCurrentEventFrame) { + NS_IF_RELEASE(mCurrentEventContent); + if (nsnull != GetCurrentEventFrame()) { //Once we have the targetFrame, handle the event in this order nsIEventStateManager *manager; if (NS_OK == mPresContext->GetEventStateManager(&manager)) { //1. Give event to event manager for pre event state changes and generation of synthetic events. - rv = manager->PreHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus); + rv = manager->PreHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView); //2. Give event to the DOM for third party and JS use. - if (nsnull != mCurrentEventFrame && NS_OK == rv) { + if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { nsIContent* targetContent; if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) { rv = targetContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull, @@ -2022,11 +2039,11 @@ PresShell::HandleEvent(nsIView *aView, //3. Give event to the Frames for browser default processing. // XXX The event isn't translated into the local coordinate space // of the frame... - if (nsnull != mCurrentEventFrame && NS_OK == rv) { + if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { rv = mCurrentEventFrame->HandleEvent(*mPresContext, aEvent, aEventStatus); //4. Give event to event manager for post event state changes and generation of synthetic events. - if (nsnull != mCurrentEventFrame && NS_OK == rv) { + if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { rv = manager->PostHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView); } } diff --git a/mozilla/layout/events/public/nsIEventStateManager.h b/mozilla/layout/events/public/nsIEventStateManager.h index 7f81f16ceb0..8146107f36d 100644 --- a/mozilla/layout/events/public/nsIEventStateManager.h +++ b/mozilla/layout/events/public/nsIEventStateManager.h @@ -44,7 +44,8 @@ public: NS_IMETHOD PreHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, nsIFrame* aTargetFrame, - nsEventStatus& aStatus) = 0; + nsEventStatus& aStatus, + nsIView* aView) = 0; NS_IMETHOD PostHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, diff --git a/mozilla/layout/events/src/nsDOMEvent.cpp b/mozilla/layout/events/src/nsDOMEvent.cpp index 6fa5128ea37..28a4963fc8c 100644 --- a/mozilla/layout/events/src/nsDOMEvent.cpp +++ b/mozilla/layout/events/src/nsDOMEvent.cpp @@ -337,14 +337,12 @@ NS_METHOD nsDOMEvent::GetButton(PRUint32* aButton) // nsINSEventInterface NS_METHOD nsDOMEvent::GetLayerX(PRInt32* aLayerX) { - *aLayerX = 0; - return NS_OK; + return GetClientX(aLayerX); } NS_METHOD nsDOMEvent::GetLayerY(PRInt32* aLayerY) { - *aLayerY = 0; - return NS_OK; + return GetClientY(aLayerY); } NS_METHOD nsDOMEvent::GetPageX(PRInt32* aPageX) diff --git a/mozilla/layout/events/src/nsEventStateManager.cpp b/mozilla/layout/events/src/nsEventStateManager.cpp index f9f3160c6b1..5a241e36519 100644 --- a/mozilla/layout/events/src/nsEventStateManager.cpp +++ b/mozilla/layout/events/src/nsEventStateManager.cpp @@ -58,6 +58,7 @@ nsEventStateManager::nsEventStateManager() { mLastMouseOverFrame = nsnull; mLastDragOverFrame = nsnull; mCurrentTarget = nsnull; + mCurrentTargetContent = nsnull; mLastLeftMouseDownContent = nsnull; mLastMiddleMouseDownContent = nsnull; mLastRightMouseDownContent = nsnull; @@ -73,6 +74,7 @@ nsEventStateManager::nsEventStateManager() { } nsEventStateManager::~nsEventStateManager() { + NS_IF_RELEASE(mCurrentTargetContent); NS_IF_RELEASE(mActiveContent); NS_IF_RELEASE(mHoverContent); NS_IF_RELEASE(mDragOverContent); @@ -91,9 +93,11 @@ NS_IMETHODIMP nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, nsIFrame* aTargetFrame, - nsEventStatus& aStatus) + nsEventStatus& aStatus, + nsIView* aView) { mCurrentTarget = aTargetFrame; + NS_IF_RELEASE(mCurrentTargetContent); nsFrameState state; mCurrentTarget->GetFrameState(&state); @@ -111,6 +115,20 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, GenerateMouseEnterExit(aPresContext, aEvent); break; case NS_GOTFOCUS: +#if 0 + nsIViewManager* viewMgr; + if (NS_SUCCEEDED(aView->GetViewManager(viewMgr)) && viewMgr) { + nsIView* rootView; + viewMgr->GetRootView(rootView); + if (rootView == aView) { + printf("send focus\n"); + } + else { + printf("don't send focus\n"); + } + NS_RELEASE(viewMgr); + } +#endif //XXX Do we need window related focus change stuff here? break; case NS_LOSTFOCUS: @@ -128,6 +146,7 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext, nsIView* aView) { mCurrentTarget = aTargetFrame; + NS_IF_RELEASE(mCurrentTargetContent); nsresult ret = NS_OK; nsFrameState state; @@ -251,6 +270,9 @@ nsEventStateManager::ClearFrameRefs(nsIFrame* aFrame) mLastMouseOverFrame = nsnull; } if (aFrame == mCurrentTarget) { + if (aFrame) { + aFrame->GetContent(&mCurrentTargetContent); + } mCurrentTarget = nsnull; } return NS_OK; @@ -881,7 +903,18 @@ nsEventStateManager::GetNextTabIndex(nsIContent* aParent, PRBool forward) NS_IMETHODIMP nsEventStateManager::GetEventTarget(nsIFrame **aFrame) { + if (!mCurrentTarget && mCurrentTargetContent) { + nsCOMPtr shell; + if (mPresContext) { + nsresult rv = mPresContext->GetShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv) && shell){ + shell->GetPrimaryFrameFor(mCurrentTargetContent, &mCurrentTarget); + } + } + } + *aFrame = mCurrentTarget; + return NS_OK; } diff --git a/mozilla/layout/events/src/nsEventStateManager.h b/mozilla/layout/events/src/nsEventStateManager.h index ebd15e44fe2..f00cc6d880a 100644 --- a/mozilla/layout/events/src/nsEventStateManager.h +++ b/mozilla/layout/events/src/nsEventStateManager.h @@ -39,7 +39,8 @@ public: NS_IMETHOD PreHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, nsIFrame* aTargetFrame, - nsEventStatus& aStatus); + nsEventStatus& aStatus, + nsIView* aView); NS_IMETHOD PostHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, @@ -70,6 +71,7 @@ protected: //Any frames here must be checked for validity in ClearFrameRefs nsIFrame* mCurrentTarget; + nsIContent* mCurrentTargetContent; nsIFrame* mLastMouseOverFrame; nsIFrame* mLastDragOverFrame; diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index bd7c9f16326..450d8c9ee48 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -382,6 +382,7 @@ protected: PRUint32 mReflowLockCount; PRBool mIsDestroying; nsIFrame* mCurrentEventFrame; + nsIContent* mCurrentEventContent; nsCOMPtr mSelection; nsCOMPtr mCaret; @@ -393,6 +394,7 @@ private: void DisableScrolling(){mScrollingEnabled = PR_FALSE;} void EnableScrolling(){mScrollingEnabled = PR_TRUE;} PRBool IsScrollingEnabled(){return mScrollingEnabled;} + nsIFrame* GetCurrentEventFrame(); }; #ifdef NS_DEBUG @@ -459,6 +461,7 @@ PresShell::PresShell() mIsDestroying = PR_FALSE; mCaretEnabled = PR_FALSE; mDisplayNonTextSelection = PR_FALSE; + mCurrentEventContent = nsnull; EnableScrolling(); } @@ -540,6 +543,8 @@ PresShell::~PresShell() mRefCnt = 99;/* XXX hack! get around re-entrancy bugs */ mIsDestroying = PR_TRUE; + + NS_IF_RELEASE(mCurrentEventContent); if (mViewManager) { // Disable paints during tear down of the frame tree mViewManager->DisableRefresh(); @@ -1285,6 +1290,7 @@ PresShell::ClearFrameRefs(nsIFrame* aFrame) } if (aFrame == mCurrentEventFrame) { + mCurrentEventFrame->GetContent(&mCurrentEventContent); mCurrentEventFrame = nsnull; } return NS_OK; @@ -1965,6 +1971,16 @@ PresShell::Paint(nsIView *aView, return rv; } +nsIFrame* +PresShell::GetCurrentEventFrame() +{ + if (!mCurrentEventFrame && mCurrentEventContent) { + GetPrimaryFrameFor(mCurrentEventContent, &mCurrentEventFrame); + } + + return mCurrentEventFrame; +} + NS_IMETHODIMP PresShell::HandleEvent(nsIView *aView, nsGUIEvent* aEvent, @@ -2003,15 +2019,16 @@ PresShell::HandleEvent(nsIView *aView, //we are a listener now. } frame->GetFrameForPoint(aEvent->point, &mCurrentEventFrame); - if (nsnull != mCurrentEventFrame) { + NS_IF_RELEASE(mCurrentEventContent); + if (nsnull != GetCurrentEventFrame()) { //Once we have the targetFrame, handle the event in this order nsIEventStateManager *manager; if (NS_OK == mPresContext->GetEventStateManager(&manager)) { //1. Give event to event manager for pre event state changes and generation of synthetic events. - rv = manager->PreHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus); + rv = manager->PreHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView); //2. Give event to the DOM for third party and JS use. - if (nsnull != mCurrentEventFrame && NS_OK == rv) { + if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { nsIContent* targetContent; if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) { rv = targetContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull, @@ -2022,11 +2039,11 @@ PresShell::HandleEvent(nsIView *aView, //3. Give event to the Frames for browser default processing. // XXX The event isn't translated into the local coordinate space // of the frame... - if (nsnull != mCurrentEventFrame && NS_OK == rv) { + if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { rv = mCurrentEventFrame->HandleEvent(*mPresContext, aEvent, aEventStatus); //4. Give event to event manager for post event state changes and generation of synthetic events. - if (nsnull != mCurrentEventFrame && NS_OK == rv) { + if (nsnull != GetCurrentEventFrame() && NS_OK == rv) { rv = manager->PostHandleEvent(*mPresContext, aEvent, mCurrentEventFrame, aEventStatus, aView); } }