The TransportFSM is now responsible for deciding what to do at all transport state transitions. The Session (via the TransportAPI) merely
provides mechanism (locate, start, stop, set_speed). Default and most recent speed requests are managed by the TransportFSM too
This fixes another deadlock calling send_change with the
Playlist's RegionWriteLock held.
In this case due to "MIDI region copies are independent"
when duplicating MIDI regions.
```
ARDOUR::Region::send_change ()
PBD::Stateful::apply_changes ()
ARDOUR::RegionFactory::create ()
ARDOUR::RegionFactory::create ()
ARDOUR::MidiRegion::clone ()
ARDOUR::RegionFactory::create ()
ARDOUR::Playlist::duplicate ()
```
This fixes various issues with signal emission(s) when creating
regions from withing playlist operations.
eg. Playlist::duplicate() takes RegionWriteLock() and then calls
RegionFactory::create().
see also 6a82aa392c
This is an initial work-around for signal emission with
Playlist:region_lock held:
Playlist::duplicate() takes RegionWriteLock() and then calls
RegionFactory::create(). The newly created region does NOT have
property-changes suspended, and the RegionFactory can change
region-properties which results in signal-emission.
This in turn can lead to a call Editor::session_gui_extents()
-> ARDOUR::Playlist::get_extent() -> Playlist::RegionReadLock
which deadlocks: https://pastebin.com/84rSbsA3
Eventually we need a mechanism to create regions with
->suspend_property_changes() and add it to the playlist's
thawlist (pass a thawlist to the region-factory).
RegionInsertDrag or Consolidate Range or any other operation
calling Playlist::add_region() previously triggered RangesMoved()
which resulted in DiskReader::move_processor_automation()
NB. insert + ripple still moves automation correctly.
Playlist changes do not include region-property changes.
When inserting a region, position(s) of other Regions may
change and those changes have to be recorded explicitly (for now).
see also RegionRippleDrag.
The undo command needs to be started before calling
playlist->add_region() because that may move automation
or include ripple changes. see the following backtrace:
```
UndoTransaction::add_command
ARDOUR::DiskReader::move_processor_automation
ARDOUR::Route::foreach_processor
ARDOUR::DiskReader::playlist_ranges_moved
ARDOUR::Playlist::flush_notifications
ARDOUR::Playlist::RegionWriteLock::~RegionWriteLock
ARDOUR::Playlist::add_region
Editor::bounce_range_selection
```
Except. it seems automation is moved incorrectly in this case..
TmpFileRt::get_samples_written() returns the number of
samples written *to disk*. It is only valid after the FileFlushed
signal is emitted.
This fixes an assert() with Limiter and Analyzer being configured
with a too low total sample-count, leading to an overflow in
the analysis graph array.
Some plugin UIs, particularly those that cannot be resized
unset `autoresizesSubviews`. Since the plugin-view is re-parented,
the host has to directly set the view's size.
However some plugins have multiple child views, apparently
for off-screen pixmaps (e.g. UAD plugins). Those additional
should not be resized (or re-stacked).
e.g.
Reason-Rack
view 0x7fe27e44e570 @ 0, 33 834 x 804
view 0x7fe288aa3770 @ 278, 268 278 x 268
UAD Tube-tech
view 0x7fe270a9cbf0 @ 0, 33 1160 x 374
view 0x7fe28883d030 @ 0, 0 1160 x 374
view 0x7fe2888546e0 @ 0, 0 1160 x 24
see also aef366c156https://discourse.ardour.org/t/uad-plugin-will-not-load-shows-as-expired-when-its-not/105756/5?u=x42
Preferences is a tabbable, a leftover artifact of when it was, in fact, intended to be a tabbable. Rather than
re-engineer this right now, add a key event handler so that Primary-w works for this just like other dialogs
1) if there is no current dialog, allow some other window to handle the keyboard event
2) make the binding (which is hard coded) visible as static members of Keyboard