Skip to content

fix(gui): stop Reset Fields wiping the search history, gate the history UI - #709

Merged
got3nks merged 1 commit into
amule-org:masterfrom
got3nks:feat/search-history-pref-gating
Jul 30, 2026
Merged

fix(gui): stop Reset Fields wiping the search history, gate the history UI#709
got3nks merged 1 commit into
amule-org:masterfrom
got3nks:feat/search-history-pref-gating

Conversation

@got3nks

@got3nks got3nks commented Jul 30, 2026

Copy link
Copy Markdown

Summary

Closes #697. Four fixes around the search Name field, addressing all three of @ghysler's proposals plus a crash found while auditing the call sites.

1. "Reset Fields" wiped the whole search history

The reported bug, and the cause is a subtle one. The call already cast to wxTextEntry specifically to avoid this, with a comment saying so — but the cast doesn't help:

// wxComboBoxBase, include/wx/combobox.h
virtual void Clear() override
{
    wxItemContainer::Clear();   // ← the dropdown's item list
    wxTextEntry::Clear();
}

wxTextEntry::Clear() is virtual, so calling it through a wxTextEntry* dispatches to the combo override and empties the item list too. Now uses SetValue(""), which only touches the text.

This also explains the second half of the report — the last term still being offered as a completion after the pull-down looked empty. The item list was being cleared while the autocomplete set stayed armed, so proposal (3) resolves with the same fix rather than needing its own.

2. Crash in "search related files"

SearchListCtrl.cpp did CastByID(IDC_SEARCHNAME, …, wxTextCtrl)->SetValue(keyword). The field became a wxComboBox in #643, and wxComboBox doesn't derive from wxTextCtrl — it's wxWindowWithItems<wxControl, wxComboBoxBase>. CastByID is a dynamic_cast, so that yielded nullptr and the SetValue() dereferenced it. Reachable whenever you're connected to an ed2k server. Cast to wxTextEntry, the common base.

3. "Clear search history" as a visible button

Proposal (2). The action already existed in the field's right-click menu, but that menu is unreachable on Windows: the editable part of a wxComboBox is a native child EDIT window, and per ShouldForwardFromEditToCombo() in src/msw/combobox.cpp wx forwards only WM_KEYUP/KEYDOWN/CHAR/SYSCHAR/SYSKEYDOWN/SYSKEYUP/SETFOCUS/KILLFOCUS/CUT/COPY/PASTE from it. WM_CONTEXTMENU isn't among them, so the native menu appears and our handler never runs — matching @ghysler's screenshot exactly.

The button sits after the search-type choice and greys out when there's nothing stored. Built in SearchDlg.cpp rather than muuli_wdr.cpp so the existing msgid keeps its catalog position — adding the same string to muuli_wdr.cpp would move the pot entry, since xgettext orders entries by file scan order, and that trips pot-sync. No catalog changes in this PR.

4. The preference now gates the whole history UI

"Remember search history" previously only stopped new terms being recorded: existing terms stayed in the dropdown, kept being offered as completions, and the field kept its dropdown regardless. Now, with it off, the Name field is a plain wxTextCtrl, the Clear button is hidden, and no stored terms are loaded. searchhistory.dat is deliberately left on disk, so re-enabling restores the previous history rather than starting over.

Applied live from PrefsUnifiedDlg::OnOk via CfgChanged(IDC_SEARCHHISTORYENABLED), following the same idiom as the existing IDC_EXTCATINFO / IDC_SLIDER branches, so no restart is needed. The swap uses wxSizer::Replace, carries the typed value across, keeps wxTE_PROCESS_ENTER so Enter still searches, and re-binds the context menu when a combo is created.

Testing

Built monolithic + amulegui clean on macOS ARM64, Ubuntu ARM64 (wxGTK3) and Windows ARM64. git clang-format origin/master clean; diff-scoped Tier-2 clang-tidy clean. Verified on the Windows portable: the crash is gone, Reset Fields keeps the dropdown, and the preference toggle swaps the field and the button live in both directions.

…ry UI

Four things, all around the IDC_SEARCHNAME field.

"Reset Fields" wiped the whole search history instead of just the Name field.
The call was already casting to wxTextEntry to avoid exactly that, with a
comment saying so, but the cast does not help: wxTextEntry::Clear() is
virtual and wxComboBoxBase overrides it as { wxItemContainer::Clear();
wxTextEntry::Clear(); }, so the call dispatched to the override and emptied
the dropdown's item list too. Use SetValue("") instead, which only touches
the text. This also explains the second half of the report -- the last term
still being offered as a completion after the list looked empty -- since the
item list was cleared while the autocomplete set was left armed.

Fixes a null dereference in SearchListCtrl's "search related files" action.
The field became a wxComboBox in amule-project#643, and wxComboBox does not derive from
wxTextCtrl -- it is wxWindowWithItems<wxControl, wxComboBoxBase> -- so the
CastByID dynamic_cast to wxTextCtrl there had been yielding nullptr, which
the following SetValue() dereferenced. Cast to wxTextEntry, the common base
of both control types.

Adds a visible "Clear search history" button after the search-type choice.
The action already existed in the field's right-click menu, but that menu is
unreachable on Windows: wxComboBox's editable part is a native child EDIT
window, and wx forwards only key, focus and clipboard messages from it
(ShouldForwardFromEditToCombo in src/msw/combobox.cpp) -- WM_CONTEXTMENU is
not among them, so the native menu appears instead and our handler never
runs. Built in SearchDlg.cpp rather than muuli_wdr so the existing msgid
keeps its catalog position; adding the same string to muuli_wdr.cpp would
move the pot entry, since xgettext orders entries by file scan order.

Gates the whole history UI on "Remember search history", which previously
only stopped new terms being recorded: existing terms stayed visible in the
dropdown and kept being offered as completions, and the field kept its
dropdown either way. Now the Name field is a plain wxTextCtrl when the
preference is off, the Clear button is hidden, and no stored terms are
loaded. searchhistory.dat is deliberately left on disk, so re-enabling
restores the previous history rather than starting over. Applied live from
PrefsUnifiedDlg::OnOk, so no restart is needed.
@got3nks
got3nks merged commit 1f14c1c into amule-org:master Jul 30, 2026
15 checks passed
@got3nks
got3nks deleted the feat/search-history-pref-gating branch July 30, 2026 11:57
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.

aMuleGUI - Improvements to search history clearing behavior

1 participant