Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions internal/cache/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,19 @@ func CleanCanvas(canvas fyne.Canvas) {
return true
}
rinfo.renderer.Destroy()
overrides.Delete(wid)
deleteOverrideFor(wid)
return true
})
}

func deleteOverrideFor(o fyne.CanvasObject) {
overrides.Delete(o)
if currentOverrideObj == o {
currentOverrideObj = nil
currentOverrideScope = nil
}
}

// ResetThemeCaches clears all the svg and text size cache maps
func ResetThemeCaches() {
svgs.Clear()
Expand All @@ -100,7 +108,7 @@ func destroyExpiredRenderers(now time.Time) {
renderers.Range(func(wid fyne.Widget, rinfo *rendererInfo) bool {
if rinfo.isExpired(now) {
rinfo.renderer.Destroy()
overrides.Delete(wid)
deleteOverrideFor(wid)
renderers.Delete(wid)
}
return true
Expand Down
39 changes: 34 additions & 5 deletions internal/cache/theme.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ import (
var (
overrides async.Map[fyne.CanvasObject, *overrideScope]
overrideCount atomic.Uint32

// Provide an extra fast means of accessing the override
// for a given object multiple times in succession.
// (e.g. repeated calls to theme.ColorForWidget(colorName, wid))
//
// This should be set to the last queried entry in the overrides map
//
// Whenever an entry is deleted from overrides during cache clean,
// if that entry is the current one here, both of these fields
// should be set to nil as well
currentOverrideObj fyne.CanvasObject
currentOverrideScope *overrideScope
)

type overrideScope struct {
Expand All @@ -30,7 +42,7 @@ func OverrideTheme(o fyne.CanvasObject, th fyne.Theme) {
}

func OverrideThemeMatchingScope(o, parent fyne.CanvasObject) bool {
scope, ok := overrides.Load(parent)
scope, ok := lookupOverride(o)
if !ok { // not overridden in parent
return false
}
Expand All @@ -40,7 +52,7 @@ func OverrideThemeMatchingScope(o, parent fyne.CanvasObject) bool {
}

func WidgetScopeID(o fyne.CanvasObject) string {
scope, ok := overrides.Load(o)
scope, ok := lookupOverride(o)
if !ok {
return ""
}
Expand All @@ -49,7 +61,7 @@ func WidgetScopeID(o fyne.CanvasObject) string {
}

func WidgetTheme(o fyne.CanvasObject) fyne.Theme {
scope, ok := overrides.Load(o)
scope, ok := lookupOverride(o)
if !ok {
return nil
}
Expand All @@ -74,13 +86,13 @@ func overrideTheme(o fyne.CanvasObject, s *overrideScope) {
case *fyne.Container:
overrideContainer(c, s)
default:
overrides.Store(c, s)
storeOverride(c, s)
}
}

func overrideWidget(w fyne.Widget, s *overrideScope) {
ResetThemeCaches()
overrides.Store(w, s)
storeOverride(w, s)

r := Renderer(w)
if r == nil {
Expand All @@ -91,3 +103,20 @@ func overrideWidget(w fyne.Widget, s *overrideScope) {
overrideTheme(o, s)
}
}

func lookupOverride(o fyne.CanvasObject) (*overrideScope, bool) {
if currentOverrideObj == o {
return currentOverrideScope, currentOverrideScope != nil
}
s, ok := overrides.Load(o)
currentOverrideObj = o
currentOverrideScope = s
return s, ok
}

func storeOverride(o fyne.CanvasObject, s *overrideScope) {
if currentOverrideObj == o {
currentOverrideScope = s
}
overrides.Store(o, s)
}
Loading