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
|
// Name: src/dfb/nonownedwnd.cpp
|
||||||
// Purpose: implementation of wxNonOwnedWindowow
|
// Purpose: implementation of wxNonOwnedWindow
|
||||||
// Author: Vaclav Slavik
|
// Author: Vaclav Slavik
|
||||||
// Created: 2006-12-24
|
// Created: 2006-12-24
|
||||||
// RCS-ID: $Id$
|
// RCS-ID: $Id$
|
||||||
@@ -243,7 +243,18 @@ bool wxNonOwnedWindow::Show(bool show)
|
|||||||
m_dfbwin->SetOpacity(show ? m_opacity : 0);
|
m_dfbwin->SetOpacity(show ? m_opacity : 0);
|
||||||
|
|
||||||
if ( show )
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -368,12 +379,66 @@ void wxNonOwnedWindow::Update()
|
|||||||
// events handling
|
// 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()
|
void wxNonOwnedWindow::SetDfbFocus()
|
||||||
{
|
{
|
||||||
wxCHECK_RET( IsShown(), _T("cannot set focus to hidden window") );
|
wxCHECK_RET( IsShown(), _T("cannot set focus to hidden window") );
|
||||||
wxASSERT_MSG( FindFocus() && FindFocus()->GetTLW() == this,
|
wxASSERT_MSG( FindFocus() && FindFocus()->GetTLW() == this,
|
||||||
_T("setting DirectFB focus to unexpected window") );
|
_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();
|
GetDirectFBWindow()->RequestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +478,10 @@ void wxNonOwnedWindow::HandleDFBWindowEvent(const wxDFBWindowEvent& event_)
|
|||||||
|
|
||||||
case DWET_GOTFOCUS:
|
case DWET_GOTFOCUS:
|
||||||
case DWET_LOSTFOCUS:
|
case DWET_LOSTFOCUS:
|
||||||
tlw->HandleFocusEvent(event_);
|
{
|
||||||
|
InsideDFBFocusHandlerSetter inside(tlw);
|
||||||
|
tlw->HandleFocusEvent(event_);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DWET_NONE:
|
case DWET_NONE:
|
||||||
|
@@ -200,6 +200,8 @@ void wxTopLevelWindowDFB::HandleFocusEvent(const wxDFBWindowEvent& event_)
|
|||||||
|
|
||||||
if ( CanAcceptFocus() )
|
if ( CanAcceptFocus() )
|
||||||
SetFocus();
|
SetFocus();
|
||||||
|
else
|
||||||
|
wxLogTrace(TRACE_EVENTS, "...which doesn't accept it");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -194,7 +194,8 @@ void wxWindowDFB::SetFocus()
|
|||||||
|
|
||||||
gs_focusedWindow = this;
|
gs_focusedWindow = this;
|
||||||
|
|
||||||
if ( IsShownOnScreen() )
|
if ( IsShownOnScreen() &&
|
||||||
|
(!oldFocusedWindow || oldFocusedWindow->GetTLW() != m_tlw) )
|
||||||
{
|
{
|
||||||
m_tlw->SetDfbFocus();
|
m_tlw->SetDfbFocus();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user