Skip to content

prefs: raise bandwidth caps and stop clipping spin buttons - #463

Merged
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:prefs-bandwidth-limits-ui
Apr 23, 2026
Merged

prefs: raise bandwidth caps and stop clipping spin buttons#463
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:prefs-bandwidth-limits-ui

Conversation

@got3nks

@got3nks got3nks commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Three small UI fixes on the Preferences → Connection and Statistics pages, all in src/muuli_wdr.cpp:

  1. Bandwidth spin caps raised from 19,375 kB/s → 1,000,000 kB/s. Anything above ~155 Mbit/s was silently clamped; gigabit and multi-gig users couldn't enter the value they wanted.
  2. Slot Allocation cap raised from 100 → 100,000 kB/s. Artificially low — the underlying pref has always been uint32.
  3. Spin control widths fixed so the + button no longer gets clipped by the hardcoded 100 px width on GTK 3 and other modern themes.

All three are cosmetic / range changes in the wxFormBuilder-generated code. No underlying behaviour / pref type / throttler change — PR #436 already widened the relevant prefs to uint32, this just lets the UI expose that.

16 lines changed in one file.


Why the caps needed bumping

Bandwidth (IDC_MAXDOWN / IDC_MAXUP / IDC_DOWNLOAD_CAP / IDC_UPLOAD_CAP)

19375 was a pre-gigabit-Ethernet era floor (19375 kB/s ≈ 155 Mbit/s). On anything faster than about 1.2 Gbit/s, users typing a real number (e.g. 65000 kB/s = 520 Mbit/s, or 125000 for gigabit) saw their value silently clamp. #436 has already widened MaxUpload / MaxDownload prefs from uint16 to uint32, so the pref layer supports anything up to 4 GB/s; the GUI just hadn't caught up.

1,000,000 kB/s is a deliberate ceiling:

  • ≈ 1 GB/s ≈ 8 Gbit/s — covers any realistic residential / small-business link for the foreseeable future.
  • Safely within the upload throttler's bytesToSpend sint32 accumulator headroom.
  • Matches the internal UNLIMITED_RATE sentinel's effective cap of 1 GiB/s that the throttler already uses for the "unlimited" path.

Slot Allocation (IDC_SLOTALLOC)

Capped at 100 kB/s per slot — originally reasonable when the whole upload cap was 19,375, but no longer: with MaxUpload = 1,000,000, a SlotAllocation = 100 divides into 10,000 slots before being clipped to MAX_UP_CLIENTS_ALLOWED = 250. The per-slot knob had effectively stopped working above that point.

The pref has always been uint32 (src/Preferences.h:228: GetSlotAllocation()), so the UI cap was the only thing in the way.

New ceiling: 100,000 kB/s = 1/10 of the MaxUpload ceiling. Beyond this point the slot-count formula MaxUpload / SlotAllocation rounds to 0 and MIN_UP_CLIENTS_ALLOWED = 2 takes over, so the knob stops being useful — 100,000 is the natural stop for this axis.

User still cannot misconfigure into a crash

What happens if SlotAllocation > MaxUpload? Looking at UploadQueue.cpp:310-320:

if (thePrefs::GetMaxUpload() >= 10) {
    nMaxSlots = floor(MaxUpload / SlotAllocation + 0.5);
    if (nMaxSlots < MIN_UP_CLIENTS_ALLOWED) {
        nMaxSlots = MIN_UP_CLIENTS_ALLOWED;   // = 2
    }
}

Always ≥ 2 slots. Misconfigured but not broken.

Why the spin button widths needed fixing

The entire src/muuli_wdr.cpp uses fixed wxSize(100, -1) for most numeric spin controls. That's too narrow for wxSpinCtrl to render both spin buttons when the value field holds 5+ digits on modern GTK / Adwaita themes — the + button clips visually. Reproducible on the stock Ubuntu Connection page with MaxUpload = 19375: the is visible but the + is hidden behind the kB/s label.

Two modes used in this patch:

Field group Size Reasoning
IDC_MAXDOWN, IDC_MAXUP, IDC_SLOTALLOC (the three-on-one-row Connection-page fields) wxSize(140, -1) Explicit uniform width so the row is visually aligned regardless of typed digit count. Fits a 7-digit value + both spin buttons comfortably on GTK 3.
Other previously-100px controls (ports, max sources, max connections, disk-space minimum, web-config ports, graph scales, IDC_MAXCON5SEC, …) wxDefaultSize Let wx compute a width from theme font metrics + max-value digit count. Handles both narrow (port 65535) and wide values without a hardcoded guess. 13 controls.
Intentionally narrow fields (wxSize(40,-1), wxSize(45,-1), wxSize(60,-1) — retry counts, search min/max, tooltip delay, OS-info update period) unchanged Single- / few-digit values where 40–60 px is correct; no clipping was observed.

Diff

 src/muuli_wdr.cpp | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

Every changed line is either a 19375 → 1000000 cap, 100 → 100000 cap (for IDC_SLOTALLOC), or a wxSize(100,-1) → wxSize(140,-1) / wxDefaultSize width change.

No changes to Preferences.{h,cpp}, PrefsUnifiedDlg.{h,cpp}, UploadQueue.cpp or any throttler code.


Risk

  • Forwards compatibility: raising a spin-control cap is backwards-compatible — prefs files that stored the old defaults still load fine, and previously-unreachable values are now reachable.
  • Layout shift: the wxDefaultSize switch widens some controls by a few pixels on GTK 3. The only rows where that could matter visually are the Connection-page multi-column rows, which have been manually normalised to wxSize(140,-1) to keep alignment.
  • No runtime code path touched. All four of MaxUpload, MaxDownload, SlotAllocation, and the IDC_*_CAP graph-scale values were already uint32 on the pref side.

Three small UI fixes on the Preferences dialog.

1. **Bandwidth spin caps raised from 19375 kB/s to 1,000,000 kB/s.**

   The bandwidth spin controls in src/muuli_wdr.cpp were capped at
   19375 kB/s (~155 Mbit/s), a floor from the pre-gigabit-Ethernet era.
   Users on gigabit or multi-gig links saw the value silently clamp
   when they typed anything higher. amule-project#436 has already widened MaxUpload /
   MaxDownload prefs to uint32, and the upload throttler's bytesToSpend
   arithmetic (sint32 accumulator ticking at ~1 kHz) still has ~2
   seconds of headroom before overflow at 1 GB/s, so 1,000,000 is a
   safe modern ceiling.

   Fields touched:
     IDC_MAXDOWN, IDC_MAXUP           — Connection page
     IDC_DOWNLOAD_CAP, IDC_UPLOAD_CAP — Statistics graph scale

2. **Slot Allocation spin cap raised from 100 to 100,000 kB/s.**

   Previously artificially pinned to 100 even though the underlying
   pref has always been uint32 (Preferences.h s_slotallocation /
   GetSlotAllocation). With MaxUpload now at 1,000,000, the per-slot
   reservation needs matching headroom. 100,000 = 1/10 of the new
   upload ceiling keeps the upload ratio sensible: below that the
   slot-count formula (MaxUpload / SlotAllocation) can still grow,
   above it MIN_UP_CLIENTS_ALLOWED=2 takes over and the knob stops
   being useful anyway.

   Field touched: IDC_SLOTALLOC (Connection page).

3. **Spin control widths: hardcoded wxSize(100,-1) fixed up so +/-
   buttons render without clipping on GTK 3 and other modern themes.**

   The hardcoded 100 px was too narrow for wxSpinCtrl to render both
   spin buttons when the value field holds 5+ digits; the + button
   ends up clipped on the Connection, Security and other prefs pages.

   - The three bandwidth fields on the Connection page (Download,
     Upload, Slot Allocation) use wxSize(140,-1) so they are visually
     aligned at the same width regardless of typed digit count.
   - The remaining 13 wider spin controls (ports, max sources, max
     connections, disk-space minimum, web-config ports, graph scales,
     MaxConnections5sec) switch to wxDefaultSize and let wx compute a
     width that fits the text + both buttons from theme metrics.
   - The few narrower fields (wxSize(40,-1), wxSize(45,-1),
     wxSize(60,-1) for single- or few-digit values like retry counts)
     are intentionally left alone.
@mrjimenez
mrjimenez merged commit afd5102 into amule-project:master Apr 23, 2026
5 checks passed
@got3nks
got3nks deleted the prefs-bandwidth-limits-ui branch May 3, 2026 15:19
got3nks added a commit to got3nks/amule that referenced this pull request May 27, 2026
…ject#737)

Six SpinCtrls in the Preferences dialog were pinned to widths
that fall below GtkSpinButton's intrinsic minimum on wxGTK 3.2 /
GTK3:

  IDC_TOOLTIPDELAY    wxSize(40, -1)    General tab
  IDC_SERVERRETRIES   wxSize(40, -1)    Server tab
  IDC_OSUPDATE        wxSize(60, -1)    Online Signature tab
  IDC_MAXDOWN         wxSize(140, -1)   Connection tab (Bandwidth limits)
  IDC_MAXUP           wxSize(140, -1)   Connection tab (Bandwidth limits)
  IDC_SLOTALLOC       wxSize(140, -1)   Connection tab (Bandwidth limits)

GTK3's GtkSpinButton is a composite widget (entry + stacked up/down
arrows). The internal box gadget needs ~80 px just to fit the entry
+ arrow column at the default theme; combined with the surrounding
wxFlexGridSizer / wxBoxSizer's tight allocation, forcing a smaller
or even an explicit "we know what we want" wx-side hint shoves the
entry's allocation below zero, which triggers

    Gtk-CRITICAL: gtk_box_gadget_distribute:
        assertion 'size >= 0' failed in GtkSpinButton

every time the panel is laid out (open Preferences, switch tabs,
expose). The 140 px hint on the bandwidth caps was originally widened
from 100 px in amule-project#463 to fit million-kB/s values; the new width itself
isn't too narrow, but combining an explicit wxSize with the column's
sizer constraints still leaves GTK's internal layout pass unhappy.
Same family as amule-project#569 / 82626f2 on the search dialog, just on the
Preferences side.

Fix: drop the explicit width to wxDefaultSize on all six and let
the layout engine pick. macOS / Windows already render side-by-side
spin buttons that fit comfortably in the default; GTK gets the
larger geometry it needs for stacked arrows. The label / unit text
on either side of each spin keeps its own sizer flags, so the row
overall still flows the same.

Reported in amule-project#737 (Diego Heras), verified on amule-dev-vm with the
fixed AppImage — no more Gtk-CRITICAL SpinButton warnings on
Preferences open or tab switch.

The Gtk-CRITICAL GtkScrollbar variant @ngosang also reported is a
separate widget family (likely a wxScrolledWindow / wxListBox
sub-widget), tracking that independently of this PR.
mrjimenez pushed a commit that referenced this pull request May 27, 2026
Six SpinCtrls in the Preferences dialog were pinned to widths
that fall below GtkSpinButton's intrinsic minimum on wxGTK 3.2 /
GTK3:

  IDC_TOOLTIPDELAY    wxSize(40, -1)    General tab
  IDC_SERVERRETRIES   wxSize(40, -1)    Server tab
  IDC_OSUPDATE        wxSize(60, -1)    Online Signature tab
  IDC_MAXDOWN         wxSize(140, -1)   Connection tab (Bandwidth limits)
  IDC_MAXUP           wxSize(140, -1)   Connection tab (Bandwidth limits)
  IDC_SLOTALLOC       wxSize(140, -1)   Connection tab (Bandwidth limits)

GTK3's GtkSpinButton is a composite widget (entry + stacked up/down
arrows). The internal box gadget needs ~80 px just to fit the entry
+ arrow column at the default theme; combined with the surrounding
wxFlexGridSizer / wxBoxSizer's tight allocation, forcing a smaller
or even an explicit "we know what we want" wx-side hint shoves the
entry's allocation below zero, which triggers

    Gtk-CRITICAL: gtk_box_gadget_distribute:
        assertion 'size >= 0' failed in GtkSpinButton

every time the panel is laid out (open Preferences, switch tabs,
expose). The 140 px hint on the bandwidth caps was originally widened
from 100 px in #463 to fit million-kB/s values; the new width itself
isn't too narrow, but combining an explicit wxSize with the column's
sizer constraints still leaves GTK's internal layout pass unhappy.
Same family as #569 / 82626f2 on the search dialog, just on the
Preferences side.

Fix: drop the explicit width to wxDefaultSize on all six and let
the layout engine pick. macOS / Windows already render side-by-side
spin buttons that fit comfortably in the default; GTK gets the
larger geometry it needs for stacked arrows. The label / unit text
on either side of each spin keeps its own sizer flags, so the row
overall still flows the same.

Reported in #737 (Diego Heras), verified on amule-dev-vm with the
fixed AppImage — no more Gtk-CRITICAL SpinButton warnings on
Preferences open or tab switch.

The Gtk-CRITICAL GtkScrollbar variant @ngosang also reported is a
separate widget family (likely a wxScrolledWindow / wxListBox
sub-widget), tracking that independently of this PR.
ngosang added a commit to ngosang/amule that referenced this pull request Jul 13, 2026
…roject#463)

Clicking a shared file in the table opens a detail panel in the lower half of
the page, separated from the table by a draggable splitter, re-fetching live
from GET /shared/{hash} while open. On phones it opens as a full-screen
drill-down sheet, mirroring the Downloads detail panel.

Shared scaffolding:
- Extract the splitter + bottom-panel structure into a reusable SplitDetail
  component consumed by both Downloads and Shared Files.
- Move the detail-panel helpers (magnetLink, copyText, Section, and the stat-row
  builder statRow) into the common components.js module; download-detail.js now
  only exports DownloadDetail. The 'session / total' counter formatter twin()
  moves to format.js so the shared table and detail panel share one copy.
- Rename the split/detail CSS classes that both pages share so they no longer
  carry the download-only dl- prefix (dl-view -> split-view, dl-detail* ->
  detail-*, etc.); the download-only pieces-* graph classes are untouched.

Shared detail panel, organised in three sections with mobile-readable labels
(the per-field tooltips are not reachable on touch):
- Sharing: Size, Uploaded / Requests / Accepted (each '(session / total)'),
  Share ratio, Complete sources. The latter is formatted like the desktop
  column (SharedFilesCtrl.cpp): '< N', 'N', or 'N - N' for the estimate range.
- Activity: Priority, Clients on queue, File type.
- Identity: Hash, Path, Parts.
- Copy ED2K / Copy magnet buttons; Media and Comment sections shown when present.
Shared files have no progress.parts, so there is no pieces graph.

Adds the en/es i18n strings, reusing downloads_detail_* keys where the text
matches.
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.

2 participants