Skip to content

fix(windows): pre-multiply alpha when setting menu item icons to fix black background#290

Open
HarshalPatel1972 wants to merge 1 commit intogetlantern:masterfrom
HarshalPatel1972:fix/menu-icon-black-background
Open

fix(windows): pre-multiply alpha when setting menu item icons to fix black background#290
HarshalPatel1972 wants to merge 1 commit intogetlantern:masterfrom
HarshalPatel1972:fix/menu-icon-black-background

Conversation

@HarshalPatel1972
Copy link

Fixes #267

Problem

Menu item icons render with a black background on Windows 11 when the
icon has transparent pixels. The tray icon itself renders correctly,
and disabled menu items also render correctly — only enabled menu items
are affected.

The root cause is that Windows GDI expects pre-multiplied alpha for
HBITMAP objects used in menus. The previous code used
CreateCompatibleBitmap which doesn't handle alpha, causing transparent
pixels to render as black.

Fix

Replaced CreateCompatibleBitmap with CreateDIBSection and added
alpha pre-multiplication for each pixel before the bitmap is passed
to SetMenuItemInfo:

  • R = R * A / 255
  • G = G * A / 255
  • B = B * A / 255

This matches the format Windows expects for alpha-blended menu bitmaps.

Tested on

Windows 11 23H2

Copilot AI review requested due to automatic review settings March 22, 2026 16:45
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes Windows 11 menu item icons rendering with a black background by generating a 32-bit DIB-backed bitmap (alpha-capable) and pre-multiplying pixel RGB values by alpha before assigning the bitmap to menu items.

Changes:

  • Replaced CreateCompatibleBitmap with CreateDIBSection for menu item icon bitmaps (preserves alpha).
  • Added per-pixel alpha pre-multiplication on the DIB’s backing buffer prior to returning the HBITMAP.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +794 to +796
if bits != nil {
pixels := (*[1 << 30]byte)(bits)[:cx*cy*4 : cx*cy*4]
// Pre-multiply alpha channel before creating HBITMAP
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

cx/cy are uintptr (returned from Proc.Call), but they’re used directly in the slice expression [:cx*cy*4]. Slice bounds must be int, so this won’t compile. Convert cx/cy to int (after sanity/overflow checks) and use those int values when computing the pixel buffer length and when passing sizes around in Go expressions.

Copilot uses AI. Check for mistakes.
Comment on lines 784 to 792
@@ -761,6 +790,18 @@ func (t *winTray) iconToBitmap(hIcon windows.Handle) (windows.Handle, error) {
if res == 0 {
return 0, err
}
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

If DrawIconEx fails, the function returns without cleaning up hMemBmp, which leaks a GDI bitmap handle on the error path. Consider adding a DeleteObject proc and deferring cleanup after CreateDIBSection succeeds, then canceling the defer when returning the bitmap successfully.

Copilot uses AI. Check for mistakes.

if bits != nil {
pixels := (*[1 << 30]byte)(bits)[:cx*cy*4 : cx*cy*4]
// Pre-multiply alpha channel before creating HBITMAP
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

The comment says “Pre-multiply alpha channel before creating HBITMAP”, but the HBITMAP (hMemBmp) has already been created at this point. Rewording to indicate this is done before returning/using the bitmap would avoid confusion for future maintenance.

Suggested change
// Pre-multiply alpha channel before creating HBITMAP
// Pre-multiply alpha channel in-place before returning/using the HBITMAP

Copilot uses AI. Check for mistakes.
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.

Icons in menu items have a black background

2 participants