Send wxEVT_COMBOBOX immediately in wxOSX

To fix the problem with GetValue() not returning the updated value from
the event handlers, just set the new value forcefully ourselves before
generating the event rather than postponing sending the event.

This makes the event order under Mac consistent with those elsewhere,
i.e. wxEVT_COMBOBOX_CLOSEUP is now received after wxEVT_COMBOBOX there
too, and not before, as without this change.

See #18973.
This commit is contained in:
Andreas Falkenhahn
2020-12-05 22:45:13 +01:00
committed by Vadim Zeitlin
parent 2b51c14609
commit 4390a092f6

View File

@@ -139,22 +139,25 @@
- (void)comboBoxSelectionDidChange:(NSNotification *)notification - (void)comboBoxSelectionDidChange:(NSNotification *)notification
{ {
wxUnusedVar(notification); wxUnusedVar(notification);
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self ); wxNSComboBoxControl* const
impl = (wxNSComboBoxControl* ) wxWidgetImpl::FindFromWXWidget( self );
if ( impl && impl->ShouldSendEvents()) if ( impl && impl->ShouldSendEvents())
{ {
wxComboBox* wxpeer = static_cast<wxComboBox*>(impl->GetWXPeer()); wxComboBox* wxpeer = static_cast<wxComboBox*>(impl->GetWXPeer());
if ( wxpeer ) { if ( wxpeer ) {
const int sel = wxpeer->GetSelection(); const int sel = wxpeer->GetSelection();
const wxString& val = wxpeer->GetString(sel);
// We need to manually set the new value because at this time it
// still contains the old value, but we want GetValue() to return
// the new one if it's called from an event handler invoked below.
impl->SetStringValue(val);
wxCommandEvent event(wxEVT_COMBOBOX, wxpeer->GetId()); wxCommandEvent event(wxEVT_COMBOBOX, wxpeer->GetId());
event.SetEventObject( wxpeer ); event.SetEventObject( wxpeer );
event.SetInt( sel ); event.SetInt( sel );
event.SetString( wxpeer->GetString(sel) ); event.SetString( val );
// For some reason, wxComboBox::GetValue will not return the newly selected item wxpeer->HandleWindowEvent( event );
// while we're inside this callback, so use AddPendingEvent to make sure
// GetValue() returns the right value.
wxpeer->GetEventHandler()->AddPendingEvent( event );
} }
} }