Skip to content

Commit

Permalink
Merge pull request #1160 from cogentcore/race
Browse files Browse the repository at this point in the history
Prevent race conditions when resizing window
  • Loading branch information
rcoreilly authored Aug 20, 2024
2 parents 2fe38ad + 21feba1 commit a6c3cd0
Show file tree
Hide file tree
Showing 33 changed files with 277 additions and 112 deletions.
2 changes: 1 addition & 1 deletion cmd/core/config/typegen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

118 changes: 118 additions & 0 deletions core/enumgen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/filepicker.go
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ func (fb *FileButton) Init() {
d.Title = "Select file"
d.DeleteChildByName("body-title") // file picker has its own title
fp = NewFilePicker(d).SetFilename(fb.Filename).SetExtensions(fb.Extensions)
fb.valueNewWindow = true
fb.setFlag(true, widgetValueNewWindow)
d.AddAppBar(fp.MakeToolbar)
}, func() {
fb.Filename = fp.SelectedFile()
Expand Down
4 changes: 2 additions & 2 deletions core/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ func (fr *Frame) laySetContentFitOverflow(nsz math32.Vector2, pass LayoutPasses)
if nosz {
continue
}
if !(fr.Scene != nil && fr.Scene.prefSizing) && oflow.Dim(d) >= styles.OverflowAuto && fr.Parent != nil {
if !(fr.Scene != nil && fr.Scene.hasFlag(scenePrefSizing)) && oflow.Dim(d) >= styles.OverflowAuto && fr.Parent != nil {
if mx.Dim(d) > 0 {
asz.SetDim(d, styles.ClampMax(styles.ClampMin(asz.Dim(d), nsz.Dim(d)), mx.Dim(d)))
}
Expand Down Expand Up @@ -1508,7 +1508,7 @@ func (wb *WidgetBase) SizeFinal() {
// any factor > 1 produces a full fill along that dimension.
// Returns true if this resulted in a change in our Total size.
func (wb *WidgetBase) growToAlloc() bool {
if (wb.Scene != nil && wb.Scene.prefSizing) || wb.Styles.GrowWrap {
if (wb.Scene != nil && wb.Scene.hasFlag(scenePrefSizing)) || wb.Styles.GrowWrap {
return false
}
sz := &wb.Geom.Size
Expand Down
77 changes: 37 additions & 40 deletions core/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (wb *WidgetBase) AsyncLock() {
rc.unlock()
select {}
}
wb.Scene.updating = true
wb.Scene.setFlag(true, sceneUpdating)
}

// AsyncUnlock must be called after making any updates in a separate goroutine
Expand All @@ -48,20 +48,20 @@ func (wb *WidgetBase) AsyncUnlock() {
if rc == nil {
return
}
rc.unlock()
if wb.Scene != nil {
wb.Scene.updating = false
wb.Scene.setFlag(false, sceneUpdating)
}
rc.unlock()
}

// NeedsRender specifies that the widget needs to be rendered.
func (wb *WidgetBase) NeedsRender() {
if DebugSettings.UpdateTrace {
fmt.Println("\tDebugSettings.UpdateTrace: NeedsRender:", wb)
}
wb.needsRender = true
wb.setFlag(true, widgetNeedsRender)
if wb.Scene != nil {
wb.Scene.sceneNeedsRender = true
wb.Scene.setFlag(true, sceneNeedsRender)
}
}

Expand All @@ -73,7 +73,7 @@ func (wb *WidgetBase) NeedsLayout() {
fmt.Println("\tDebugSettings.UpdateTrace: NeedsLayout:", wb)
}
if wb.Scene != nil {
wb.Scene.needsLayout = true
wb.Scene.setFlag(true, sceneNeedsLayout)
}
}

Expand Down Expand Up @@ -144,7 +144,7 @@ func (wb *WidgetBase) doNeedsRender() {
return
}
wb.WidgetWalkDown(func(cw Widget, cwb *WidgetBase) bool {
if cwb.needsRender {
if cwb.hasFlag(widgetNeedsRender) {
cw.RenderWidget()
return tree.Break // don't go any deeper
}
Expand All @@ -168,56 +168,53 @@ var sceneShowIters = 2
// returns false if already updating.
// This is the main update call made by the RenderWindow at FPS frequency.
func (sc *Scene) doUpdate() bool {
if sc.updating {
if sc.hasFlag(sceneUpdating) {
return false
}
sc.updating = true // prevent rendering
defer func() { sc.updating = false }()
sc.setFlag(true, sceneUpdating) // prevent rendering
defer func() { sc.setFlag(false, sceneUpdating) }()

rc := sc.renderContext()

if sc.showIter < sceneShowIters {
sc.needsLayout = true
sc.setFlag(true, sceneNeedsLayout)
sc.showIter++
}

switch {
case rc.rebuild:
pr := profile.Start("rebuild")
sc.doRebuild()
sc.needsLayout = false
sc.sceneNeedsRender = false
sc.imageUpdated = true
sc.setFlag(false, sceneNeedsLayout, sceneNeedsRender)
sc.setFlag(true, sceneImageUpdated)
pr.End()
case sc.lastRender.needsRestyle(rc):
pr := profile.Start("restyle")
sc.applyStyleScene()
sc.layoutRenderScene()
sc.needsLayout = false
sc.sceneNeedsRender = false
sc.imageUpdated = true
sc.setFlag(false, sceneNeedsLayout, sceneNeedsRender)
sc.setFlag(true, sceneImageUpdated)
sc.lastRender.saveRender(rc)
pr.End()
case sc.needsLayout:
case sc.hasFlag(sceneNeedsLayout):
pr := profile.Start("layout")
sc.layoutRenderScene()
sc.needsLayout = false
sc.sceneNeedsRender = false
sc.imageUpdated = true
sc.setFlag(false, sceneNeedsLayout, sceneNeedsRender)
sc.setFlag(true, sceneImageUpdated)
pr.End()
case sc.sceneNeedsRender:
case sc.hasFlag(sceneNeedsRender):
pr := profile.Start("render")
sc.doNeedsRender()
sc.sceneNeedsRender = false
sc.imageUpdated = true
sc.setFlag(false, sceneNeedsRender)
sc.setFlag(true, sceneImageUpdated)
pr.End()
default:
return false
}

if sc.showIter == sceneShowIters { // end of first pass
sc.showIter++
if !sc.prefSizing {
if !sc.hasFlag(scenePrefSizing) {
sc.Events.activateStartFocus()
}
}
Expand All @@ -232,8 +229,8 @@ func (sc *Scene) doUpdate() bool {
// is first drawn or resized, or during rebuild,
// once the full sizing information is available.
func (sc *Scene) updateScene() {
sc.updating = true // prevent rendering
defer func() { sc.updating = false }()
sc.setFlag(true, sceneUpdating) // prevent rendering
defer func() { sc.setFlag(false, sceneUpdating) }()

sc.UpdateTree()
}
Expand All @@ -242,11 +239,11 @@ func (sc *Scene) updateScene() {
// This is needed whenever the window geometry, DPI,
// etc is updated, which affects styling.
func (sc *Scene) applyStyleScene() {
sc.updating = true // prevent rendering
defer func() { sc.updating = false }()
sc.setFlag(true, sceneUpdating) // prevent rendering
defer func() { sc.setFlag(false, sceneUpdating) }()

sc.StyleTree()
sc.needsLayout = true
sc.setFlag(true, sceneNeedsLayout)
}

// doRebuild does the full re-render and RenderContext Rebuild flag
Expand All @@ -262,16 +259,16 @@ func (sc *Scene) doRebuild() {
// initSz is the initial size -- e.g., size of screen.
// Used for auto-sizing windows.
func (sc *Scene) prefSize(initSz image.Point) image.Point {
sc.updating = true // prevent rendering
defer func() { sc.updating = false }()
sc.setFlag(true, sceneUpdating) // prevent rendering
defer func() { sc.setFlag(false, sceneUpdating) }()

sc.prefSizing = true
sc.setFlag(true, scenePrefSizing)
sc.updateScene()
sc.applyStyleScene()
sc.layoutScene()
sz := &sc.Geom.Size
psz := sz.Actual.Total
sc.prefSizing = false
sc.setFlag(false, scenePrefSizing)
sc.showIter = 0
return psz.ToPointFloor()
}
Expand All @@ -288,8 +285,8 @@ func (wb *WidgetBase) PushBounds() bool {
if wb == nil || wb.This == nil {
return false
}
wb.needsRender = false // done!
if !wb.IsVisible() { // checks deleted etc
wb.setFlag(false, widgetNeedsRender) // done!
if !wb.IsVisible() { // checks deleted etc
return false
}
if wb.Geom.TotalBBox.Empty() {
Expand All @@ -304,12 +301,12 @@ func (wb *WidgetBase) PushBounds() bool {
return false
}
if len(pc.BoundsStack) == 0 && wb.Parent != nil {
wb.firstRender = true
wb.setFlag(true, widgetFirstRender)
// push our parent's bounds if we are the first to render
pw := wb.parentWidget()
pc.PushBoundsGeom(pw.Geom.TotalBBox, pw.Styles.Border.Radius.Dots())
} else {
wb.firstRender = false
wb.setFlag(false, widgetFirstRender)
}
pc.PushBoundsGeom(wb.Geom.TotalBBox, wb.Styles.Border.Radius.Dots())
pc.Defaults() // start with default values
Expand Down Expand Up @@ -360,9 +357,9 @@ func (wb *WidgetBase) PopBounds() {
}

pc.PopBounds()
if wb.firstRender {
if wb.hasFlag(widgetFirstRender) {
pc.PopBounds()
wb.firstRender = false
wb.setFlag(false, widgetFirstRender)
}
}

Expand Down
Loading

0 comments on commit a6c3cd0

Please sign in to comment.