From 07c173f2f684323fc878540f9588badd97ecbc43 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 27 Feb 2024 14:16:29 +0100 Subject: [PATCH 01/11] widget: Move some minsize calculations to the renderer --- widget/activity.go | 3 +-- widget/gridwrap.go | 1 - widget/hyperlink.go | 7 ++----- widget/label.go | 9 ++------- widget/list.go | 1 - widget/separator.go | 6 ++---- 6 files changed, 7 insertions(+), 20 deletions(-) diff --git a/widget/activity.go b/widget/activity.go index 07b62fb431..1bfa3eb584 100644 --- a/widget/activity.go +++ b/widget/activity.go @@ -34,8 +34,7 @@ func NewActivity() *Activity { func (a *Activity) MinSize() fyne.Size { a.ExtendBaseWidget(a) - - return fyne.NewSquareSize(a.Theme().Size(theme.SizeNameInlineIcon)) + return a.BaseWidget.MinSize() } // Start the activity indicator animation diff --git a/widget/gridwrap.go b/widget/gridwrap.go index 6be54a6a92..b6245396fc 100644 --- a/widget/gridwrap.go +++ b/widget/gridwrap.go @@ -112,7 +112,6 @@ func (l *GridWrap) FocusLost() { // MinSize returns the size that this widget should not shrink below. func (l *GridWrap) MinSize() fyne.Size { l.ExtendBaseWidget(l) - return l.BaseWidget.MinSize() } diff --git a/widget/hyperlink.go b/widget/hyperlink.go index e07f3156e9..728bfa5111 100644 --- a/widget/hyperlink.go +++ b/widget/hyperlink.go @@ -163,11 +163,8 @@ func (hl *Hyperlink) Refresh() { // MinSize returns the smallest size this widget can shrink to func (hl *Hyperlink) MinSize() fyne.Size { - if len(hl.provider.Segments) == 0 { - hl.syncSegments() - } - - return hl.provider.MinSize() + hl.ExtendBaseWidget(hl) + return hl.BaseWidget.MinSize() } // Resize sets a new size for the hyperlink. diff --git a/widget/label.go b/widget/label.go index e3bab90a57..a587137d36 100644 --- a/widget/label.go +++ b/widget/label.go @@ -3,7 +3,6 @@ package widget import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/data/binding" - "fyne.io/fyne/v2/internal/cache" "fyne.io/fyne/v2/theme" ) @@ -77,12 +76,8 @@ func (l *Label) CreateRenderer() fyne.WidgetRenderer { // // Implements: fyne.Widget func (l *Label) MinSize() fyne.Size { - if l.provider == nil { - l.ExtendBaseWidget(l) - cache.Renderer(l.super()) - } - - return l.provider.MinSize() + l.ExtendBaseWidget(l) + return l.BaseWidget.MinSize() } // Refresh triggers a redraw of the label. diff --git a/widget/list.go b/widget/list.go index 53bca499b1..dab4f25b91 100644 --- a/widget/list.go +++ b/widget/list.go @@ -110,7 +110,6 @@ func (l *List) FocusLost() { // MinSize returns the size that this widget should not shrink below. func (l *List) MinSize() fyne.Size { l.ExtendBaseWidget(l) - return l.BaseWidget.MinSize() } diff --git a/widget/separator.go b/widget/separator.go index 8f61de80ef..30d9433156 100644 --- a/widget/separator.go +++ b/widget/separator.go @@ -55,8 +55,7 @@ func (s *Separator) CreateRenderer() fyne.WidgetRenderer { // Implements: fyne.Widget func (s *Separator) MinSize() fyne.Size { s.ExtendBaseWidget(s) - t := s.Theme().Size(theme.SizeNameSeparatorThickness) - return fyne.NewSize(t, t) + return s.BaseWidget.MinSize() } var _ fyne.WidgetRenderer = (*separatorRenderer)(nil) @@ -68,8 +67,7 @@ type separatorRenderer struct { } func (r *separatorRenderer) MinSize() fyne.Size { - t := r.d.Theme().Size(theme.SizeNameSeparatorThickness) - return fyne.NewSize(t, t) + return fyne.NewSquareSize(r.d.Theme().Size(theme.SizeNameSeparatorThickness)) } func (r *separatorRenderer) Refresh() { From 36c10daf847d7caeeb20f6549cc3b9c4f58eadb8 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 27 Feb 2024 17:53:32 +0100 Subject: [PATCH 02/11] Move MinSize calculation from Entry into renderer --- widget/entry.go | 49 ++++++++++++++++++++++++-------------------- widget/entry_test.go | 2 +- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/widget/entry.go b/widget/entry.go index 1398341d2c..26545c2e38 100644 --- a/widget/entry.go +++ b/widget/entry.go @@ -409,16 +409,7 @@ func (e *Entry) MinSize() fyne.Size { } e.ExtendBaseWidget(e) - - th := e.Theme() - iconSpace := th.Size(theme.SizeNameInlineIcon) + th.Size(theme.SizeNameLineSpacing) min := e.BaseWidget.MinSize() - if e.ActionItem != nil { - min = min.Add(fyne.NewSize(iconSpace, 0)) - } - if e.Validator != nil { - min = min.Add(fyne.NewSize(iconSpace, 0)) - } e.propertyLock.Lock() e.minCache = min @@ -1679,25 +1670,39 @@ func (r *entryRenderer) MinSize() fyne.Size { if rend := cache.Renderer(r.entry.content); rend != nil { rend.(*entryContentRenderer).updateScrollDirections() } - if r.scroll.Direction == widget.ScrollNone { - return r.entry.content.MinSize().Add(fyne.NewSize(0, r.entry.Theme().Size(theme.SizeNameInputBorder)*2)) - } - innerPadding := r.entry.Theme().Size(theme.SizeNameInnerPadding) - textSize := r.entry.Theme().Size(theme.SizeNameText) - charMin := r.entry.placeholderProvider().charMinSize(r.entry.Password, r.entry.TextStyle, textSize) - minSize := charMin.Add(fyne.NewSquareSize(innerPadding)) + th := r.entry.Theme() + minSize := fyne.Size{} + + if r.scroll.Direction == widget.ScrollNone { + minSize = r.entry.content.MinSize().AddWidthHeight(0, th.Size(theme.SizeNameInputBorder)*2) + } else { + innerPadding := th.Size(theme.SizeNameInnerPadding) + textSize := th.Size(theme.SizeNameText) + charMin := r.entry.placeholderProvider().charMinSize(r.entry.Password, r.entry.TextStyle, textSize) + minSize = charMin.Add(fyne.NewSquareSize(innerPadding)) + + if r.entry.MultiLine { + count := r.entry.multiLineRows + if count <= 0 { + count = multiLineRows + } - if r.entry.MultiLine { - count := r.entry.multiLineRows - if count <= 0 { - count = multiLineRows + minSize.Height = charMin.Height*float32(count) + innerPadding } - minSize.Height = charMin.Height*float32(count) + innerPadding + minSize = minSize.AddWidthHeight(innerPadding*2, innerPadding) + } + + iconSpace := th.Size(theme.SizeNameInlineIcon) + th.Size(theme.SizeNameLineSpacing) + if r.entry.ActionItem != nil { + minSize.Width += iconSpace + } + if r.entry.Validator != nil { + minSize.Width += iconSpace } - return minSize.Add(fyne.NewSize(innerPadding*2, innerPadding)) + return minSize } func (r *entryRenderer) Objects() []fyne.CanvasObject { diff --git a/widget/entry_test.go b/widget/entry_test.go index 9a00103ce5..b2bab74d27 100644 --- a/widget/entry_test.go +++ b/widget/entry_test.go @@ -454,7 +454,7 @@ func TestEntry_MinSize(t *testing.T) { min = entry.MinSize() entry.ActionItem = canvas.NewCircle(color.Black) entry.Refresh() - assert.Equal(t, min.Add(fyne.NewSize(theme.IconInlineSize()+theme.Padding(), 0)), entry.MinSize()) + assert.Equal(t, min.Add(fyne.NewSize(theme.IconInlineSize()+theme.LineSpacing(), 0)), entry.MinSize()) } func TestEntryMultiline_MinSize(t *testing.T) { From 9a0d7b82977e7f9a8fea87daaaa87a4e022f0b03 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 27 Feb 2024 11:19:55 +0100 Subject: [PATCH 03/11] RFC for adding a cache for MinSize --- widget/entry.go | 17 ++--------------- widget/widget.go | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/widget/entry.go b/widget/entry.go index 26545c2e38..697b94180d 100644 --- a/widget/entry.go +++ b/widget/entry.go @@ -95,7 +95,6 @@ type Entry struct { ActionItem fyne.CanvasObject `json:"-"` binder basicBinder conversionError error - minCache fyne.Size multiLineRows int // override global default number of visible lines // undoStack stores the data necessary for undo/redo functionality @@ -401,9 +400,7 @@ func (e *Entry) KeyUp(key *fyne.KeyEvent) { // // Implements: fyne.Widget func (e *Entry) MinSize() fyne.Size { - e.propertyLock.RLock() - cached := e.minCache - e.propertyLock.RUnlock() + cached := e.GetMinSizeCache() if !cached.IsZero() { return cached } @@ -411,9 +408,7 @@ func (e *Entry) MinSize() fyne.Size { e.ExtendBaseWidget(e) min := e.BaseWidget.MinSize() - e.propertyLock.Lock() - e.minCache = min - e.propertyLock.Unlock() + e.SetMinSizeCache(min) return min } @@ -479,14 +474,6 @@ func (e *Entry) Redo() { e.Refresh() } -func (e *Entry) Refresh() { - e.propertyLock.Lock() - e.minCache = fyne.Size{} - e.propertyLock.Unlock() - - e.BaseWidget.Refresh() -} - // SelectedText returns the text currently selected in this Entry. // If there is no selection it will return the empty string. func (e *Entry) SelectedText() string { diff --git a/widget/widget.go b/widget/widget.go index c5335485d8..713f29191b 100644 --- a/widget/widget.go +++ b/widget/widget.go @@ -16,6 +16,7 @@ import ( // BaseWidget provides a helper that handles basic widget behaviours. type BaseWidget struct { size async.Size + minCache async.Size position async.Position Hidden bool @@ -69,6 +70,16 @@ func (w *BaseWidget) Move(pos fyne.Position) { // MinSize for the widget - it should never be resized below this value. func (w *BaseWidget) MinSize() fyne.Size { + minCache := w.minCache.Load() + if !minCache.IsZero() { + return minCache + } + + return w.MinSizeFromRenderer() +} + +// MinSizeFromRenderer returns the MinSize has defined by this widget's renderer. +func (w *BaseWidget) MinSizeFromRenderer() fyne.Size { impl := w.super() r := cache.Renderer(impl) @@ -88,6 +99,18 @@ func (w *BaseWidget) Visible() bool { return !w.Hidden } +// GetMinSizeCache returns the currently cached MinSize value. +// This value is set to zero on calling Refresh(). +func (w *BaseWidget) GetMinSizeCache() fyne.Size { + return w.minCache.Load() +} + +// SetMinSizeCache updates the internal cache for the MinSize. +// This cached value will be used until the next Refresh. +func (w *BaseWidget) SetMinSizeCache(cache fyne.Size) { + w.minCache.Store(cache) +} + // Show this widget so it becomes visible func (w *BaseWidget) Show() { if w.Visible() { @@ -123,6 +146,8 @@ func (w *BaseWidget) Refresh() { return } + w.minCache.Store(fyne.Size{}) + w.propertyLock.Lock() w.themeCache = nil w.propertyLock.Unlock() From d40e12a57103e1370f41eb3ca92aba562ecc1c64 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 27 Feb 2024 11:27:34 +0100 Subject: [PATCH 04/11] Add a similar MinSize cache to the container as well --- container.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/container.go b/container.go index 726e77a626..24647dc259 100644 --- a/container.go +++ b/container.go @@ -1,6 +1,8 @@ package fyne -import "sync" +import ( + "sync" +) // Declare conformity to CanvasObject var _ CanvasObject = (*Container)(nil) @@ -10,7 +12,8 @@ var _ CanvasObject = (*Container)(nil) type Container struct { size Size // The current size of the Container position Position // The current position of the Container - Hidden bool // Is this Container hidden + minCache Size + Hidden bool // Is this Container hidden Layout Layout // The Layout algorithm for arranging child CanvasObjects lock sync.Mutex @@ -86,6 +89,10 @@ func (c *Container) Hide() { // MinSize calculates the minimum size of a Container. // This is delegated to the Layout, if specified, otherwise it will mimic MaxLayout. func (c *Container) MinSize() Size { + if !c.minCache.IsZero() { + return c.minCache + } + if c.Layout != nil { return c.Layout.MinSize(c.Objects) } @@ -95,6 +102,7 @@ func (c *Container) MinSize() Size { minSize = minSize.Max(child.MinSize()) } + c.minCache = minSize return minSize } @@ -123,6 +131,7 @@ func (c *Container) Refresh() { return } o.Refresh(c) + c.minCache = Size{} } // Remove updates the contents of this container to no longer include the specified object. From 2b0b8290c0f7f54b7053800732d12afdf7677011 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 27 Feb 2024 11:33:21 +0100 Subject: [PATCH 05/11] A few cache fixes --- internal/widget/base.go | 11 ++++++++++- widget/widget.go | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/internal/widget/base.go b/internal/widget/base.go index 36d2c9aaef..a09deb71dd 100644 --- a/internal/widget/base.go +++ b/internal/widget/base.go @@ -14,6 +14,7 @@ type Base struct { hidden atomic.Bool position async.Position size async.Size + minCache async.Size impl atomic.Pointer[fyne.Widget] } @@ -63,6 +64,11 @@ func (w *Base) Move(pos fyne.Position) { // MinSize for the widget - it should never be resized below this value. func (w *Base) MinSize() fyne.Size { + minCache := w.minCache.Load() + if !minCache.IsZero() { + return minCache + } + impl := w.super() r := cache.Renderer(impl) @@ -70,7 +76,9 @@ func (w *Base) MinSize() fyne.Size { return fyne.NewSize(0, 0) } - return r.MinSize() + min := r.MinSize() + w.minCache.Store(min) + return min } // Visible returns whether or not this widget should be visible. @@ -114,6 +122,7 @@ func (w *Base) Refresh() { render := cache.Renderer(impl) render.Refresh() + w.minCache.Store(fyne.Size{}) } // super will return the actual object that this represents. diff --git a/widget/widget.go b/widget/widget.go index 713f29191b..da2bddbaa1 100644 --- a/widget/widget.go +++ b/widget/widget.go @@ -75,7 +75,9 @@ func (w *BaseWidget) MinSize() fyne.Size { return minCache } - return w.MinSizeFromRenderer() + min := w.MinSizeFromRenderer() + w.minCache.Store(min) + return min } // MinSizeFromRenderer returns the MinSize has defined by this widget's renderer. From 6e37a9db7c1ab1a9545f7ab9e9ac6b6dbe64018c Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 27 Feb 2024 13:32:34 +0100 Subject: [PATCH 06/11] Rework entry so we can use BaseWidget cache --- widget/entry.go | 10 +--------- widget/widget.go | 23 +++-------------------- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/widget/entry.go b/widget/entry.go index 697b94180d..56a18cc922 100644 --- a/widget/entry.go +++ b/widget/entry.go @@ -400,16 +400,8 @@ func (e *Entry) KeyUp(key *fyne.KeyEvent) { // // Implements: fyne.Widget func (e *Entry) MinSize() fyne.Size { - cached := e.GetMinSizeCache() - if !cached.IsZero() { - return cached - } - e.ExtendBaseWidget(e) - min := e.BaseWidget.MinSize() - - e.SetMinSizeCache(min) - return min + return e.BaseWidget.MinSize() } // MouseDown called on mouse click, this triggers a mouse click which can move the cursor, diff --git a/widget/widget.go b/widget/widget.go index da2bddbaa1..743ac7b661 100644 --- a/widget/widget.go +++ b/widget/widget.go @@ -75,13 +75,6 @@ func (w *BaseWidget) MinSize() fyne.Size { return minCache } - min := w.MinSizeFromRenderer() - w.minCache.Store(min) - return min -} - -// MinSizeFromRenderer returns the MinSize has defined by this widget's renderer. -func (w *BaseWidget) MinSizeFromRenderer() fyne.Size { impl := w.super() r := cache.Renderer(impl) @@ -89,7 +82,9 @@ func (w *BaseWidget) MinSizeFromRenderer() fyne.Size { return fyne.Size{} } - return r.MinSize() + min := r.MinSize() + w.minCache.Store(min) + return min } // Visible returns whether or not this widget should be visible. @@ -101,18 +96,6 @@ func (w *BaseWidget) Visible() bool { return !w.Hidden } -// GetMinSizeCache returns the currently cached MinSize value. -// This value is set to zero on calling Refresh(). -func (w *BaseWidget) GetMinSizeCache() fyne.Size { - return w.minCache.Load() -} - -// SetMinSizeCache updates the internal cache for the MinSize. -// This cached value will be used until the next Refresh. -func (w *BaseWidget) SetMinSizeCache(cache fyne.Size) { - w.minCache.Store(cache) -} - // Show this widget so it becomes visible func (w *BaseWidget) Show() { if w.Visible() { From 98bd384c4d9888c9bf2f66f70c89aa63761ef873 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 27 Feb 2024 13:33:20 +0100 Subject: [PATCH 07/11] Less ugly import formatting --- container.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/container.go b/container.go index 24647dc259..77de7f2a79 100644 --- a/container.go +++ b/container.go @@ -1,8 +1,6 @@ package fyne -import ( - "sync" -) +import "sync" // Declare conformity to CanvasObject var _ CanvasObject = (*Container)(nil) From e2cb641067dccc1e96a8eae73fd57e7eac8ea43b Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 27 Feb 2024 13:35:23 +0100 Subject: [PATCH 08/11] Reset cache consistently --- container.go | 3 ++- internal/widget/base.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/container.go b/container.go index 77de7f2a79..cfd8257d07 100644 --- a/container.go +++ b/container.go @@ -117,6 +117,8 @@ func (c *Container) Position() Position { // Refresh causes this object to be redrawn in it's current state func (c *Container) Refresh() { + c.minCache = Size{} + c.layout() for _, child := range c.Objects { @@ -129,7 +131,6 @@ func (c *Container) Refresh() { return } o.Refresh(c) - c.minCache = Size{} } // Remove updates the contents of this container to no longer include the specified object. diff --git a/internal/widget/base.go b/internal/widget/base.go index a09deb71dd..236f35e045 100644 --- a/internal/widget/base.go +++ b/internal/widget/base.go @@ -120,9 +120,10 @@ func (w *Base) Refresh() { return } + w.minCache.Store(fyne.Size{}) + render := cache.Renderer(impl) render.Refresh() - w.minCache.Store(fyne.Size{}) } // super will return the actual object that this represents. From 0fd0cf574f39040f3fd4a2acf43e5f8cd2ca5cd5 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 27 Feb 2024 13:44:07 +0100 Subject: [PATCH 09/11] Lat the renderer define the MinSize --- widget/check.go | 15 +++++++-------- widget/richtext.go | 11 +++-------- widget/select_entry.go | 2 +- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/widget/check.go b/widget/check.go index b03bfeedae..96368f41b0 100644 --- a/widget/check.go +++ b/widget/check.go @@ -24,8 +24,6 @@ type Check struct { hovered bool binder basicBinder - - minSize fyne.Size // cached for hover/tap position calculations } // NewCheck creates a new check widget with the set label and change handler @@ -119,8 +117,9 @@ func (c *Check) MouseMoved(me *desktop.MouseEvent) { // only hovered if cached minSize has not been initialized (test code) // or the pointer is within the "active" area of the widget (its minSize) - c.hovered = c.minSize.IsZero() || - (me.Position.X <= c.minSize.Width && me.Position.Y <= c.minSize.Height) + minSize := c.MinSize() + c.hovered = minSize.IsZero() || + (me.Position.X <= minSize.Width && me.Position.Y <= minSize.Height) if oldHovered != c.hovered { c.Refresh() @@ -132,8 +131,9 @@ func (c *Check) Tapped(pe *fyne.PointEvent) { if c.Disabled() { return } - if !c.minSize.IsZero() && - (pe.Position.X > c.minSize.Width || pe.Position.Y > c.minSize.Height) { + minSize := c.MinSize() + if !minSize.IsZero() && + (pe.Position.X > minSize.Width || pe.Position.Y > minSize.Height) { // tapped outside the active area of the widget return } @@ -151,8 +151,7 @@ func (c *Check) Tapped(pe *fyne.PointEvent) { // MinSize returns the size that this widget should not shrink below func (c *Check) MinSize() fyne.Size { c.ExtendBaseWidget(c) - c.minSize = c.BaseWidget.MinSize() - return c.minSize + return c.BaseWidget.MinSize() } // CreateRenderer is a private method to Fyne which links this widget to its renderer diff --git a/widget/richtext.go b/widget/richtext.go index 007b8e3c67..d237c0ec56 100644 --- a/widget/richtext.go +++ b/widget/richtext.go @@ -45,7 +45,6 @@ type RichText struct { visualCache map[RichTextSegment][]fyne.CanvasObject cacheLock sync.Mutex - minCache fyne.Size } // NewRichText returns a new RichText widget that renders the given text and segments. @@ -89,19 +88,14 @@ func (t *RichText) CreateRenderer() fyne.WidgetRenderer { // MinSize calculates the minimum size of a rich text widget. // This is based on the contained text with a standard amount of padding added. func (t *RichText) MinSize() fyne.Size { - // we don't return the minCache here, as any internal segments could have caused it to change... t.ExtendBaseWidget(t) - - min := t.BaseWidget.MinSize() - t.minCache = min - return min + return t.BaseWidget.MinSize() } // Refresh triggers a redraw of the rich text. // // Implements: fyne.Widget func (t *RichText) Refresh() { - t.minCache = fyne.Size{} t.updateRowBounds() for _, s := range t.Segments { @@ -123,10 +117,11 @@ func (t *RichText) Resize(size fyne.Size) { } t.size.Store(size) + minSize := t.MinSize() t.propertyLock.RLock() segments := t.Segments - skipResize := !t.minCache.IsZero() && size.Width >= t.minCache.Width && size.Height >= t.minCache.Height && t.Wrapping == fyne.TextWrapOff && t.Truncation == fyne.TextTruncateOff + skipResize := !minSize.IsZero() && size.Width >= minSize.Width && size.Height >= minSize.Height && t.Wrapping == fyne.TextWrapOff && t.Truncation == fyne.TextTruncateOff t.propertyLock.RUnlock() if skipResize { diff --git a/widget/select_entry.go b/widget/select_entry.go index 806d17c8c0..d6161252f9 100644 --- a/widget/select_entry.go +++ b/widget/select_entry.go @@ -55,7 +55,7 @@ func (e *SelectEntry) Disable() { // Implements: fyne.Widget func (e *SelectEntry) MinSize() fyne.Size { e.ExtendBaseWidget(e) - return e.Entry.MinSize() + return e.BaseWidget.MinSize() } // Move changes the relative position of the select entry. From 27c9f22f64f9792cad1ee62895fdafeb7c8ca6c8 Mon Sep 17 00:00:00 2001 From: Jacob Date: Tue, 27 Feb 2024 18:36:57 +0100 Subject: [PATCH 10/11] Fix a few hyperlink tests --- widget/hyperlink.go | 1 + widget/widget.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/widget/hyperlink.go b/widget/hyperlink.go index 728bfa5111..91d00a2fd4 100644 --- a/widget/hyperlink.go +++ b/widget/hyperlink.go @@ -188,6 +188,7 @@ func (hl *Hyperlink) SetText(text string) { return // Not initialized yet. } hl.syncSegments() + hl.ResetMinSizeCache() hl.provider.Refresh() } diff --git a/widget/widget.go b/widget/widget.go index 743ac7b661..43e7a21a7b 100644 --- a/widget/widget.go +++ b/widget/widget.go @@ -141,6 +141,11 @@ func (w *BaseWidget) Refresh() { render.Refresh() } +// ResetMinSizeCache resets the cached MinSize for this widget. +func (w *BaseWidget) ResetMinSizeCache() { + w.minCache.Store(fyne.Size{}) +} + // Theme returns a cached Theme instance for this widget (or its extending widget). // This will be the app theme in most cases, or a widget specific theme if it is inside a ThemeOverride container. // @@ -181,6 +186,7 @@ func (w *BaseWidget) SetFieldsAndRefresh(f func()) { return } impl.Refresh() + w.ResetMinSizeCache() } // super will return the actual object that this represents. From e673db4d9e0f1d5f5e6ea5d115bfbaebbe9391e6 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sun, 10 Mar 2024 11:22:02 +0100 Subject: [PATCH 11/11] Remove fundamentally broken container minsize cache --- container.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/container.go b/container.go index cfd8257d07..726e77a626 100644 --- a/container.go +++ b/container.go @@ -10,8 +10,7 @@ var _ CanvasObject = (*Container)(nil) type Container struct { size Size // The current size of the Container position Position // The current position of the Container - minCache Size - Hidden bool // Is this Container hidden + Hidden bool // Is this Container hidden Layout Layout // The Layout algorithm for arranging child CanvasObjects lock sync.Mutex @@ -87,10 +86,6 @@ func (c *Container) Hide() { // MinSize calculates the minimum size of a Container. // This is delegated to the Layout, if specified, otherwise it will mimic MaxLayout. func (c *Container) MinSize() Size { - if !c.minCache.IsZero() { - return c.minCache - } - if c.Layout != nil { return c.Layout.MinSize(c.Objects) } @@ -100,7 +95,6 @@ func (c *Container) MinSize() Size { minSize = minSize.Max(child.MinSize()) } - c.minCache = minSize return minSize } @@ -117,8 +111,6 @@ func (c *Container) Position() Position { // Refresh causes this object to be redrawn in it's current state func (c *Container) Refresh() { - c.minCache = Size{} - c.layout() for _, child := range c.Objects {