automation line drag: fix crash during segment drags

a drag on a segment without adjacent points would crash because we never
set the _grab_button for the Drag, so the LineDrag object never gets deleted
on mouse-up. This leaves a dangling reversible command, which will then
cause an assert(false) crash in the next Editor::begin_reversible_command()
This commit is contained in:
Paul Davis 2022-10-26 16:55:27 -06:00
parent 83ad0a10b5
commit 44f169bc56
2 changed files with 41 additions and 3 deletions

View file

@ -306,6 +306,12 @@ Drag::swap_grab (ArdourCanvas::Item* new_item, Gdk::Cursor* cursor, uint32_t /*t
_item->grab (); _item->grab ();
} }
void
Drag::set_grab_button_anyway (GdkEvent* ev)
{
_grab_button = ev->button.button;
}
void void
Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor) Drag::start_grab (GdkEvent* event, Gdk::Cursor *cursor)
{ {
@ -4830,10 +4836,19 @@ LineDrag::LineDrag (Editor* e, ArdourCanvas::Item* i)
, _cumulative_y_drag (0) , _cumulative_y_drag (0)
, _before (0) , _before (0)
, _after (0) , _after (0)
, have_command (false)
{ {
DEBUG_TRACE (DEBUG::Drags, "New LineDrag\n"); DEBUG_TRACE (DEBUG::Drags, "New LineDrag\n");
} }
LineDrag::~LineDrag ()
{
if (have_command) {
_editor->abort_reversible_command ();
have_command = false;
}
}
void void
LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
{ {
@ -4853,8 +4868,15 @@ LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/)
samplecnt_t const sample_within_region = (samplecnt_t) floor (mx * _editor->samples_per_pixel); samplecnt_t const sample_within_region = (samplecnt_t) floor (mx * _editor->samples_per_pixel);
if (!_line->control_points_adjacent (sample_within_region, _before, _after)) { if (!_line->control_points_adjacent (sample_within_region, _before, _after)) {
/* no adjacent points */ /* no adjacent points
*
* Will not grab, but must set grab button so that we can end
* the drag properly.
*/
set_grab_button_anyway (event);
return; return;
} }
@ -4896,9 +4918,9 @@ LineDrag::motion (GdkEvent* event, bool first_move)
if (first_move) { if (first_move) {
float const initial_fraction = 1.0 - (_fixed_grab_y / _line->height()); float const initial_fraction = 1.0 - (_fixed_grab_y / _line->height());
_editor->begin_reversible_command (_("automation range move")); _editor->begin_reversible_command (_("automation range move"));
_line->start_drag_line (_before, _after, initial_fraction); _line->start_drag_line (_before, _after, initial_fraction);
have_command = true;
} }
/* we are ignoring x position for this drag, so we can just pass in anything */ /* we are ignoring x position for this drag, so we can just pass in anything */
@ -4914,12 +4936,17 @@ LineDrag::finished (GdkEvent* event, bool movement_occurred)
if (movement_occurred) { if (movement_occurred) {
motion (event, false); motion (event, false);
_line->end_drag (false, 0); _line->end_drag (false, 0);
if (have_command) {
_editor->commit_reversible_command (); _editor->commit_reversible_command ();
have_command = false;
}
} else { } else {
/* add a new control point on the line */ /* add a new control point on the line */
AutomationTimeAxisView* atv; AutomationTimeAxisView* atv;
_editor->begin_reversible_command (_("add automation point"));
if ((atv = dynamic_cast<AutomationTimeAxisView*>(_editor->clicked_axisview)) != 0) { if ((atv = dynamic_cast<AutomationTimeAxisView*>(_editor->clicked_axisview)) != 0) {
timepos_t where = grab_time (); timepos_t where = grab_time ();
@ -4936,6 +4963,8 @@ LineDrag::finished (GdkEvent* event, bool movement_occurred)
arv->add_gain_point_event (&arv->get_gain_line()->grab_item(), event, false); arv->add_gain_point_event (&arv->get_gain_line()->grab_item(), event, false);
} }
} }
_editor->commit_reversible_command ();
} }
} }
@ -4943,6 +4972,11 @@ void
LineDrag::aborted (bool) LineDrag::aborted (bool)
{ {
_line->reset (); _line->reset ();
if (have_command) {
_editor->abort_reversible_command ();
have_command = false;
}
} }
FeatureLineDrag::FeatureLineDrag (Editor* e, ArdourCanvas::Item* i) FeatureLineDrag::FeatureLineDrag (Editor* e, ArdourCanvas::Item* i)

View file

@ -172,6 +172,8 @@ public:
bool was_double_click() const { return _was_double_click; } bool was_double_click() const { return _was_double_click; }
void set_double_click (bool yn) { _was_double_click = yn; } void set_double_click (bool yn) { _was_double_click = yn; }
void set_grab_button_anyway (GdkEvent*);
/** Called to start a grab of an item. /** Called to start a grab of an item.
* @param e Event that caused the grab to start. * @param e Event that caused the grab to start.
* @param c Cursor to use, or 0. * @param c Cursor to use, or 0.
@ -1156,6 +1158,7 @@ class LineDrag : public Drag
{ {
public: public:
LineDrag (Editor *e, ArdourCanvas::Item *i); LineDrag (Editor *e, ArdourCanvas::Item *i);
~LineDrag ();
void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool); void motion (GdkEvent *, bool);
@ -1174,6 +1177,7 @@ private:
double _cumulative_y_drag; double _cumulative_y_drag;
uint32_t _before; uint32_t _before;
uint32_t _after; uint32_t _after;
bool have_command;
}; };
/** Transient feature line drags*/ /** Transient feature line drags*/