Introspect Undo/Redo Stack DepthsFrançois Vogel$Revision: 1.9 $Tk
Tk features a generic undo/redo mechanism (see ). This is used in practice by the text widget, within the edit command. The present TIP proposes to add two new subcommands to the edit command allowing the user to know whether undo and redo is possible for a text widget.
The undo/redo feature of Tk is handy and works very well. In modern GUIs, there is usually a button in a menubar to call the "Undo" command, and likewise for "Redo". It is good practice to enhance the user experience by greying out or otherwise changing the button aspect when there is nothing to undo (or redo). This cannot be achieved currently with the curent Tk implementation because there is no way to know whether the undo and redo stacks are empty or not.
This feature was requested for the text widget in RFE 1273358 []
It is proposed to add the following subcommands to the text widget's edit command:
canundo:
Returns a boolean true if undo is possible, i.e. when the undo stack is not empty. Otherwise returns false.
canredo:
Returns a boolean true if redo is possible, i.e. when the undo stack is not empty. Otherwise returns false.
When the -undo option of the text widget is false both subcommands return false since indeed no undo nor redo action is possible in this case. The undo/redo stacks are however not cleared, so that when -undo becomes eventually true again the two new subcommands will return their value in accordance with the contents of the stacks (this is current behavior of the undo/redo feature - the TIP does not intend to change this).
This new capability will be implemented in the generic code for undo (generic/tkUndo.c), so that any client of the generic undo/redo mechanism can make use of it. Currently, only the text widget is concerned since no other Tk widget is featuring undo/redo.
Besides the two new subcommands, it is also proposed to add a new virtual event <<UndoStack>>, that will trigger each time the undo or redo stack becomes empty or unempty. When this condition is met, the event will trigger once for each peer widget.
Despite this is a new feature, this TIP targets Tk 8.6.6 since no change of any existing behavior is proposed: only new, additonal, features are proposed. It is therefore believed there is no risk regarding backwards compatibility in the 8.6.x series.
ICBwYWNrYWdlIHJlcXVpcmUgVGs=ICBwYWNrIFt0ZXh0IC50IC11bmRvIGZhbHNlIC1hdXRvc2VwYXJhdG9ycyBmYWxzZV0=ICBzZXQgbmJVUyAwICBiaW5kIC50IDw8VW5kb1N0YWNrPj4ge2luY3IgbmJVU30=ICAudCBlZGl0IGNhbnVuZG8gICAgOyAjIDA=ICAudCBlZGl0IGNhbnJlZG8gICAgOyAjIDA=ICAudCBjb25maWd1cmUgLXVuZG8gdHJ1ZQ==ICAudCBlZGl0IGNhbnVuZG8gICAgOyAjIDA=ICAudCBlZGl0IGNhbnJlZG8gICAgOyAjIDA=ICAudCBpbnNlcnQgZW5kICJBQkNcbiI=ICAudCBlZGl0IHNlcGFyYXRvcg==ICAudCBpbnNlcnQgZW5kICJERUZcbiI=ICAudCBpbnNlcnQgZW5kICJERUYgYWdhaW5cbiI=ICAudCBlZGl0IHNlcGFyYXRvcg==ICAudCBlZGl0IGNhbnVuZG8gICAgOyAjIDE=ICAudCBlZGl0IGNhbnJlZG8gICAgOyAjIDA=ICAudCBlZGl0IHVuZG8=ICAudCBlZGl0IGNhbnVuZG8gICAgOyAjIDE=ICAudCBlZGl0IGNhbnJlZG8gICAgOyAjIDE=ICAjIEEgcXVpY2sgaW50ZXJhY3RpdmUgdGVzdGluZyBlbnZpcm9ubWVudC4uLjo=ICA=ICBwYWNrIFtsYWJlbCAubF0=ICA=ICBwcm9jIHNob3dpdCB7fSB7ICAgIGdsb2JhbCBuYlVTICAgIC5sIGNvbmZpZ3VyZSAtdGV4dCAiQ2FuIHVuZG86IFsudCBlZGl0IGNhbnVuZG9dXHRcdFx0IFw=ICAgICAgICAgICAgICAgICAgICAgICAgQ2FuIHJlZG86IFsudCBlZGl0IGNhbnJlZG9dXHRcdFx0IFw=ICAgICAgICAgICAgICAgICAgICAgICAgPDxVbmRvU3RhY2s+PiB0cmlnZ2VyZWQ6ICRuYlVTIg==ICAgIGFmdGVyIDIwMCBzaG93aXQ=ICB9ICBzaG93aXQ=ICA=ICBwcm9jIHRvZ2dsZWF1dG9zZXAge30gew==ICAgIGdsb2JhbCBhdXRvc2Vwc2V0ICAgIHNldCBhdXRvc2Vwc2V0IFsudCBjZ2V0IC1hdXRvc2VwYXJhdG9yc10=ICAgIGlmIHskYXV0b3NlcHNldH0gew==ICAgICAgLnQgY29uZmlndXJlIC1hdXRvc2VwYXJhdG9ycyBmYWxzZQ==ICAgIH0gZWxzZSB7ICAgICAgLnQgY29uZmlndXJlIC1hdXRvc2VwYXJhdG9ycyB0cnVlICAgIH0=ICAgIHNldCBhdXRvc2Vwc2V0IFsudCBjZ2V0IC1hdXRvc2VwYXJhdG9yc10=ICB9ICBwcm9jIHRvZ2dsZXVuZG8ge30gew==ICAgIGdsb2JhbCB1bmRvc2V0ICAgIHNldCB1bmRvc2V0IFsudCBjZ2V0IC11bmRvXQ==ICAgIGlmIHskdW5kb3NldH0gew==ICAgICAgLnQgY29uZmlndXJlIC11bmRvIGZhbHNlICAgIH0gZWxzZSB7ICAgICAgLnQgY29uZmlndXJlIC11bmRvIHRydWU=ICAgIH0=ICAgIHNldCB1bmRvc2V0IFsudCBjZ2V0IC11bmRvXQ==ICB9ICBidXR0b24gLmIxIC10ZXh0ICJJbnNlcnQgc2VwYXJhdG9yIiAtY29tbWFuZCB7LnQgZWRpdCBzZXBhcmF0b3J9ICBidXR0b24gLmIyIC10ZXh0ICJVbmRvIiAtY29tbWFuZCB7LnQgZWRpdCB1bmRvfQ==ICBidXR0b24gLmIzIC10ZXh0ICJSZWRvIiAtY29tbWFuZCB7LnQgZWRpdCByZWRvfQ==ICBidXR0b24gLmIzMiAtdGV4dCAiUmVzZXQiIC1jb21tYW5kIHsudCBlZGl0IHJlc2V0fQ==ICBjaGVja2J1dHRvbiAuYjQgLXRleHQgIi1hdXRvc2VwYXJhdG9ycyIgLWNvbW1hbmQgdG9nZ2xlYXV0b3NlcCAtdmFyaWFibGUgYXV0b3NlcHNldA==ICBjaGVja2J1dHRvbiAuYjUgLXRleHQgIi11bmRvIiAtY29tbWFuZCB0b2dnbGV1bmRvIC12YXJpYWJsZSB1bmRvc2V0IDsgLmI1IHNlbGVjdA==ICA=ICBwYWNrIC5iMSAuYjIgLmIzIC5iMzIgLmI0IC5iNSAtc2lkZSBsZWZ0IC1wYWR4IDEw
A reference implementation is available in branch tip-446 of the fossil repository. Credits for this implementation largely go to Neil Hodgson, the author of TkTextPlus (for canundo/canredo) and to Koen Danckaert (for <<UndoStack>>).
This document has been placed in the public domain.