AppKit: Disable Undo and Redo when a text view does not allow undo

A text view handled undo: and redo: and registered its changes even when allowsUndo was NO, so Edit > Undo stayed enabled and did nothing.

Behaviour now follows canonical Cocoa: a text view that does not allow undo registers nothing and passes undo: and redo: on to the window, and Undo and Redo are enabled only when there is a change to undo or redo.

* CPTextView/CPTextView.j: Register changes only when undo is allowed, stop responding to undo: and redo: when it is not, and validate the Undo and Redo items against the undo manager.

* CPWindow/CPWindow.j: Validate the Undo and Redo items against the window's undo manager.

* Tests/AppKit/CPTextViewTest.j: Add tests for responding to undo:, registering changes and validating the Undo item.

* Tests/Manual/TextEditor/DocumentWindowController.j: Add toggleAllowsUndo: and validateMenuItem:, so that undo can be turned on and off for the active document.

* Tests/Manual/TextEditor/Resources/MainMenu.xib, Resources/MainMenu.cib: Add Edit > Allow Undo.

* Tests/Manual/TextEditor/WORKLIST.md: Remove the entry for this gap, record Allow Undo as tested, and add the key equivalent behaviour of disabled menu items for discussion.
This commit is contained in:
David Richardson committed 2026-10-23 17:20:27 -06:00
1 parent 92b8039c71
commit 66ea130c8d
7 files changed
+171 -14

No files matched your search

+11 -2
View File
@@ -2830,13 +2830,22 @@ CPTexturedBackgroundWindowMask
For \c -toggleToolbarShown:, the item's title becomes "Hide Toolbar" or "Show Toolbar"
to reflect the toolbar's visibility, and the item is enabled only when the window has
a toolbar. Every other item is enabled.
a toolbar. \c -undo: and \c -redo: are enabled only when the window's undo manager has a
change to undo or redo. Every other item is enabled.
@param anItem the item to validate
@return \c YES if the item should be enabled
*/
- (BOOL)validateUserInterfaceItem:(id /*<CPValidatedUserInterfaceItem>*/)anItem
{
if ([anItem action] !== @selector(toggleToolbarShown:))
var action = [anItem action];
if (action === @selector(undo:))
return [[self undoManager] canUndo];
if (action === @selector(redo:))
return [[self undoManager] canRedo];
if (action !== @selector(toggleToolbarShown:))
return YES;
var toolbar = [self toolbar];