- 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.
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.
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.
Closes#138
This implementation works around most of the locking issues that arose
the first few times I tried fixing this. Unfortunately it's been just
long enough for me to forget how I triggered some catastrophic issues in
the past, but all of the current examples that would invoke this
behavior continue to work, and some of the side projects that have some
weird usages also still work.