Measure shifts back and forth with each layout

• Dec 14, 2017 - 01:38
Reported version
S3 - Major

In the attached score, any relayout operation anywhere in the score causes a measure on the second page to jump from the end of the second system to the beginning the third. The next relayout causes it jump back, and the next causes it to jump back again, and so on. We've seen layout shifts before, but I don't think we've seen behavior quite like this. Reproduced in 2.2-dev 68c1238 as well as 2.1 release.

Note that you may need to install the Old Standard TT font to load the score properly.

Attachment Size
Variations_on_a_Rainy_Day.mscz 40.25 KB


The re-positioning of the canvas that MuseScore does in continuous view is completely unrelated. Those are not layout changes at all - just an effort to try to second-guess what you might want to do next and how you might want to re-position the canvas to make that easier, and sometimes guessing wrong. But the layout itself is never affected.

The issue at hand is a layout issue indeed, but not one that is unheard of. There have been half a dozen or so similar issues identified and fixed over the past couple of years. Most have to do with the calculation of the size of generated elements like the clef/key/time signature at the beginning of a system or the courtesy elements at the end. And that seems to be the case here as well - the measure in question has a key change.

What happens is, we try to decide if measure 34 will fit on the system along with measures 29-33. We realize that if we don't place it there, we'll need a courtesy key signature after measure 33 and a regular system header in measure 34, but if we do place measure 34 on the previous system, we won't need either - just the key change. We try to calculate things out both ways to see which makes sense, but if if something goes wrong with the calculation, we do the wrong thing, and then keep making the same mistake over and over on each layout.

As I said, we've found and fixed a bunch of other cases where we got the calculation wrong. Looking at this example and playing with it a little (I didn't need to load any other fonts), my money is on the small size setting for the top staff messing up our calculation. Probably that is somehow causing us to overestimate or underestimate something - either the size of the courtesy key change or system header if we place measure 34 on the next system, or the size of the key change if we place it on the previous system, and that discrepancy is just enough to make the difference between the measure appearing to fit or not. Increase the small staff size to 75% and the problem goes away. We're probably still miscalculating, but not by enough to affect the final result.

EDIT: quick look at Score::cautionaryWidth() suggests the discrepancy might be in not scaling the leftMargin correctly, as everything else looks good at first glance.

I write all this detail not so much for anyone else's benefit as for mine, should I end up not being able to look at this further before I forget :-). All this stuff is changed for 3.0 so my guess is anything fix will be 2.2-specific, although there is no particular reason to assume 3.0 is actually immune to this even if this particular score doesn't trigger it.

Doesn't seem to be (just) about leftMargin - the fix I had in mind doesn't help. New theory: it might have do with the natural in the key signature. The measure with the key change has a natural sign in it if it occurs at the end of the system, but no natural if it occurs at the beginning of the next. This might be causing confusion. Because it does seem the problem occurs in the calculation of the width of the measure after the key change, not the measure before (which is the measure with the courtesy signature).

Got it, I think.

Problem is indeed the natural sign. The staff size is a red herring, relevant only in that it affected the overall calculation of measure width, so that measure 33 no longer was right on the edge of fitting or not.

Fix is to make sure we realize we need the natural sign when testing to see if the measure will fit (and thus it doesn't fit - the measure belongs on the next system). It's a one-line fix, but I need to test more to be sure it is safe.

Status (old) patch (code needs review) fixed
Status fixed

Fixed in branch 2.2, commit a09f8e2f40

Merge pull request #3356 from MarcSabatella/267602-natural-jump

fix #267602: layout jump with naturals in keysig

Further testing definitely appreciated!

The fix involved changing the algorithm for deciding when to display naturals in key signatures. The main purpose of the fix was to make sure we always realize we don't need the natural for a key change at the beginning of a system if the courtesy signature at the end of the previous system, instead of sometimes realizing it and sometimes not. And keep in mind, the presence of a horizontal frame also indicates a new system internally. So you may start seeing naturals in places you didn't before, and not seeing them in places you did. I would like to think any such change is an improvement, but that's where more testing will come in handy.

For example, in 2.1, if you have a horizontal frame in the middle of a system right at the point of a key change, the naturals appear both in the courtesy signature before the frame and in the first measure after the frame. I think that's wrong, the naturals don't below after the frame for the same reason they don't belong at the start of the next "real" system. So I fixed it. Note that the naturals appear after the frame if you turn off the courtesy signature. I also fixed the issue described in #251706: Changing key signature after section break on horizontal frame force a courtesy key signature..

Here's a much-reduced version of the file that shows the problem in 2.2.1. I've got it down to a single decision about a single system. Measure 6 either fits on the first system or doesn't depending on whether we think we need a courtesy key signature and how wide we think it is. Debugging from this case should make the job a lot easier.

Attachment Size
The Producers - short.mscz 5.08 KB

Pretty sure I understand the cause, working on a solution. Hard to put into words, but we are removing naturals from the real keysig while calculating the width of the courtesy keysig.