From 508a409f7e53d790ab38f8f34c011e7a43c3044f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 4 Feb 2018 00:05:48 +0100 Subject: [PATCH] Suppress focus loss on opening combobox popup in wxGTK Make GTKHandleFocusOut() virtual and override it in wxChoice in order to avoid generating wxEVT_KILL_FOCUS events when the combobox dropdown button is clicked. This is important because it allows fatal problems when using a combobox-based in-place editor in wxDataViewCtrl as getting these events totally broke the UI before. See #17034. --- docs/changes.txt | 1 + include/wx/gtk/choice.h | 1 + include/wx/gtk/window.h | 2 +- src/gtk/choice.cpp | 17 +++++++++++++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/changes.txt b/docs/changes.txt index 41b4baba6d..bcf61cd909 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -206,6 +206,7 @@ wxGTK: - Implement XYToPosition() for single-line wxTextCtrl. - Implement ShowPosition() for single-line wxTextCtrl. - Improve wx{Client,Paint,Screen,Window}DC::GetPPI() (GTK+ 3). +- Suppress focus loss events for wxChoice and wxComboBox on opening popup. wxMSW: diff --git a/include/wx/gtk/choice.h b/include/wx/gtk/choice.h index ce43533dd3..c594624812 100644 --- a/include/wx/gtk/choice.h +++ b/include/wx/gtk/choice.h @@ -101,6 +101,7 @@ protected: virtual void DoClear() wxOVERRIDE; virtual void DoDeleteOneItem(unsigned int n) wxOVERRIDE; + virtual bool GTKHandleFocusOut() wxOVERRIDE; virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE; virtual void DoApplyWidgetStyle(GtkRcStyle *style) wxOVERRIDE; diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index 2430773c43..16c755c413 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -197,7 +197,7 @@ public: GdkWindow* GTKGetDrawingWindow() const; bool GTKHandleFocusIn(); - bool GTKHandleFocusOut(); + virtual bool GTKHandleFocusOut(); void GTKHandleFocusOutNoDeferring(); void GTKHandleDeferredFocusOut(); diff --git a/src/gtk/choice.cpp b/src/gtk/choice.cpp index db2240b11e..41bece0eed 100644 --- a/src/gtk/choice.cpp +++ b/src/gtk/choice.cpp @@ -111,6 +111,23 @@ wxChoice::~wxChoice() #endif // __WXGTK3__ } +bool wxChoice::GTKHandleFocusOut() +{ + if ( wx_is_at_least_gtk2(10) ) + { + gboolean isShown; + g_object_get( m_widget, "popup-shown", &isShown, NULL ); + + // Don't send "focus lost" events if the focus is grabbed by our own + // popup, it counts as part of this window, even though wx doesn't know + // about it (and can't, because GtkComboBox doesn't expose it). + if ( isShown ) + return true; + } + + return wxChoiceBase::GTKHandleFocusOut(); +} + void wxChoice::GTKInsertComboBoxTextItem( unsigned int n, const wxString& text ) { #ifdef __WXGTK3__