expect the behaviour to be that it ungroups all.
Right, that is what I would expect, too, and this is how it has worked before undo.
The new limitation (only ungroup one group, keep all others grouped) comes from the strong encouragement (by the undo design) to describe the entire modification to the level before committing anything to the level.
After one group tile has been deleted and its parts have been inserted in the level, the next group tile will potentially sit at a different z-order (counted from the front of the terrain list), and this messes with the iteration if we commit the first ungrouping to the level. If we
don't commit the first ungrouping yet, then the iteration continues well, but I save absolute positions (index numbers within the terrain list) in the Undoables, and the future absolute positions for the next ungrouping will be computed wrongly.
There are hack solutions around this: Create ungrouping Undoable, commit to level, create next ungrouping Undoable, commit to level, ..., then undo all these Undoables, create a CompoundUndoable of them, and recommit this CompoundUndoable. Or track meticulously all the index shifts in some complex data structure.
But ungrouping is already very rare, and, as you say, normallly used on single groups. Hacking or complex counting code doesn't seem appropriate, even though it would be technically correct.
We could also limit this command to work only on single selections, i.e., offer it only in the menu when a single group tile is selected. Generally, in the UI, I should offer only the buttons that are meaningful for the current selection, and hide/grey out the others. This will be a nice long-term improvement for the editor.
-- Simon