Repository: fyne-io/fyne
File: internal/driver/glfw/menu_darwin.go (Go)

Code before:
			items := make([]*fyne.MenuItem, 0, len(menu.Items)-1)
			items = append(items, menu.Items[:i]...)
			items = append(items, menu.Items[i+1:]...)
			menu.Items = items

			insertNativeMenuItem(C.darwinAppMenu(), item, nextItemID, 1)
			if addSeparator {
				C.insertDarwinMenuItem(
					C.darwinAppMenu(),
					C.CString(""),
					C.CString(""),
					C.uint(0),
					C.int(nextItemID),
					C.int(1),
					C.bool(true),
					unsafe.Pointer(nil),
					C.uint(0),
				)
			}
			nextItemID = registerCallback(w, item, nextItemID)
		case "About":
			items := make([]*fyne.MenuItem, 0, len(menu.Items)-1)
			items = append(items, menu.Items[:i]...)
			if i < len(menu.Items)-1 {
				items = append(items, menu.Items[i+1:]...)
			}
			menu.Items = items

			insertNativeMenuItem(C.darwinAppMenu(), item, nextItemID, 1)
			if addSeparator {
				C.insertDarwinMenuItem(
					C.darwinAppMenu(),
					C.CString(""),
					C.CString(""),
					C.uint(0),
					C.int(nextItemID),
					C.int(1),
					C.bool(true),
					unsafe.Pointer(nil),
					C.uint(0),
				)
			}
			nextItemID = registerCallback(w, item, nextItemID)
		}
	}
	return menu, nextItemID
}

// TODO: theme change support, see NSSystemColorsDidChangeNotification
func insertNativeMenuItem(nsMenu unsafe.Pointer, item *fyne.MenuItem, nextItemID, index int) unsafe.Pointer {
	var imgData unsafe.Pointer

Review comment (bug):
I guess, this is a countermeasure against `i > len(menu.Items)` because the latter shrinks with the new implementation.
This reveals several flaws of the new implementation:
1. You did not apply the same protection to the old branch but only to the copied new branch.
2. You did not apply the protection to `menu.Items[i:]` which might also crash now.
3. Your `i` and `item` are no longer in sync with `menu.Items` after a change to `menu.Items` leading to unwanted effects.

Instead we should use
```go
for i := 0; i < len(menu.Items); i++ {
  item := menu.Items[i]
  …
    i-- // if special item
  …
}
```

Code after:
		switch item.Label {
		case "About", "Settings", "Settings…", "Preferences", "Preferences…":
			items := make([]*fyne.MenuItem, 0, len(menu.Items)-1)
			items = append(items, menu.Items[:i]...)
			items = append(items, menu.Items[i+1:]...)
			menu, nextItemID = handleSpecialItems(w, fyne.NewMenu(menu.Label, items...), nextItemID, false)
			i--

			insertNativeMenuItem(C.darwinAppMenu(), item, nextItemID, 1)
			if addSeparator && item.Label != "About" {
				C.insertDarwinMenuItem(
					C.darwinAppMenu(),
					C.CString(""),
					C.CString(""),
					C.uint(0),
					C.int(nextItemID),
					C.int(1),
					C.bool(true),
					unsafe.Pointer(nil),
					C.uint(0),
				)
			}
			nextItemID = registerCallback(w, item, nextItemID)
		}
	}
	return menu, nextItemID
}

// TODO: theme change support, see NSSystemColorsDidChangeNotification
func insertNativeMenuItem(nsMenu unsafe.Pointer, item *fyne.MenuItem, nextItemID, index int) unsafe.Pointer {
	var imgData unsafe.Pointer
	var imgDataLength uint
	if item.Icon != nil {
		if svg.IsResourceSVG(item.Icon) {
			rsc := item.Icon
			if _, isThemed := rsc.(*theme.ThemedResource); isThemed {
				var r, g, b, a C.int
				C.getTextColorRGBA(&r, &g, &b, &a)
				rsc = &fyne.StaticResource{
					StaticName:    rsc.Name(),
					StaticContent: svg.Colorize(rsc.Content(), color.NRGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: uint8(a)}),
				}
			}
			size := int(C.menuFontSize())
			img := painter.PaintImage(&canvas.Image{Resource: rsc}, nil, size, size)
			var buf bytes.Buffer
			if err := png.Encode(&buf, img); err != nil {
				fyne.LogError("failed to render menu icon", err)
			} else {
				imgData = unsafe.Pointer(&buf.Bytes()[0])
				imgDataLength = uint(buf.Len())