Fix sizing of Mac OS X tray icon after image change

- Consolidate logic that applies view dimensions into a function
- Use `NSVariableStatusItemLength` instead of trying to sync status item width
- Use modern Obj-C syntax `@[], @{}` in a few places
- Recompute view bounds after updating image in `setImage:`
This commit is contained in:
Ben Gotow 2015-11-17 13:43:55 -08:00
parent 312a79165b
commit 9c69416e32
2 changed files with 28 additions and 25 deletions

View file

@ -40,15 +40,9 @@ const CGFloat kVerticalTitleMargin = 2;
trayIcon_ = icon; trayIcon_ = icon;
isHighlightEnable_ = YES; isHighlightEnable_ = YES;
// Get the initial size. if ((self = [super initWithFrame: CGRectZero])) {
NSStatusBar* statusBar = [NSStatusBar systemStatusBar];
NSRect frame = NSMakeRect(0, 0, [self fullWidth], [statusBar thickness]);
if ((self = [super initWithFrame:frame])) {
// Setup the image view. // Setup the image view.
NSRect iconFrame = frame; image_view_.reset([[NSImageView alloc] initWithFrame: CGRectZero]);
iconFrame.size.width = [self iconWidth];
image_view_.reset([[NSImageView alloc] initWithFrame:iconFrame]);
[image_view_ setImageScaling:NSImageScaleNone]; [image_view_ setImageScaling:NSImageScaleNone];
[image_view_ setImageAlignment:NSImageAlignCenter]; [image_view_ setImageAlignment:NSImageAlignCenter];
[self addSubview:image_view_]; [self addSubview:image_view_];
@ -56,17 +50,27 @@ const CGFloat kVerticalTitleMargin = 2;
// Unregister image_view_ as a dragged destination, allows its parent view // Unregister image_view_ as a dragged destination, allows its parent view
// (StatusItemView) handle dragging events. // (StatusItemView) handle dragging events.
[image_view_ unregisterDraggedTypes]; [image_view_ unregisterDraggedTypes];
NSArray* types = [NSArray arrayWithObjects:NSFilenamesPboardType, nil]; [self registerForDraggedTypes: @[NSFilenamesPboardType]];
[self registerForDraggedTypes:types];
// Create the status item. // Create the status item.
statusItem_.reset([[[NSStatusBar systemStatusBar] NSStatusItem * item = [[NSStatusBar systemStatusBar]
statusItemWithLength:NSWidth(frame)] retain]); statusItemWithLength:NSVariableStatusItemLength];
statusItem_.reset([item retain]);
[statusItem_ setView:self]; [statusItem_ setView:self];
// Finalize setup by sizing our views
[self updateDimensions];
} }
return self; return self;
} }
- (void)updateDimensions {
NSStatusBar * bar = [NSStatusBar systemStatusBar];
[image_view_ setFrame: NSMakeRect(0, 0, [self iconWidth], [bar thickness])];
[self setFrame: NSMakeRect(0, 0, [self fullWidth], [bar thickness])];
[self setNeedsDisplay:YES];
}
- (void)removeItem { - (void)removeItem {
[[NSStatusBar systemStatusBar] removeStatusItem:statusItem_]; [[NSStatusBar systemStatusBar] removeStatusItem:statusItem_];
statusItem_.reset(); statusItem_.reset();
@ -81,9 +85,7 @@ const CGFloat kVerticalTitleMargin = 2;
// Draw background. // Draw background.
BOOL highlight = [self shouldHighlight]; BOOL highlight = [self shouldHighlight];
CGFloat thickness = [[statusItem_ statusBar] thickness]; CGFloat thickness = [[statusItem_ statusBar] thickness];
NSRect statusItemBounds = NSMakeRect(0, 0, [statusItem_ length], thickness); [statusItem_ drawStatusBarBackgroundInRect:self.bounds withHighlight:highlight];
[statusItem_ drawStatusBarBackgroundInRect:statusItemBounds
withHighlight:highlight];
// Make use of NSImageView to draw the image, which can correctly draw // Make use of NSImageView to draw the image, which can correctly draw
// template image under dark menu bar. // template image under dark menu bar.
@ -157,10 +159,10 @@ const CGFloat kVerticalTitleMargin = 2;
NSColor* foregroundColor = highlight ? NSColor* foregroundColor = highlight ?
[NSColor whiteColor] : [NSColor whiteColor] :
[NSColor colorWithRed:0.265625 green:0.25390625 blue:0.234375 alpha:1.0]; [NSColor colorWithRed:0.265625 green:0.25390625 blue:0.234375 alpha:1.0];
return [NSDictionary dictionaryWithObjectsAndKeys: return @{
font, NSFontAttributeName, NSFontAttributeName: font,
foregroundColor, NSForegroundColorAttributeName, NSForegroundColorAttributeName: foregroundColor
nil]; };
} }
- (NSDictionary*)titleAttributes { - (NSDictionary*)titleAttributes {
@ -169,7 +171,7 @@ const CGFloat kVerticalTitleMargin = 2;
- (void)setImage:(NSImage*)image { - (void)setImage:(NSImage*)image {
image_.reset([image copy]); image_.reset([image copy]);
[self setNeedsDisplay:YES]; [self updateDimensions];
} }
- (void)setAlternateImage:(NSImage*)image { - (void)setAlternateImage:(NSImage*)image {
@ -181,12 +183,12 @@ const CGFloat kVerticalTitleMargin = 2;
} }
- (void)setTitle:(NSString*)title { - (void)setTitle:(NSString*)title {
if (title.length > 0) if (title.length > 0) {
title_.reset([title copy]); title_.reset([title copy]);
else } else {
title_.reset(); title_.reset();
[statusItem_ setLength:[self fullWidth]]; }
[self setNeedsDisplay:YES]; [self updateDimensions];
} }
- (void)setMenuController:(AtomMenuController*)menu { - (void)setMenuController:(AtomMenuController*)menu {

View file

@ -158,7 +158,8 @@ Sets the title displayed aside of the tray icon in the status bar.
* `highlight` Boolean * `highlight` Boolean
Sets whether the tray icon is highlighted when it is clicked. Sets whether the tray icon's background becomes highlighted (in blue)
when the tray icon is clicked. Defaults to true.
### `Tray.displayBalloon(options)` _Windows_ ### `Tray.displayBalloon(options)` _Windows_