Skip to content

feat(gui): add Alt+<letter> tab-switch shortcuts, mirrored as a macOS menu - #642

Merged
got3nks merged 3 commits into
amule-org:masterfrom
LSalami:add-alt-shortcuts-tab-switch
Jul 28, 2026
Merged

feat(gui): add Alt+<letter> tab-switch shortcuts, mirrored as a macOS menu#642
got3nks merged 3 commits into
amule-org:masterfrom
LSalami:add-alt-shortcuts-tab-switch

Conversation

@LSalami

@LSalami LSalami commented Jul 27, 2026

Copy link
Copy Markdown

Summary

Gives keyboard/screen-reader users a way to switch between the main
tabs (Networks, Search, Downloads, Shared Files, Messages, Statistics,
Preferences) without the mouse, matching the classic eMule shortcuts
(Alt+S for Search, etc.) requested in #180 by a VoiceOver user, and
called out there by @got3nks as reasonable and independent of the
larger accessibility refactor also tracked in that issue.

Implementation

  • Windows/Linux: plain wxAcceleratorEntry additions to the
    existing shortcut table.
  • macOS: a different mechanism was needed. An accelerator-table
    entry there only fires its wxEVT_MENU once per click-to-refocus
    (tested with wxWidgets 3.3.3 / macOS 26) — the first Alt+
    after the window regains key status works, every subsequent press
    is silently swallowed by Cocoa's key-equivalent dispatch until the
    user clicks something in the window again. A real NSMenuItem key
    equivalent doesn't share that bug, since the OS dispatches it
    directly rather than routing through the window's own event
    handling — so on macOS this adds a "Navigate" menu (aMule has no
    menu bar otherwise) whose items carry the same accelerators. As a
    side benefit, VoiceOver can navigate that menu directly, which the
    toolbar currently can't offer (also tracked in Accessibility bug report: Search results list is invisible with VoiceOver on macOS #180).

Test plan

  • Built locally on macOS (arm64) with CMake/wxWidgets 3.3.3
  • Verified the "Navigate" menu appears correctly in the macOS menu bar with all 7 items and their accelerators
  • Verified real menu-item clicks land on the correct handler with the correct button ID
  • Verified Alt+ keyboard shortcuts (via System Events key-code injection, spaced several seconds apart to avoid CGEventPost coalescing artifacts) land on the correct handler for every one of the 7 shortcuts

Scope note

This addresses only the Alt-letter shortcuts sub-item discussed in
#180. The issue's two bigger accessibility bugs — the custom-drawn
search results list and the Preferences sidebar being invisible to
VoiceOver — remain open and need the larger wxDataViewCtrl refactor
discussed there. Not claiming to close #180 with this PR.

@got3nks got3nks left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the "Navigate" menu and the shortcuts work (macOS + Linux/GTK). Two things to address before merge, plus a couple of minors.

1. Toolbar doesn't highlight the new tab on a shortcut/menu switch (confirmed on both platforms). OnToolBarButton ends with:

m_wndToolbar->ToggleTool(lastbutton, lastbutton == ev.GetId());
lastbutton = ev.GetId();

That only ever un-checks the old tool. The new tool is normally checked by the physical click (wx auto-toggles a wxITEM_CHECK tool on click), but an accelerator/menu event doesn't click anything — so via Alt+<letter> (or the macOS menu) the new tab's button never lights up, leaving the toolbar with no active button until a mouse click. SetActiveDialog doesn't touch the toolbar either. Fix — check the new tool explicitly:

if (lastbutton != ev.GetId()) {
    m_wndToolbar->ToggleTool(lastbutton, false);
}
m_wndToolbar->ToggleTool(ev.GetId(), true);
lastbutton = ev.GetId();

2. Append "(Alt+X)" as a non-translatable literal — this removes the entire po/ diff. The base tooltips ("Networks Window", etc.) already exist and are translated on master ("Networks Window""Finestra reti" in it.po; all 7 are in the pot). Baking the shortcut into the string (_("Networks Window (Alt+N)")) orphans those translations and forces a full regen — the ~5k-line, 40-catalog diff here. Instead concatenate the suffix outside _():

_("Networks Window") + " (Alt+N)"

That reuses the existing translated msgids, so regenerating po/ yields no changes at all — the PR shrinks from 42 files to just amuleDlg.cpp, with zero translator work. It's also exactly what the macOS menu in this PR already does (_("Networks") + "\tAlt+N").

Minor:

  • On macOS the tooltip says "Alt+N" but the key is Option / the menu shows ⌥N — slight wording mismatch.
  • Global Alt+<letter> accelerators shadow any control mnemonics — low risk today, worth keeping in mind.

The wxOSX menu workaround is well-reasoned and clearly documented — it just needs the toolbar-highlight fix (functional) and the non-translatable tooltip suffix (keeps this a one-file change).

LSalami added 3 commits July 28, 2026 07:37
… menu

Gives keyboard/screen-reader users a way to switch between the main
tabs (Networks, Search, Downloads, Shared Files, Messages, Statistics,
Preferences) without the mouse, matching the classic eMule shortcuts
(Alt+S for Search, etc.) requested in amule-org#180 by a VoiceOver user, and
called out there by a maintainer as reasonable and independent of the
larger accessibility refactor also tracked in that issue.

Windows/Linux get this via a plain wxAcceleratorEntry addition to the
existing shortcut table.

macOS needs a different mechanism: an accelerator-table entry there
only fires its wxEVT_MENU once per click-to-refocus (tested with
wxWidgets 3.3.3 / macOS 26) -- the first Alt+<letter> after the window
regains key status works, every subsequent press is silently swallowed
by Cocoa's key-equivalent dispatch until the user clicks something in
the window again. A real NSMenuItem key equivalent doesn't share that
bug, since the OS dispatches it directly rather than routing through
the window's own event handling -- so on macOS this adds a "Navigate"
menu (aMule has no menu bar otherwise) whose items carry the same
accelerators. As a side benefit, VoiceOver can navigate that menu
directly, which the toolbar currently can't offer (also tracked in
amule-org#180).

Verified interactively on macOS: menu-click and Alt+<letter> (via
System Events key-code injection, several seconds apart to avoid
CGEventPost coalescing) both land on CamuleDlg::OnToolBarButton /
OnPrefButton with the expected button ID, for every shortcut.

Addresses the Alt-letter shortcuts sub-item of amule-org#180. The issue's two
bigger accessibility bugs -- the custom-drawn search list and the
Preferences sidebar being invisible to VoiceOver -- remain open and
need the larger wxDataViewCtrl refactor discussed there, so this does
not close amule-org#180 on its own.
Addresses got3nks's review of amule-org#642, both points:

1. OnToolBarButton only ever untoggled the *previous* tool -- the new
   one got checked by wx's own click-auto-toggle on wxITEM_CHECK, which
   an accelerator or menu event (Alt+<letter>, the macOS Navigate menu)
   never triggers. So switching tabs via keyboard left no toolbar
   button active until the next mouse click. Toggle the new tool
   explicitly instead of relying on the click side effect.

2. The Alt+<letter> suffix was baked into the translatable tooltip
   strings (`_("Networks Window (Alt+N)")`), orphaning the existing
   translations for those msgids and forcing a full po/ regen.
   Concatenated the suffix outside `_()` instead, reusing the msgids
   already translated on master -- same pattern the macOS Navigate menu
   in this PR already uses for its own labels.
Mechanical rebase to resolve the po/ conflicts against master's
amule-org#643/amule-org#646/amule-org#648/amule-org#650/amule-org#651 -- no source changes here. Confirms got3nks's
prediction on the Alt+<letter>-outside-_() fix: the only genuinely new
msgid in the diff is "Navigate" (the new macOS menu itself); every
other hunk is line-number-comment churn from the rebase, not orphaned
or duplicated translations.
@LSalami
LSalami force-pushed the add-alt-shortcuts-tab-switch branch from a79e2f2 to d6022f2 Compare July 28, 2026 05:39
@LSalami

LSalami commented Jul 28, 2026

Copy link
Copy Markdown
Author

Done in a184976 — both fixed exactly as suggested:

  1. OnToolBarButton now explicitly toggles the new tool on, instead of relying on wx's click-auto-toggle (which an accelerator/menu event never triggers). Verified the toolbar lights up correctly switching tabs via Alt+ now, not just on click.
  2. Moved the (Alt+X) suffix outside _() for all seven tooltips, reusing the existing translated msgids.

Rebased onto current master and regenerated po/ as the final step (d6022f2). Confirms your prediction: the only genuinely new msgid in the diff is "Navigate" (the new macOS menu itself, unavoidable) — every other hunk is line-number-comment churn from the rebase, not orphaned or duplicated translations.

Left the macOS Alt-vs-⌥ tooltip wording mismatch as-is per your "minor" framing — happy to fix if you'd rather have it in this PR than deferred.

Verified for real: built and ran locally, full unit test suite passing (26/26).

@got3nks got3nks left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both fixes verified — toolbar now lights the new tab on accelerator/menu switches, and moving the (Alt+X) suffix outside _() kept all seven tooltip translations intact ("Networks Window""Finestra reti" still there). Confirmed "Navigate" is the only genuinely new msgid; the rest of the pot diff is just position/line-comment churn. Also audited the Alt+letter set against the rest of the app — the only letter overlaps (&Stop, &Pause, Send &Message) are context-menu mnemonics, which only capture keys while their popup is open, so nothing gets shadowed. Merging.

@got3nks
got3nks merged commit 400f7fe into amule-org:master Jul 28, 2026
13 checks passed
@got3nks

got3nks commented Jul 28, 2026

Copy link
Copy Markdown

One small follow-up would be appreciated when you get a chance: the macOS tooltips still read "(Alt+N)" while the Navigate menu right above renders the same shortcut as ⌥N — worth making them consistent with a platform-conditional suffix, e.g.

#ifdef __WXMAC__
    #define TAB_ACCEL(k) wxString(" (⌥" k ")")   // ⌥N
#else
    #define TAB_ACCEL(k) wxString(" (Alt+" k ")")
#endif
...
_("Networks Window") + TAB_ACCEL("N")

Stays outside _() so there's still no catalog impact, and ⌥ is the glyph every Mac app uses. No rush — purely cosmetic polish on an already-good change.

LSalami added a commit to LSalami/amule that referenced this pull request Jul 28, 2026
Mechanical rebase to resolve the po/ conflicts against master's amule-org#642
(just merged) -- no source changes here.
got3nks pushed a commit that referenced this pull request Jul 28, 2026
* feat(search): persist search history across restarts (#641)

The search field was a plain text control with no memory of past
searches. Swap it for a wxComboBox (a wxTextEntry, like wxTextCtrl,
so the existing GetValue()/Clear() call sites keep working via that
shared base) and persist submitted terms to wxConfig, most-recent
first, capped at 20 entries and deduplicated case-insensitively.

Right-clicking the field opens a small menu ("Remember search
history" checkbox + "Clear search history") so history can be paused
or wiped without a dedicated Preferences page.

i18n: ran scripts/update-po.sh to register the two new menu strings.

* style(search): separate the destructive Clear item from the toggle above

A separator between the checkbox and "Clear search history" keeps the
one-shot destructive action visually distinct from the persistent
on/off state, instead of reading as a second toggle in the same group.

* style(search): use nullptr instead of NULL for the new combo box

Fixes the modernize-use-nullptr clang-tidy finding on the changed
line; matches the nullptr convention already used a couple of
wxComboBox constructions below in the same file.

* feat(search): rework query history per #643 review — file, prefs toggle, edit menu

Addresses all four blocking points from got3nks's review, plus both
optional suggestions:

1. Edit context menu restored. Overriding the field's context menu no
   longer drops Cut/Copy/Paste/Select All -- same custom-Paste-ID idiom
   as CMuleTextCtrl::OnRightDown (wxMenu over-permits wxID_PASTE, so it
   gets a manual clipboard-content check), plus a separator, plus the
   history's own Clear action.

2. Persisted to a dedicated searchhistory.dat (via CTextFile, one term
   per line) instead of amule.conf -- mirrors eMule's AC_SearchStrings.dat.
   Query terms no longer bloat the main config or travel with config
   backups / the --amule-config-file push to amuleweb/amuleapi.

3. "Remember search history" moved into Preferences > General as an
   ordinary Cfg_Bool checkbox (IDC_SEARCHHISTORYENABLED), same
   NewCfgItem wiring as every other GUI-behavior toggle on that page.
   It's a client-side-only setting, so the one checkbox works unchanged
   in both amule and amuleGUI. The context menu keeps only Clear (a
   one-shot action, not a setting to toggle from a hidden menu).

4. Cap raised from 20 to 30, matching eMule's CCustomAutoComplete default.

Optional, done anyway:
- wxComboBox::AutoComplete() wired up (eMule's ACO_AUTOSUGGEST
  equivalent), re-armed after every load/record/clear so it always
  reflects the current entry set.
- Explicitly framed as *query* history throughout (comments, tooltip)
  to distinguish it from the separate, not-yet-implemented result
  persistence that's the rest of #641.

The dedup/move-to-front/cap logic that used to live inline in
CSearchDlg::RecordSearchHistory is extracted into a pure function,
ApplySearchHistoryEntry() (SearchHistory.h/.cpp), decoupled from
wxComboBox/wxConfig specifically so it's unit-testable without a wx
event loop -- new SearchHistoryTest covers empty-list insert, reorder
of an existing term, case-insensitive dedup, empty-term no-op, and
capping (including locking in the actual 30-entry constant).

Rebased onto current master; po/ catalogs regenerated as the final
step so the diff is just the new/changed strings in sync with the tree.

Verified for real: built and ran both amule and amulegui, plus the
full unit test suite (27/27 passing, including the new
SearchHistoryTest's 7 cases).

* fix(tests): link Format.cpp + strerror_r.c into SearchHistoryTest

Same Linux/mingw-only link failure as CMuleCollectionTest/MagnetURITest
already work around: muleunit's MuleDebug.cpp needs CFormat for its
glibc backtrace path, which isn't compiled in on macOS -- so the
target linked fine locally but failed on the Ubuntu/mingw CI builds
(and the clang-tidy jobs, which build the tree first).

* i18n: regenerate po/ catalogs after rebasing onto current master

Mechanical rebase to resolve the po/ catalog conflicts against master's
#648/#650/#651 (per got3nks's note on #643) -- no source changes here,
scripts/update-po.sh output only, so the diff is just the tree back in
sync with the current strings.

* fix(search): avoid an unnamed EReadTextFile bitmask cast in history load

txtIgnoreEmptyLines|txtStripWhitespace has no single named enumerator
to cast to -- clang-tidy Tier-1 flagged it (clang-analyzer-optin.core.
EnumCastOutOfRange), correctly: EReadTextFile isn't a flag enum, so a
synthesized OR'd value is genuinely out of its declared range even
though CTextFile::ReadLines treats it as bitflags at runtime.

txtReadDefault would dodge the cast but also drops '#'-led lines,
silently eating a legitimate search term that happens to start with
one. Read unfiltered (txtReadAll, a real enumerator) and do the
trim/empty-line-drop by hand instead -- same behavior, no cast, no
lost terms.

* i18n: regenerate po/ catalogs after rebasing onto current master

Mechanical rebase to resolve the po/ conflicts against master's #642
(just merged) -- no source changes here.
LSalami added a commit to LSalami/amule that referenced this pull request Jul 28, 2026
Mechanical rebase to resolve po/ conflicts against master's amule-org#642/amule-org#643
-- no source changes here. Also resolved a real conflict in
muuli_wdr.h: amule-org#643's IDC_SEARCHHISTORYENABLED (10488) landed on master,
which this branch had already anticipated and reserved 10489 for.
LSalami added a commit to LSalami/amule that referenced this pull request Jul 28, 2026
Mechanical rebase to resolve conflicts against master's amule-org#642/amule-org#643 --
no source changes here. Resolved a real conflict in amuleDlg.cpp's
event table: amule-org#642 added the Alt+<letter> EVT_MENU block right where
this branch removed the EVT_TOOL(ID_BUTTONCONNECT, ...) line; kept
amule-org#642's block, dropped the connect-button line as intended.
LSalami added a commit to LSalami/amule that referenced this pull request Jul 28, 2026
Follow-up to amule-org#642 per got3nks's post-merge comment: the macOS Navigate
menu renders its own "\tAlt+N"-style accelerator using the platform's
native glyph automatically (Cocoa substitutes Alt for Option/⌥ on a real
NSMenuItem key equivalent), but the toolbar tooltips are plain text, so
wx never touches them -- they kept reading "(Alt+N)" even on macOS,
inconsistent with the menu right above them.

Added TabAccelSuffix(), a small platform-conditional helper building
" (⌥N)" on __WXMAC__ and " (Alt+N)" everywhere else, kept outside _()
so translated msgids are untouched -- confirmed via the po/ diff after
regenerating: zero added/removed/changed msgids, purely line-number
churn.

Verified: built and ran both amule and amuleGUI, full unit test suite
passing (27/27).
LSalami added a commit to LSalami/amule that referenced this pull request Jul 28, 2026
Mechanical rebase to resolve po/ conflicts against master's amule-org#642/amule-org#643
-- no source changes here. Also resolved a real conflict in
muuli_wdr.h: amule-org#643's IDC_SEARCHHISTORYENABLED (10488) landed on master,
which this branch had already anticipated and reserved 10489 for.
got3nks pushed a commit that referenced this pull request Jul 28, 2026
#664)

The macOS Navigate menu renders its accelerators with the native Option glyph automatically, but toolbar tooltips are plain text, so they still read "(Alt+N)". Build a platform-conditional suffix from the U+2325 codepoint rather than a raw literal, so it cannot be mangled by a narrow-to-wide conversion through a non-UTF-8 system encoding (macOS reports Mac OS Roman). Kept outside _() so no translated msgids change. Follow-up to #642.
LSalami added a commit to LSalami/amule that referenced this pull request Jul 28, 2026
Mechanical rebase to resolve po/ conflicts against master's amule-org#642/amule-org#643
-- no source changes here. Also resolved a real conflict in
muuli_wdr.h: amule-org#643's IDC_SEARCHHISTORYENABLED (10488) landed on master,
which this branch had already anticipated and reserved 10489 for.
LSalami added a commit to LSalami/amule that referenced this pull request Jul 28, 2026
Mechanical rebase to resolve conflicts against master's amule-org#642/amule-org#643 --
no source changes here. Resolved a real conflict in amuleDlg.cpp's
event table: amule-org#642 added the Alt+<letter> EVT_MENU block right where
this branch removed the EVT_TOOL(ID_BUTTONCONNECT, ...) line; kept
amule-org#642's block, dropped the connect-button line as intended.

Regenerated again via scripts/update-po.sh after later rebasing onto
master's amule-org#671 (Preferences sidebar) and amule-org#665/amule-org#662 (amuleapi
credentials, sparse part-file setting), which had added strings this
branch's catalogs didn't have yet.
LSalami added a commit to LSalami/amule that referenced this pull request Jul 28, 2026
Mechanical rebase to resolve conflicts against master's amule-org#642/amule-org#643 --
no source changes here. Resolved a real conflict in amuleDlg.cpp's
event table: amule-org#642 added the Alt+<letter> EVT_MENU block right where
this branch removed the EVT_TOOL(ID_BUTTONCONNECT, ...) line; kept
amule-org#642's block, dropped the connect-button line as intended.

Regenerated again via scripts/update-po.sh after later rebasing onto
master's amule-org#671 (Preferences sidebar) and amule-org#665/amule-org#662 (amuleapi
credentials, sparse part-file setting), which had added strings this
branch's catalogs didn't have yet.
got3nks pushed a commit that referenced this pull request Jul 28, 2026
* feat(gui): remove the global Connect/Disconnect toolbar button

Closes #402. Per-network controls already exist (Kad pane's Start/Stop,
Servers pane's ED2K connect/disconnect), the connection state is
already shown in the status bar, and after discussing relocating it
into the Networks view the agreed call (got3nks + ngosang) was simply
to remove it -- mirrors what #585 already did on the Web UI side.

Removed the toolbar tool, its three skin icons (Toolbar_Connect/
Disconnect/Connecting) and their bitmap wiring, the button-update block
in ShowConnectionState(), and the two EnableTool(ID_BUTTONCONNECT, ...)
call sites.

CamuleDlg::OnBnConnect() itself stays -- CMuleTrayIcon::DoConnectDisconnect()
still calls it for the tray icon's own connect/disconnect action, which
is unaffected by this change.

ShowConnectionState()'s skinChanged parameter was only ever read by the
now-removed block, so it's gone too, along with the one call site that
passed true and the forceUpdate plumbing that reached it through
GuiEvents.cpp's ShowConnState() free function.

Left ID_BUTTONCONNECT and muuli_wdr.cpp's muleToolbar() (which still
calls it) alone -- that function predates Apply_Toolbar_Skin, is never
called anywhere, and touching pre-existing dead code is out of scope
for this fix.

Verified: built and ran both amule and amulegui cleanly, full unit
test suite passing (26/26). Confirmed via the po/ diff that "Connect"/
"Disconnect"/"Cancel" remain in the catalog (still used by other
per-network buttons) -- only their now-orphaned toolbar-specific
tooltip strings were dropped. Could not get a real on-screen visual
confirmation of the toolbar layout -- same macOS Accessibility
automation limitations as #180 got in the way of screenshotting the
actual app window.

* i18n: regenerate po/ catalogs after rebasing onto current master

Mechanical rebase to resolve conflicts against master's #642/#643 --
no source changes here. Resolved a real conflict in amuleDlg.cpp's
event table: #642 added the Alt+<letter> EVT_MENU block right where
this branch removed the EVT_TOOL(ID_BUTTONCONNECT, ...) line; kept
#642's block, dropped the connect-button line as intended.

Regenerated again via scripts/update-po.sh after later rebasing onto
master's #671 (Preferences sidebar) and #665/#662 (amuleapi
credentials, sparse part-file setting), which had added strings this
branch's catalogs didn't have yet.

* feat(gui): turn the per-network Disconnect buttons into Connect/Cancel/Disconnect toggles

Relocates the removed global toolbar button's functionality into the
ED2K (IDC_ED2KDISCONNECT) and Kad (ID_KADDISCONNECT) panes instead of
just dropping it, per got3nks's proposal on #663: each button now
mirrors ed2kState/kadState (off/connecting/connected) using the
existing connButImg() bitmaps, and can independently connect or
cancel/disconnect its own network -- something the old OR-toggled
global button never allowed. The ED2K pane also gains a Connect
button it never had (previously Disconnect-only).

CServerWnd::UpdateED2KConnectButton() / CKadDlg::UpdateConnectButton()
are called from CamuleDlg::ShowConnectionState() alongside the
existing UpdateED2KInfo()/UpdateKadInfo() calls, and once from each
pane's own ctor/Init() for the initial paint. OnBnClickedED2KDisconnect
and OnBnClickedDisconnectKad gained the missing "connect when off"
branch; OnBnConnect and the tray icon are untouched.

Verified interactively on Windows: both buttons show the correct
label/icon for their live state, ED2K disconnect/reconnect works from
its own button, and disabling ED2K in Preferences while Kad stays
connected confirms the two toggle independently.

po/ regenerated via scripts/update-po.sh to match the new button
labels ("Disconnect Kad" is now unused and moves to the obsolete
section; no new translatable strings).

* fix(gui): drop the per-network connect-button state cache

got3nks flagged two bugs in review (PR #663): the static cache's
early return also skipped Enable(), so the button could get stuck
disabled once IsReady()/network-pref state changed without the
Connect/Cancel/Disconnect state itself changing (master had two now-
deleted escape hatches -- the skinChanged force-path and an
unconditional EnableTool call -- that used to paper over this). Worse,
the cache was function-scope static, surviving widget recreation, so
a fresh pane's Init() call could early-return and leave the wxDesigner
default label ("Disconnect Kad") on screen.

Dropping the cache removes both: SetLabel/SetBitmap/Enable are cheap
on a plain wxButton (unlike the old toolbar tool, which had real
native-image-list reasons to memoize, see amuleDlg.cpp:1054-ish), and
master's own second call site already did an unconditional EnableTool
every tick without issue.

Second review round (macOS + Ubuntu ARM64, monolithic + amuleGUI)
confirmed the toggle works functionally but flagged three cosmetic
issues, all fixed here:

- No gap between the connect-button icon and its label. The obvious
  fix, wxButton::SetBitmapMargins(), is NOT portable (wxOSX overrides
  it, wxGTK inherits the base no-op) -- prefixing the label with a
  literal space outside the _() call behaves identically on both and
  introduces no new msgid.
- The Kad button was stretched full-width by its sizer's .Expand()
  flag, while the ED2K one sizes naturally; GTK and macOS then filled
  the slack differently (centered vs. icon-left). Dropped .Expand()
  so the two buttons size the same way -- trades away lining up with
  the "Bootstrap from known clients" button above it, but the two
  connect buttons reading as the same control matters more.
- CServerWnd::UpdateED2KConnectButton() and CKadDlg::UpdateConnectButton()
  were near-identical (same 3-state enum, same switch, same three
  bitmaps). Factored into a shared SetConnectButtonState(button, state,
  enabled) helper in muuli_wdr.cpp/.h, next to connButImg() which it
  reuses -- so the icon-spacing fix above lives in one place instead
  of two.

Verified interactively on Windows: re-tested full disconnect/reconnect
cycle on both panes, toggling ED2K off and back on via Preferences
(existing behavior: needs an app restart to re-enable) with correct
state on the fresh post-restart paint, and confirmed by screenshot
that both buttons now show a visible icon/label gap and size the same
way (Kad no longer stretched). Also confirmed amulegui (CLIENT_GUI)
builds clean with these changes; did not perform full interactive
remote-daemon testing.

* fix(gui): first-paint layout bug + connect-button placement, per review

Two more issues from got3nks's Linux/GTK pass on #663.

1. Bug: the ED2K connect button painted with the icon overlapping the
   label on first show (Kad was fine, only by luck of timing).
   CServerWnd::UpdateED2KConnectButton() runs after sizer->Show(this,
   TRUE) in the ctor, so SetBitmap() grows the button's best size
   after the row was already measured against the text-only label,
   and nothing re-lays it out until a window resize. Fixed by calling
   Layout() on the button's parent at the end of the shared
   SetConnectButtonState() helper -- covers both panes, and stops Kad
   from relying on being laid out late (its notebook page is only
   measured once shown, after Init() already set its bitmap).

2. Layout: moved both connect/disconnect toggles to lead their pane
   instead of sitting among secondary controls, per got3nks's request:
   - ED2K (serverListDlgUp): toggle now on its own top row, right-
     aligned via a stretch spacer, directly above the server list.
     The "Add server manually" form (name/IP/port/Add) moved below
     the table instead of sharing a row with the toggle; the vertical
     separator that used to sit between them is gone (no longer
     needed once they're not adjacent).
   - Kad (KadDlg): toggle moved out of the "Bootstrap" static box
     (where it sat under "Bootstrap from known clients") to its own
     top row above the box, right-aligned the same way as ED2K's.
     item0 changed from a 1x1 FlexGridSizer (which only ever held the
     two-column area) to a plain vertical wxBoxSizer so it can hold
     the new top row plus the existing two-column layout.

Both panes now read "primary control on top, secondary/manual
controls below" -- matching shape on both tabs.

Verified interactively on Windows: screenshotted both panes, confirmed
no icon/label overlap on first paint (no window resize needed), and
re-ran the disconnect/reconnect toggle cycle on both after the layout
change.
@LSalami
LSalami deleted the add-alt-shortcuts-tab-switch branch August 5, 2026 14:12
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.

Accessibility bug report: Search results list is invisible with VoiceOver on macOS

2 participants