How MinSize() is used in WidgetRenderer(), where is it called from? #5513
-
I was reading through the documentation, and I think I understood these concepts:
But I don't see how the renderer is related to the widget, after the renderer has been created. A widget can be asked to create a new renderer, but a renderer cannot tell its widget (by its interface), and a widget cannot tell if it already created a renderer. Let's say that a widget is created and used somewhere inside a Window. Some code calls its CreateRenderer() method, in order to create a renderer for the widget.
And finally, there is WidgetRenderer.Layout(), it has the following documentation:
I would like to know when it needs to be laid out exactly. I suspect that it is needed when the widget's size or position changes (since size and position is not stored/implemented by its renderer). But is it synchronous? Or does it happen some time after the size and/or position of the widget has changed? Is it called by a message queue processor, in a specific order? Or is it called directly in the same call chain that begins with widget.SetSize() or widget.Move()? Can somebody please tell me exactly when it happens? |
Beta Was this translation helpful? Give feedback.
Replies: 9 comments 5 replies
-
Correct, the renderer is managed in our drivers - a widget should not care if it has created a renderer - there may be more than one created during the lifecycle of a widget. However a renderer can know about the widget it renders (most have to!) by passing the widget into the renderer instance you create (assuming it is a custom renderer).
This is usually handled in
As above, the drivers keep track of what is rendered and public APIs or 3rd party code need to track this.
No, that is incorrect - custom widgets can override whatever they want (including MinSize, CreateRenderer etc). If they have a good reason to. Often you will want to call to the replaced method as well, but that depends on your reason for replacing.
Layout is called when size changes. A position change does not have to update anything - because all items in a widget are positioned relative to that parent.
That is a lot of questions and I'm not sure what you are trying to understand. When a widget resizes its renderer will be asked to update accordingly. It should be that simple - what isn't working out for you? |
Beta Was this translation helpful? Give feedback.
-
I'm trying to find out if it is safe to call various methods from various places, especially goroutines. I have a test program that logs this message every time I press ENTER in the terminal, or resize it:
It is coming from termgrid.go, while calling The other thing is that terminal is very very slow. Sometimes I do a simple BTW thank you for answering these questions, it is really helpful! I also want to know how it works, because otherwise I tend to write bad code and then ask the wrong questions. |
Beta Was this translation helpful? Give feedback.
-
All right I came up with this minimalistic application: package main
import (
"fyne.io/fyne/v2/app"
"github.com/fyne-io/terminal"
)
func main() {
a := app.New()
w := a.NewWindow("Test")
t := terminal.New()
go func() {
_ = t.RunLocalShell()
}()
w.SetContent(t)
w.ShowAndRun()
} There is a video that shows the speed difference between fyne and urxvt: https://www.youtube.com/shorts/jmZrKgJmVPo I did not do a profiling, because CPU consumption is really low. However, the terminal itself is very slow, I would say it is unusable.
This minimalistic program also dumps thousands of messages like this:
I was experimenting with various terminal sizes. It becomes slow when the terminal needs to be scrolled. Without scrolling, it is quite fast. I got a segfault too:
Unfortunately, I was not able to replicate the error since then. |
Beta Was this translation helpful? Give feedback.
-
I could come up with a case where the terminal just freezes and does nothing. It happens when I start mc (midnight commander) in a specific directory. It starts drawing the interface, and it stops working in the middle of that operation. Then it does not respond to anything. Unfortunately, there is no error message, it simply hangs forever. Even more interesting is that this happens with a specific screen size and a specific folder. If I resize the window before starting mc, or if I open it in a different folder, then it works. When it works, then it becomes increasingly slow. The top part of https://youtube.com/shorts/DCdyK4dldAQ?feature=share Please let me know if I can do anything else to find what is causing it. |
Beta Was this translation helpful? Give feedback.
-
Here is my go.mod file that was used for this test:
The fyne is in |
Beta Was this translation helpful? Give feedback.
-
That's right, I was just using "go get github.com/fyne-io/terminal" for this. But fyne terminal is not versioned, can you please suggest which tag/branch should I use? I only see a master branch there https://github.com/fyne-io/terminal/branches |
Beta Was this translation helpful? Give feedback.
-
Thank you, I still see the issue. This is how I did this: git clone [email protected]:fyne-io/terminal.git
git clone -b develop https://github.com/fyne-io/fyne
mkdir test
cd test
go mod init test
go get fyne.io/fyne/v2@latest
go get github.com/fyne-io/terminal
echo 'package main
import (
"fyne.io/fyne/v2/app"
"github.com/fyne-io/terminal"
)
func main() {
a := app.New()
w := a.NewWindow("Test")
t := terminal.New()
go func() {
_ = t.RunLocalShell()
}()
w.SetContent(t)
w.ShowAndRun()
}
' > main.go Then I added these to go.mod:
And finally: go mod tidy
go run main.go fyne is at 9cdc384 and terminal is at b4bdba95f3fae53baeceef651a2d32f685433610 |
Beta Was this translation helpful? Give feedback.
-
I missed this part, sorry. I'll try again |
Beta Was this translation helpful? Give feedback.
-
fyne 621fc22 plus terminal b4bdba95f3fae53baeceef651a2d32f685433610 works well, thank you! Should I use 2.6 alpha when it comes out? Thank you again! |
Beta Was this translation helpful? Give feedback.
Correct, the renderer is managed in our drivers - a widget should not care if it has created a renderer - there may be more than one created during the lifecycle of a widget. However a renderer can know about the widget it renders (most have to!) by passing the widget into the renderer instance you create (assuming it is a custom renderer).