b=568101 use the value of aRaise in SetFocus to determine whether to set gFocusWindow r=enndeakin

--HG--
extra : rebase_source : bb755e470a77360d0d0aef703fa3377df0bec5fe
This commit is contained in:
Karl Tomlinson 2010-06-03 15:50:49 +12:00
parent 780ed6d996
commit 2386399bb6
2 changed files with 55 additions and 11 deletions

View File

@ -459,7 +459,15 @@ class nsIWidget : public nsISupports {
NS_IMETHOD IsEnabled(PRBool *aState) = 0;
/**
* Give focus to this widget.
* Request activation of this window or give focus to this widget.
*
* @param aRaise If PR_TRUE, this function requests activation of this
* widget's toplevel window.
* If PR_FALSE, the appropriate toplevel window (which in
* the case of popups may not be this widget's toplevel
* window) is already active, and this function indicates
* that keyboard events should be reported through the
* aHandleEventFunction provided to this->Create().
*/
NS_IMETHOD SetFocus(PRBool aRaise = PR_FALSE) = 0;

View File

@ -289,8 +289,9 @@ guint32 nsWindow::sLastButtonReleaseTime = 0;
static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
// the current focus window
// The window from which the focus manager asks us to dispatch key events.
static nsWindow *gFocusWindow = NULL;
static PRBool gBlockActivateEvent = PR_FALSE;
static PRBool gGlobalsInitialized = PR_FALSE;
static PRBool gRaiseWindows = PR_TRUE;
static nsWindow *gPluginFocusWindow = NULL;
@ -1336,7 +1337,7 @@ nsWindow::SetFocus(PRBool aRaise)
// Make sure that our owning widget has focus. If it doesn't try to
// grab it. Note that we don't set our focus flag in this case.
LOGFOCUS((" SetFocus [%p]\n", (void *)this));
LOGFOCUS((" SetFocus %d [%p]\n", aRaise, (void *)this));
GtkWidget *owningWidget = GetMozContainerWidget();
if (!owningWidget)
@ -1363,20 +1364,42 @@ nsWindow::SetFocus(PRBool aRaise)
if (!owningWindow)
return NS_ERROR_FAILURE;
if (!GTK_WIDGET_HAS_FOCUS(owningWidget)) {
LOGFOCUS((" grabbing focus for the toplevel [%p]\n", (void *)this));
if (aRaise) {
// aRaise == PR_TRUE means request toplevel activation.
// Set focus to the window
if (gRaiseWindows && aRaise && toplevelWidget &&
!GTK_WIDGET_HAS_FOCUS(toplevelWidget) &&
owningWindow->mIsShown && GTK_IS_WINDOW(owningWindow->mShell))
gtk_window_present(GTK_WINDOW(owningWindow->mShell));
// This is asynchronous.
// If and when the window manager accepts the request, then the focus
// widget will get a focus-in-event signal.
if (gRaiseWindows && owningWindow->mIsShown && owningWindow->mShell &&
!gtk_window_is_active(GTK_WINDOW(owningWindow->mShell))) {
gtk_widget_grab_focus(owningWidget);
LOGFOCUS((" requesting toplevel activation [%p]\n", (void *)this));
NS_ASSERTION(owningWindow->mWindowType != eWindowType_popup
|| mParent,
"Presenting an override-redirect window");
gtk_window_present(GTK_WINDOW(owningWindow->mShell));
}
return NS_OK;
}
// aRaise == PR_FALSE means that keyboard events should be dispatched
// from this widget.
// Ensure owningWidget is the focused GtkWidget within its toplevel window.
//
// For eWindowType_popup, this GtkWidget may not actually be the one that
// receives the key events as it may be the parent window that is active.
if (!gtk_widget_is_focus(owningWidget)) {
// This is synchronous. It takes focus from a plugin or from a widget
// in an embedder. The focus manager already knows that this window
// is active so gBlockActivateEvent avoids another (unnecessary)
// NS_ACTIVATE event.
gBlockActivateEvent = PR_TRUE;
gtk_widget_grab_focus(owningWidget);
gBlockActivateEvent = PR_FALSE;
}
// If this is the widget that already has focus, return.
if (gFocusWindow == this) {
LOGFOCUS((" already have focus [%p]\n", (void *)this));
@ -3092,7 +3115,20 @@ nsWindow::OnContainerFocusInEvent(GtkWidget *aWidget, GdkEventFocus *aEvent)
if (top_window && (GTK_WIDGET_VISIBLE(top_window)))
SetUrgencyHint(top_window, PR_FALSE);
// Return if being called within SetFocus because the focus manager
// already knows that the window is active.
if (gBlockActivateEvent) {
LOGFOCUS(("NS_ACTIVATE event is blocked [%p]\n", (void *)this));
return;
}
// This is not usually the correct window for dispatching key events,
// but the focus manager will call SetFocus to set the correct window if
// keyboard input will be accepted. Setting a non-NULL value here
// prevents OnButtonPressEvent() from dispatching NS_ACTIVATE if the
// widget is already active.
gFocusWindow = this;
DispatchActivateEvent();
LOGFOCUS(("Events sent from focus in event [%p]\n", (void *)this));