This issue was being caused by the fact that the overridden
-setDelegate: method on PXSourceListDelegateDataSourceProxy doesn't
correctly remove the old delegate as observing the PXSourceList
notifications.
Setting the same delegate twice will cause this issue to
occur.
The cause of this bug was returning YES in
-[PXSourceListDelegateDataSourceProxy respondsToSelector:] for the
NSControl delegate methods -controlTextDidEndEditing:,
-controlTextDidBeginEditing: and -controlTextDidChange: when they were
called on the proxy because NSOutlineView implements them internally.
However we weren't returning a method signature for them in -methodSignatureForSelector:
which was throwing an exception.
This fix has two components:
- We only allow forwarding of NSOutlineView(Delegate|DataSource) methods
to the source list PXSourceListDelegateDataSourceProxy (which
was the original intention). If PXSourceList returns YES for
-respondsToSelector: we ignore it if the method is not from one of
these two protocols.
- The NSControl delegate methods have been added to the fast-path
forwarding delegate methods array in
PXSourceListDelegateDataSourceProxy (the array which contains method
names which can be forwarded to the source list's delegate as-is, without
modifying the selector or arguments).
These fix the underlying cause of the exception and implement
the missing behaviour of allowing invocation of these NSControl methods
on the source list's delegate.
Fast-path delegate and data source methods (those whose method
signature doesn't need modification) don't need to be checked in
-methodSignatureForSelector: because they are handled in
-forwardingTargetForSelector: which bypasses the
-methodSignatureForSelector:/forwardInvocation: path.
This fix consists of two parts:
1) We first need to check the backgroundStyle property in
PXSourceListBadgeCell to determine whether to draw the light badge
background or not.
2) Next we need to determine whether the enclosing Source List (or child
view) is focused to decide whether to draw the badge text using the bright
blue or grey-blue. To do this, we walk up the view hierarchy
from the common ancestor view of the controlView and firstResponder
until we hit a PXSourceList instance. If we find one, then the source
list is selected, otherwise not.
Walking up the tree from the common ancestor view catches the highly-
unlikely but possible scenario where there are two PXSourceList
instances on screen and one is focused.