mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 09:55:40 +00:00
app: only perform actions and apply options on wakeups
In particular, avoid a race between the setup of the platform window returned by NewWindow and Window.Perform. Fixes: https://todo.sr.ht/~eliasnaur/gio/405 Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+21
-13
@@ -62,6 +62,10 @@ type Window struct {
|
|||||||
closing bool
|
closing bool
|
||||||
// dead is closed when the window is destroyed.
|
// dead is closed when the window is destroyed.
|
||||||
dead chan struct{}
|
dead chan struct{}
|
||||||
|
// options are the options waiting to be applied.
|
||||||
|
options []Option
|
||||||
|
// actions are the actions waiting to be performed.
|
||||||
|
actions system.Action
|
||||||
|
|
||||||
stage system.Stage
|
stage system.Stage
|
||||||
animating bool
|
animating bool
|
||||||
@@ -322,9 +326,8 @@ func (w *Window) Invalidate() {
|
|||||||
|
|
||||||
// Option applies the options to the window.
|
// Option applies the options to the window.
|
||||||
func (w *Window) Option(opts ...Option) {
|
func (w *Window) Option(opts ...Option) {
|
||||||
w.driverDefer(func(d driver) {
|
w.options = append(w.options, opts...)
|
||||||
d.Configure(opts)
|
w.wakeup()
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadClipboard initiates a read of the clipboard in the form
|
// ReadClipboard initiates a read of the clipboard in the form
|
||||||
@@ -435,6 +438,16 @@ func (c *callbacks) Event(e event.Event) bool {
|
|||||||
c.waitEvents = c.waitEvents[:len(c.waitEvents)-1]
|
c.waitEvents = c.waitEvents[:len(c.waitEvents)-1]
|
||||||
handled = c.w.processEvent(c.d, e)
|
handled = c.w.processEvent(c.d, e)
|
||||||
}
|
}
|
||||||
|
if _, iswakeup := e.(wakeupEvent); iswakeup {
|
||||||
|
if len(c.w.options) > 0 {
|
||||||
|
c.d.Configure(c.w.options)
|
||||||
|
c.w.options = nil
|
||||||
|
}
|
||||||
|
if c.w.actions != 0 {
|
||||||
|
c.d.Perform(c.w.actions)
|
||||||
|
c.w.actions = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
c.w.updateState(c.d)
|
c.w.updateState(c.d)
|
||||||
if c.w.closing {
|
if c.w.closing {
|
||||||
c.w.closing = false
|
c.w.closing = false
|
||||||
@@ -980,15 +993,14 @@ func (w *Window) decorate(d driver, e system.FrameEvent, o *op.Ops) image.Point
|
|||||||
|
|
||||||
// Perform the actions on the window.
|
// Perform the actions on the window.
|
||||||
func (w *Window) Perform(actions system.Action) {
|
func (w *Window) Perform(actions system.Action) {
|
||||||
var options []Option
|
|
||||||
walkActions(actions, func(action system.Action) {
|
walkActions(actions, func(action system.Action) {
|
||||||
switch action {
|
switch action {
|
||||||
case system.ActionMinimize:
|
case system.ActionMinimize:
|
||||||
options = append(options, Minimized.Option())
|
w.options = append(w.options, Minimized.Option())
|
||||||
case system.ActionMaximize:
|
case system.ActionMaximize:
|
||||||
options = append(options, Maximized.Option())
|
w.options = append(w.options, Maximized.Option())
|
||||||
case system.ActionUnmaximize:
|
case system.ActionUnmaximize:
|
||||||
options = append(options, Windowed.Option())
|
w.options = append(w.options, Windowed.Option())
|
||||||
case system.ActionClose:
|
case system.ActionClose:
|
||||||
w.closing = true
|
w.closing = true
|
||||||
default:
|
default:
|
||||||
@@ -996,12 +1008,8 @@ func (w *Window) Perform(actions system.Action) {
|
|||||||
}
|
}
|
||||||
actions &^= action
|
actions &^= action
|
||||||
})
|
})
|
||||||
w.driverDefer(func(d driver) {
|
w.actions = w.actions | actions
|
||||||
if len(options) > 0 {
|
w.wakeup()
|
||||||
d.Configure(options)
|
|
||||||
}
|
|
||||||
d.Perform(actions)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *queue) Events(k event.Tag) []event.Event {
|
func (q *queue) Events(k event.Tag) []event.Event {
|
||||||
|
|||||||
Reference in New Issue
Block a user