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
|
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
|
// SetTitle sets the application's title. If in a window, it will appear as the
|
||||||
// window's name.
|
// window's name.
|
||||||
func (application *Application) SetTitle (title string) (err error) {
|
func (application *Application) SetTitle (title string) (err error) {
|
||||||
|
@ -7,6 +7,7 @@ type Backend interface {
|
|||||||
Run (channel chan(Event))
|
Run (channel chan(Event))
|
||||||
SetTitle (title string) (err error)
|
SetTitle (title string) (err error)
|
||||||
SetIcon (icons []image.Image) (err error)
|
SetIcon (icons []image.Image) (err error)
|
||||||
|
Draw ()
|
||||||
}
|
}
|
||||||
|
|
||||||
type BackendFactory func (application *Application) (backend Backend, err error)
|
type BackendFactory func (application *Application) (backend Backend, err error)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package x
|
package x
|
||||||
|
|
||||||
import "os"
|
import "os"
|
||||||
|
import "sync"
|
||||||
import "image"
|
import "image"
|
||||||
import "image/draw"
|
import "image/draw"
|
||||||
import "golang.org/x/image/font"
|
import "golang.org/x/image/font"
|
||||||
@ -28,6 +29,8 @@ type Backend struct {
|
|||||||
canvas *xgraphics.Image
|
canvas *xgraphics.Image
|
||||||
channel chan(stone.Event)
|
channel chan(stone.Event)
|
||||||
|
|
||||||
|
drawLock sync.Mutex
|
||||||
|
|
||||||
ping struct {
|
ping struct {
|
||||||
before chan(struct { })
|
before chan(struct { })
|
||||||
after 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) {
|
func (backend *Backend) SetTitle (title string) (err error) {
|
||||||
err = ewmh.WmNameSet(backend.connection, backend.window.Id, title)
|
err = ewmh.WmNameSet(backend.connection, backend.window.Id, title)
|
||||||
return
|
return
|
||||||
@ -191,6 +205,9 @@ func (backend *Backend) calculateWindowSize () (x, y int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (backend *Backend) reallocateCanvas () {
|
func (backend *Backend) reallocateCanvas () {
|
||||||
|
backend.drawLock.Lock()
|
||||||
|
defer backend.drawLock.Unlock()
|
||||||
|
|
||||||
if backend.canvas != nil {
|
if backend.canvas != nil {
|
||||||
backend.canvas.Destroy()
|
backend.canvas.Destroy()
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,11 @@ import _ "image/png"
|
|||||||
import "git.tebibyte.media/sashakoshka/stone"
|
import "git.tebibyte.media/sashakoshka/stone"
|
||||||
import _ "git.tebibyte.media/sashakoshka/stone/backends/x"
|
import _ "git.tebibyte.media/sashakoshka/stone/backends/x"
|
||||||
|
|
||||||
|
var application = &stone.Application { }
|
||||||
|
var currentTime = time.Time { }
|
||||||
|
var tickPing = make(chan(struct { }))
|
||||||
|
|
||||||
func main () {
|
func main () {
|
||||||
application := &stone.Application { }
|
|
||||||
application.SetTitle("hellorld")
|
application.SetTitle("hellorld")
|
||||||
application.SetSize(12, 2)
|
application.SetSize(12, 2)
|
||||||
|
|
||||||
@ -29,15 +32,29 @@ func main () {
|
|||||||
channel, err := application.Run()
|
channel, err := application.Run()
|
||||||
if err != nil { panic(err) }
|
if err != nil { panic(err) }
|
||||||
|
|
||||||
currentTime := time.Time { }
|
redraw()
|
||||||
|
application.Draw()
|
||||||
|
go tick()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
event := <- channel
|
select {
|
||||||
|
case <- tickPing:
|
||||||
|
redraw()
|
||||||
|
application.Draw()
|
||||||
|
|
||||||
|
case event := <- channel:
|
||||||
switch event.(type) {
|
switch event.(type) {
|
||||||
case stone.EventQuit:
|
case stone.EventQuit:
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
|
||||||
case stone.EventResize:
|
case stone.EventResize:
|
||||||
|
redraw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func redraw () {
|
||||||
currentTime = time.Now()
|
currentTime = time.Now()
|
||||||
|
|
||||||
application.ResetDot()
|
application.ResetDot()
|
||||||
@ -55,6 +72,11 @@ func main () {
|
|||||||
application.SetRune(5, 1, ':')
|
application.SetRune(5, 1, ':')
|
||||||
application.SetRune(6, 1, rune(second / 10 + 48))
|
application.SetRune(6, 1, rune(second / 10 + 48))
|
||||||
application.SetRune(7, 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