-[NSOutlineView autosaveExpandedItems] bug?
-[NSOutlineView autosaveExpandedItems] bug?
- Subject: -[NSOutlineView autosaveExpandedItems] bug?
- From: Bill Cheeseman <email@hidden>
- Date: Sun, 13 Jul 2014 13:42:30 -0400
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@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden