From e528a0d5397ed35517cdc71015a1c490b8004242 Mon Sep 17 00:00:00 2001 From: "rods%netscape.com" Date: Mon, 20 Sep 1999 22:18:57 +0000 Subject: [PATCH] Added code to make sure that focus gets set on the window for mouse down --- content/events/src/nsEventStateManager.cpp | 63 +++++++++++++++++++++- content/events/src/nsEventStateManager.h | 3 +- layout/events/src/nsEventStateManager.cpp | 63 +++++++++++++++++++++- layout/events/src/nsEventStateManager.h | 3 +- 4 files changed, 126 insertions(+), 6 deletions(-) diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index ffce5f1f23fb..69f57dcdf3d4 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -78,6 +78,7 @@ nsEventStateManager::nsEventStateManager() mDocument = nsnull; mPresContext = nsnull; mCurrentTabIndex = 0; + mLastWindowToHaveFocus = nsnull; NS_INIT_REFCNT(); } @@ -95,6 +96,8 @@ nsEventStateManager::~nsEventStateManager() NS_IF_RELEASE(mCurrentFocus); NS_IF_RELEASE(mDocument); + + NS_IF_RELEASE(mLastWindowToHaveFocus); } NS_IMPL_ADDREF(nsEventStateManager) @@ -370,9 +373,13 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext, PRBool focusChangeFailed = PR_TRUE; if (focusable) { - nsCOMPtr content = do_QueryInterface(focusable); - if (ChangeFocus(content, PR_TRUE)) + if (current != mCurrentFocus) { + nsCOMPtr content = do_QueryInterface(focusable); + if (ChangeFocus(content, PR_TRUE)) + focusChangeFailed = PR_FALSE; + } else { focusChangeFailed = PR_FALSE; + } } if (focusChangeFailed) { @@ -1405,6 +1412,58 @@ nsEventStateManager::SendFocusBlur(nsIContent *aContent) if (NS_OK == ec) { mCurrentTabIndex = val; } + + // Check to see if the mCurrentTarget has a view with a widget + // i.e TextField or TextArea, if so, don't set the focus on their window + PRBool shouldSetFocusOnWindow = PR_TRUE; + if (nsnull != mCurrentTarget) { + nsIView * view = nsnull; + mCurrentTarget->GetView(&view); + if (view != nsnull) { + nsIWidget *window = nsnull; + view->GetWidget(window); + if (window != nsnull) { // addrefs + shouldSetFocusOnWindow = PR_FALSE; + NS_RELEASE(window); + } + } + } + + // Find the window that this frame is in and + // make sure it has focus + // XXX Note: mLastWindowToHaveFocus this does not track when ANY focus + // event comes through, the only place this gets set is here + // so some windows may get multiple focus events + // For example, if you clicked in the window (generates focus event) + // then click on a gfx control (generates another focus event) + if (shouldSetFocusOnWindow && nsnull != mCurrentTarget) { + nsIFrame * parentFrame; + mCurrentTarget->GetParentWithView(&parentFrame); + if (nsnull != parentFrame) { + nsIView * pView; + parentFrame->GetView(&pView); + if (nsnull != pView) { + nsIWidget *window = nsnull; + + nsIView *ancestor = pView; + while (nsnull != ancestor) { + ancestor->GetWidget(window); // addrefs + if (nsnull != window) { + if (window != mLastWindowToHaveFocus) { + window->SetFocus(); + NS_IF_RELEASE(mLastWindowToHaveFocus); + mLastWindowToHaveFocus = window; + } else { + NS_IF_RELEASE(window); + } + break; + } + ancestor->GetParent(ancestor); + } + } + } + } + } return NS_OK; diff --git a/content/events/src/nsEventStateManager.h b/content/events/src/nsEventStateManager.h index a619f1bdb10a..6a2699fd92d4 100644 --- a/content/events/src/nsEventStateManager.h +++ b/content/events/src/nsEventStateManager.h @@ -97,7 +97,8 @@ protected: nsIContent* mDragOverContent; nsIContent* mCurrentFocus; PRInt32 mCurrentTabIndex; - + nsIWidget * mLastWindowToHaveFocus; // last native window to get focus via the evs + nsIPresContext* mPresContext; // Not refcnted nsIDocument* mDocument; // [OWNER], but doesn't need to be. }; diff --git a/layout/events/src/nsEventStateManager.cpp b/layout/events/src/nsEventStateManager.cpp index ffce5f1f23fb..69f57dcdf3d4 100644 --- a/layout/events/src/nsEventStateManager.cpp +++ b/layout/events/src/nsEventStateManager.cpp @@ -78,6 +78,7 @@ nsEventStateManager::nsEventStateManager() mDocument = nsnull; mPresContext = nsnull; mCurrentTabIndex = 0; + mLastWindowToHaveFocus = nsnull; NS_INIT_REFCNT(); } @@ -95,6 +96,8 @@ nsEventStateManager::~nsEventStateManager() NS_IF_RELEASE(mCurrentFocus); NS_IF_RELEASE(mDocument); + + NS_IF_RELEASE(mLastWindowToHaveFocus); } NS_IMPL_ADDREF(nsEventStateManager) @@ -370,9 +373,13 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext, PRBool focusChangeFailed = PR_TRUE; if (focusable) { - nsCOMPtr content = do_QueryInterface(focusable); - if (ChangeFocus(content, PR_TRUE)) + if (current != mCurrentFocus) { + nsCOMPtr content = do_QueryInterface(focusable); + if (ChangeFocus(content, PR_TRUE)) + focusChangeFailed = PR_FALSE; + } else { focusChangeFailed = PR_FALSE; + } } if (focusChangeFailed) { @@ -1405,6 +1412,58 @@ nsEventStateManager::SendFocusBlur(nsIContent *aContent) if (NS_OK == ec) { mCurrentTabIndex = val; } + + // Check to see if the mCurrentTarget has a view with a widget + // i.e TextField or TextArea, if so, don't set the focus on their window + PRBool shouldSetFocusOnWindow = PR_TRUE; + if (nsnull != mCurrentTarget) { + nsIView * view = nsnull; + mCurrentTarget->GetView(&view); + if (view != nsnull) { + nsIWidget *window = nsnull; + view->GetWidget(window); + if (window != nsnull) { // addrefs + shouldSetFocusOnWindow = PR_FALSE; + NS_RELEASE(window); + } + } + } + + // Find the window that this frame is in and + // make sure it has focus + // XXX Note: mLastWindowToHaveFocus this does not track when ANY focus + // event comes through, the only place this gets set is here + // so some windows may get multiple focus events + // For example, if you clicked in the window (generates focus event) + // then click on a gfx control (generates another focus event) + if (shouldSetFocusOnWindow && nsnull != mCurrentTarget) { + nsIFrame * parentFrame; + mCurrentTarget->GetParentWithView(&parentFrame); + if (nsnull != parentFrame) { + nsIView * pView; + parentFrame->GetView(&pView); + if (nsnull != pView) { + nsIWidget *window = nsnull; + + nsIView *ancestor = pView; + while (nsnull != ancestor) { + ancestor->GetWidget(window); // addrefs + if (nsnull != window) { + if (window != mLastWindowToHaveFocus) { + window->SetFocus(); + NS_IF_RELEASE(mLastWindowToHaveFocus); + mLastWindowToHaveFocus = window; + } else { + NS_IF_RELEASE(window); + } + break; + } + ancestor->GetParent(ancestor); + } + } + } + } + } return NS_OK; diff --git a/layout/events/src/nsEventStateManager.h b/layout/events/src/nsEventStateManager.h index a619f1bdb10a..6a2699fd92d4 100644 --- a/layout/events/src/nsEventStateManager.h +++ b/layout/events/src/nsEventStateManager.h @@ -97,7 +97,8 @@ protected: nsIContent* mDragOverContent; nsIContent* mCurrentFocus; PRInt32 mCurrentTabIndex; - + nsIWidget * mLastWindowToHaveFocus; // last native window to get focus via the evs + nsIPresContext* mPresContext; // Not refcnted nsIDocument* mDocument; // [OWNER], but doesn't need to be. };