From f048a03ea6b954ba199f5e56fd15cd90453d7a91 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Sat, 13 Feb 2021 01:24:21 +0100 Subject: [PATCH] Fix parent of extra control not being a wxFileDialogBase on macOS A wxEVT_UPDATE_UI handler expects the parent of the extra control panel to be at least a wxFileDialogBase. However with wxMac when showing file types the extra control gets reparented and has the panel containing file type controls as a parent. Fix by not reparenting in case the extra control itself already is a panel, and then instead use the extra control as a container for the file type controls. --- src/osx/cocoa/filedlg.mm | 45 +++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/osx/cocoa/filedlg.mm b/src/osx/cocoa/filedlg.mm index 3a5fecae72..102a105e93 100644 --- a/src/osx/cocoa/filedlg.mm +++ b/src/osx/cocoa/filedlg.mm @@ -246,16 +246,25 @@ void wxFileDialog::ShowWindowModal() } -// Create a panel with the file type drop down list -// If extra controls need to be added (see wxFileDialog::SetExtraControlCreator), add -// them to the panel as well -// Returns the newly created wxPanel +// Fill a new or existing panel with the file type drop down list. +// If extra controls need to be added (see wxFileDialog::SetExtraControlCreator), +// use that as a panel if possible, otherwise add them to a new panel. +// Returns a newly created wxPanel or extracontrol if it's suitable as a filter +// panel. wxWindow* wxFileDialog::CreateFilterPanel(wxWindow *extracontrol) { - wxPanel *extrapanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); + // Try to use extracontrol as a filter panel instead of creating a new one + // and then reparenting extracontrol. Reparenting is less desired as user + // code may expect the parent to be a wxFileDialog as on other platforms. + const bool useExtraControlAsPanel = extracontrol && + wxDynamicCast(extracontrol, wxPanel) != NULL; + + wxWindow* extrapanel = useExtraControlAsPanel + ? extracontrol + : static_cast(new wxPanel(this)); + wxBoxSizer *verticalSizer = new wxBoxSizer(wxVERTICAL); - extrapanel->SetSizer(verticalSizer); // the file type control { @@ -278,13 +287,29 @@ wxWindow* wxFileDialog::CreateFilterPanel(wxWindow *extracontrol) if(extracontrol) { - wxBoxSizer *horizontalSizer = new wxBoxSizer(wxHORIZONTAL); - verticalSizer->Add(horizontalSizer, 0, wxEXPAND, 0); + // Either use an extra control's existing sizer or the extra control + // itself, to be in the vertical sizer. - extracontrol->Reparent(extrapanel); - horizontalSizer->Add(extracontrol); + wxSizer* existingSizer = extracontrol->GetSizer(); + if ( useExtraControlAsPanel && existingSizer ) + { + // Move extra control's sizer to verticalSizer. + extracontrol->SetSizer(NULL, /* deleteOld = */ false); + verticalSizer->Add(existingSizer); + } + else + { + wxBoxSizer* horizontalSizer = new wxBoxSizer(wxHORIZONTAL); + verticalSizer->Add(horizontalSizer, 0, wxEXPAND, 0); + + if ( !useExtraControlAsPanel ) + extracontrol->Reparent(extrapanel); + horizontalSizer->Add(extracontrol); + } } + extrapanel->SetSizer(verticalSizer); + verticalSizer->Layout(); verticalSizer->SetSizeHints(extrapanel); return extrapanel;