Merge branch 'gtk-combo-focus'

Fix spurious focus loss events for wxGTK comboboxes.

See https://github.com/wxWidgets/wxWidgets/pull/714
This commit is contained in:
Vadim Zeitlin
2018-02-04 14:52:27 +01:00
5 changed files with 29 additions and 15 deletions

View File

@@ -207,6 +207,7 @@ wxGTK:
- Implement XYToPosition() for single-line wxTextCtrl. - Implement XYToPosition() for single-line wxTextCtrl.
- Implement ShowPosition() for single-line wxTextCtrl. - Implement ShowPosition() for single-line wxTextCtrl.
- Improve wx{Client,Paint,Screen,Window}DC::GetPPI() (GTK+ 3). - Improve wx{Client,Paint,Screen,Window}DC::GetPPI() (GTK+ 3).
- Suppress focus loss events for wxChoice and wxComboBox on opening popup.
wxMSW: wxMSW:

View File

@@ -101,6 +101,7 @@ protected:
virtual void DoClear() wxOVERRIDE; virtual void DoClear() wxOVERRIDE;
virtual void DoDeleteOneItem(unsigned int n) wxOVERRIDE; virtual void DoDeleteOneItem(unsigned int n) wxOVERRIDE;
virtual bool GTKHandleFocusOut() wxOVERRIDE;
virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE; virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE;
virtual void DoApplyWidgetStyle(GtkRcStyle *style) wxOVERRIDE; virtual void DoApplyWidgetStyle(GtkRcStyle *style) wxOVERRIDE;

View File

@@ -197,9 +197,9 @@ public:
GdkWindow* GTKGetDrawingWindow() const; GdkWindow* GTKGetDrawingWindow() const;
bool GTKHandleFocusIn(); bool GTKHandleFocusIn();
bool GTKHandleFocusOut(); virtual bool GTKHandleFocusOut();
void GTKHandleFocusOutNoDeferring(); void GTKHandleFocusOutNoDeferring();
static void GTKHandleDeferredFocusOut(); void GTKHandleDeferredFocusOut();
// Called when m_widget becomes realized. Derived classes must call the // Called when m_widget becomes realized. Derived classes must call the
// base class method if they override it. // base class method if they override it.

View File

@@ -111,6 +111,23 @@ wxChoice::~wxChoice()
#endif // __WXGTK3__ #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 ) void wxChoice::GTKInsertComboBoxTextItem( unsigned int n, const wxString& text )
{ {
#ifdef __WXGTK3__ #ifdef __WXGTK3__

View File

@@ -3828,7 +3828,7 @@ bool wxWindowGTK::GTKShowFromOnIdle()
void wxWindowGTK::OnInternalIdle() void wxWindowGTK::OnInternalIdle()
{ {
if ( gs_deferredFocusOut ) if ( gs_deferredFocusOut )
GTKHandleDeferredFocusOut(); gs_deferredFocusOut->GTKHandleDeferredFocusOut();
// Check if we have to show window now // Check if we have to show window now
if (GTKShowFromOnIdle()) return; if (GTKShowFromOnIdle()) return;
@@ -4348,7 +4348,7 @@ bool wxWindowGTK::GTKHandleFocusIn()
// otherwise we need to send focus-out first // otherwise we need to send focus-out first
wxASSERT_MSG ( gs_deferredFocusOut != this, wxASSERT_MSG ( gs_deferredFocusOut != this,
"GTKHandleFocusIn(GTKFocus_Normal) called even though focus changed back to itself - derived class should handle this" ); "GTKHandleFocusIn(GTKFocus_Normal) called even though focus changed back to itself - derived class should handle this" );
GTKHandleDeferredFocusOut(); gs_deferredFocusOut->GTKHandleDeferredFocusOut();
} }
@@ -4459,23 +4459,18 @@ void wxWindowGTK::GTKHandleFocusOutNoDeferring()
GTKProcessEvent( event ); GTKProcessEvent( event );
} }
/*static*/
void wxWindowGTK::GTKHandleDeferredFocusOut() void wxWindowGTK::GTKHandleDeferredFocusOut()
{ {
// NB: See GTKHandleFocusOut() for explanation. This function is called // NB: See GTKHandleFocusOut() for explanation. This function is called
// from either GTKHandleFocusIn() or OnInternalIdle() to process // from either GTKHandleFocusIn() or OnInternalIdle() to process
// deferred event. // deferred event for this window.
if ( gs_deferredFocusOut )
{
wxWindowGTK *win = gs_deferredFocusOut;
gs_deferredFocusOut = NULL; gs_deferredFocusOut = NULL;
wxLogTrace(TRACE_FOCUS, wxLogTrace(TRACE_FOCUS,
"processing deferred focus_out event for %s(%p, %s)", "processing deferred focus_out event for %s(%p, %s)",
win->GetClassInfo()->GetClassName(), win, win->GetLabel()); GetClassInfo()->GetClassName(), this, GetLabel());
win->GTKHandleFocusOutNoDeferring(); GTKHandleFocusOutNoDeferring();
}
} }
void wxWindowGTK::SetFocus() void wxWindowGTK::SetFocus()