fix(gui): scale main-toolbar icons on hi-DPI displays - #294
Merged
Conversation
The toolbar icons (Downloads, Shared Files, etc.) were stored in a fixed 32x32 wxImageList and handed to wxToolBar as plain wxBitmaps. Since the executable declares PerMonitorV2 DPI awareness (amule-org#780), those bitmaps are drawn at 32 *physical* pixels, so on 4K / scaled displays the icons render tiny and blurry while the rest of the UI scales. Store each toolbar icon as a wxBitmapBundle instead (wx >= 3.2), built from the original 32px art plus a wxIMAGE_QUALITY_HIGH 2x upscale, converting the transparency mask to an alpha channel first so the scaler doesn't smear the mask colour into the icon edges. Drop the hard-coded SetToolBitmapSize(32,32) so the toolbar derives the logical size from the bundles and scales it per monitor DPI. SetMessagesTool gains a bounds guard because m_CurrentBlinkBitmap starts as a stale sentinel (24) that the old wxImageList::GetBitmap tolerated but vector indexing must not. Co-Authored-By: Claude Fable 5 <[email protected]>
Code-review follow-ups to the wxBitmapBundle toolbar change: - Add ToolbarSkinEnum (mirroring ClientSkinEnum) so the m_tblist indexes duplicated across Apply_Toolbar_Skin, ShowConnectionState, OnGUITimer and the constructor are named instead of magic numbers whose meaning depends on the Add_Skin_Icon call order. - Initialize m_CurrentBlinkBitmap to Toolbar_Messages instead of the stale sentinel 24 (a fossil amuleDlgImages() resource id, never a valid m_tblist index) and drop the SetMessagesTool bounds guard that existed only to defend against it; both callers assign a valid index right before calling, so behavior is identical. - Remove the #ifdef __WXCOCOA__ branches in ShowConnectionState and SetMessagesTool: the old wxCocoa port was removed from wxWidgets before the 3.2 minimum this project requires (modern macOS defines __WXOSX_COCOA__), so those lines could never compile again. - Use the two-bitmap wxBitmapBundle::FromBitmaps overload instead of building a wxVector by hand. Co-Authored-By: Claude Fable 5 <[email protected]>
Fixes the clang-tidy Tier-2 modernize-use-emplace warning on the wxBitmapBundle fallback path in Add_Skin_Icon. Co-Authored-By: Claude Fable 5 <[email protected]>
|
Thanks for the contribution, @Zeyckler — clean, well-scoped patch. Verified locally on all three platforms:
The Messages blink path wasn't exercised in these runs; the vector-index fix ( Applies to both the monolithic Merging once CI is green. |
got3nks
pushed a commit
that referenced
this pull request
Jul 5, 2026
The preferences dialog's page list (General, Connection, Directories, etc.) fed 16x16 bitmaps into a fixed-size wxImageList, so on DPI-aware builds the icons render at 16 physical pixels — tiny and blurry on hi-DPI screens, same problem as the main toolbar (#294). Hand the icons to the list control as wxBitmapBundles instead (wxListCtrl::SetSmallImages, wx >= 3.2), each built from the 16px art plus a wxIMAGE_QUALITY_HIGH 2x upscale with the mask converted to an alpha channel first. The macOS-only right/bottom padding is applied per resolution so the padded canvas keeps its proportions at 2x. Co-authored-by: Carlos Barrero <[email protected]> Co-authored-by: Claude Fable 5 <[email protected]>
Cflsft
pushed a commit
to Cflsft/amule
that referenced
this pull request
Jul 6, 2026
* fix(gui): scale main-toolbar icons on hi-DPI displays The toolbar icons (Downloads, Shared Files, etc.) were stored in a fixed 32x32 wxImageList and handed to wxToolBar as plain wxBitmaps. Since the executable declares PerMonitorV2 DPI awareness (amule-org#780), those bitmaps are drawn at 32 *physical* pixels, so on 4K / scaled displays the icons render tiny and blurry while the rest of the UI scales. Store each toolbar icon as a wxBitmapBundle instead (wx >= 3.2), built from the original 32px art plus a wxIMAGE_QUALITY_HIGH 2x upscale, converting the transparency mask to an alpha channel first so the scaler doesn't smear the mask colour into the icon edges. Drop the hard-coded SetToolBitmapSize(32,32) so the toolbar derives the logical size from the bundles and scales it per monitor DPI. SetMessagesTool gains a bounds guard because m_CurrentBlinkBitmap starts as a stale sentinel (24) that the old wxImageList::GetBitmap tolerated but vector indexing must not. Co-Authored-By: Claude Fable 5 <[email protected]> * refactor(gui): name toolbar icon indexes and drop dead code after review Code-review follow-ups to the wxBitmapBundle toolbar change: - Add ToolbarSkinEnum (mirroring ClientSkinEnum) so the m_tblist indexes duplicated across Apply_Toolbar_Skin, ShowConnectionState, OnGUITimer and the constructor are named instead of magic numbers whose meaning depends on the Add_Skin_Icon call order. - Initialize m_CurrentBlinkBitmap to Toolbar_Messages instead of the stale sentinel 24 (a fossil amuleDlgImages() resource id, never a valid m_tblist index) and drop the SetMessagesTool bounds guard that existed only to defend against it; both callers assign a valid index right before calling, so behavior is identical. - Remove the #ifdef __WXCOCOA__ branches in ShowConnectionState and SetMessagesTool: the old wxCocoa port was removed from wxWidgets before the 3.2 minimum this project requires (modern macOS defines __WXOSX_COCOA__), so those lines could never compile again. - Use the two-bitmap wxBitmapBundle::FromBitmaps overload instead of building a wxVector by hand. Co-Authored-By: Claude Fable 5 <[email protected]> * style(gui): use emplace_back for the fallback toolbar bundle Fixes the clang-tidy Tier-2 modernize-use-emplace warning on the wxBitmapBundle fallback path in Add_Skin_Icon. Co-Authored-By: Claude Fable 5 <[email protected]> --------- Co-authored-by: Carlos Barrero <[email protected]> Co-authored-by: Claude Fable 5 <[email protected]>
Cflsft
pushed a commit
to Cflsft/amule
that referenced
this pull request
Jul 6, 2026
) The preferences dialog's page list (General, Connection, Directories, etc.) fed 16x16 bitmaps into a fixed-size wxImageList, so on DPI-aware builds the icons render at 16 physical pixels — tiny and blurry on hi-DPI screens, same problem as the main toolbar (amule-org#294). Hand the icons to the list control as wxBitmapBundles instead (wxListCtrl::SetSmallImages, wx >= 3.2), each built from the 16px art plus a wxIMAGE_QUALITY_HIGH 2x upscale with the mask converted to an alpha channel first. The macOS-only right/bottom padding is applied per resolution so the padded canvas keeps its proportions at 2x. Co-authored-by: Carlos Barrero <[email protected]> Co-authored-by: Claude Fable 5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The main-toolbar icons (Downloads, Shared Files, Networks, etc.) render tiny and blurry on hi-DPI screens (e.g. 4K at 150–200% scaling). They are stored in a fixed 32x32
wxImageListand handed towxToolBaras plainwxBitmaps, and since the executable declares PerMonitorV2 DPI awareness (#780) they get drawn at 32 physical pixels while the rest of the UI scales.This PR stores each toolbar icon as a
wxBitmapBundle(available since wx 3.2, the project minimum):m_tblistbecomes astd::vector<wxBitmapBundle>;AddTool/SetToolNormalBitmapreceive bundles, so the toolbar picks a correctly sized bitmap per monitor DPI.wxIMAGE_QUALITY_HIGH2x upscale. The transparency mask is converted to an alpha channel before scaling, otherwise the smooth scaler smears the mask colour into the icon edges (halos). Works for both built-in art and skin PNGs.SetToolBitmapSize(32, 32)is dropped so the toolbar derives the logical size from the bundles and scales it with the monitor's DPI.SetMessagesToolgains a bounds guard:m_CurrentBlinkBitmapstarts as a stale sentinel (24) that the oldwxImageList::GetBitmaptolerated (returnedwxNullBitmap) but vector indexing must not reach.Since the source art only exists at 32px, the result is a correctly sized, smoothly scaled icon rather than a pixel-perfect one — redrawing the icons as SVG (
wxBitmapBundle::FromSVG) can layer on top of this later, as can the same treatment for the client-status / tab / flag image lists.Test plan
clang-format18 passes on both touched files (matches the CI gate).AddTool,SetToolNormalBitmapandwxToolBarToolBase::SetNormalBitmapall takewxBitmapBundlesince 3.2).🤖 Generated with Claude Code