fixes to handling of focus changes for toplevel windows
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@46998 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: src/dfb/nonownedwnd.cpp
|
||||
// Purpose: implementation of wxNonOwnedWindowow
|
||||
// Purpose: implementation of wxNonOwnedWindow
|
||||
// Author: Vaclav Slavik
|
||||
// Created: 2006-12-24
|
||||
// RCS-ID: $Id$
|
||||
@@ -243,7 +243,18 @@ bool wxNonOwnedWindow::Show(bool show)
|
||||
m_dfbwin->SetOpacity(show ? m_opacity : 0);
|
||||
|
||||
if ( show )
|
||||
SetDfbFocus();
|
||||
{
|
||||
wxWindow *focused = FindFocus();
|
||||
if ( focused && focused->GetTLW() == this )
|
||||
{
|
||||
// focus is on this frame or its children, apply it to DirectFB
|
||||
SetDfbFocus();
|
||||
}
|
||||
// else: don't do anything, if this is wxFrame or wxDialog that should
|
||||
// get focus when it's shown,
|
||||
// wxTopLevelWindowDFB::HandleFocusEvent() will do it as soon as
|
||||
// the event loop starts
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -368,12 +379,66 @@ void wxNonOwnedWindow::Update()
|
||||
// events handling
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
static wxNonOwnedWindow *gs_insideDFBFocusHandlerOf = NULL;
|
||||
|
||||
struct InsideDFBFocusHandlerSetter
|
||||
{
|
||||
InsideDFBFocusHandlerSetter(wxNonOwnedWindow *win)
|
||||
{
|
||||
wxASSERT( gs_insideDFBFocusHandlerOf == NULL );
|
||||
gs_insideDFBFocusHandlerOf = win;
|
||||
}
|
||||
~InsideDFBFocusHandlerSetter()
|
||||
{
|
||||
gs_insideDFBFocusHandlerOf = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
void wxNonOwnedWindow::SetDfbFocus()
|
||||
{
|
||||
wxCHECK_RET( IsShown(), _T("cannot set focus to hidden window") );
|
||||
wxASSERT_MSG( FindFocus() && FindFocus()->GetTLW() == this,
|
||||
_T("setting DirectFB focus to unexpected window") );
|
||||
|
||||
// Don't set DirectFB focus if we're called from HandleFocusEvent() on
|
||||
// this window, because we already have the focus in that case. Not only
|
||||
// would it be unnecessary, it would be harmful: RequestFocus() adds
|
||||
// an event to DirectFB event queue and calling it when in
|
||||
// HandleFocusEvent() could result in a window being focused when it
|
||||
// should not be. Consider this example:
|
||||
//
|
||||
// tlw1->SetFocus(); // (1)
|
||||
// tlw2->SetFocus(); // (2)
|
||||
//
|
||||
// This results in adding these events to DFB queue:
|
||||
//
|
||||
// DWET_GOTFOCUS(tlw1)
|
||||
// DWET_LOSTFOCUS(tlw1)
|
||||
// DWET_GOTFOCUS(tlw2)
|
||||
//
|
||||
// Note that the events are processed by event loop, i.e. not between
|
||||
// execution of lines (1) and (2) above. So by the time the first
|
||||
// DWET_GOTFOCUS event is handled, tlw2->SetFocus() was already executed.
|
||||
// If we onconditionally called RequestFocus() from here, handling the
|
||||
// first event would result in this change to the event queue:
|
||||
//
|
||||
// DWET_LOSTFOCUS(tlw1)
|
||||
// DWET_GOTFOCUS(tlw2) // (3)
|
||||
// DWET_LOSTFOCUS(tlw2)
|
||||
// DWET_GOTFOCUS(tlw1)
|
||||
//
|
||||
// And the focus would get back to tlw1 even though that's not what we
|
||||
// wanted.
|
||||
|
||||
if ( gs_insideDFBFocusHandlerOf == this )
|
||||
return;
|
||||
|
||||
GetDirectFBWindow()->RequestFocus();
|
||||
}
|
||||
|
||||
@@ -413,7 +478,10 @@ void wxNonOwnedWindow::HandleDFBWindowEvent(const wxDFBWindowEvent& event_)
|
||||
|
||||
case DWET_GOTFOCUS:
|
||||
case DWET_LOSTFOCUS:
|
||||
tlw->HandleFocusEvent(event_);
|
||||
{
|
||||
InsideDFBFocusHandlerSetter inside(tlw);
|
||||
tlw->HandleFocusEvent(event_);
|
||||
}
|
||||
break;
|
||||
|
||||
case DWET_NONE:
|
||||
|
@@ -200,6 +200,8 @@ void wxTopLevelWindowDFB::HandleFocusEvent(const wxDFBWindowEvent& event_)
|
||||
|
||||
if ( CanAcceptFocus() )
|
||||
SetFocus();
|
||||
else
|
||||
wxLogTrace(TRACE_EVENTS, "...which doesn't accept it");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -194,7 +194,8 @@ void wxWindowDFB::SetFocus()
|
||||
|
||||
gs_focusedWindow = this;
|
||||
|
||||
if ( IsShownOnScreen() )
|
||||
if ( IsShownOnScreen() &&
|
||||
(!oldFocusedWindow || oldFocusedWindow->GetTLW() != m_tlw) )
|
||||
{
|
||||
m_tlw->SetDfbFocus();
|
||||
}
|
||||
|
Reference in New Issue
Block a user