Hairpin and other symbols are shifting when relayout occurs

• Apr 29, 2016 - 15:59
Reported version
S3 - Major

When you open the attached score, all looks fine.

Now follow these steps to see the problem/issue:
- Go to measure 79/80 in the 1st Bariton part
- Double click the hairpin
- Select the middle handle
- Press CTRL + up-Arrow
Now a relayout of the score takes place, measure 80 is moved to the next page (15) and there are 20 pages in total.
- Press ESC
- Save the score
- Close the score
- Reopen the score
At this moment the previous 20 pages have changed back to 19 pages. Measure 80 is back on the same page (14) it was before changing the hairpin. However the hairpin is placed into measure 80 and next to this measure (where there is no staff).

See also:


That page with 79/80 is just on the edge of fitting/not fitting. Even adding a line break at the end of the first system on top of page 14 causes measure 80 to jump to the next page.

But I do wonder where that horizontal offset of 22.76 is coming from when the page relayout occurs.

Well, the two are almost certainly connected: the horizontal offset almost undoubtledly is created *because* the measure moves. I think we are recording an absolute page position (rather than an offset) in the score file but that ends up being wrong on the reload because the layout has shifted back. Actually, I think that may be it, because if after adjusting the hairpin, I add an explicit line break to lock in this layout, then on reload it's still fine.

So the problem definitely has to do with the layout shift that occurs. I initially though we were getting confused because the layout shift happens in the middle of the adjustment, but that's actually not true. I see the same bug even if I do a Ctrl+A to force the relayout that mvoes measure 80 to the next page to happen *before* the hairpin adjustment. Now I'm clearly adjusting just the first segment of the hairpin (for the portion still on the current page) and I can see the haprin starts about an inch from the right margin. But on save/reload, measure 80 is back on the original page, but hairpin is *still* starting about an inch from the right margin - the correct physical page location based on the layout that existed when I did the adjustment.

Meaning, a possible (but not very good) solution might be to change things so hairpins save their offsets rather than their absolute page position. My guess is that this breaks something else - I know there have a been a number of bugs foudn and fixed over the eyars tht relate to saving as offset versus page position.

We really need to figure out why the layout shift occurs in the first place, since that's the true cause of this. Saving physical position on page would be safe if we could rely on measures being in the same position on reload.

BTW, the issue presumably exists for any element whose manual position is normally stored using a page position. Actually, technically, it's not really a "page" position, it's a position relative to the *system* (the parent of the hairpin and other spanner segments).

Another piece of information on this-
I'm 99.99% certain that the mystery hairpin shifts only happen when the hairpin default position has been changed (for instance, to avoid collision with dynamics or lyrics).

IME, resetting the horizontal offset for the hairpin (or other line) and applying line-breaks at the end of each system seems to resolve the issue.

I'm going to bump this thread because I'm having the same problem, but also, I am unable to select the hairpin in Musescore in order to move it back to the proper position!

In the attached file, select one of the horn parts in measure 3 and you will see a hairpin in measure 7 light up, but now it's impossible to directly select the hairpin in measure 7 to move it back into its proper position.

Does anyone have a workaround for this?

Attachment Size
hairpins.mscz 28.29 KB

@daloonik, it would be preferable to use the forum.
I set to Continuous View;
I selected an hairpin (right click) -> All similar elements;
Check it

Attachment Size
hairpinbis.mscz 28.57 KB

I have always found Shoichi's method to work. However, because it will affect every hairpin, if you have a single (or just a few) hairpins of concern, sometimes you can switch to Continuous View and the hairpin becomes selectable.

Lately I've been able to avoid this problem by making changes to my work flow:
>When initially entering music (including hairpins and crescendo lines), leave the hairpins & lines in their default (original) position.
>Finish all other work on the score.
>Set the line & page breaks *manually* using the appropriate tools from the Breaks & Spacers palette. (Even if you're satisfied with the automatic settings, re-enforce them manually.) Do this at every line break and page break. This should prevent any automatic relayouts from happening.
>Finally, make any necessary changes to the hairpin/line default positions.

Final comment: I believe this approach works because the relayout issue only affects hairpins that have been manually moved from the position where MuseScore initially placed them. (At least, that's my experience.)

Update: The workflow that I describe above continues to be 100% effective in preventing the problem, even in scores approaching 200 measures long with a dozen or more staves.
I would like to add re: my comment on the hairpin default position, that relayout seems to affect only hairpins that have been moved vertically or horizontally by dragging them with the mouse or selecting the hairpin and using the keyboard arrow keys with the element's middle handle selected, or moving the left or right end of the element. Hairpins left in their original position, or edited by shift+arrow to move the left or right ends to the next note or rest, never seem to be affected by relayout.

Another helpful workaround: If a hairpin's left or right termination isn't associated with a note (see the attached Capture for an example), rather than use the left or right arrow key to drag it to an "empty" place in the measure (which subjects it to the relayout issue), use voice 2 (or another unused voice) to create rests in the measure. The hairpin can then be shifted to a rest using Shift+arrow key. Then, select the rests and press "v" to make them invisible. (See Capture2 for an example.)

Attachment Size
Capture.PNG 49.76 KB
Capture2.PNG 8.42 KB

What I observe:
I notice a changing behaviour on May 6, 2015, with the attached file in first message ( Mexican Shuffle - Crescendo Reset to default_0.mscz ) and steps as described in same location ie:

Go to measure 79/80 in the 1st Bariton part
- Double click the hairpin
- Select the middle handle
- Press CTRL + up-Arrow

- With this nightly (last one of May 5): 151c717 the behaviour is as expected after Ctrl + Up.
And always after save and reload:

- With this one on May 6 (one of the first, or the first (?) of this day); 499ea8e, the behaviour is the same observed with the 2.0.3 (hairpin crossed on two pages/layout change):. ie:
And after save and reload:


- Between (and including one of these two nightlies), I see apparently harmless commits about "fix compilation".
So, no idea.

It seems that this was more or less when the big change to using FreeType to do score font calculations happened. It may well be that the change didn't fully go into effect on Windows until that last commit.

Anyhow, I can easily believe the change to FreeType would explain why the problem only started showing up for this particular file at that time. However, that doesn't really mean the change the FreeType was the *cause*. I still suspect the problem is going to turn out to be that a measure was right on the edge of either fitting on the system or not and something - whether floating point round-off or some uninitialized variable or other bug in a size calculation - is causing it to flip back and forth. That could have happened before FreeType just as easily; it just might not have happened *on this particular file*, because maybe before FreeType the size calculation came out just different enough that it wasn't right on the edge. But some other file might then have demonstrated the same problem.

Of course, I could easily be wrong, and maybe soemthing about our use of FreeType really is the problem in itself. Or maybe it has nothing to do with FreeType and I'm interpreting the logs incorrectly.

It would of course be useful to try building a debuggable 2.1 and investigating there. Unfortunately, as I said, the problem doesn't occur in the master.

BTW, in 2.1 at least, you don't need to actually edit the hairpin to see the issue. Measure 80 jumps to the next system the moment you do *anything* that causes a relayout, including just Ctrl+A. So the measure jumping is not *caused* by the hairpin edit.

"Measure 80 jumps to the next system the moment you do *anything* that causes a relayout, including just Ctrl+A."

With this way/step - only by applying Ctrl + A after opening the file -, I see exactly the same results and behaviour change with the layout and hairpin between the nightly on May 5, and the nightly on May 6.

I *might* have figured figured out the source of the problem. Trying not to get my or anyone's hopes up too much. But I instrumented a version of MuseScore to report the values reported for the minimum of each measure during system layout, and compared the values on initial load with the values after the first relayout. What I find is that most measures produce the same value, but measure containing repeat barlines show up as narrower during the initial load than they do afterwards - perhaps because the barlines are not actually generated yet based on the repeat flags on the measure until later in the process?

Anyhow, what I see happening is that some measure shows as fitting on the system during the initial load, then on the first layout, the added width of the repeat barlines somewhere on that same system (whether the same measure or earlier) prevents that last measure from fitting any more.

Speculating here, but I suspect what is happening is this:

That measure didn't fit when the file was saved, either, and the offsets written to the file for manually adjusted elements (spanners only, I guess?) are relative to that layout. When the score is loaded and a *different* (incorrect, because it doesn't account for repeat barlines) layout is encountered, those offsets get rebased to the new layout (adjustReadPos), and are no longer appropriate. And then after the first relayout when the correct layout is reestablished, it's too late.

So, if nothing else, we should try to make sure we calculate correct measure widths on initial layout for measures with repeat barlines. If I'm right, that should solve this particular problem right there. Although I still wonder if we should eventually reconsider how we write offsets for spanners.

Fixing this is not something I am up for right now, but hopefully this analysis helps!

I the post you are answering/elaborating on, there was discussion of bars moving between one page and the next with nothing changing except the ctrl-a combo was pressed. As you know I have reported similar events as well. My only problem with your analysis is that I have scores with no repeats having this problem. Does the same thing happen with ANY double barline? I guess my question about your boils down to, "Are repeat barlines the only barlines not accounted for in the initial layout?"

I have thus far been testing primarily with the score from In this one, I can definitely say the issue is due to measure 34 migrating from one system to the next, and this is due to an error in the calculation of the width of measures 23 and 24 (shows as 24 and 25 in the score). These are measures where we need to adjust the widths after the initial calculation to account for the repeat barline, which we do here:…

But we come up a little short, and as a result, by the time we hit measure 33 (34 in score), we think it fits, just barely. On the next layout, the calculated with of measures 23 and 24 is a bit wider - and just enough to push measure 33 to the next system.

Looking at the code where we adjust the widths to account for the barline, I see one possible error, and that has to do with the treatment of the mag parameter. We are scaling by this factor here:…

But I think that's not right - this parameter is about *staff* scaling, whereas the mag parameter as passed in already includes scaling due to the score have a relative small sp value. So I believe we are basically scaling down twice and underestimating the barline width as a result. However, removing that second scale still leaves the calculation off by a little bit. Not as much as before, but enough that the bug still strikes.

More good news!

It turns out there is a crazy simple one-line fix (one character, actually!) for this particular aspect of the issue. Change "magS()" to "mag()" here:…

Now the calculated measure size on load is correct.

I have verified this fixes the jumping measure - and hence also the jumping hairpin / trill - in both the score I was looking at mostly ("Dixieland Strut") and also the one in the original post for this thread ("Mexican Shuffle").

However, it has been claimed by some that they see this issue in cases where there are no repeat barlines. If so, that would probably be due to some other underlying cause, although I guess in theory ordinary double bars could trigger this as well (not sure). So we could use some more sample scores that demonstrate the problem. I suspect the same type of analysis will lead to a similar discovery of discrepancy in measure width calculations, and hopefully a similarly simple fix.

I'll hold off on submitting a PR until we understand more, but at this point I am highly encouraged that we've finally nabbed at least one cause for this.

Status (old) active patch (code needs review)

The PR is simple and should fix these problems safely. Again, only for cases where barline widths are the issue. I had said it is repeat barlines specifically, but it could conceivably be other generated non-default barlines - I just don't know what other cases that might include. Maybe the automatically double bar before a courtesy key signature, but actually that seems to be handled differently, and I don't think this same issue exists in that case. Also, this particular issue only affects scores with a spatium setting that differs from the nominal 1.764 value. So anyone seeing wandering hairpin issues in scores without repeat barlines or that use the standard spatium value, we will still need reproducible cases to investigate.