internal/uidriver/glfw: Bug fix: Enable to specify ebiten.Image to SetWindowIcon

Closes #1468
This commit is contained in:
Hajime Hoshi 2021-02-07 21:16:09 +09:00
parent acb8bcae38
commit d999b4dc8e
3 changed files with 50 additions and 25 deletions

View File

@ -66,18 +66,23 @@ var (
func createRandomIconImage() image.Image {
const size = 32
r := byte(rand.Intn(0x100))
g := byte(rand.Intn(0x100))
b := byte(rand.Intn(0x100))
img := image.NewNRGBA(image.Rect(0, 0, size, size))
rf := float64(rand.Intn(0x100))
gf := float64(rand.Intn(0x100))
bf := float64(rand.Intn(0x100))
img := ebiten.NewImage(size, size)
pix := make([]byte, 4*size*size)
for j := 0; j < size; j++ {
for i := 0; i < size; i++ {
img.Pix[j*img.Stride+4*i] = r
img.Pix[j*img.Stride+4*i+1] = g
img.Pix[j*img.Stride+4*i+2] = b
img.Pix[j*img.Stride+4*i+3] = byte(float64(i+j) / float64(2*size) * 0xff)
af := float64(i+j) / float64(2*size)
if af > 0 {
pix[4*(j*size+i)] = byte(rf * af)
pix[4*(j*size+i)+1] = byte(gf * af)
pix[4*(j*size+i)+2] = byte(bf * af)
pix[4*(j*size+i)+3] = byte(af * 0xff)
}
}
}
img.ReplacePixels(pix)
return img
}

View File

@ -68,8 +68,8 @@ type UserInterface struct {
initWindowFloating bool
initWindowMaximized bool
initScreenTransparent bool
initIconImages []image.Image
initFocused bool
iconImages []image.Image
vsyncInited bool
@ -308,16 +308,16 @@ func (u *UserInterface) setInitScreenTransparent(transparent bool) {
u.m.RUnlock()
}
func (u *UserInterface) getInitIconImages() []image.Image {
func (u *UserInterface) getIconImages() []image.Image {
u.m.RLock()
i := u.initIconImages
i := u.iconImages
u.m.RUnlock()
return i
}
func (u *UserInterface) setInitIconImages(iconImages []image.Image) {
func (u *UserInterface) setIconImages(iconImages []image.Image) {
u.m.Lock()
u.initIconImages = iconImages
u.iconImages = iconImages
u.m.Unlock()
}
@ -685,10 +685,6 @@ func (u *UserInterface) init() error {
return err
}
if i := u.getInitIconImages(); i != nil {
u.window.SetIcon(i)
}
setPosition := func() {
u.iwindow.setPosition(u.getInitWindowPosition())
}
@ -807,6 +803,7 @@ func (u *UserInterface) loop() error {
return nil
})
}()
for {
var unfocused bool
@ -840,6 +837,35 @@ func (u *UserInterface) loop() error {
return err
}
if imgs := u.getIconImages(); imgs != nil {
u.setIconImages(nil)
// Convert the icons in the different goroutine, as (*ebiten.Image).At cannot be invoked
// from this goroutine. At works only in between BeginFrame and EndFrame.
go func() {
newImgs := make([]image.Image, len(imgs))
for i, img := range imgs {
// TODO: If img is not *ebiten.Image, this converting is not necessary.
// However, this package cannot refer *ebiten.Image due to the package
// dependencies.
b := img.Bounds()
rgba := image.NewRGBA(b)
for j := b.Min.Y; j < b.Max.Y; j++ {
for i := b.Min.X; i < b.Max.X; i++ {
rgba.Set(i, j, img.At(i, j))
}
}
newImgs[i] = rgba
}
_ = u.t.Call(func() error {
u.window.SetIcon(newImgs)
return nil
})
}()
}
// swapBuffers also checks IsGL, so this condition is redundant.
// However, (*thread).Call is not good for performance due to channels.
// Let's avoid this whenever possible (#1367).

View File

@ -249,14 +249,8 @@ func (w *window) SetSize(width, height int) {
}
func (w *window) SetIcon(iconImages []image.Image) {
if !w.ui.isRunning() {
w.ui.setInitIconImages(iconImages)
return
}
_ = w.ui.t.Call(func() error {
w.ui.window.SetIcon(iconImages)
return nil
})
// The icons are actually set at (*UserInterface).loop.
w.ui.setIconImages(iconImages)
}
func (w *window) SetTitle(title string) {