Skip to content

fix(macos): persist list-control settings on Dock → Quit - #141

Merged
got3nks merged 1 commit into
amule-org:masterfrom
got3nks:fix/dock-quit-persist-settings
Jun 13, 2026
Merged

fix(macos): persist list-control settings on Dock → Quit#141
got3nks merged 1 commit into
amule-org:masterfrom
got3nks:fix/dock-quit-persist-settings

Conversation

@got3nks

@got3nks got3nks commented Jun 13, 2026

Copy link
Copy Markdown

Summary

On macOS, quitting aMule via the Dock right-click → Quit silently lost all list-control persisted state — column widths, sort orders, hidden-column choices on Downloads / Search / Server lists. CMD+Q and the red-X close button both worked. Reported in passing while testing column widths on the Downloads list.

Root cause

CMuleListCtrl::SaveSettings is called from the destructor. The destructor chain only runs if the wx main loop drains its pending-delete queue (which is where CamuleGuiApp::ShutDown puts the main frame via amuledlg->Destroy() — that call is lazy, scheduling deletion on the loop tail rather than running it inline).

  • CMD+Q / red-X: the main loop continues spinning after OnClose returns and naturally processes the pending-delete queue before CamuleApp::OnExit runs → CamuleDlg and its child list controls destruct with a live wxConfigSaveSettings writes correctly.
  • Dock → Quit: CamuleGuiApp::OnEndSession calls OnExit() directly. CamuleApp::OnExit at amule.cpp:263 deletes wxConfig immediately, then at amule.cpp:419 calls std::_Exit(0) which bypasses static destructors. The pending-delete queue is never processed → CamuleDlg destructor never runs → CMuleListCtrl::SaveSettings never fires.

Fix

Drain the pending-delete queue (DeletePendingObjects()) at the top of CamuleApp::OnExit, before the wxConfig teardown. The frame + child destructor chain now runs with a live config on every quit path. CMD+Q and red-X are unaffected — the pending queue is already empty by the time OnExit runs on those paths, so DeletePendingObjects() is a no-op.

Test plan

  • macOS arm64 build clean.
  • Manual: resize a column on the Downloads list → Dock right-click → Quit → relaunch → width persisted. Repeat with CMD+Q and red-X to confirm those still work.
  • CI build matrix.

CMuleListCtrl::SaveSettings runs from the destructor. On the CMD+Q
and red-X close paths the wx main loop naturally drains its pending-
delete queue (where amuledlg->Destroy() puts the frame) before
returning to CamuleApp::OnExit, so the destructor chain runs against
a live wxConfig and column widths / sort orders persist.

The macOS Dock right-click → Quit path skips that drain:
CamuleGuiApp::OnEndSession calls OnExit() directly, which then
deletes wxConfig (line 263) and, on macOS, std::_Exit(0) past every
static destructor (line 419). The CamuleDlg pending-Destroy is never
processed, so no list-control destructor ever fires and persisted
state is silently lost. Reported on macOS with the Downloads list.

Drain the pending-delete queue at the top of CamuleApp::OnExit,
before tearing down wxConfig. Frame + child destructors now run with
a live config on every quit path; CMD+Q and red-X are unaffected
(the queue is already empty by the time OnExit runs).
@got3nks
got3nks merged commit 7fd3eeb into amule-org:master Jun 13, 2026
10 checks passed
@got3nks
got3nks deleted the fix/dock-quit-persist-settings branch June 13, 2026 09:13
got3nks added a commit that referenced this pull request Jul 4, 2026
…#290)

CMuleListCtrl::SaveSettings runs from the frame's destructor, which
CamuleDlg::OnClose -> CamuleRemoteGuiApp::ShutDown only schedules
(amuledlg->Destroy(), lazy). CamuleRemoteGuiApp::OnExit then std::_Exit(0)s
to dodge the wxWebSession dtor crash, which skips wx's own cleanup, so the
queued destroy and the wxConfig flush never happen and freshly-resized column
widths / sort orders are silently lost. Cmd+Q happened to drain the queue
naturally, which is why only that path persisted.

Two fixes, mirroring the monolithic app:

- OnExit: DeletePendingObjects() + tear down wxConfig (which flushes it)
  before _Exit(0), so the red-X + confirm path runs the list-control
  destructors against a live config. Mirrors CamuleApp::OnExit (#141).

- OnQueryEndSession / OnEndSession handlers: the macOS Dock right-click ->
  Quit path ends the session without going through OnExit, so route it through
  ShutDown + OnExit explicitly. Mirrors CamuleGuiApp (amule-gui.cpp).
Cflsft pushed a commit to Cflsft/amule that referenced this pull request Jul 6, 2026
…amule-org#290)

CMuleListCtrl::SaveSettings runs from the frame's destructor, which
CamuleDlg::OnClose -> CamuleRemoteGuiApp::ShutDown only schedules
(amuledlg->Destroy(), lazy). CamuleRemoteGuiApp::OnExit then std::_Exit(0)s
to dodge the wxWebSession dtor crash, which skips wx's own cleanup, so the
queued destroy and the wxConfig flush never happen and freshly-resized column
widths / sort orders are silently lost. Cmd+Q happened to drain the queue
naturally, which is why only that path persisted.

Two fixes, mirroring the monolithic app:

- OnExit: DeletePendingObjects() + tear down wxConfig (which flushes it)
  before _Exit(0), so the red-X + confirm path runs the list-control
  destructors against a live config. Mirrors CamuleApp::OnExit (amule-org#141).

- OnQueryEndSession / OnEndSession handlers: the macOS Dock right-click ->
  Quit path ends the session without going through OnExit, so route it through
  ShutDown + OnExit explicitly. Mirrors CamuleGuiApp (amule-gui.cpp).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant