app: don't panic when the client doesn't call FrameEvent.Frame

Fixes: https://todo.sr.ht/~eliasnaur/gio/396
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2022-04-14 09:16:49 +02:00
parent 6a14269682
commit dc25afda07
+12 -9
View File
@@ -674,20 +674,19 @@ func (w *Window) destroyGPU() {
} }
// waitFrame waits for the client to either call FrameEvent.Frame // waitFrame waits for the client to either call FrameEvent.Frame
// or to continue event handling. It returns whether the client // or to continue event handling.
// called Frame or not. func (w *Window) waitFrame(d driver) *op.Ops {
func (w *Window) waitFrame(d driver) (*op.Ops, chan<- struct{}) {
for { for {
select { select {
case f := <-w.driverFuncs: case f := <-w.driverFuncs:
f(d) f(d)
case frame := <-w.frames: case frame := <-w.frames:
// The client called FrameEvent.Frame. // The client called FrameEvent.Frame.
return frame, w.frameAck return frame
case w.out <- ackEvent: case w.out <- ackEvent:
// The client ignored FrameEvent and continued processing // The client ignored FrameEvent and continued processing
// events. // events.
return nil, nil return nil
case <-w.immediateRedraws: case <-w.immediateRedraws:
// Invalidate was called during frame processing. // Invalidate was called during frame processing.
w.setNextFrame(time.Time{}) w.setNextFrame(time.Time{})
@@ -803,10 +802,14 @@ func (w *Window) processEvent(d driver, e event.Event) {
size := e2.Size // save the initial window size as the decorations will change it. size := e2.Size // save the initial window size as the decorations will change it.
e2.FrameEvent.Size = w.decorate(d, e2.FrameEvent, wrapper) e2.FrameEvent.Size = w.decorate(d, e2.FrameEvent, wrapper)
w.out <- e2.FrameEvent w.out <- e2.FrameEvent
frame, signal := w.waitFrame(d) frame := w.waitFrame(d)
cl := clip.Rect(image.Rectangle{Max: e2.FrameEvent.Size}).Push(wrapper) var signal chan<- struct{}
ops.AddCall(&wrapper.Internal, &frame.Internal, ops.PC{}, ops.PCFor(&frame.Internal)) if frame != nil {
cl.Pop() signal = w.frameAck
cl := clip.Rect(image.Rectangle{Max: e2.FrameEvent.Size}).Push(wrapper)
ops.AddCall(&wrapper.Internal, &frame.Internal, ops.PC{}, ops.PCFor(&frame.Internal))
cl.Pop()
}
err := w.validateAndProcess(d, size, e2.Sync, wrapper, signal) err := w.validateAndProcess(d, size, e2.Sync, wrapper, signal)
if err != nil { if err != nil {
w.destroyGPU() w.destroyGPU()