With Big Sur, one can no longer rely on dark vs light theme to determine if an TrayIcon should be using light or dark colors.
The system wide menubar is by default transparent and the color and type of wallpaper influences if the background turns out to be light or dark.
After a long search I found that the image of a trayicon (NSStatusItem?) can have an option to do this automatically by using the setTemplate function of the image to true. When doing this, macOS will automatically adjust a transparent icon with only black pixels.
This can be activated relatively easy by adding a single line to the file
lazarus/lcl/interfaces/cocoa/cocoatrayicon.inc
and simply setting the image to a "template".
In cocoatrayicon.inc add the following line to the lclSetTrayIcon procedure:
image.setTemplate(true);
I've added it below to the if (ATrayIcon.icon <> nil) section (line 11):
procedure TCocoaStatusItemHandle.lclSetTrayIcon(ATrayIcon: TCustomTrayIcon);
var
image: NSImage;
begin
TrayIcon := ATrayIcon;
// Shows the icon
if (ATrayIcon.icon <> nil) and (ATrayIcon.icon.Handle <> 0) then
begin
image := TCocoaBitmap(ATrayIcon.icon.Handle).image;
image.setTemplate(true); // < --- added this line
if image <> nil then statusitem.setImage(image);
end;
// Show the menu
if (ATrayIcon.PopUpMenu <> nil) then
begin
ATrayIcon.PopUpMenu.HandleNeeded();
//ATrayIcon.PopUpMenu.
if Assigned(statusitem.menu) and (statusitem.menu.delegate = NSMenuDelegateProtocol(self)) then
statusitem.menu.setDelegate(nil);
statusitem.setMenu(TCocoaMenu(ATrayIcon.PopUpMenu.Handle));
TCocoaMenu(ATrayIcon.PopUpMenu.Handle).setDelegate( self);
end;
end;
I've done some testing with this and this work great.
Downside: when using trayicons (menubar) with multiple colors, this may result in not so pretty icons.