From 3b40ff0d4135076ef7811a98687e14c7b21cd1a4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 29 Jan 2018 18:32:54 +0100 Subject: [PATCH] Send wxEVT_SET_FOCUS for composite window when a child gets focus wxCompositeWindow already connected to child wxEVT_KILL_FOCUS events and generated the same event for the composite window itself, but didn't do it for wxEVT_SET_FOCUS, resulting in not getting these events for the main window as expected. E.g. this resulted in never getting any wxEVT_SET_FOCUS events for wxSearchCtrl when using its generic version (i.e. not under Mac). Fix this by connecting to wxEVT_SET_FOCUS events for the children too. Note that this relies on having a correct "previously focused window" in these events, if this doesn't work reliably for some ports, we might need to maintain a "bool m_hasFocus" field in wxCompositeWindow itself instead. Also note that we might avoid having all this code in wxCompositeWindow if we translated the underlying native focus event to wxFocusEvents for both the real window and its GetMainWindowOfCompositeControl() if it's different. This could potentially be simpler and would definitely be more efficient, but would require more changes. Closes #15569. --- include/wx/compositewin.h | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/include/wx/compositewin.h b/include/wx/compositewin.h index 567d0e8999..c9a339ac44 100644 --- a/include/wx/compositewin.h +++ b/include/wx/compositewin.h @@ -193,7 +193,10 @@ private: if ( child == this ) return; // not a child, we don't want to Connect() to ourselves - // Always capture wxEVT_KILL_FOCUS: + child->Connect(wxEVT_SET_FOCUS, + wxFocusEventHandler(wxCompositeWindow::OnSetFocus), + NULL, this); + child->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(wxCompositeWindow::OnKillFocus), NULL, this); @@ -221,6 +224,27 @@ private: event.Skip(); } + void OnSetFocus(wxFocusEvent& event) + { + event.Skip(); + + // When a child of a composite window gains focus, the entire composite + // focus gains focus as well -- unless it had it already. + // + // We suppose that we hadn't had focus if the event doesn't carry the + // previously focused window as it normally means that it comes from + // outside of this program. + wxWindow* const oldFocus = event.GetWindow(); + if ( !oldFocus || oldFocus->GetMainWindowOfCompositeControl() != this ) + { + wxFocusEvent eventThis(wxEVT_SET_FOCUS, this->GetId()); + eventThis.SetEventObject(this); + eventThis.SetWindow(event.GetWindow()); + + this->ProcessWindowEvent(eventThis); + } + } + void OnKillFocus(wxFocusEvent& event) { // Ignore focus changes within the composite control: