Skip to content

Instantly share code, notes, and snippets.

@vilhalmer
Created November 1, 2014 01:28
Show Gist options
  • Save vilhalmer/3052f7e9e7f34b92a40f to your computer and use it in GitHub Desktop.
Save vilhalmer/3052f7e9e7f34b92a40f to your computer and use it in GitHub Desktop.
NSVisualEffectView undocumentation
NSVisualEffectMaterial constants, and the undocumented materials they coorespond to in various modes:
+----------------------+-------+----------+------+---------+
| MATERIAL # | LIGHT | LIGHT EM | DARK | DARK EM |
+----------------------+-------+----------+------+---------+
| | | | | |
| 0 - Appearance Based | 3 | 3 | 5 | 5 |
| | | | | |
| 1 - Light | 3 | 3 | 3 | 3 |
| | | | | |
| 2 - Dark | 4 | 4 | 4 | 4 |
| | | | | |
| 3 - Titlebar | 6 | 6 | 5 | 5 |
| | | | | |
| 4 - Menu Selection | 9 | 7 | 12 | 10 | (Material 4 is undocumented, but can just be passed in.)
+----------------------+-------+----------+------+---------+
(light/dark = light or dark mode from General System Preferences, "em" = -setEmphasized:YES)
The undocumented, real material types:
+------------+---------------------------+-------------------------------+
| MATERIAL # | CGS MATERIAL (BLUE THEME) | CGS MATERIAL (GRAPHITE THEME) |
+------------+---------------------------+-------------------------------+
| | | |
| 0 | L | L | (I have no idea what the names of 0-3 mean.
| | | | It would be very interesting to find out.)
| 1 | HL | HL |
| | | |
| 2 | UL | UL |
| | | |
| 3 | HUL | HUL |
| | | |
| 4 | MacDark | MacDark |
| | | |
| 5 | MacUltraDark | MacUltraDark |
| | | |
| 6 | HL | HL | (Duplicate of #1)
| | | |
| 7 | SelectionBlue | SelectionGraphite | (Redirected when using the graphite theme)
| | | |
| 8 | SelectionGraphite | SelectionGraphite |
| | | |
| 9 | SelectionUnfocused | SelectionUnfocused |
| | | |
| 10 | SelectionBlue | SelectionDark | (Redirected when using the graphite theme)
| | | |
| 11 | SelectionDark | SelectionDark |
| | | |
| 12 | SelectionUnfocusedDark | SelectionUnfocusedDark |
| | | |
| 13 | MacMediumDark | MacMediumDark |
| | | |
| 14 | MacDark | MacDark | (Duplicate of #4)
+------------+---------------------------+-------------------------------+
There's also a 15th internal material called "Clear", which is activated by using -_setClear:YES, and operates independently of the internal material setting. It's exactly what it sounds like.
I've noted a few interesting things along the side. While you can force use of the graphite materials when the blue theme is active, the opposite seems to be impossible. I haven't explored which ones appear in contexts outside of the menubar. If you do so, please report back where they can be found!
Some useful undocumented methods on NSVisualEffectView:
- (NSUInteger)_internalMaterialType;
- (void)_setInternalMaterialType:(NSUInteger)type;
- (BOOL)isEmphasized;
- (void)setEmphasized:(BOOL)emphasized;
- (void)_setClear:(BOOL)clear;
There's lots more hidden in the class that I haven't dug into yet, I recommend playing with dtrace/Instruments or other similar tools if you're interested in going deeper. The -debugDescription will print out the internal material and some other info.
------------------------------------------------------------------------------------------------------
Here’s how to emulate the menus:
NSStatusItem * statusItem = …make a status item…
NSVisualEffectView * highlightView = [[NSVisualEffectView alloc] initWithFrame:[[statusItem valueForKey:@"window"] frame]];
[highlightView setFrameOrigin:NSZeroPoint];
[highlightView setMaterial:4];
[highlightView setEmphasized:YES];
[highlightView setState:NSVisualEffectStateActive];
[[[statusItem button] superview] addSubview:highlightView positioned:NSWindowBelow relativeTo:[statusItem button]];
This places the new NSVisualEffectView inside of the status item window's contentView, right behind the NSStatusBarButton. This allows you to simulate the highlight of the button in whatever manner you want, instead of being beholden to the button's highlightMode and menu. The final line of code would ideally be used inside of a method that's set up as the status bar button's target-action, so you can show and hide the highlight as appropriate. It has the extra benefit of allowing the system to continue managing the appearance of the button, since there are so many appearance combos in Yosemite.
(The reason I went through all of this trouble is that -drawStatusBarBackgroundInRect:withHighlight: doesn't work unless you've actually set a custom view, which leaves you to fend for yourself with the icon. I still need to get the button's color to flip when pressed, as if using -setHighlightMode:YES, but that's another problem.)
Other interesting notes:
The status item's window uses another NSVisualEffectView as its contentView. This view uses the special Clear material. I'm not sure exactly what the purpose of this view is, someone with deeper knowledge of the compositing system might have some insight. Turning off Clear and setting the selection material directly on this view causes some funky (reverse?) rendering with the button.
@avaidyam
Copy link

Thanks for sharing this info! For those interested in finding out more about internal material types, see here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment