Consistently use Tertiary for Group Override on all platforms (and be consistent about it)
Consistently use Primary-mod for Momentary on all platforms (partially reverts 47932f)
Primary modifier is used for fine-adjust on knobs and sliders, with no analogous operation on switches.
The pre-nutemo code used fmod() to calculate the offset into the bar:
`bar_fract = fmod (barbeat, 1.0); // fraction of bar elapsed`
with nutempo, beats start at 1, and the tick offset must also be
taken into account.
The bug was introduced in f67029bd0
PortIndex is sorted by name, and uses port-name as unique identifier.
Ports can be re-named concurrently with processing.
::set_port_name() updates the RCU in the background. The engine
may concurrently process with an old RCU reader value.
In this case valid_port() failed in the process-callback.
and ::get_buffer() returned NULL
We need to delete all existing region views before we redisplay the track. This
was removed as part of an "experimental performance optimization" in 4f7a4cd233
but playlist switching is a rare and non-performance limited operation
is_button2_event() was used to detect the user's desire for a
momentary-click on some buttons (mute, solo, mixer scenes)
is_momentary_push_event() disambiguates this action from is_button2_event()
for the special case of momentary, we can drop the workarounds for
the lack of middle-mouse buttons on Mac, and instead just use
shift+left-click on all platforms.
Note position in samples must be calculated using absolute position
on the timeline. Otherwise the tempo-map is not applied correctly.
Previously this caused issues since the position was first
offset back by _region->position() - time relative to region left
edge - and then the tempo-map was applied.
Another solution identically would be:
(note_start + session_source_start).samples() - _region->position().samples()
When TempoMap::copy_points() is called, the new points are intended to belong
to the (nascent) new map. But the copy constructor for the points leaves the
_map member of a Point unchanged, and so the new points reference the old
map (forever!). ::copy_points() must reset each Point to reference the new map.
Refactored the object that has the _map member, so that we could limit access
to its ::set_map() method to TempoMap.
Since we're reconnecting visible marker objects with a new map, there's a good
chance that the map will contain map points that don't correspond to the map
points currently referenced by those markers. Thus, tests for address
equivalence will often fail.
Instead, repeat what has been done elsewhere and use the heuristic that we only
allow one point of a given type at the same superclock position.
Note that ::find_all_sources_across_snapshots() finds and retains
all sources in the SourceList of other snapshots regardless
if they are used in those snapshots.
A route may be processed before latency-compensation callback
sets the route's output_latency. In this case a random offset
was added to the start/end position (via latency_offset).
UIConfig insert-at-position saves/restores the enum as integer.
This is used directly as parameter for insert_at_combo.set_active().
For this to work, the enum needs to match the order of elements
in the dropdown.
It would be preferable to register the enum, and map the
dropdown entries, but for now this does the trick, without
breaking existing UIConfigs.
PresentationInfo::Change (Properties::selected) is emitted and
handled before Mixer_UI::add_routes() is called. At that point
in time the MixerStrip(s) to be selected may not exist.
Visual selection state was lost.
Furthermore move_stripable_into_view() calling translate_coordinates()
only works after GTK has completed the resize operation.
This lead to the mixer scrolling back to the left edge when creating
new tracks.
Also each selection change caused all tracks to be re-packed.
Now redisplay_track_list() is only called if visibility or order
changes. This signficanly improves performance with large sessions.