Dragging dynamics symbols from an empty measure into a multimeasure rest shuts down the program.

• Nov 29, 2020 - 02:02
Reported version
3.5
Type
Functional
Frequency
Once
Severity
S2 - Critical
Reproducibility
Always
Status
closed
Regression
No
Workaround
Yes
Project

To Reproduce:

in the attached score, in the view for the violin part, attempt to drag the "mp" dynamic, as shown in the screenshot. MuseScore crashes when you attempt to do this.

OS: macOS 10.16, Arch.: x86_64, MuseScore version (64-bit): 3.5.2.312126096, revision: 465e7b6

Note: I was able to work around the issue by deleting the dynamic symbol and adding it where I wanted it. However, this was after MuseScore had crashed twice when I tried moving the symbol.

Attachment Size
screenshot.png 93.98 KB
crash_info.txt 133.45 KB
OperationCobra.mscz 81.72 KB

Comments

Title Crash when dragging dynamic symbol Dragging dynamics symbols from an empty measure into a multimeasure rest shuts down the program.

OS: Windows 10 (10.0), Arch.: x86_64, MuseScore version (64-bit): 3.5.2.311459983, revision: 465e7b6

To reproduce. Steps:
1) Default score
2) Add a dynamic in the first measure
3) Press "M"
File test at this step: dynamics mm rests.mscz
4) Drag the dynamic in the next measure (so the mm rest)

Result: crash

Which is not what the OP did, he dragged it to the first note after the multimeasure rest
Doesn't matter much though, as it crashes as soon as you start dragging it... (and it is not dragging it from the palette as I first understood, that is working)

So it is apparently the re-anchoring that causes this, when a multimeasure rest is met on the way

Stack trace:
1 QListData::size qlist.h 115 0x105d4dc
2 QList::operator[] qlist.h 575 0x1048441
3 Ms::System::staffCanvasYpage system.cpp 1263 0xacd852
4 Ms::Element::genericDragAnchorLines element.cpp 2082 0x989210
5 Ms::TextBase::dragAnchorLines textbase.cpp 2269 0xae0f72
6 Ms::ScoreView::doDragElement dragelement.cpp 100 0x6fd09d
7 Ms::ScoreView::mouseMoveEvent events.cpp 686 0x66d747
8 QWidget::event(QEvent *) 0x31583d78
9 Ms::ScoreView::event events.cpp 106 0x66ad46
10 QApplicationPrivate::notify_helper(QObject *, QEvent *) 0x3154790e
11 QApplication::notify(QObject *, QEvent *) 0x3154f1ea
12 QCoreApplication::sendSpontaneousEvent(QObject *, QEvent *) 0x68a65f78
13 QApplicationPrivate::sendMouseEvent(QWidget *, QMouseEvent *, QWidget *, QWidget *, QWidget * *, QPointer&, bool, bool) 0x3154d83b
14 QWidgetWindow::handleMouseEvent(QMouseEvent *) 0x31599962
15 QWidgetWindow::event(QEvent *) 0x3159cc06
16 QApplicationPrivate::notify_helper(QObject *, QEvent *) 0x3154790e
17 QApplication::notify(QObject *, QEvent *) 0x3154e3e3
18 QCoreApplication::sendSpontaneousEvent(QObject *, QEvent *) 0x68a65f78
19 QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *) 0x6197a0a4
20 QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *) 0x6197b3d5
...

QVector<QLineF> Element::genericDragAnchorLines() const
      {
      qreal xp = 0.0;
      for (Element* e = parent(); e; e = e->parent())
            xp += e->x();
      qreal yp;
      if (parent()->isSegment()) {
            System* system = toSegment(parent())->measure()->system();
            const int stIdx = staffIdx();
            yp = system->staffCanvasYpage(stIdx);       // <<<<<<<<<<<<<<<< here's the crash, system being NULL on an MM rest
            if (placement() == Placement::BELOW)
                  yp += system->staff(stIdx)->bbox().height();
            }
      else
            yp = parent()->canvasPos().y();
      QPointF p1(xp, yp);
      QLineF anchorLine(p1, canvasPos());
      return { anchorLine };
      }

The issue appears to be that dragging the dynamic into the mmrest creates a situation where now the measure that originally contained the dynamic is empty and becomes part of the mmrest, thus increasing its length, and the old mmrest no longer exists. Probably there is some solution involving making sure we drag into the underlying measure instead.

And for the record, my fix does allow passing through. But as for actually allowing it someday, the behavior is somewhat questionable. After all, the moment the dynamic leaves the original measure, it is then completely empty and now joins the mmrest as its new first measure. So now you're trying to add the dynamic to the second measure of the rest?

Anyhow, the crash is fixed by this:

https://github.com/musescore/MuseScore/pull/7176

BTW, other workarounds include temporarily disabling mmrests before dragging, or using cut & paste rather than actually deleting and adding (that's how I'd normally recommend moving things in most cases anyhow).

Status PR created fixed

Fixed in branch 3.x, commit b669598dc9

_fix #313721: crash dragging dynamic into mmrest

Resolves: https://musescore.org/en/node/313721

Dragging a dynamic out of an empty measure into an adjacent mmrest
causes the original measure to now be subsumed into the mmrest,
and the original mmrest no longer exists.
This leads to a crash upon trying to draw the anchor lines.

While it might be possible to re-parent the dynamic again
after the multimeasure rests are recalculated,
or to force the parent to be a segment within the underlying measure
(and then taking pains to draw the anchor lines relative to the mmrest,
since the underlying measure may not yet have been laid out),
these solutions seem likely to be complex and fragile,
depending on the specifics of the order in which layout happens.
The simpler / safer solution is to disable dragging a dynamic
into a multimeasure rest at all._

Fix version
3.6.0