I have encountered what I consider a bug, or at least a design error, in the 
NSOutlineView autosaveExpandedItems mechanism.

Normally, when you expand or collapse an outline row, AppKit calls the 
NSOutlineViewDataSource method -outineView:persistentObjectForItem:, if it is 
implemented, to autosave an archive of the expanded or collapsed item. After 
you quit and relaunch the application, AppKit calls 
-outlineView:itemForPersistentObject: to read the archive and expand or 
collapse rows just as you left them when you quit.

Here's the bug: When you expand or collapse an empty outline row, AppKit does 
not call -outineView:persistentObjectForItem:. As a result, after quit and 
relaunch the row is always in the collapsed state (the triangle points sideways 
instead of down), even if it was left in the expanded state at the previous 
quit. I suspect that Apple considers this to be correct behavior, since the 
NSOutlineViewItemDidExpandeNotification and 
NSOutlineViewItemDidCollapseNotification are correctly posted even when an 
empty row is expanded or collapsed. It therefore looks like Apple coded the 
autosave behavior deliberately.

You might argue that this is proper behavior because it doesn't mean much to 
call an empty row "expanded." But the Finder, for one example, honors the 
expanded state of empty rows across relaunches, and I find it useful so that I 
can monitor at a glance whether files have been added to particular folders 
behind my back (in my Public Folder's Drop Box, for example). I like to leave 
some empty folders expanded across relaunches.

But the bug really bites when you expand an empty row and then add a child row 
to it. AppKit did not call -outineView:persistentObjectForItem: when you 
expanded the empty row, and it does not call it when you add a new child row, 
either. As a result, after quit and relaunch the row is collapsed, even though 
when you quit you left it expanded and non-empty.

I can fix this with a hack. When I add a child row, my application checks 
whether the newly added row has any siblings and, if not, collapses and 
re-expands the row programmatically. Because the parent row now has a child, 
AppKit calls -outineView:persistentObjectForItem: and all is well. On my fast 
Mac Pro Late-2013, I don't see a flicker. I haven't tried it on a slower 
machine yet.

A more dubious fix is to archive the expanded row in user defaults myself. I 
took a stab at coding that, and it wasn't hard, but I didn't carry it all the 
way through because I realized that I can't be sure I am capturing all the 
wrinkles of Apple's implementation. I consider this fix inappropriate for a 
released product because it depends on the implementation details of AppKit's 
autosaveExpandedItems mechanism, which is mostly hidden behind the scenes.

Before I report this to Apple, does anybody have any other thoughts or 
workarounds?

-- 

Bill Cheeseman - [email protected]

_______________________________________________

Cocoa-dev mailing list ([email protected])

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 [email protected]

Reply via email to