1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsLookAndFeel.h"
7 #include "nsCocoaFeatures.h"
8 #include "nsIServiceManager.h"
9 #include "nsNativeThemeColors.h"
10 #include "nsStyleConsts.h"
11 #include "nsCocoaFeatures.h"
13 #include "gfxFontConstants.h"
14 #include "mozilla/gfx/2D.h"
16 #import <Cocoa/Cocoa.h>
18 // This must be included last:
19 #include "nsObjCExceptions.h"
22 mozNSScrollerStyleLegacy = 0,
23 mozNSScrollerStyleOverlay = 1
25 typedef NSInteger mozNSScrollerStyle;
27 @interface NSScroller(AvailableSinceLion)
28 + (mozNSScrollerStyle)preferredScrollerStyle;
31 nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel()
35 nsLookAndFeel::~nsLookAndFeel()
39 static nscolor GetColorFromNSColor(NSColor* aColor)
41 NSColor* deviceColor = [aColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
42 return NS_RGB((unsigned int)([deviceColor redComponent] * 255.0),
43 (unsigned int)([deviceColor greenComponent] * 255.0),
44 (unsigned int)([deviceColor blueComponent] * 255.0));
48 nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
50 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
55 case eColorID_WindowBackground:
56 aColor = NS_RGB(0xff,0xff,0xff);
58 case eColorID_WindowForeground:
59 aColor = NS_RGB(0x00,0x00,0x00);
61 case eColorID_WidgetBackground:
62 aColor = NS_RGB(0xdd,0xdd,0xdd);
64 case eColorID_WidgetForeground:
65 aColor = NS_RGB(0x00,0x00,0x00);
67 case eColorID_WidgetSelectBackground:
68 aColor = NS_RGB(0x80,0x80,0x80);
70 case eColorID_WidgetSelectForeground:
71 aColor = NS_RGB(0x00,0x00,0x80);
73 case eColorID_Widget3DHighlight:
74 aColor = NS_RGB(0xa0,0xa0,0xa0);
76 case eColorID_Widget3DShadow:
77 aColor = NS_RGB(0x40,0x40,0x40);
79 case eColorID_TextBackground:
80 aColor = NS_RGB(0xff,0xff,0xff);
82 case eColorID_TextForeground:
83 aColor = NS_RGB(0x00,0x00,0x00);
85 case eColorID_TextSelectBackground:
86 aColor = GetColorFromNSColor([NSColor selectedTextBackgroundColor]);
88 case eColorID_highlight: // CSS2 color
89 aColor = GetColorFromNSColor([NSColor alternateSelectedControlColor]);
91 case eColorID__moz_menuhover:
92 aColor = GetColorFromNSColor([NSColor alternateSelectedControlColor]);
94 case eColorID_TextSelectForeground:
95 GetColor(eColorID_TextSelectBackground, aColor);
96 if (aColor == 0x000000)
97 aColor = NS_RGB(0xff,0xff,0xff);
99 aColor = NS_DONT_CHANGE_COLOR;
101 case eColorID_highlighttext: // CSS2 color
102 case eColorID__moz_menuhovertext:
103 aColor = GetColorFromNSColor([NSColor alternateSelectedControlTextColor]);
105 case eColorID_IMESelectedRawTextBackground:
106 case eColorID_IMESelectedConvertedTextBackground:
107 case eColorID_IMERawInputBackground:
108 case eColorID_IMEConvertedTextBackground:
109 aColor = NS_TRANSPARENT;
111 case eColorID_IMESelectedRawTextForeground:
112 case eColorID_IMESelectedConvertedTextForeground:
113 case eColorID_IMERawInputForeground:
114 case eColorID_IMEConvertedTextForeground:
115 aColor = NS_SAME_AS_FOREGROUND_COLOR;
117 case eColorID_IMERawInputUnderline:
118 case eColorID_IMEConvertedTextUnderline:
119 aColor = NS_40PERCENT_FOREGROUND_COLOR;
121 case eColorID_IMESelectedRawTextUnderline:
122 case eColorID_IMESelectedConvertedTextUnderline:
123 aColor = NS_SAME_AS_FOREGROUND_COLOR;
125 case eColorID_SpellCheckerUnderline:
126 aColor = NS_RGB(0xff, 0, 0);
130 // css2 system colors http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
132 // It's really hard to effectively map these to the Appearance Manager properly,
133 // since they are modeled word for word after the win32 system colors and don't have any
134 // real counterparts in the Mac world. I'm sure we'll be tweaking these for
137 // Thanks to mpt26@student.canterbury.ac.nz for the hardcoded values that form the defaults
138 // if querying the Appearance Manager fails ;)
140 case eColorID__moz_mac_buttonactivetext:
141 case eColorID__moz_mac_defaultbuttontext:
142 if (nsCocoaFeatures::OnYosemiteOrLater()) {
143 aColor = NS_RGB(0xFF,0xFF,0xFF);
146 // Otherwise fall through and return the regular button text:
148 case eColorID_buttontext:
149 case eColorID__moz_buttonhovertext:
150 aColor = GetColorFromNSColor([NSColor controlTextColor]);
152 case eColorID_captiontext:
153 case eColorID_menutext:
154 case eColorID_infotext:
155 case eColorID__moz_menubartext:
156 aColor = GetColorFromNSColor([NSColor textColor]);
158 case eColorID_windowtext:
159 aColor = GetColorFromNSColor([NSColor windowFrameTextColor]);
161 case eColorID_activecaption:
162 aColor = GetColorFromNSColor([NSColor gridColor]);
164 case eColorID_activeborder:
165 aColor = NS_RGB(0x00,0x00,0x00);
167 case eColorID_appworkspace:
168 aColor = NS_RGB(0xFF,0xFF,0xFF);
170 case eColorID_background:
171 aColor = NS_RGB(0x63,0x63,0xCE);
173 case eColorID_buttonface:
174 case eColorID__moz_buttonhoverface:
175 aColor = NS_RGB(0xF0,0xF0,0xF0);
177 case eColorID_buttonhighlight:
178 aColor = NS_RGB(0xFF,0xFF,0xFF);
180 case eColorID_buttonshadow:
181 aColor = NS_RGB(0xDC,0xDC,0xDC);
183 case eColorID_graytext:
184 aColor = GetColorFromNSColor([NSColor disabledControlTextColor]);
186 case eColorID_inactiveborder:
187 aColor = GetColorFromNSColor([NSColor controlBackgroundColor]);
189 case eColorID_inactivecaption:
190 aColor = GetColorFromNSColor([NSColor controlBackgroundColor]);
192 case eColorID_inactivecaptiontext:
193 aColor = NS_RGB(0x45,0x45,0x45);
195 case eColorID_scrollbar:
196 aColor = GetColorFromNSColor([NSColor scrollBarColor]);
198 case eColorID_threeddarkshadow:
199 aColor = NS_RGB(0xDC,0xDC,0xDC);
201 case eColorID_threedshadow:
202 aColor = NS_RGB(0xE0,0xE0,0xE0);
204 case eColorID_threedface:
205 aColor = NS_RGB(0xF0,0xF0,0xF0);
207 case eColorID_threedhighlight:
208 aColor = GetColorFromNSColor([NSColor highlightColor]);
210 case eColorID_threedlightshadow:
211 aColor = NS_RGB(0xDA,0xDA,0xDA);
214 aColor = GetColorFromNSColor([NSColor alternateSelectedControlTextColor]);
216 case eColorID_infobackground:
217 aColor = NS_RGB(0xFF,0xFF,0xC7);
219 case eColorID_windowframe:
220 aColor = GetColorFromNSColor([NSColor gridColor]);
222 case eColorID_window:
223 case eColorID__moz_field:
224 case eColorID__moz_combobox:
225 aColor = NS_RGB(0xff,0xff,0xff);
227 case eColorID__moz_fieldtext:
228 case eColorID__moz_comboboxtext:
229 aColor = GetColorFromNSColor([NSColor controlTextColor]);
231 case eColorID__moz_dialog:
232 aColor = GetColorFromNSColor([NSColor controlHighlightColor]);
234 case eColorID__moz_dialogtext:
235 case eColorID__moz_cellhighlighttext:
236 case eColorID__moz_html_cellhighlighttext:
237 aColor = GetColorFromNSColor([NSColor controlTextColor]);
239 case eColorID__moz_dragtargetzone:
240 aColor = GetColorFromNSColor([NSColor selectedControlColor]);
242 case eColorID__moz_mac_chrome_active:
243 case eColorID__moz_mac_chrome_inactive: {
244 int grey = NativeGreyColorAsInt(toolbarFillGrey, (aID == eColorID__moz_mac_chrome_active));
245 aColor = NS_RGB(grey, grey, grey);
248 case eColorID__moz_mac_focusring:
249 aColor = GetColorFromNSColor([NSColor keyboardFocusIndicatorColor]);
251 case eColorID__moz_mac_menushadow:
252 aColor = NS_RGB(0xA3,0xA3,0xA3);
254 case eColorID__moz_mac_menutextdisable:
255 aColor = NS_RGB(0x98,0x98,0x98);
257 case eColorID__moz_mac_menutextselect:
258 aColor = GetColorFromNSColor([NSColor selectedMenuItemTextColor]);
260 case eColorID__moz_mac_disabledtoolbartext:
261 aColor = GetColorFromNSColor([NSColor disabledControlTextColor]);
263 case eColorID__moz_mac_menuselect:
264 aColor = GetColorFromNSColor([NSColor alternateSelectedControlColor]);
266 case eColorID__moz_buttondefault:
267 aColor = NS_RGB(0xDC,0xDC,0xDC);
269 case eColorID__moz_cellhighlight:
270 case eColorID__moz_html_cellhighlight:
271 case eColorID__moz_mac_secondaryhighlight:
272 // For inactive list selection
273 aColor = GetColorFromNSColor([NSColor secondarySelectedControlColor]);
275 case eColorID__moz_eventreerow:
276 // Background color of even list rows.
277 aColor = GetColorFromNSColor([[NSColor controlAlternatingRowBackgroundColors] objectAtIndex:0]);
279 case eColorID__moz_oddtreerow:
280 // Background color of odd list rows.
281 aColor = GetColorFromNSColor([[NSColor controlAlternatingRowBackgroundColors] objectAtIndex:1]);
283 case eColorID__moz_nativehyperlinktext:
284 // There appears to be no available system defined color. HARDCODING to the appropriate color.
285 aColor = NS_RGB(0x14,0x4F,0xAE);
288 NS_WARNING("Someone asked nsILookAndFeel for a color I don't know about");
289 aColor = NS_RGB(0xff,0xff,0xff);
290 res = NS_ERROR_FAILURE;
296 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
300 nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
302 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
304 nsresult res = nsXPLookAndFeel::GetIntImpl(aID, aResult);
305 if (NS_SUCCEEDED(res))
310 case eIntID_CaretBlinkTime:
313 case eIntID_CaretWidth:
316 case eIntID_ShowCaretDuringSelection:
319 case eIntID_SelectTextfieldsOnKeyFocus:
320 // Select textfield content when focused by kbd
321 // used by EventStateManager::sTextfieldSelectModel
324 case eIntID_SubmenuDelay:
327 case eIntID_TooltipDelay:
330 case eIntID_MenusCanOverlapOSBar:
331 // xul popups are not allowed to overlap the menubar.
334 case eIntID_SkipNavigatingDisabledMenuItem:
337 case eIntID_DragThresholdX:
338 case eIntID_DragThresholdY:
341 case eIntID_ScrollArrowStyle:
342 if (nsCocoaFeatures::OnLionOrLater()) {
343 // OS X Lion's scrollbars have no arrows
344 aResult = eScrollArrow_None;
346 NSString *buttonPlacement = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleScrollBarVariant"];
347 if ([buttonPlacement isEqualToString:@"Single"]) {
348 aResult = eScrollArrowStyle_Single;
349 } else if ([buttonPlacement isEqualToString:@"DoubleMin"]) {
350 aResult = eScrollArrowStyle_BothAtTop;
351 } else if ([buttonPlacement isEqualToString:@"DoubleBoth"]) {
352 aResult = eScrollArrowStyle_BothAtEachEnd;
354 aResult = eScrollArrowStyle_BothAtBottom; // The default is BothAtBottom.
358 case eIntID_ScrollSliderStyle:
359 aResult = eScrollThumbStyle_Proportional;
361 case eIntID_UseOverlayScrollbars:
362 aResult = SystemWantsOverlayScrollbars() ? 1 : 0;
364 case eIntID_AllowOverlayScrollbarsOverlap:
365 aResult = AllowOverlayScrollbarsOverlap() ? 1 : 0;
367 case eIntID_ScrollbarDisplayOnMouseMove:
370 case eIntID_ScrollbarFadeBeginDelay:
373 case eIntID_ScrollbarFadeDuration:
376 case eIntID_TreeOpenDelay:
379 case eIntID_TreeCloseDelay:
382 case eIntID_TreeLazyScrollDelay:
385 case eIntID_TreeScrollDelay:
388 case eIntID_TreeScrollLinesMax:
391 case eIntID_DWMCompositor:
392 case eIntID_WindowsClassic:
393 case eIntID_WindowsDefaultTheme:
394 case eIntID_TouchEnabled:
395 case eIntID_WindowsThemeIdentifier:
396 case eIntID_OperatingSystemVersionIdentifier:
398 res = NS_ERROR_NOT_IMPLEMENTED;
400 case eIntID_MacGraphiteTheme:
401 aResult = [NSColor currentControlTint] == NSGraphiteControlTint;
403 case eIntID_MacLionTheme:
404 aResult = nsCocoaFeatures::OnLionOrLater();
406 case eIntID_MacYosemiteTheme:
407 aResult = nsCocoaFeatures::OnYosemiteOrLater();
409 case eIntID_AlertNotificationOrigin:
410 aResult = NS_ALERT_TOP;
412 case eIntID_TabFocusModel:
414 // we should probably cache this
415 CFPropertyListRef fullKeyboardAccessProperty;
416 fullKeyboardAccessProperty = ::CFPreferencesCopyValue(CFSTR("AppleKeyboardUIMode"),
417 kCFPreferencesAnyApplication,
418 kCFPreferencesCurrentUser,
419 kCFPreferencesAnyHost);
420 aResult = 1; // default to just textboxes
421 if (fullKeyboardAccessProperty) {
422 int32_t fullKeyboardAccessPrefVal;
423 if (::CFNumberGetValue((CFNumberRef) fullKeyboardAccessProperty, kCFNumberIntType, &fullKeyboardAccessPrefVal)) {
424 // the second bit means "Full keyboard access" is on
425 if (fullKeyboardAccessPrefVal & (1 << 1))
426 aResult = 7; // everything that can be focused
428 ::CFRelease(fullKeyboardAccessProperty);
432 case eIntID_ScrollToClick:
434 aResult = [[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollerPagingBehavior"];
437 case eIntID_ChosenMenuItemsShouldBlink:
440 case eIntID_IMERawInputUnderlineStyle:
441 case eIntID_IMEConvertedTextUnderlineStyle:
442 case eIntID_IMESelectedRawTextUnderlineStyle:
443 case eIntID_IMESelectedConvertedTextUnderline:
444 aResult = NS_STYLE_TEXT_DECORATION_STYLE_SOLID;
446 case eIntID_SpellCheckerUnderlineStyle:
447 aResult = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED;
449 case eIntID_ScrollbarButtonAutoRepeatBehavior:
452 case eIntID_SwipeAnimationEnabled:
454 if ([NSEvent respondsToSelector:@selector(
455 isSwipeTrackingFromScrollEventsEnabled)]) {
456 aResult = [NSEvent isSwipeTrackingFromScrollEventsEnabled] ? 1 : 0;
459 case eIntID_ColorPickerAvailable:
464 res = NS_ERROR_FAILURE;
468 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
472 nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult)
474 nsresult res = nsXPLookAndFeel::GetFloatImpl(aID, aResult);
475 if (NS_SUCCEEDED(res))
480 case eFloatID_IMEUnderlineRelativeSize:
483 case eFloatID_SpellCheckerUnderlineRelativeSize:
488 res = NS_ERROR_FAILURE;
494 bool nsLookAndFeel::UseOverlayScrollbars()
496 return GetInt(eIntID_UseOverlayScrollbars) != 0;
499 bool nsLookAndFeel::SystemWantsOverlayScrollbars()
501 return ([NSScroller respondsToSelector:@selector(preferredScrollerStyle)] &&
502 [NSScroller preferredScrollerStyle] == mozNSScrollerStyleOverlay);
505 bool nsLookAndFeel::AllowOverlayScrollbarsOverlap()
507 return (UseOverlayScrollbars() && nsCocoaFeatures::OnMountainLionOrLater());
510 // copied from gfxQuartzFontCache.mm, maybe should go in a Cocoa utils
512 static void GetStringForNSString(const NSString *aSrc, nsAString& aDest)
514 aDest.SetLength([aSrc length]);
515 [aSrc getCharacters:reinterpret_cast<unichar*>(aDest.BeginWriting())];
519 nsLookAndFeel::GetFontImpl(FontID aID, nsString &aFontName,
520 gfxFontStyle &aFontStyle,
521 float aDevPixPerCSSPixel)
523 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
526 if (aID == eFont_Window || aID == eFont_Document) {
527 aFontStyle.style = NS_FONT_STYLE_NORMAL;
528 aFontStyle.weight = NS_FONT_WEIGHT_NORMAL;
529 aFontStyle.stretch = NS_FONT_STRETCH_NORMAL;
530 aFontStyle.size = 14 * aDevPixPerCSSPixel;
531 aFontStyle.systemFont = true;
533 aFontName.AssignLiteral("sans-serif");
537 /* possibilities, see NSFont Class Reference:
538 [NSFont boldSystemFontOfSize: 0.0]
539 [NSFont controlContentFontOfSize: 0.0]
540 [NSFont labelFontOfSize: 0.0]
541 [NSFont menuBarFontOfSize: 0.0]
542 [NSFont menuFontOfSize: 0.0]
543 [NSFont messageFontOfSize: 0.0]
544 [NSFont paletteFontOfSize: 0.0]
545 [NSFont systemFontOfSize: 0.0]
546 [NSFont titleBarFontOfSize: 0.0]
547 [NSFont toolTipsFontOfSize: 0.0]
548 [NSFont userFixedPitchFontOfSize: 0.0]
549 [NSFont userFontOfSize: 0.0]
550 [NSFont systemFontOfSize: [NSFont smallSystemFontSize]]
551 [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]]
554 NSFont *font = nullptr;
558 font = [NSFont systemFontOfSize:0.0];
560 case eFont_Icon: // used in urlbar; tried labelFont, but too small
561 font = [NSFont controlContentFontOfSize:0.0];
564 font = [NSFont systemFontOfSize:0.0];
566 case eFont_MessageBox:
567 font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
569 case eFont_SmallCaption:
570 font = [NSFont boldSystemFontOfSize:[NSFont smallSystemFontSize]];
572 case eFont_StatusBar:
573 font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
576 //case eFont_Window: = 'sans-serif'
577 //case eFont_Document: = 'sans-serif'
578 case eFont_Workspace:
579 font = [NSFont controlContentFontOfSize:0.0];
582 font = [NSFont controlContentFontOfSize:0.0];
585 font = [NSFont controlContentFontOfSize:0.0];
588 font = [NSFont systemFontOfSize:0.0];
591 font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
593 case eFont_PullDownMenu:
594 font = [NSFont menuBarFontOfSize:0.0];
597 font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
600 font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
604 font = [NSFont toolTipsFontOfSize:0.0];
607 font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
614 NS_WARNING("failed to find a system font!");
618 NSFontSymbolicTraits traits = [[font fontDescriptor] symbolicTraits];
620 (traits & NSFontItalicTrait) ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL;
622 (traits & NSFontBoldTrait) ? NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL;
624 (traits & NSFontExpandedTrait) ?
625 NS_FONT_STRETCH_EXPANDED : (traits & NSFontCondensedTrait) ?
626 NS_FONT_STRETCH_CONDENSED : NS_FONT_STRETCH_NORMAL;
627 // convert size from css pixels to device pixels
628 aFontStyle.size = [font pointSize] * aDevPixPerCSSPixel;
629 aFontStyle.systemFont = true;
631 GetStringForNSString([font familyName], aFontName);
634 NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);