NSWindow - borderless, transparent window - flickering shadow when animating window height

Here's another NSWindow question ... I have a borderless window that is transparent, which is created this way ...

 - (id)initWithView:(NSView *)view anchorPoint:(NSPoint)anchorPoint position:(NSPoint)position distance:(CGFloat)distance { if ( !view ) { return nil; } NSSize size = view.intrinsicContentSize; NSRect contentRect = NSMakeRect( 0, 0, size.width, size.height ); self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]; if ( !self ) { return nil; } _windowView = view; _anchorPoint = anchorPoint; _position = position; _distance = distance; [self setContentView:_windowView]; [self setExcludedFromWindowsMenu:YES]; [self setMovableByWindowBackground:NO]; [self setOpaque:NO]; [self setBackgroundColor:[NSColor clearColor]]; [self setHasShadow:YES]; [self useOptimizedDrawing:YES]; [self setReleasedWhenClosed:NO]; [self setFrame:[self windowRectWithSize:contentRect.size] display:YES]; [self setAnchorAttribute:NSLayoutAttributeTop forOrientation:NSLayoutConstraintOrientationVertical]; [self setAnchorAttribute:NSLayoutAttributeCenterX forOrientation:NSLayoutConstraintOrientationHorizontal]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:nil]; return self; } 

... and viewFrameDidChange: defined as ...

 - (void)viewFrameDidChange:(NSNotification *)note { if ( note.object != self.contentView ) { return; } [self display]; [self setHasShadow:NO]; [self setHasShadow:YES]; } 

... this is the only way to have the correct shadow NSWindow . In other words, whenever the window is resized, I have to call display , setHasShadow:NO and setHasShadow:YES , otherwise the window shadow is crippled - it's not around the whole window - only part of the window, etc.

This works until I start the height animation. If the height is animated, the shadow is correctly recounted and displayed, but the whole window and shadow flicker, and it's pretty ugly.

The idea why the shadow flickers? I tried replacing display , setHasShadow:NO/YES with [self invalidateShadow] , but it does not work at all, and the shadow does not display correctly.

How to avoid window height animation with shadow in unlimited / transparent window?

Here is a video of the shimmering shadow. http://d.pr/v/lbkQ

+8
objective-c cocoa nswindow
source share
2 answers

Shadow calculation and drawing is a very resource-intensive operation. Therefore, I would not recommend that you cancel and recount the shadow every time you change the frame. In addition, NSWindowDelegate has a โ€“windowDidResize: method, so why use an observer?

  • How can you resize a window? Maybe adding NSResizableWindowMask to a window style mask will do the trick? You must try.

  • Another suggestion is to make sure that the contents of your window change correctly with the window. You will set a transparent window. But if there is no content inside the window, the shadows are not displayed. You can also try adding your view as a subview to an existing contentView window instead of replacing it.

I have almost the same setting in my project, and I can say that the window shadow is displayed correctly when the window is resized.

PS Recommendation: do not rely on the "I" in the method of initializing the object. It may not yet be fully ready for use. Initiate a minimum, adjust the window after it has been created in your controller (for example, you cannot be sure that setFrame: the display will do what you expect with the correct dimensions). Perhaps this is due to a glitch.

+2
source share

It might be better to turn off the shadow at the beginning of the animation and come back when you're done. Do not switch this option during animation. I thought I saw this in other windows.

+2
source share

All Articles