Good morning,

I’m implementing a floating document inspector for my document-based app, and 
am having trouble getting undo/redo working reliably when the inspector is the 
key window. Specifically, NSWindowDelegate’s -windowWillReturnUndoManager: 
doesn’t seem to be doing the trick like everything else I’ve read on this topic 
says it should — at least not reliably. I am developing with Xcode 5.0.2 on 
Mavericks 10.9.1, targeting the Mountain Lion 10.8 SDK.

The inspector window is an NSPanel in its own XIB file. File’s Owner is an 
NSWindowController subclass, MTInspectorPanelController. The controller is the 
panel’s delegate. The controller tracks the current document by KVO observing 
mainWindow.windowController.document on NSApp, the same way as is done in the 
TextEdit sample app. This all seems to work just fine.

When I realized that my undo/redo menu items weren’t active when the inspector 
panel was key, I went in search of a solution and found [NSWindowDelegate 
windowWillReturnUndoManager:]. All signs pointed to implementing this function 
in the inspector panel controller (the panel’s delegate) to return the undo 
manager for the current document, so thats what I did:

- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window
{
    if (window == [self window])
    {
        return [[self inspectedDocument] undoManager];
    }

    return nil;
}

Unfortunately, this only seems to partially work. There are two issues I’m 
running into:

1. The application supports window restoration, and if the inspector panel was 
open when the app last quit (and is thus restored when the app runs next) *and* 
I have full keyboard access disabled (which causes one of the text fields in 
the inspector panel to be first responder when the app launches), then the 
undo/redo menu items will never be enabled when the inspector panel is key 
(although they work just fine if the main document window is key). On the other 
hand, if the inspector panel is closed when the app quits (and is thus not 
restored on next run), *or* full keyboard access is enabled (which causes one 
of the buttons in the NSSegmentedControl to be first responder in the inspector 
panel when the app launches) then the undo/redo menu items will work when the 
inspector panel is key (once it is reopened).

I suspect this has something to do with the fact that when the inspector is 
being restored on app startup with full keyboard access disabled, 
-windowWillReturnUndoManager: gets called on the inspector panel controller 
early during window restoration when there is not yet an active document, and 
thus the method returns nil. After that, windowWillReturnUndoManager: never 
gets called again — not when the inspector becomes key, not when I open the 
Edit menu, never. On the other hand, when the inspector panel is not open (and 
thus not restored during app startup), or when full keyboard access is enabled, 
-windowWillReturnUndoManager: doesn’t get called on the inspector panel 
controller during app startup. In fact, it doesn’t get called until I either 
open the Edit menu while the inspector panel is key, or one of the text fields 
in the inspector panel becomes first responder. At that point all of the 
application’s open documents have been fully loaded and the inspector knows 
which one is active, so the method has an undo manager to return rather than 
nil. It seems that if -windowWillReturnUndoManager: returns nil, then the 
method never gets called again.

2. In the case where the inspector was *not* open when the app launches or full 
keyboard access is enabled and thus undo/redo is working when the inspector is 
key, it sometimes does not correctly switch to the undo manager for the current 
document. For example, if I have multiple clean documents open and then make 
several undoable edits in one document and then switch to a different (clean) 
document and then make the inspector key, occasionally — and this only happens 
sometimes and I can’t seem to reliably replicate it — the Edit menu will still 
show the Undo/Redo menu items corresponding to the initial dirty document. I 
can even execute those menu items and watch the changes take place in the 
document window for the dirty document, even though it is not the main window 
and the inspector (which is key) is correctly tracking the document whose 
window is main. If I make the main (clean) document’s window key, the undo/redo 
menu items go back to being disabled (which is correct since there are no 
actions on the undo/redo stack for that document). With a log statement in 
windowWillReturnUndoManager:, I can see that on the occasions when this 
happens, windowWillReturnUndoManager: is not getting called when the Edit menu 
is opened, as it usually does.

I’ve verified that both of these behaviors exist on a coworker’s machine as 
well, which is running Xcode 5.0.2 on Mountain Lion 10.8.5.

Any clues? Both of these sound like bugs to me, but I’m open to whatever 
suggestions for workarounds or troubleshooting anyone may have before I log a 
radar.

Thanks!

Matt


_______________________________________________

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Reply via email to