From 45f5a10d5df6a950fff69e58e224b7dcf3bfa95b Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 29 Jul 2015 13:27:07 +0800 Subject: [PATCH] Use NSImageView to draw tray icon. * Fixes Tempate image doesn't show correctly in dark mode. * Fixes the tray icon is stretched showing in menubar. * Fixes title color will not reversed in dark mode. --- atom/browser/ui/tray_icon_cocoa.mm | 73 ++++++++++++++++++------------ 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/atom/browser/ui/tray_icon_cocoa.mm b/atom/browser/ui/tray_icon_cocoa.mm index 0f5a768e5d59..c4f3975afedb 100644 --- a/atom/browser/ui/tray_icon_cocoa.mm +++ b/atom/browser/ui/tray_icon_cocoa.mm @@ -12,8 +12,8 @@ namespace { -const CGFloat kStatusItemLength = 26; -const CGFloat kMargin = 3; +// By default, OS X sets 4px to tray image as left and right padding margin. +const CGFloat kHorizontalMargin = 4; } // namespace @@ -24,6 +24,7 @@ const CGFloat kMargin = 3; BOOL inMouseEventSequence_; base::scoped_nsobject image_; base::scoped_nsobject alternateImage_; + base::scoped_nsobject image_view_; base::scoped_nsobject title_; base::scoped_nsobject statusItem_; } @@ -37,11 +38,17 @@ const CGFloat kMargin = 3; isHighlightEnable_ = YES; statusItem_.reset([[[NSStatusBar systemStatusBar] statusItemWithLength: NSVariableStatusItemLength] retain]); + CGFloat itemLength = [[statusItem_ statusBar] thickness]; NSRect frame = NSMakeRect(0, 0, - kStatusItemLength, - [[statusItem_ statusBar] thickness]); + itemLength, + itemLength); if ((self = [super initWithFrame:frame])) { + image_view_.reset([[[NSImageView alloc] initWithFrame:frame] retain]); + // Unregister image_view_ as a dragged destination, allows its parent view + // (StatusItemView) handle dragging events. + [image_view_ unregisterDraggedTypes]; + [self addSubview:image_view_]; [self registerForDraggedTypes: [NSArray arrayWithObjects:NSFilenamesPboardType, nil]]; [statusItem_ setView:self]; @@ -55,44 +62,53 @@ const CGFloat kMargin = 3; } - (void)drawRect:(NSRect)dirtyRect { - // Draw the tray icon and title that align with NSSStatusItem, layout: + // Draw the tray icon and title that align with NSStatusItem, layout: // ---------------- // | icon | title | /// ---------------- BOOL highlight = [self shouldHighlight]; CGFloat titleWidth = [self titleWidth]; - // Calculate the total icon bounds. + CGFloat statusItemHeight = [[statusItem_ statusBar] thickness]; + CGFloat iconWidth =((highlight && alternateImage_) ? + [alternateImage_ size].width : [image_ size].width) + + 2 * kHorizontalMargin; + NSRect iconRect = NSMakeRect(0, 0, iconWidth, statusItemHeight); + + // Calculate the total status item bounds. + CGFloat statusItemWidth = iconWidth + titleWidth; + // If title is set, need to add right margin to the title. + if (title_) { + statusItemWidth += kHorizontalMargin; + } NSRect statusItemBounds = NSMakeRect(0, 0, - kStatusItemLength + titleWidth, - [[statusItem_ statusBar] thickness]); + statusItemWidth, + statusItemHeight); [statusItem_ drawStatusBarBackgroundInRect:statusItemBounds withHighlight:highlight]; - [statusItem_ setLength:titleWidth + kStatusItemLength]; + [statusItem_ setLength:statusItemWidth]; + + // Custom ImageView + [image_view_ setFrame: iconRect]; + if (highlight && alternateImage_) { + [image_view_ setImage:alternateImage_]; + } else { + [image_view_ setImage:image_]; + } + if (title_) { - NSRect titleDrawRect = NSMakeRect(kStatusItemLength, + NSRect titleDrawRect = NSMakeRect(iconWidth, 0, - titleWidth + kStatusItemLength, - [[statusItem_ statusBar] thickness]); + statusItemWidth - kHorizontalMargin, + statusItemHeight); [title_ drawInRect:titleDrawRect withAttributes:[self titleAttributes]]; } +} - NSRect iconRect = NSMakeRect(0, - 0, - kStatusItemLength, - [[statusItem_ statusBar] thickness]); - if (highlight && alternateImage_) { - [alternateImage_ drawInRect:NSInsetRect(iconRect, kMargin, kMargin) - fromRect:NSZeroRect - operation:NSCompositeSourceOver - fraction:1]; - } else { - [image_ drawInRect:NSInsetRect(iconRect, kMargin, kMargin) - fromRect:NSZeroRect - operation:NSCompositeSourceOver - fraction:1]; - } +- (BOOL) isDarkMode { + return [[[NSAppearance currentAppearance] name] hasPrefix: + NSAppearanceNameVibrantDark]; } - (CGFloat)titleWidth { @@ -105,7 +121,8 @@ const CGFloat kMargin = 3; - (NSDictionary*)titleAttributes { NSFont* font = [NSFont menuBarFontOfSize:0]; - NSColor* foregroundColor = [NSColor blackColor]; + NSColor* foregroundColor = + [self isDarkMode] ? [NSColor whiteColor] : [NSColor blackColor]; return [NSDictionary dictionaryWithObjectsAndKeys: font, NSFontAttributeName,