On 6 Dec 2009, at 10:53, Graham Cox wrote:

> 
> On 06/12/2009, at 8:12 PM, Uli Kusterer wrote:
> 
>> I thought that was what undo groups were for? Open a group at the start of 
>> the drag manually, close it at the end, and everything in between gets 
>> lumped into one big action at the end. It may get "replayed" internally, but 
>> will all be triggered by one Cmd-Z.
> 
> 
> Indeed, undo groups are great. Unfortunately, NSUndoManager has a bug where 
> if you open a group (on mouse down, say), do nothing (no drag), and close it 
> again (on mouse up), an empty Undo task appears in the Undo menu. It's 
> harmless, in that it does nothing, but it's also a nuisance, since the user 
> doesn't expect this and reports it as a bug with your app.

But why are you opening a group without registering an undo action? Why not 
just wait until the first action actually needs to be registered?

> It's working around this bug that is horrible and surprisingly complicated 
> (for two reasons - one, you can't peek at the top of the undo stack to see 
> what's there and two, even if you could there's no way to tell whether the 
> task there is empty, because the 'tasks' are all private classes. Therefore 
> you have to come up with another way either to detect this case, or to 
> prevent it from happening. Either way, it's a complicated and nasty hack). 
> Incidentally I have reported this bug but it came back as a dupe. It's been 
> there since I started with Cocoa, on 10.2.

I'm not even sure it is a bug, since the undo manager is designed to work in 
terms of groups, not individual actions.
> 
> In addition, you don't really want a group to record every intermediate step 
> of a drag - theoretically that could run to any number of tasks, which on 
> Undo would be 'replayed', so the drag would eventually get undone but who 
> cares about all the in-between steps? You just want the object to return to 
> the position at the start of the drag. This is what 'task coalescing' 
> achieves, along with the potentially huge memory saving of not recording the 
> irrelevant in-between steps. Unfortunately NSUndoManager doesn't support task 
> coalescing, so you have to subclass it to add this. It's not a huge deal but 
> the bogus task problem is.

So again, why not just wait till the end of the drag and record a single action?
> 
> I've now written my own undo manager from scratch. It's much more 
> straightforward than NSUndoManager in that it uses Cocoa collection classes 
> internally - I'm guessing that one reason for NSUndoManager's arcane 
> implementation with all its weird group end and start markers and so on is so 
> that it also works with Core Foundation alone. It turns out my approach is 
> coincidentally very near identical to GNUStep's implementation. I was 
> concerned that because it subclasses NSObject, not NSUndoManager, it would 
> cause trouble when passed to NSDocument's -setUndoManager: method, but so far 
> I can report that it works perfectly with no issues, supports coalescing and 
> doesn't exhibit the empty group bug. It has an identical public API to 
> NSUndoManager so my main concern was whether internal parts of Cocoa were 
> using private API but that does not appear to be the case. I followed the 
> documentation with respect to when the various notifications are sent, and 
> that didn't quite keep NSDocument's dirty state properly in synch, so I did 
> what was necessary to keep it happy and so now it's slightly not as 
> documented - but I suspect the issue there is that the docs are subtly 
> incorrect. There's also a suspicion among users who contacted me off-list 
> that Core Data is doing something with private Undo API, so mine may not 
> support a Core Data app, but for now that doesn't concern me.
> 
> I've still got some testing to do to really prove it's safe to use, but so 
> far I'm much happier with it than NSUndoManager (and if things do go wrong I 
> can at least debug it directly instead of having to guess what's going on 
> inside the black box and relying on the inaccurate documentation). I'll put 
> it out on my website when I'm done - not seeing those useless 'undo manager 
> is in an invalid state' logs is liberating, I can tell you.
> 
> --Graham
> 
> 
> _______________________________________________
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/cocoadev%40mikeabdullah.net
> 
> This email sent to cocoa...@mikeabdullah.net

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to