X backend better handles expose events

Previously, when an expose event was recieved, the backend would
call Window.paste, converting RGBA image data to BGRA image data.
Now we only call Window.pushRegion with the bounds given to us by
the expose event(s). This speeds up window resizing significantly.
This commit is contained in:
2023-03-07 12:48:29 -05:00
parent 803812f9c9
commit 423e6869c0
4 changed files with 29 additions and 11 deletions

View File

@@ -1,5 +1,6 @@
package x
import "image"
import "git.tebibyte.media/sashakoshka/tomo/input"
import "git.tebibyte.media/sashakoshka/tomo/elements"
@@ -47,8 +48,8 @@ func (window *Window) handleExpose (
connection *xgbutil.XUtil,
event xevent.ExposeEvent,
) {
_ = window.compressExpose(*event.ExposeEvent)
window.redrawChildEntirely()
_, region := window.compressExpose(*event.ExposeEvent)
window.pushRegion(region)
}
func (window *Window) handleConfigureNotify (
@@ -234,7 +235,13 @@ func (window *Window) compressExpose (
firstEvent xproto.ExposeEvent,
) (
lastEvent xproto.ExposeEvent,
region image.Rectangle,
) {
region = image.Rect (
int(firstEvent.X), int(firstEvent.Y),
int(firstEvent.X + firstEvent.Width),
int(firstEvent.Y + firstEvent.Height))
window.backend.connection.Sync()
xevent.Read(window.backend.connection, false)
lastEvent = firstEvent
@@ -245,8 +252,12 @@ func (window *Window) compressExpose (
typedEvent, ok := untypedEvent.Event.(xproto.ExposeEvent)
if !ok { continue }
// FIXME: union all areas into the last event
if firstEvent.Window == typedEvent.Window {
region = region.Union (image.Rect (
int(typedEvent.X), int(typedEvent.Y),
int(typedEvent.X + typedEvent.Width),
int(typedEvent.Y + typedEvent.Height)))
lastEvent = typedEvent
defer func (index int) {
xevent.DequeueAt(window.backend.connection, index)

View File

@@ -12,6 +12,7 @@ import "git.tebibyte.media/sashakoshka/tomo/theme"
import "git.tebibyte.media/sashakoshka/tomo/config"
import "git.tebibyte.media/sashakoshka/tomo/canvas"
import "git.tebibyte.media/sashakoshka/tomo/elements"
// import "runtime/debug"
type Window struct {
backend *Backend
@@ -290,6 +291,7 @@ func (window *Window) childDrawCallback (region canvas.Canvas) {
func (window *Window) paste (canvas canvas.Canvas) (updatedRegion image.Rectangle) {
data, stride := canvas.Buffer()
bounds := canvas.Bounds().Intersect(window.xCanvas.Bounds())
// debug.PrintStack()
for x := bounds.Min.X; x < bounds.Max.X; x ++ {
for y := bounds.Min.Y; y < bounds.Max.Y; y ++ {
rgba := data[x + y * stride]