Is there any documentation of the undo system in MuseScore 3?

• Jun 29, 2019 - 16:15

Query for the MuseScore C++ developer community....

Is there any documentation of the undo system in MuseScore 3?

In particular I'm interested in how to ensure a plugin that changes to the state of the score are accounted for when using QML operations.

The driver for this question can be found here:



In reply to by Jojo-Schmitz

The only plugin I found that uses it is random2.qml.

In its MuseScore declarations I see:

MuseScore {
version: "3.0"
description: "Create random score."
menuPath: "Plugins.random2"
requiresScore: false
pluginType: "dock"
dockArea: "left"
width: 150
height: 75

This suggests it's a UI related item.

I don't know why that would matter but it does.

From mscorePlugins.cpp (Line 460ish) function pluginTriggered():

  // don’t call startCmd for non modal dialog
  if (cs && p->pluginType() != "dock")
  if (cs && p->pluginType() != "dock")
 //      endCmd();

In reply to by [DELETED] 1831606

>Sounds like some breakpointing of endCmd and watching its behavior in, say, TempoChange.qml is in order...

That's precisely what I did. I followed the code from "start" through "end" . There isn't much to see really. It sets up a stack, calls the plugin, and tears it down. The problem seems to be that nothing adds to the stack related to state changes.

It's time for a knowledgeable developer to weigh in on this part of the code. It's just too fuzzy (yep I said it) and there is some important tribal knowledge missing here.


In reply to by DLLarson

Is it possible that other attribute-modifying API availabilities are expressed (on the C++ side) with some kind of wrapper or interface function that does exactly that, records in that stack exactly what quantity in some inviolable way and how it changed?

In reply to by [DELETED] 1831606

From my brief visit to undo.cpp, it certainly seems as though that if you want to be undoable, you have to push undo records on the undo stack; there must be other stuff in the QML API that does that for other quantities. Are there any other qml-changeable note properties at all, now that I think about it? How does the PRE do it, separate stack or not?

In reply to by [DELETED] 1831606

I finally got it all working.

You can find my latest patch here:

I will say, the small amount of code needed provide the new features does not reflect at all the time needed to arrive at that result. While the MuseScore C++ code is clean and well presented, it is almost devoid of any comments to help new programmers glean actual intention. It took me a lot of building and single stepping to figure this out.

We had an old saying that "The code doesn't lie!" While this is true, a few comments would have certainly have helped! It's almost as if comments were/are forbidden in the code. Rant off...

With regard to the implementation I wonder if we should replace the "offTimeOffset" value with a length value instead. Even in the Piano Roll UI you set length rather than note offTimeOffset. We could call it "onTimeLength" to be consistent with its associated "onTimeOffest".

It addition, it doesn't seem like 'onTimeLength' should ever be negative but the UI allows it. This seem wrong to me. It makes the note vanish in the piano roll editor.


I haven't submitted the patch to the upstream yet until we're happy with the results.


In reply to by DLLarson

This is terrific. Haven't checked out (inspected) the code yet -- I will.
I think that the reverse is true, though --- and I'd already submitted a bug report -- the user-visible artifact should be off-time, not length; if you change the on-time, you should not have to change the length, right (but that's controversial).

I'll get to this soon, thanks again. I had already downloaded the tree and started studying the api system....

In reply to by DLLarson

"Length" can't be less than 0 (but in MS2 PRE it often got that way by bugs and the app would crash). Off-time can never be less than on time (or allowed to be set so). length = off_time - on_time. None of these can be negative. Requests to set either quantity so that this is not so should be rejected, actually. It shouldn't be possible to set bad values via QML.

In reply to by Jojo-Schmitz

Ok... I have all the limit checks in the code, tested, and pushed up to my repository.

It's ready to go if this looks copacetic to you.

One issue...I did notice that my builds against 'master' still have the "no plugins" problem. It's like the patch for 3.2.2 didn't make it into master?

I haven't tried building it for the 3.2.2 branch yet.


In reply to by [DELETED] 1831606

> have no knowledge apropos to the branch/version issue.

I can handle that stuff.

I'm more interested if the feature meets your expectations as we've defined it.

Once I submit a pull request I'm sure it will get more attention from others prior to being accepted. Perhaps they even have nightly builds that can be tested.

Some additional feedback...

I rebuilt this new feature onto the current 3.2.2. branch and the plugin menus are working. This suggests that the 3.2.2 plugin fix did not make it into the master branch.

Executing the plugin test from the menu works well in 3.2.2. You can undo and redo the script changes in one shot.

I think it's ready to go!


In reply to by [DELETED] 1831606

I assume the PR will be posted to this thread

If someone creates a suggestion issue, the PR can be linked to the the issue by calling it fix #1234 - change on/off times (or what ever is appropriate) and then git will update the issue automatically without needing to look at the PR to see its status.

In reply to by [DELETED] 1831606

It can be a big chore.

The instructions for Windows targets was pretty accurate and worked well for me. But I still had to install a lot of things to feed the beast.

Once it was set up it was simple to use. I just had to get there.

I have no idea how that all transfers to a Mac.

I'm equipped for Linux and Windoze only.

Do you still have an unanswered question? Please log in first to post your question.