Avoid spurious focus events for composite windows in wxMSW

Composite windows, i.e. wxWindows composed of several HWNDs at MSW
level, didn't handle focus events correctly and, for example, generated
wxEVT_KILL_FOCUS event when the focus simply switched from wxComboBox
itself to the EDIT control inside it, which broke using non-readonly
wxComboBox as in-place editor inside wxDataViewCtrl.

Check if the focus event notifies about the focus switching to, or from,
another HWND belonging to the same window, and suppress wx event
generation in this case as they don't make sense because the focus
doesn't change at wx level.

See #17034.
This commit is contained in:
Vadim Zeitlin 2018-02-03 22:32:37 +01:00
parent 43c1baf1bd
commit d7b88827b8

View File

@ -4169,6 +4169,14 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
return false;
}
if ( ContainsHWND(hwnd) )
{
// If another subwindow of this window already had focus before, this
// window should already have focus at wx level, no need for another
// event.
return false;
}
// notify the parent keeping track of focus for the kbd navigation
// purposes that we got it
wxChildFocusEvent eventFocus((wxWindow *)this);
@ -4193,6 +4201,20 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
{
// Don't send the event when in the process of being deleted. This can
// only cause problems if the event handler tries to access the object.
if ( m_isBeingDeleted )
{
return false;
}
if ( ContainsHWND(hwnd) )
{
// If the focus switches to another HWND which is part of the same
// wxWindow, we must not generate a wxEVT_KILL_FOCUS.
return false;
}
#if wxUSE_CARET
// Deal with caret
if ( m_caret )
@ -4201,13 +4223,6 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
}
#endif // wxUSE_CARET
// Don't send the event when in the process of being deleted. This can
// only cause problems if the event handler tries to access the object.
if ( m_isBeingDeleted )
{
return false;
}
wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
event.SetEventObject(this);