walk icon indicating copy to clipboard operation
walk copied to clipboard

Partial transparency loss when using PaintFuncImage as a tray icon

Open arisudesu opened this issue 3 months ago • 0 comments

While experimenting with tray icons, I noticed that icons drawn on a canvas have some or all transparency lost when displayed. This is not something that happens while drawing, as I'm able to dump intermediate image to a file and it looks correct when I overlay it to the taskbar in image editor. Rather, the problem manifests only when PFI is set to a notify icon.

Example code:

package main

import (
	"image/png"
	"log"
	"os"

	"github.com/tailscale/walk"
)

func main() {
	app, err := walk.InitApp()
	if err != nil {
		log.Fatal(err)
	}

	ni, err := walk.NewNotifyIcon()
	if err != nil {
		log.Fatal(err)
	}
	defer ni.Dispose()

	doPfi := false

	if !doPfi {
		if err := ni.SetIcon(walk.IconQuestionSmall()); err != nil {
			log.Fatal(err)
		}
		if err := ni.SetToolTip("Normal transparency"); err != nil {
			log.Fatal(err)
		}
	} else {
		pfi := walk.NewPaintFuncImagePixels(walk.Size{16, 16}, func(canvas *walk.Canvas, bounds walk.Rectangle) error {
			if err := canvas.DrawImagePixels(walk.IconQuestionSmall(), walk.Point{0, 0}); err != nil {
				return err
			}
			// Here I will draw an overlay in a real code
			return nil
		})

		bmp, err := walk.NewBitmapFromImageWithSize(pfi, walk.Size{16, 16})
		if err != nil {
			log.Fatal(err)
		}
		defer bmp.Dispose()

		rgba, err := bmp.ToImage()
		if err != nil {
			log.Fatal(err)
		}

		out, err := os.Create("dump.png")
		if err != nil {
			log.Fatal(err)
		}
		defer out.Close()

		if err := png.Encode(out, rgba); err != nil {
			log.Fatal(err)
		}

		if err := ni.SetIcon(pfi); err != nil {
			log.Fatal(err)
		}
		if err := ni.SetToolTip("Invalid transparency"); err != nil {
			log.Fatal(err)
		}
	}

	if err := ni.SetVisible(true); err != nil {
		log.Fatal(err)
	}

	app.Run()
}

And here's how it looks in the taskbar:

Image

arisudesu avatar Oct 15 '25 09:10 arisudesu