Display issues with custom Touch Bar escape keys

Originator:robotspacer
Number:rdar://33439477 Date Originated:July 20 2017, 6:33 PM
Status:Open Resolved:
Product:macOS + SDK Product Version:macOS 10.12.2 through 10.12.6
Classification:Suggestion/Bug Reproducible:
 
Summary:
I have an app with Touch Bar support. It shows a custom escape key whenever it's appropriate, to clarify what that key will do. In a couple of different places I use a button that says "Cancel". When setting this up I found that the key was more cramped than it should be. It seems that the system automatically adds a constraint to an escape key replacement: "<NSLayoutConstraint:0x600000886ae0 _NSFunctionRowRootView:0x600000145540.width == 64   (active)>"

I found that if I added my own constraint (width >= 72), I'd get an error about conflicting constraints, but the key would display how I wanted it to. If I set my constraint to a priority less than required (say, 950), the conflict was resolved, and I still had the appearance I wanted. I never say any problems from this, and neither did any of my beta testers, so I shipped it.

Since then I've been getting a slow but steady number of crash reports related to this custom escape key. For some people, the app gets stuck in a loop, calling -[NSApplicationFunctionRowController _updateEscapeKeyItem] over and over until it crashes. For some people it happens repeatedly; for most people it never happens. I don't know for certain yet, but I have a hunch that this is related to the constraint I added to the escape key.

So I have two closely related complaints:
1. I think the constraint added by the system should be set to "width >= 64", or configured in some way that it does not force the button to be smaller than it would naturally be.
2. If there is some need to keep the current default behavior, I would like a supported and safe way to override that constraint, supplying my own minimum width.

I've attached a screenshot that should help illustrate this problem, as well as crash reports from several users using my current workaround.


Steps to Reproduce:
1. Create an app with Touch Bar support.
2. Add a custom escape key by overriding makeTouchBar and setting the escapeKeyReplacementItemIdentifier.
3. Create the escape key as appropriate (example A):

	NSString *title = NSLocalizedString(@"Cancel", nil);
	NSButton *button = [NSButton buttonWithTitle:title target:nil action:@selector(cancelOperation:)];
	NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
	item.view = button;
	return item;

Or alternatively, for a better appearance (example B):

    NSString *title = NSLocalizedString(@"Cancel", nil);
    NSButton *button = [NSButton buttonWithTitle:title target:nil action:@selector(cancelOperation:)];
    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:72.0];
    constraint.priority = 950;
    constraint.active = YES;
    NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
    item.view = button;
    return item;


Expected Results:
Either snippet of code should create a button that looks identical to the same button used anywhere else in the Touch Bar.


Observed Results:
Example A creates a "Cancel" button that is a bit cramped. It looks different than the same button used elsewhere in the Touch Bar, and it is different from the "Cancel" escape key sometimes used by the system (after pressing command-shift-4 for example).

Example B works around this problem, and has the correct appearance. However I suspect it is the cause of a rare crash some of my users are getting—that crash only happens when an escape key with a width constraint is displayed, and not when other custom escape keys are displayed.


Version:
Both issues exist in macOS 10.12.2 through 10.12.6. My complaint with the appearance is still present in 10.13 beta 3 (17A306f). I am unable to verify whether the crash with code example B is still present in 10.13.


Configuration:
My sizing complaint with example A applies to all MacBook Pro with Touch Bar models. I'm using example B in my app "Deliveries: a package tracker". I've gotten crash reports from these machines:
MACBOOKPRO13,2
MACBOOKPRO13,3
MACBOOKPRO14,2

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!