ref: dfa5cf23ef37674aadba82bb9b680f8086669374
parent: b55ebe59d1db6178d010f1ee44969bfa89988aa6
author: Philip Silva <[email protected]>
date: Thu Mar 4 15:49:13 EST 2021
render/download outside of main loop
--- a/browser/browser.go
+++ b/browser/browser.go
@@ -366,7 +366,10 @@
return
}
- b.submit(f.DomSubtree, n.DomSubtree)
+ if !b.loading {
+ b.loading = true
+ go b.submit(f.DomSubtree, n.DomSubtree)
+ }
return duit.Event{
Consumed: true,
@@ -404,7 +407,10 @@
if f == nil {
return
}
- browser.submit(f.DomSubtree, nil)
+ if !browser.loading {
+ browser.loading = true
+ go browser.submit(f.DomSubtree, nil)
+ }
return duit.Event{
Consumed: true,
NeedLayout: true,
@@ -1240,6 +1246,7 @@
Website *Website
StatusBar *duit.Label
LocationField *duit.Field
+ loading bool
client *http.Client
Download func(done chan int) chan string
}
@@ -1265,7 +1272,8 @@
Text: initUrl,
Font: Style.Font(),
Keys: func(k rune, m draw.Mouse) (e duit.Event) {
- if k == EnterKey {
+ if k == EnterKey && !b.loading {
+ b.loading = true
a := b.LocationField.Text
if !strings.HasPrefix(strings.ToLower(a), "http") {
a = "http://" + a
@@ -1336,7 +1344,8 @@
}
func (b *Browser) Back() (e duit.Event) {
- if len(b.History.urls) > 0 {
+ if len(b.History.urls) > 0 && !b.loading {
+ b.loading = true
b.History.Back()
b.LocationField.Text = b.History.URL().String()
b.LoadUrl(b.History.URL())
@@ -1347,8 +1356,11 @@
func (b *Browser) SetAndLoadUrl(u *url.URL) func() duit.Event {
return func() duit.Event {
- b.LocationField.Text = u.String()
- b.LoadUrl(u)
+ if !b.loading {
+ b.loading = true
+ b.LocationField.Text = u.String()
+ b.LoadUrl(u)
+ }
return duit.Event{
Consumed: true,
@@ -1366,7 +1378,15 @@
dui.Render()
}
+// LoadUrl after from location field,
func (b *Browser) LoadUrl(url *url.URL) (e duit.Event) {
+ go b.loadUrl(url)
+ e.Consumed = true
+
+ return
+}
+
+func (b *Browser) loadUrl(url *url.URL) {
buf, contentType, err := b.get(url, true)
if err != nil {
log.Errorf("error loading %v: %v", url, err)
@@ -1374,6 +1394,7 @@
err = er
}
b.showBodyMessage(err.Error())
+ b.loading = false
return
}
if contentType.IsHTML() || contentType.IsPlain() || contentType.IsEmpty() {
@@ -1384,24 +1405,19 @@
log.Infof("Download unhandled content type: %v", contentType)
- go func() {
- fn := <-res
+ fn := <-res
- if fn != "" {
- log.Infof("Download to %v", fn)
- f, _ := os.Create(fn)
- f.Write(buf)
- f.Close()
- }
-
+ if fn != "" {
+ log.Infof("Download to %v", fn)
+ f, _ := os.Create(fn)
+ f.Write(buf)
+ f.Close()
+ }
+ dui.Call <- func() {
done <- 1
- }()
+ b.loading = false
+ }
}
- return duit.Event{
- Consumed: true,
- NeedLayout: true,
- NeedDraw: true,
- }
}
func (b *Browser) render(buf []byte) {
@@ -1415,19 +1431,22 @@
b.Website.html = string(buf) // TODO: correctly interpret UTF8
b.Website.layout(b, InitialLayout)
- dui.MarkLayout(dui.Top.UI)
- dui.MarkDraw(dui.Top.UI)
- TraverseTree(b.Website.UI, func(ui duit.UI) {
- // just checking for nil elements. That would be a bug anyway and it's better
- // to notice it before it gets rendered
-
- if ui == nil {
- panic("nil")
- }
- })
- PrintTree(b.Website.UI)
log.Printf("Render...")
- dui.Render()
+ dui.Call <- func() {
+ TraverseTree(b.Website.UI, func(ui duit.UI) {
+ // just checking for nil elements. That would be a bug anyway and it's better
+ // to notice it before it gets rendered
+
+ if ui == nil {
+ panic("nil")
+ }
+ })
+ PrintTree(b.Website.UI)
+ dui.MarkLayout(dui.Top.UI)
+ dui.MarkDraw(dui.Top.UI)
+ dui.Render()
+ b.loading = false
+ }
log.Printf("Rendering done")
}
@@ -1449,26 +1468,29 @@
if dui == nil || dui.Top.UI == nil {
return
}
- if msg == "" {
- b.StatusBar.Text = ""
- } else {
- b.StatusBar.Text += msg + "\n"
- }
- if emptyBody {
- b.Website.UI = &duit.Label{}
- }
- // Workaround to clear background to white for websites that don't use the whole window
- white, err := dui.Display.AllocImage(image.Rect(0, 0, 10, 10), draw.ARGB32, true, 0xffffffff)
- if err != nil {
- log.Errorf("%v", err)
+ dui.Call <- func() {
+ if msg == "" {
+ b.StatusBar.Text = ""
+ } else {
+ b.StatusBar.Text += msg + "\n"
+ }
+ if emptyBody {
+ b.Website.UI = &duit.Label{}
+ }
+
+ // Workaround to clear background to white for websites that don't use the whole window
+ white, err := dui.Display.AllocImage(image.Rect(0, 0, 10, 10), draw.ARGB32, true, 0xffffffff)
+ if err != nil {
+ log.Errorf("%v", err)
+ }
+ tmp := dui.Background
+ dui.Background = white
+ dui.MarkLayout(dui.Top.UI)
+ dui.MarkDraw(dui.Top.UI)
+ dui.Render()
+ dui.Background = tmp
}
- tmp := dui.Background
- dui.Background = white
- dui.MarkLayout(dui.Top.UI)
- dui.MarkDraw(dui.Top.UI)
- dui.Render()
- dui.Background = tmp
}
func (b *Browser) get(uri *url.URL, isNewOrigin bool) (buf []byte, contentType opossum.ContentType, err error) {
--- a/cmd/browse/main.go
+++ b/cmd/browse/main.go
@@ -70,50 +70,52 @@
func confirm(b *browser.Browser, text, value string) chan string {
res := make(chan string)
-
- f := &duit.Field{
- Text: value,
- }
- dui.Top.UI = &duit.Box{
- Kids: duit.NewKids(
- &duit.Grid{
- Columns: 3,
- Padding: duit.NSpace(3, duit.SpaceXY(5, 3)),
- Halign: []duit.Halign{duit.HalignLeft, duit.HalignLeft, duit.HalignRight},
- Valign: []duit.Valign{duit.ValignMiddle, duit.ValignMiddle, duit.ValignMiddle},
- Kids: duit.NewKids(
- &duit.Button{
- Text: "Ok",
- Font: browser.Style.Font(),
- Click: func() (e duit.Event) {
- res <- f.Text
- e.Consumed = true
- return
+ dui.Call <- func() {
+ f := &duit.Field{
+ Text: value,
+ }
+
+ dui.Top.UI = &duit.Box{
+ Kids: duit.NewKids(
+ &duit.Grid{
+ Columns: 3,
+ Padding: duit.NSpace(3, duit.SpaceXY(5, 3)),
+ Halign: []duit.Halign{duit.HalignLeft, duit.HalignLeft, duit.HalignRight},
+ Valign: []duit.Valign{duit.ValignMiddle, duit.ValignMiddle, duit.ValignMiddle},
+ Kids: duit.NewKids(
+ &duit.Button{
+ Text: "Ok",
+ Font: browser.Style.Font(),
+ Click: func() (e duit.Event) {
+ res <- f.Text
+ e.Consumed = true
+ return
+ },
},
- },
- &duit.Button{
- Text: "Abort",
- Font: browser.Style.Font(),
- Click: func() (e duit.Event) {
- res <- ""
- e.Consumed = true
- return
+ &duit.Button{
+ Text: "Abort",
+ Font: browser.Style.Font(),
+ Click: func() (e duit.Event) {
+ res <- ""
+ e.Consumed = true
+ return
+ },
},
- },
- f,
- ),
- },
- &duit.Label{
- Text: text,
- },
- ),
+ f,
+ ),
+ },
+ &duit.Label{
+ Text: text,
+ },
+ ),
+ }
+ log.Printf("Render.....")
+ dui.MarkLayout(dui.Top.UI)
+ dui.MarkDraw(dui.Top.UI)
+ dui.Render()
+ log.Printf("Rendering done")
}
- log.Printf("Render.....")
- dui.MarkLayout(dui.Top.UI)
- dui.MarkDraw(dui.Top.UI)
- dui.Render()
- log.Printf("Rendering done")
return res
}
@@ -135,7 +137,9 @@
b.Download = func(done chan int) chan string {
go func() {
<-done
- render(b)
+ dui.Call <- func() {
+ render(b)
+ }
}()
return confirm(b, fmt.Sprintf("Download %v", b.URL()), "/download.file")
}