Applications can now manually call a screen redraw in a way that I think is thread safe
This commit is contained in:
parent
ea32b7899b
commit
05c448f058
@ -46,6 +46,11 @@ func (application *Application) Run () (
|
||||
return
|
||||
}
|
||||
|
||||
// Draw "commits" changes made in the buffer to the display.
|
||||
func (application *Application) Draw () {
|
||||
application.backend.Draw()
|
||||
}
|
||||
|
||||
// SetTitle sets the application's title. If in a window, it will appear as the
|
||||
// window's name.
|
||||
func (application *Application) SetTitle (title string) (err error) {
|
||||
|
@ -7,6 +7,7 @@ type Backend interface {
|
||||
Run (channel chan(Event))
|
||||
SetTitle (title string) (err error)
|
||||
SetIcon (icons []image.Image) (err error)
|
||||
Draw ()
|
||||
}
|
||||
|
||||
type BackendFactory func (application *Application) (backend Backend, err error)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package x
|
||||
|
||||
import "os"
|
||||
import "sync"
|
||||
import "image"
|
||||
import "image/draw"
|
||||
import "golang.org/x/image/font"
|
||||
@ -28,6 +29,8 @@ type Backend struct {
|
||||
canvas *xgraphics.Image
|
||||
channel chan(stone.Event)
|
||||
|
||||
drawLock sync.Mutex
|
||||
|
||||
ping struct {
|
||||
before chan(struct { })
|
||||
after chan(struct { })
|
||||
@ -80,6 +83,17 @@ func (backend *Backend) Run (channel chan(stone.Event)) {
|
||||
}
|
||||
}
|
||||
|
||||
func (backend *Backend) Draw () {
|
||||
backend.drawLock.Lock()
|
||||
defer backend.drawLock.Unlock()
|
||||
|
||||
backend.drawCells(true)
|
||||
backend.canvas.XDraw()
|
||||
backend.canvas.XPaint(backend.window.Id)
|
||||
// FIXME use this instead once it works
|
||||
// backend.updateWindowAreas(...)
|
||||
}
|
||||
|
||||
func (backend *Backend) SetTitle (title string) (err error) {
|
||||
err = ewmh.WmNameSet(backend.connection, backend.window.Id, title)
|
||||
return
|
||||
@ -191,6 +205,9 @@ func (backend *Backend) calculateWindowSize () (x, y int) {
|
||||
}
|
||||
|
||||
func (backend *Backend) reallocateCanvas () {
|
||||
backend.drawLock.Lock()
|
||||
defer backend.drawLock.Unlock()
|
||||
|
||||
if backend.canvas != nil {
|
||||
backend.canvas.Destroy()
|
||||
}
|
||||
|
@ -8,8 +8,11 @@ import _ "image/png"
|
||||
import "git.tebibyte.media/sashakoshka/stone"
|
||||
import _ "git.tebibyte.media/sashakoshka/stone/backends/x"
|
||||
|
||||
var application = &stone.Application { }
|
||||
var currentTime = time.Time { }
|
||||
var tickPing = make(chan(struct { }))
|
||||
|
||||
func main () {
|
||||
application := &stone.Application { }
|
||||
application.SetTitle("hellorld")
|
||||
application.SetSize(12, 2)
|
||||
|
||||
@ -29,32 +32,51 @@ func main () {
|
||||
channel, err := application.Run()
|
||||
if err != nil { panic(err) }
|
||||
|
||||
currentTime := time.Time { }
|
||||
redraw()
|
||||
application.Draw()
|
||||
go tick()
|
||||
|
||||
for {
|
||||
event := <- channel
|
||||
switch event.(type) {
|
||||
case stone.EventQuit:
|
||||
os.Exit(0)
|
||||
select {
|
||||
case <- tickPing:
|
||||
redraw()
|
||||
application.Draw()
|
||||
|
||||
case event := <- channel:
|
||||
switch event.(type) {
|
||||
case stone.EventQuit:
|
||||
os.Exit(0)
|
||||
|
||||
case stone.EventResize:
|
||||
currentTime = time.Now()
|
||||
|
||||
application.ResetDot()
|
||||
fmt.Fprintln(application, "hellorld!")
|
||||
|
||||
hour := currentTime.Hour()
|
||||
minute := currentTime.Minute()
|
||||
second := currentTime.Second()
|
||||
|
||||
application.SetRune(0, 1, rune(hour / 10 + 48))
|
||||
application.SetRune(1, 1, rune(hour % 10 + 48))
|
||||
application.SetRune(2, 1, ':')
|
||||
application.SetRune(3, 1, rune(minute / 10 + 48))
|
||||
application.SetRune(4, 1, rune(minute % 10 + 48))
|
||||
application.SetRune(5, 1, ':')
|
||||
application.SetRune(6, 1, rune(second / 10 + 48))
|
||||
application.SetRune(7, 1, rune(second % 10 + 48))
|
||||
case stone.EventResize:
|
||||
redraw()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func redraw () {
|
||||
currentTime = time.Now()
|
||||
|
||||
application.ResetDot()
|
||||
fmt.Fprintln(application, "hellorld!")
|
||||
|
||||
hour := currentTime.Hour()
|
||||
minute := currentTime.Minute()
|
||||
second := currentTime.Second()
|
||||
|
||||
application.SetRune(0, 1, rune(hour / 10 + 48))
|
||||
application.SetRune(1, 1, rune(hour % 10 + 48))
|
||||
application.SetRune(2, 1, ':')
|
||||
application.SetRune(3, 1, rune(minute / 10 + 48))
|
||||
application.SetRune(4, 1, rune(minute % 10 + 48))
|
||||
application.SetRune(5, 1, ':')
|
||||
application.SetRune(6, 1, rune(second / 10 + 48))
|
||||
application.SetRune(7, 1, rune(second % 10 + 48))
|
||||
}
|
||||
|
||||
func tick () {
|
||||
for {
|
||||
tickPing <- struct { } { }
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user