Support wxFileDialog extra controls in sandboxed apps on macOS (PR #26908)

20 views
Skip to first unread message

Daniel Kulp

unread,
Aug 24, 2026, 4:27:35 PM (3 days ago) Aug 24
to wx-...@googlegroups.com, Subscribed

Extra controls (including the file type filter choice) have been disabled in sandboxed applications since the 2013-era workaround for #14906: the native save/open panel runs out of process (Powerbox / NSRemoteView) when sandboxed, and inserting wx-created views into the panel's own view hierarchy crashed.

The supported contract for accessory views is to build the NSView entirely in-process and hand the finished view to -[NSSavePanel setAccessoryView:]; the panel then hosts it safely even when it is remote. This PR does exactly that: the extra control and the filter panel are created as children of a hidden in-process host window instead of being parented to the (possibly remote) panel, and only the finished view is handed over.

This makes extra controls and file type filters work in sandboxed applications too, removing the APP_SANDBOX_CONTAINER_ID bail-out. As a safety valve, setting WX_DISABLE_FILEDIALOG_EXTRA_CONTROLS in the environment restores the old behaviour of skipping the extra controls.

This has been shipping for a while in xLights (a sandboxed Mac App Store wxWidgets application) without issues, with the file type filter and custom extra controls working in the sandboxed file dialogs.

🤖 Generated with Claude Code


You can view, comment on, or merge this pull request online at:

  https://github.com/wxWidgets/wxWidgets/pull/26908

Commit Summary

  • 8e692e7 Support wxFileDialog extra controls in sandboxed apps on macOS

File Changes

(2 files)

Patch Links:


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908@github.com>

Copilot

unread,
Aug 24, 2026, 4:54:40 PM (3 days ago) Aug 24
to wx-...@googlegroups.com, Subscribed
@Copilot commented on this pull request.

## Pull request overview

> [!WARNING]
> Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a `copilot-code-review.yml` file specifying one with the `runs-on` attribute. See the [docs](https://gh.io/AA11tgch) for more details.

Adds support for wxFileDialog accessory (extra) controls in sandboxed macOS apps by building the accessory view in-process and attaching the finished NSView to the native panel, removing the previous sandbox bail-out.

**Changes:**
- Introduces a hidden in-process host window to own accessory controls (extra controls + file type filter UI).
- Switches accessory view creation to parent controls under the host window rather than the (possibly remote) native panel.
- Replaces the sandbox env-var bail-out with an opt-out env var (`WX_DISABLE_FILEDIALOG_EXTRA_CONTROLS`).

### Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

| File | Description |
| ---- | ----------- |
| src/osx/cocoa/filedlg.mm | Creates/destroys an in-process host window and reparents accessory UI creation to it; adjusts env-var behavior. |
| include/wx/osx/filedlg.h | Adds a member pointer for the in-process accessory host window and documents intent. |







---

💡 <a href="/wxWidgets/wxWidgets/new/master?filename=.github/skills/code-review/SKILL.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add a `code-review` agent skill</a> or configure MCP servers for context-aware, tailored reviews. <a href="https://docs.github.com/en/copilot/how-tos/use-copilot-agents/request-a-code-review/use-code-review#mcp-servers-and-agent-skills" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn more in the docs.</a>

> + // The extra controls and the file-type filter panel are created as children
+ // of a hidden, in-process host window (see SetupExtraControls), so
+ // destroying the host tears down the whole accessory view hierarchy

VZ

unread,
Aug 26, 2026, 10:53:58 AM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed

@vadz commented on this pull request.

Thanks, this looks good to me, but it would be nice if you could check the issue with the potentially null m_accessoryHost.

And fix the other minor comments too if possible. TIA!


In include/wx/osx/filedlg.h:

> @@ -91,6 +91,9 @@ class WXDLLIMPEXP_CORE wxFileDialog: public wxFileDialogBase
     wxArrayString m_filterNames;
     wxChoice* m_filterChoice;
     wxWindow* m_filterPanel;
+    // Hidden in-process window owning the accessory controls; see
+    // wxFileDialog::SetupExtraControls() in filedlg.mm.
+    wxWindow* m_accessoryHost;

There is no reason not to initialize new members in their declarations in the new code:

⬇️ Suggested change
-    wxWindow* m_accessoryHost;
+    wxWindow* m_accessoryHost = nullptr;

In src/osx/cocoa/filedlg.mm:

> @@ -111,6 +112,7 @@ - (void)setAllowedExtensions:(const wxArrayString &)extensions
     m_filterChoice = nullptr;
     m_useFileTypeFilter = false;
     m_firstFileTypeFilter = 0;
+    m_accessoryHost = nullptr;

As per above

⬇️ Suggested change
-    m_accessoryHost = nullptr;

In src/osx/cocoa/filedlg.mm:

>      wxWindow* extrapanel = useExtraControlAsPanel
                             ? extracontrol
-                            : static_cast<wxWindow*>(new wxPanel(this));
+                            : static_cast<wxWindow*>(new wxPanel(m_accessoryHost));

I'm not sure Copilot is wrong here. Couldn't this be called even if there are no extra controls?


In src/osx/cocoa/filedlg.mm:

> +    if ( [panel contentView] == nil ||
+         getenv("WX_DISABLE_FILEDIALOG_EXTRA_CONTROLS") != nullptr )
         return;

It's not wrong again here either, although somewhat besides the point: we should use something like wxSystemOptions::GetOptionInt("osx.openfiledialog.disable-extra-controls") here, see the existing uses of ``wxSystemOptions` in wxOSX.

The corresponding env variable would be wx_osx_openfiledialog_disable_extra_controls=1.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/review/5031859216@github.com>

Daniel Kulp

unread,
Aug 26, 2026, 11:10:32 AM (yesterday) Aug 26
to wx-...@googlegroups.com, Push

@dkulp pushed 1 commit.

  • 48df49d Address review comments for sandboxed wxFileDialog extra controls


View it on GitHub or unsubscribe.


Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/before/8e692e7a3e9f20c0f1cdbe38bac0618b68249865/after/48df49d9f727eb2908b05622ec612027525caef6@github.com>

Daniel Kulp

unread,
Aug 26, 2026, 11:10:38 AM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed

@dkulp commented on this pull request.


In include/wx/osx/filedlg.h:

> @@ -91,6 +91,9 @@ class WXDLLIMPEXP_CORE wxFileDialog: public wxFileDialogBase
     wxArrayString m_filterNames;
     wxChoice* m_filterChoice;
     wxWindow* m_filterPanel;
+    // Hidden in-process window owning the accessory controls; see
+    // wxFileDialog::SetupExtraControls() in filedlg.mm.
+    wxWindow* m_accessoryHost;

Done in 48df49d.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/review/5032130238@github.com>

Daniel Kulp

unread,
Aug 26, 2026, 11:10:42 AM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed

@dkulp commented on this pull request.


In src/osx/cocoa/filedlg.mm:

>      wxWindow* extrapanel = useExtraControlAsPanel
                             ? extracontrol
-                            : static_cast<wxWindow*>(new wxPanel(this));
+                            : static_cast<wxWindow*>(new wxPanel(m_accessoryHost));

Right — CreateFilterPanel() is virtual and could in principle be reached without SetupExtraControls() having created the host first. The host window is now created on demand via a GetAccessoryHost() helper used by both call sites, so it can never be null there.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/review/5032130596@github.com>

Daniel Kulp

unread,
Aug 26, 2026, 11:10:44 AM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed

@dkulp commented on this pull request.


In src/osx/cocoa/filedlg.mm:

> +    if ( [panel contentView] == nil ||
+         getenv("WX_DISABLE_FILEDIALOG_EXTRA_CONTROLS") != nullptr )
         return;

Switched to wxSystemOptions::GetOptionInt(wxOSX_FILEDIALOG_DISABLE_EXTRA_CONTROLS) with the option name osx.openfiledialog.disable-extra-controls (env var wx_osx_openfiledialog_disable_extra_controls=1 via the existing wxSystemOptions environment fallback), following the wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES precedent, and documented it in interface/wx/sysopt.h.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/review/5032130743@github.com>

Daniel Kulp

unread,
Aug 26, 2026, 11:10:46 AM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed

@dkulp commented on this pull request.


In src/osx/cocoa/filedlg.mm:

> +    // The extra controls and the file-type filter panel are created as children
+    // of a hidden, in-process host window (see SetupExtraControls), so
+    // destroying the host tears down the whole accessory view hierarchy

Daniel Kulp

unread,
Aug 26, 2026, 11:10:53 AM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed
dkulp left a comment (wxWidgets/wxWidgets#26908)

Thanks for the review! All comments addressed in 48df49d:

  • m_accessoryHost is initialized in its declaration.
  • The host window is now created lazily via GetAccessoryHost(), so CreateFilterPanel() can no longer see a null host even if called outside of SetupExtraControls().
  • The destructor resets the pointers to the host's (destroyed) children so nothing dangles.
  • The env var was replaced with the osx.openfiledialog.disable-extra-controls system option (wxOSX_FILEDIALOG_DISABLE_EXTRA_CONTROLS, or wx_osx_openfiledialog_disable_extra_controls=1 in the environment), documented in interface/wx/sysopt.h.

Regarding Copilot's remaining comment about a pre-existing m_extraControl not being reparented: on wxOSX the only place that creates it is SetupExtraControls() itself (the base CreateExtraControl() is no longer called), so an already-created control is always parented to the host; the !m_extraControl check just makes a second setup pass reuse it.

Happy to squash before merge if you prefer.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/c5427341326@github.com>

Daniel Kulp

unread,
Aug 26, 2026, 11:10:53 AM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed

@dkulp commented on this pull request.


In src/osx/cocoa/filedlg.mm:

> @@ -111,6 +112,7 @@ - (void)setAllowedExtensions:(const wxArrayString &)extensions
     m_filterChoice = nullptr;
     m_useFileTypeFilter = false;
     m_firstFileTypeFilter = 0;
+    m_accessoryHost = nullptr;

Done.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/review/5032130425@github.com>

VZ

unread,
Aug 26, 2026, 12:25:37 PM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#26908)

Thanks for the update! This looks good to me now, @csomor any objections to merging?

P.S. I'll try rerunning the CI jobs once GitHub Actions is alive again, but I don't expect this to break anything as we don't have any tests exercising this code anyhow.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/c5428006008@github.com>

Stefan Csomor

unread,
Aug 26, 2026, 1:48:21 PM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed
csomor left a comment (wxWidgets/wxWidgets#26908)

@dkulp thanks a lot, wow, I was not aware of such a documentation for the right workaround at the time I was fighting with these controls, even though I thought I had watched all the corresponding WWDC vidos, great you found it :-)


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/c5428958438@github.com>

Stefan Csomor

unread,
Aug 26, 2026, 1:48:57 PM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed
csomor left a comment (wxWidgets/wxWidgets#26908)

Thanks for the update! This looks good to me now, @csomor any objections to merging?

No, I'm fine with this, really neat :-)


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/c5428964744@github.com>

VZ

unread,
Aug 26, 2026, 5:11:11 PM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed

Closed #26908 via e3c466e.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/pull/26908/issue_event/30068718791@github.com>

Reply all
Reply to author
Forward
0 new messages