Crash on load of score with horizontal frame taking an entire system

• Dec 22, 2015 - 18:36
S2 - Critical

Ubuntu 14.04, GIT commit: 600306e

1) My First Score
2) click measure 5
3) add / Frames / Insert Horizontal Frame
4) gradually increase size of frame until it pushes all measures to next system
5) save
5) load

Result: crash

After step 4, if you open the object debugger, you will notice that the system containing frame also contains measure 5 - this is the source of the problem. Measure 5 shows up on both that system and the next. It doesn't cause a crash now, but causes other issues with layout as you might imagine.

I discovered this working on #90766: Issue during creating horizontal frame. This is a simplified case of what I reported in In those steps, I created two adjacent horizontal frames and was assuming this was part of the problem, but it turns out the problem is any time there is a system containing only a single horizontal frame (two adjacent horizontal frames counts as two separate systems).

Basically, we are insisting on adding a measure to the system even though it doesn't fit. Forcing a measure to be added to the first seems to have the intent of the fix for #76006: if insert clef to measure after single-measure system with section break, then should not display courtesy clef, but it isn't appropriate here. So somehow we need to be more careful about this.


Since I'm already thinking about this and do have free time this week, I am continuing to investigate. I believe I have a fix, but hoped to get opinions on it.

I can see why we are always adding the first measure to the system before calling minWidth2(). I do wonder if maybe a better solution to the original problem might have been to change Clef::layout() to somehow not require this - like to force showClef to true in the case where meas->system()->lastMeasure() is null. But given that things are otherwise working OK, I will accept for now this was the right decision.

So, we are always adding the first measure to the system, on the assumption that systems always have one measure. But the problem is that if the system starts with a horizontal frame, it is *not* a given that we will need a measure. And in the case where the measure does not fit, that means we will have added it prematurely.

The simple solution seems to be to remove curMeasure from the system after determining it won't fit. This seems safe to me. In most cases, the measure that doesn't fit won't be the first measure of the system, so it won't have been prematurely added, so removing it will be a no-op. And in the cases where the system begins with this measure, we will accept it whether it fits or not. Only in the case where the system begins with a horizontal frame and then we find the first true measure does not fit is there a problem, and the problem appears to be solved by removing the measure from the system.

I will submit a PR that implements this, but still welcome comments from others who have studied this code.