- synchronize_platform_window is now called prior to the first redraw.
This allows the `visible` attribute to be changed from false to true.
- Some window attributes are automatically set based on the incoming
dynamic.
- Some initial window values are delayed until after the first layout to
minimze "noisy" values.
All of these changes now allow a window that is resize_to_fit to be
initially hidden and show itself centered after being initially resized
without any flashing or on-screen movement/resizing.
Removing widgets would affect the visual order, and sometimes nodes just
aren't available anymore. It might be that this should be cleaned up
more aggressively during widget removal, but by ignoring the removed
nodes, the code just becomes more resilliant to similar edge cases in
the future.
During the change callback process, unlocked is called to allow the
change callbacks to run while the dynamic is unlocked. The error with
the previous version of this code is that the during_callback_state was
always overwritten when being returned. The problem is that another
thread could currently have the mutex locked and could have stored its
own state -- which can happen if two threads are both trying to invoke
change callbacks at the same time.
By moving the state saving and reloading to only happen when the mutex
guard is acquired, we can ensure that interleaving threads will work
correctly.
Refs #153
This turned out to be "needed" by the debug window due to how dynamic
locking was nested when a for_each call was being invoked. To keep the
code simple, for_each_subsequent was added.
I'm not sure exactly what caused this that other simpler cases were not,
but essentially nodes were already removed once by the time this loop is
evaluated, so we can skip adding them back to the list again.