NSPopupButton doesn't truncate - drawing outside its bounds

Since we started building our application on Tahoe, all NSPopupButtons in the UI stop truncating when the window they're in is moved to a different screen.

Even though their frame is correct, if the selected item string is longer than what can fit, they just draw outside of their bounds, overlapping other neighbouring controls.

This is reproducible only in our app target even though they are not subclassed or overridden in any way. The same window copied to a test app doesn't have the issue.

Initially good

After dragging to another screen

Frame is correct in the View Hierarchy debugger, but the contents are incorrect.

Very simple constraint setup, with content compression resistance set lower to allow resizing below the intrinsic content size.

This is what happens on this simple test window. The rest of the popups in more complex windows are all bad right away, without requiring you to move them to a different screen.

When built on Sequoia, all is well regardless of which OS the app is run on.

Looking for ideas on how to troubleshoot this and figure out what's triggering it.

Hello @AAntonini,

If you share a sample project here, you may get a more direct answer. Since you mention it happens when the screen changes, you might find helpful tips in NSWindowDidChangeScreenNotification and NSWindowDidChangeBackingPropertiesNotification

When you move to a new screen, NSWindowDidChangeBackingPropertiesNotification triggers which regenerates layer contents and applies clipping.

Alternatively, it could be the case that in the initial window the button's cell is drawing its text before the layer clipping is properly established. To check if this is the case you could force an immediate refresh after layout.

You can attach files in this thread, or if you prefer a private conversation you can contact us here

I hope this helps!

 Travis Trotto - DTS Engineer

Hi @DTS Engineer Travis,

Thanks for the quick reply. As I mentioned in my original message, I haven't been able to recreate this condition in a sample project. I'd love to have a private conversation and show the issue in more detail, but we're ineligible to file a DTS ticket due to it.

As you can see from the example above, the setup in the test window is all very simple so there must be something else causing this not to work properly.

I understand what you're saying about the layer clipping, however there's no code associated with that window. No subclassed controls, no modified layers, no swizzling that I can see.

We shouldn't need to do anything to get the truncation to work.

One additional data point I can give you is that, before the issue occurs, we have this:

p ((NSPopUpButton *)0x13426484d00).bounds
(NSRect) (origin = (x = 0, y = 0), size = (width = 300, height = 24))

p (NSRect)[((NSPopUpButton *)0x13426484d00).cell titleRectForBounds:((NSPopUpButton *)0x13426484d00).bounds]
(NSRect) (origin = (x = 5, y = 4), size = (width = 265.5, height = 16))

After changing screen, the bounds are the same but the titleRectForBounds method returns a rect that doesn't make sense to me.

(NSRect) (origin = (x = -58.5, y = 4), size = (width = 393.5, height = 16))

Why would it return a rect that is larger than the bounds provided as input?

Hope this helps narrow down the issue.

NSPopupButton doesn't truncate - drawing outside its bounds
 
 
Q