indragiek / INAppStoreWindow

NSWindow subclass with a highly customizable title bar and traffic lights
BSD 2-Clause "Simplified" License
1.06k stars 160 forks source link

Using INAppStoreWindow with NSSharingService causes the window to get a little shorter every time the service opens or closes. #66

Closed PadraigK closed 11 years ago

PadraigK commented 12 years ago

A window with a taller-than-standard titlebar will lose a few pixels on top each time the Twitter or Facebook NSSharingService window appears / disappears.

Sample project here:

http://supercrazyawesome.com/jump/SharingINAppStoreWindow.zip

PadraigK commented 12 years ago

It gets shorter by the exact amount more you set titleBarHeight past the standard size (22).

indragiek commented 12 years ago

Hmm, this sounds like it would be pretty difficult to fix, as the share sheet itself seems to be resizing the window. I don't think this could be resolved from within INAppStoreWindow, but maybe you could try fiddling around with the NSSharingServiceDelegate method sharingService:sourceFrameOnScreenForShareItem::

http://developer.apple.com/library/Mac/#documentation/AppKit/Reference/NSSharingServiceDelegate_Protocol/Reference/Reference.html

PadraigK commented 12 years ago

After a bit of testing, sharingService:sourceFrameOnScreenForShareItem: seems to determine only where the animation of the tweet window begins from, not the rect the shaded area works with.

indragiek commented 12 years ago

I see, thanks for looking into it. I can't really think of a good way to fix this from within INAppStoreWindow. The sharing service picker itself is modifying the window somehow, in a way that INAppStoreWindow doesn't like. There's no code inside INAppStoreWindow to resize the window by itself, so what I'm assuming is that the picker uses the window's content/frame rects to calculate some geometry and screws up the calculations as a result of INAppStoreWindow modifying the content view frame.

I did a bit of quick testing by overriding NSWindow layout methods like -contentRectForFrameRect: to see if any of those are called when the sheet appears, but they aren't. I'll keep thinking on this one, but if you discover a fix in the mean time, a pull request would be greatly appreciated!

gcox commented 11 years ago

This is actually caused by setting the styleMask property of the window, which is what NSSharingService is doing before the sharing modal is displayed and when it is dismissed.

You can reproduce this by replacing the code in the example's shareOnTwitter: action with:

-(IBAction)shareOnTwitter:(id)sender
{
    [self.window setStyleMask:self.window.styleMask & ~NSResizableWindowMask];
    [NSThread sleepForTimeInterval:1];
    [self.window setStyleMask:self.window.styleMask | NSResizableWindowMask];
}

When that runs the window's height is reduced after both calls to setStyleMask.

The following is my work-around for the problem, maybe it gives someone an idea on how to fix the problem in INAppStoreWindow itself:

@implementation CustomINAppStoreWindow {
    BOOL _preventResizing;
}

-(void)setFrame:(NSRect)frameRect display:(BOOL)flag {
    if (_preventResizing)
        return;
    [super setFrame:frameRect display:flag];
}
-(void)setStyleMask:(NSUInteger)styleMask {
    _preventResizing = YES;
    [super setStyleMask:styleMask];
    _preventResizing = NO;
}

@end
indragiek commented 11 years ago

Awesome! Your fix is a good one and after trying it with Padraig's example project, it seems that the issue is resolved :) I'll merge this fix into master.