Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

widgets still displayed after being removed from fyne.Container.Objects #2103

Closed
r-ricci opened this issue Mar 22, 2021 · 7 comments
Closed
Labels
bug Something isn't working

Comments

@r-ricci
Copy link

r-ricci commented Mar 22, 2021

Describe the bug:

In the example code below, every time the button is pressed, the contents of outBox.Objects will be eventually removed and replaced with new labels and separators. The code does not work as expected and sometimes also crashes.
With the same code, I also reproduced #1897 and #1946.

To Reproduce:

Steps to reproduce the behaviour:

  1. Compile and run the example code
  2. Type "a" in the entry and press the button
    A label with the corresponding text and a separator are displayed. This is OK.
  3. Type "b" in the entry and press again the button
    A separator, a label with the text corresponding to "b" and another separator are displayed. This is not OK, the first separator should not be there.
  4. Type again "a" and press the button
    A label with "B..." text, a label with "A..." text and a separator are displayed. It seems that one of the old widgets is still displayed after being passed to .Remove().
  5. Click repeatedly and quickly on the button
    The program panics and something like the following is printed on the terminal:
panic
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x58 pc=0x6801be]

goroutine 12 [running, locked to thread]:
fyne.io/fyne/v2/layout.(*boxLayout).MinSize(0xc000016e28, 0xc0000a0b00, 0x3, 0x4, 0xc0006862c8)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/layout/boxlayout.go:125 +0x7e
fyne.io/fyne/v2.(*Container).MinSize(0xc000058500, 0x827320)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/container.go:71 +0x176
fyne.io/fyne/v2/internal/widget.(*Scroll).MinSize(0xc000092960, 0xc000071801)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/widget/scroller.go:514 +0x108
fyne.io/fyne/v2/internal/driver/glfw.(*glCanvas).ensureMinSize.func1(0xc0000a0400)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/glfw/canvas.go:335 +0x112
fyne.io/fyne/v2/internal/driver/glfw.(*glCanvas).walkTree.func2(0x82bb98, 0xc000092960, 0x82b658, 0xc0000a02c0)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/glfw/canvas.go:550 +0xe3
fyne.io/fyne/v2/internal/driver.walkObjectTree(0x82bb98, 0xc000092960, 0x4080000040800000, 0x82b658, 0xc0000a02c0, 0x4080000040800000, 0x0, 0x4f0000004f000000, 0xc0000c5d28, 0xc0000c5d00, ...)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/util.go:197 +0x31a
fyne.io/fyne/v2/internal/driver.walkObjectTree.func1(...)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/util.go:176
fyne.io/fyne/v2/internal/driver.walkObjectTree(0x82b658, 0xc0000a02c0, 0x53900f00, 0x0, 0x0, 0x0, 0x0, 0x4f0000004f000000, 0xc0000c5d28, 0xc0000c5d00, ...)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/util.go:190 +0x3ff
fyne.io/fyne/v2/internal/driver.WalkVisibleObjectTree(0x82b658, 0xc0000a02c0, 0xc0000c5d28, 0xc0000c5d00, 0xc0000c5d18)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/util.go:134 +0x94
fyne.io/fyne/v2/internal/driver/glfw.(*glCanvas).walkTree(0xc0002f8000, 0xc00004c040, 0x0, 0xc0000c5e00)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/glfw/canvas.go:556 +0x15c
fyne.io/fyne/v2/internal/driver/glfw.(*glCanvas).walkTrees(0xc0002f8000, 0x0, 0xc0000c5e00)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/glfw/canvas.go:563 +0x4f
fyne.io/fyne/v2/internal/driver/glfw.(*glCanvas).ensureMinSize(0xc0002f8000, 0xc0000c5e70)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/glfw/canvas.go:358 +0x98
fyne.io/fyne/v2/internal/driver/glfw.(*gLDriver).repaintWindow.func1()
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/glfw/loop.go:155 +0x45
fyne.io/fyne/v2/internal/driver/glfw.(*window).RunWithContext(0xc0001481c0, 0xc0000c5ea8)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/glfw/window.go:1186 +0x4f
fyne.io/fyne/v2/internal/driver/glfw.(*gLDriver).repaintWindow(0xc0000643c0, 0xc0001481c0)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/glfw/loop.go:154 +0x65
fyne.io/fyne/v2/internal/driver/glfw.(*gLDriver).startDrawThread.func1(0xc0000643c0, 0xc0000664e0, 0xc0000644b0)
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/glfw/loop.go:210 +0x309
created by fyne.io/fyne/v2/internal/driver/glfw.(*gLDriver).startDrawThread
	/home/ricci/go/pkg/mod/fyne.io/fyne/v2@v2.0.1/internal/driver/glfw/loop.go:181 +0xbd

It is interesting to note that the longer is the text, the easier is to crash the program. What's in the file data.go (which is not exceptionally long) requires only a few clicks, at least on my machine. Shorter text requires to click very fast to get a crash.

The crash could be related to #1957, but I don't know why the widgets are not removed from the screen. There are issues reporting memory leaks, but in theory a memory leak only affects memory usage, not the behaviour of the program.

Example code:

main.go
package main

import (
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/data/binding"
	"fyne.io/fyne/v2/widget"
)

func main() {
	w := app.New().NewWindow("test")

	input := binding.NewString()

	outBox := container.NewVBox()

	w.SetContent(container.NewBorder(
		container.NewVBox(
			widget.NewEntryWithData(input),
			widget.NewButton("Search", func() {
				s, err := input.Get()
				if err != nil {
					panic(err)
				}

				for _, v := range outBox.Objects {
					outBox.Remove(v)
				}

				//dict is [][2]string, as defined in data.go
				for _, v := range dict {
					if v[0] == s {
						label := widget.NewLabel(v[1])
						label.Wrapping = fyne.TextWrapWord
						outBox.Add(label)
						outBox.Add(widget.NewSeparator())
					}
				}
			})),
		nil,
		nil,
		nil,
		container.NewVScroll(outBox),
	))

	w.ShowAndRun()
}
data.go
package main

var dict = [][2]string{
	{"a", `AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`},
	{"b", `BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB`},
}

Device:

I was able to reproduce the behaviour on the following:

  • OS: Void Linux (GNU libc)
  • Go version: go1.16.2 linux/amd64
  • Fyne version: v2.0.1


  • OS: Debian
  • Version: 11 (bullseye)
  • Go version: go1.15.9 linux/amd64
  • Fyne version: v2.0.1


  • OS: Android, arm64
  • Version: 9
  • APK compiled on Void Linux, NDK r21e
@r-ricci r-ricci added the bug Something isn't working label Mar 22, 2021
@fpabl0
Copy link
Member

fpabl0 commented Mar 22, 2021

The crash could be related to #1957

I think the crash you got is due to a race condition, as you are removing objects from the container while in the background those objects are used to render the screen.

but I don't know why the widgets are not removed from the screen.

This is because currently container.Remove does not automatically refresh itself, you need to call container.Refresh manually to ensure the screen is updated.

Nevertheless, for the use case you are trying to achieve, I think you should try widget.List as it has all the functionalities you need (scroll and add/remove objects dynamically).

@r-ricci
Copy link
Author

r-ricci commented Mar 22, 2021

but I don't know why the widgets are not removed from the screen.

This is because currently container.Remove does not automatically refresh itself, you need to call container.Refresh manually to ensure the screen is updated.

No, calling container.Refresh after replacing the widgets (the code below) gives exactly the same results.

main.go
package main

import (
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/data/binding"
	"fyne.io/fyne/v2/widget"
)

func main() {
	w := app.New().NewWindow("test")

	input := binding.NewString()

	outBox := container.NewVBox()

	w.SetContent(container.NewBorder(
		container.NewVBox(
			widget.NewEntryWithData(input),
			widget.NewButton("Search", func() {
				s, err := input.Get()
				if err != nil {
					panic(err)
				}

				for _, v := range outBox.Objects {
					outBox.Remove(v)
				}

				//dict is [][2]string, as defined in data.go
				for _, v := range dict {
					if v[0] == s {
						label := widget.NewLabel(v[1])
						label.Wrapping = fyne.TextWrapWord
						outBox.Add(label)
						outBox.Add(widget.NewSeparator())
					}
				}
				outBox.Refresh()
			})),
		nil,
		nil,
		nil,
		container.NewVScroll(outBox),
	))

	w.ShowAndRun()
}

Nevertheless, for the use case you are trying to achieve, I think you should try widget.List as it has all the functionalities you need (scroll and add/remove objects dynamically).

Thanks for the hint, I'll try it.

@andydotxyz
Copy link
Member

The Add and Remove methods are mostly designed for single operation - they will cause a refresh every time called.
If you want to do a batch then edit the Objects field directly. Lots of code could be replaced with:

outBox.Objects = []fyne.CanvasObject{label}
outBox.Refresh()

@r-ricci
Copy link
Author

r-ricci commented Mar 22, 2021

If you want to do a batch then edit the Objects field directly. Lots of code could be replaced with:

outBox.Objects = []fyne.CanvasObject{label}
outBox.Refresh()

This is surely a better approach and doing it solves both the problems I faced.

However using container.Remove() and container.Add() should work as well. Refreshing more times than necessary should only affect performance, not the output, so I still think there's a bug somewhere.
My question is whether both the problems I described are caused by a known bug, or just the crash.

@andydotxyz
Copy link
Member

My question is whether both the problems I described are caused by a known bug, or just the crash.

You are quite right that it should not crash.
The issue seems to be that the container ends up with a nil child element in the Object list, which should not happen.
If you were able to debug a little to figure out why that is the case, we'd have found the bug I think :).

@r-ricci
Copy link
Author

r-ricci commented Mar 23, 2021

The issue seems to be that the container ends up with a nil child element in the Object list, which should not happen.

There is no nil in outBox.Objects, the issue is simply that some elements are not removed. The bug is not in fyne, but in my code.
For the go compiler

for _, v := range outBox.Objects {
	outBox.Remove(v)
}

is just a shorthand to

for i := 0; i < len(outBox.Objects); i++ {
	outBox.Remove(outBox.Objects[i])
}

so the index is incremented while the slice is shifted to the left, and obviously some elements are skipped.
This is a very stupid mistake.

If one wants to remove all the objects using .Remove() instead of assign []fyne.CanvasObject{}, then the correct way would be

for len(outBox.Objects) > 0 {
	outBox.Remove(outBox.Objects[0])
}

This seems to be unrelated to the crash, which is caused by an already known bug, so I'm closing the issue.

@r-ricci r-ricci closed this as completed Mar 23, 2021
@andydotxyz
Copy link
Member

Thanks for the clarification there @4ricci, very helpful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants