Range selection is asymmetric, causes breakage with measure deletion
Steps to reproduce:
1) Create a score with more than one system (or use uploaded score).
2a) Click on the first note of the last measure in the first system.
2b) Shift-click on the last note of that measure (to select the whole measure).
3a) Click on the last note of the last measure in the first system.
3b) Shift-click on the first note of that measure (to select the whole measure).
4) Delete the measure (by key shortcut or using Remove Selected Range in the Tools menu).
Expected result:
The state is the same after performing 2b) and after performing 3b).
After performing 4), the last measure in the first system is removed, without affecting the contents of the remainder of the score.
Actual result:
After 2b), the whole measure is selected, as expected. After 3b), the whole measure is selected, along with a small piece of the next measure.
After 4), the last measure in the first system is removed, but the first note of the next measure is now concurrent with the second note of that measure.
A few notes, for what they're worth:
The asymmetry in forward/reverse selection actually occurs at the end of any measure, but the deletion issue only occurs at the end of a system. Also, the asymmetry shows up in the status line as well as on the score (the reverse selection claims to end on beat 1 of the next measure).
Tested on:
OS: macOS 10.15, Arch.: x86_64, MuseScore version (64-bit): 3.4.2.25137, revision: 148e43f
Also tested on 3.x and 4.0 nightlies:
OS: macOS 10.15, Arch.: x86_64, MuseScore version (64-bit): 3.5.0.28425, revision: aabf881
OS: macOS 10.15, Arch.: x86_64, MuseScore version (64-bit): 4.0.0.28503, revision: da7a4fc
Attachment | Size |
---|---|
Selection Bug.mscz | 9.32 KB |
Comments
I can confirm this. The selection in the second case is wrong in that it extends past the end of the measure; you can see the selection box extend to the next system. The selection actually includes the clef in the system header in the next measure, whereas it really should only extend to the last note of the current measure. Specifically, in the good case, endSegment points to the barline at the end end of the current measure; in the bad case, it points to the first note of the next system. This seems to give localTimeDelete() fits. BTW, if you save / reload the score, the apparent corruption is gone, but so is the first note of the measure
In theory that shouldn't actually cause the strange corruption we see here, so it could be worth addressing that symptom - behavior of the localTimeDelete() when endSegment points to the first note of a measure. But, the selection is bad, and possibly leads to other effects, so better address the actual cause - the bad selection. You can reproduce the same by extending the select backwards from the last note via Shift+Left, so the issue must be somewhere deeper within the select management code, not the Shift+click code specifically.
https://github.com/musescore/MuseScore/pull/6415
FWIW, the bad selection has been true since MuseScore 2 at least, but it wasn't as problematic because ctrl+delete always worked on full measures. Now that can delete partial measures as of MuseScore 3, the fact that we've technically selected a small portion of the next measure is problematic.
Came up again in #309016: Remove selected range sometimes delete invisible parts of bars not selected
Fixed in branch 3.x, commit a963bc360a
_fix #308568: bad selection and corruption on delete
Resolves: https://musescore.org/en/node/308568
If you make a range selection "in reverse",
by selecting a note then extending it to the left
(whether using Shift+Left or Shift+click),
you get a bad selection where the endSemgent is in the next measure.
And in the case of a measure at the end of a system,
it means the selection includes the header of the next system.
This glitch has been the case since MuseScore 2 at least,
but with the reimplementation of measure delete as time delete,
it actually causes corruption when deleting the select range.
That is because we are getting the wrong measure
for the end of the selection, and attempting to do a partial time delete
(with length of 0) in the next measure.
This change fixes the basic problem with selection, so reverse selection
no longer causes this bad result.
This is done by adjusting the initial range to end with
the first segment after the originally-selected CR
rather than the last.
I also fix the calculation of the range of measures
to not be fooled if the endSegment comes after a header -
this was causing an unnecessary invocation of time delete
to delete the beginning of that next measure.
Finally, I also check to be sure we aren't trying to delete zero time,
since that was where the corruption was coming from._
Fixed in branch 3.x, commit d3bf912024
_Merge pull request #6415 from MarcSabatella/308568-range-left
fix #308568: bad selection and corruption on delete_
Automatically closed -- issue fixed for 2 weeks with no activity.