Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #include "nsLookAndFeel.h" |
michael@0 | 7 | #include <windows.h> |
michael@0 | 8 | #include <shellapi.h> |
michael@0 | 9 | #include "nsStyleConsts.h" |
michael@0 | 10 | #include "nsUXThemeData.h" |
michael@0 | 11 | #include "nsUXThemeConstants.h" |
michael@0 | 12 | #include "gfxFont.h" |
michael@0 | 13 | #include "gfxWindowsPlatform.h" |
michael@0 | 14 | #include "mozilla/Telemetry.h" |
michael@0 | 15 | #include "mozilla/WindowsVersion.h" |
michael@0 | 16 | #include "gfxFontConstants.h" |
michael@0 | 17 | |
michael@0 | 18 | using namespace mozilla; |
michael@0 | 19 | using namespace mozilla::widget; |
michael@0 | 20 | |
michael@0 | 21 | //static |
michael@0 | 22 | LookAndFeel::OperatingSystemVersion |
michael@0 | 23 | nsLookAndFeel::GetOperatingSystemVersion() |
michael@0 | 24 | { |
michael@0 | 25 | static OperatingSystemVersion version = eOperatingSystemVersion_Unknown; |
michael@0 | 26 | |
michael@0 | 27 | if (version != eOperatingSystemVersion_Unknown) { |
michael@0 | 28 | return version; |
michael@0 | 29 | } |
michael@0 | 30 | |
michael@0 | 31 | if (IsWin8OrLater()) { |
michael@0 | 32 | version = eOperatingSystemVersion_Windows8; |
michael@0 | 33 | } else if (IsWin7OrLater()) { |
michael@0 | 34 | version = eOperatingSystemVersion_Windows7; |
michael@0 | 35 | } else if (IsVistaOrLater()) { |
michael@0 | 36 | version = eOperatingSystemVersion_WindowsVista; |
michael@0 | 37 | } else { |
michael@0 | 38 | version = eOperatingSystemVersion_WindowsXP; |
michael@0 | 39 | } |
michael@0 | 40 | |
michael@0 | 41 | return version; |
michael@0 | 42 | } |
michael@0 | 43 | |
michael@0 | 44 | static nsresult GetColorFromTheme(nsUXThemeClass cls, |
michael@0 | 45 | int32_t aPart, |
michael@0 | 46 | int32_t aState, |
michael@0 | 47 | int32_t aPropId, |
michael@0 | 48 | nscolor &aColor) |
michael@0 | 49 | { |
michael@0 | 50 | COLORREF color; |
michael@0 | 51 | HRESULT hr = GetThemeColor(nsUXThemeData::GetTheme(cls), aPart, aState, aPropId, &color); |
michael@0 | 52 | if (hr == S_OK) |
michael@0 | 53 | { |
michael@0 | 54 | aColor = COLOREF_2_NSRGB(color); |
michael@0 | 55 | return NS_OK; |
michael@0 | 56 | } |
michael@0 | 57 | return NS_ERROR_FAILURE; |
michael@0 | 58 | } |
michael@0 | 59 | |
michael@0 | 60 | static int32_t GetSystemParam(long flag, int32_t def) |
michael@0 | 61 | { |
michael@0 | 62 | DWORD value; |
michael@0 | 63 | return ::SystemParametersInfo(flag, 0, &value, 0) ? value : def; |
michael@0 | 64 | } |
michael@0 | 65 | |
michael@0 | 66 | namespace mozilla { |
michael@0 | 67 | namespace widget { |
michael@0 | 68 | // This is in use here and in dom/events/TouchEvent.cpp |
michael@0 | 69 | int32_t IsTouchDeviceSupportPresent() |
michael@0 | 70 | { |
michael@0 | 71 | int32_t touchCapabilities; |
michael@0 | 72 | touchCapabilities = ::GetSystemMetrics(SM_DIGITIZER); |
michael@0 | 73 | return ((touchCapabilities & NID_READY) && |
michael@0 | 74 | (touchCapabilities & (NID_EXTERNAL_TOUCH | NID_INTEGRATED_TOUCH))); |
michael@0 | 75 | } |
michael@0 | 76 | } } |
michael@0 | 77 | |
michael@0 | 78 | nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel() |
michael@0 | 79 | { |
michael@0 | 80 | mozilla::Telemetry::Accumulate(mozilla::Telemetry::TOUCH_ENABLED_DEVICE, |
michael@0 | 81 | IsTouchDeviceSupportPresent()); |
michael@0 | 82 | } |
michael@0 | 83 | |
michael@0 | 84 | nsLookAndFeel::~nsLookAndFeel() |
michael@0 | 85 | { |
michael@0 | 86 | } |
michael@0 | 87 | |
michael@0 | 88 | nsresult |
michael@0 | 89 | nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor) |
michael@0 | 90 | { |
michael@0 | 91 | nsresult res = NS_OK; |
michael@0 | 92 | |
michael@0 | 93 | int idx; |
michael@0 | 94 | switch (aID) { |
michael@0 | 95 | case eColorID_WindowBackground: |
michael@0 | 96 | idx = COLOR_WINDOW; |
michael@0 | 97 | break; |
michael@0 | 98 | case eColorID_WindowForeground: |
michael@0 | 99 | idx = COLOR_WINDOWTEXT; |
michael@0 | 100 | break; |
michael@0 | 101 | case eColorID_WidgetBackground: |
michael@0 | 102 | idx = COLOR_BTNFACE; |
michael@0 | 103 | break; |
michael@0 | 104 | case eColorID_WidgetForeground: |
michael@0 | 105 | idx = COLOR_BTNTEXT; |
michael@0 | 106 | break; |
michael@0 | 107 | case eColorID_WidgetSelectBackground: |
michael@0 | 108 | idx = COLOR_HIGHLIGHT; |
michael@0 | 109 | break; |
michael@0 | 110 | case eColorID_WidgetSelectForeground: |
michael@0 | 111 | idx = COLOR_HIGHLIGHTTEXT; |
michael@0 | 112 | break; |
michael@0 | 113 | case eColorID_Widget3DHighlight: |
michael@0 | 114 | idx = COLOR_BTNHIGHLIGHT; |
michael@0 | 115 | break; |
michael@0 | 116 | case eColorID_Widget3DShadow: |
michael@0 | 117 | idx = COLOR_BTNSHADOW; |
michael@0 | 118 | break; |
michael@0 | 119 | case eColorID_TextBackground: |
michael@0 | 120 | idx = COLOR_WINDOW; |
michael@0 | 121 | break; |
michael@0 | 122 | case eColorID_TextForeground: |
michael@0 | 123 | idx = COLOR_WINDOWTEXT; |
michael@0 | 124 | break; |
michael@0 | 125 | case eColorID_TextSelectBackground: |
michael@0 | 126 | case eColorID_IMESelectedRawTextBackground: |
michael@0 | 127 | case eColorID_IMESelectedConvertedTextBackground: |
michael@0 | 128 | idx = COLOR_HIGHLIGHT; |
michael@0 | 129 | break; |
michael@0 | 130 | case eColorID_TextSelectForeground: |
michael@0 | 131 | case eColorID_IMESelectedRawTextForeground: |
michael@0 | 132 | case eColorID_IMESelectedConvertedTextForeground: |
michael@0 | 133 | idx = COLOR_HIGHLIGHTTEXT; |
michael@0 | 134 | break; |
michael@0 | 135 | case eColorID_IMERawInputBackground: |
michael@0 | 136 | case eColorID_IMEConvertedTextBackground: |
michael@0 | 137 | aColor = NS_TRANSPARENT; |
michael@0 | 138 | return NS_OK; |
michael@0 | 139 | case eColorID_IMERawInputForeground: |
michael@0 | 140 | case eColorID_IMEConvertedTextForeground: |
michael@0 | 141 | aColor = NS_SAME_AS_FOREGROUND_COLOR; |
michael@0 | 142 | return NS_OK; |
michael@0 | 143 | case eColorID_IMERawInputUnderline: |
michael@0 | 144 | case eColorID_IMEConvertedTextUnderline: |
michael@0 | 145 | aColor = NS_SAME_AS_FOREGROUND_COLOR; |
michael@0 | 146 | return NS_OK; |
michael@0 | 147 | case eColorID_IMESelectedRawTextUnderline: |
michael@0 | 148 | case eColorID_IMESelectedConvertedTextUnderline: |
michael@0 | 149 | aColor = NS_TRANSPARENT; |
michael@0 | 150 | return NS_OK; |
michael@0 | 151 | case eColorID_SpellCheckerUnderline: |
michael@0 | 152 | aColor = NS_RGB(0xff, 0, 0); |
michael@0 | 153 | return NS_OK; |
michael@0 | 154 | |
michael@0 | 155 | // New CSS 2 Color definitions |
michael@0 | 156 | case eColorID_activeborder: |
michael@0 | 157 | idx = COLOR_ACTIVEBORDER; |
michael@0 | 158 | break; |
michael@0 | 159 | case eColorID_activecaption: |
michael@0 | 160 | idx = COLOR_ACTIVECAPTION; |
michael@0 | 161 | break; |
michael@0 | 162 | case eColorID_appworkspace: |
michael@0 | 163 | idx = COLOR_APPWORKSPACE; |
michael@0 | 164 | break; |
michael@0 | 165 | case eColorID_background: |
michael@0 | 166 | idx = COLOR_BACKGROUND; |
michael@0 | 167 | break; |
michael@0 | 168 | case eColorID_buttonface: |
michael@0 | 169 | case eColorID__moz_buttonhoverface: |
michael@0 | 170 | idx = COLOR_BTNFACE; |
michael@0 | 171 | break; |
michael@0 | 172 | case eColorID_buttonhighlight: |
michael@0 | 173 | idx = COLOR_BTNHIGHLIGHT; |
michael@0 | 174 | break; |
michael@0 | 175 | case eColorID_buttonshadow: |
michael@0 | 176 | idx = COLOR_BTNSHADOW; |
michael@0 | 177 | break; |
michael@0 | 178 | case eColorID_buttontext: |
michael@0 | 179 | case eColorID__moz_buttonhovertext: |
michael@0 | 180 | idx = COLOR_BTNTEXT; |
michael@0 | 181 | break; |
michael@0 | 182 | case eColorID_captiontext: |
michael@0 | 183 | idx = COLOR_CAPTIONTEXT; |
michael@0 | 184 | break; |
michael@0 | 185 | case eColorID_graytext: |
michael@0 | 186 | idx = COLOR_GRAYTEXT; |
michael@0 | 187 | break; |
michael@0 | 188 | case eColorID_highlight: |
michael@0 | 189 | case eColorID__moz_html_cellhighlight: |
michael@0 | 190 | case eColorID__moz_menuhover: |
michael@0 | 191 | idx = COLOR_HIGHLIGHT; |
michael@0 | 192 | break; |
michael@0 | 193 | case eColorID__moz_menubarhovertext: |
michael@0 | 194 | if (!IsVistaOrLater() || !IsAppThemed()) |
michael@0 | 195 | { |
michael@0 | 196 | idx = nsUXThemeData::sFlatMenus ? |
michael@0 | 197 | COLOR_HIGHLIGHTTEXT : |
michael@0 | 198 | COLOR_MENUTEXT; |
michael@0 | 199 | break; |
michael@0 | 200 | } |
michael@0 | 201 | // Fall through |
michael@0 | 202 | case eColorID__moz_menuhovertext: |
michael@0 | 203 | if (IsVistaOrLater() && IsAppThemed()) |
michael@0 | 204 | { |
michael@0 | 205 | res = ::GetColorFromTheme(eUXMenu, |
michael@0 | 206 | MENU_POPUPITEM, MPI_HOT, TMT_TEXTCOLOR, aColor); |
michael@0 | 207 | if (NS_SUCCEEDED(res)) |
michael@0 | 208 | return res; |
michael@0 | 209 | // fall through to highlight case |
michael@0 | 210 | } |
michael@0 | 211 | case eColorID_highlighttext: |
michael@0 | 212 | case eColorID__moz_html_cellhighlighttext: |
michael@0 | 213 | idx = COLOR_HIGHLIGHTTEXT; |
michael@0 | 214 | break; |
michael@0 | 215 | case eColorID_inactiveborder: |
michael@0 | 216 | idx = COLOR_INACTIVEBORDER; |
michael@0 | 217 | break; |
michael@0 | 218 | case eColorID_inactivecaption: |
michael@0 | 219 | idx = COLOR_INACTIVECAPTION; |
michael@0 | 220 | break; |
michael@0 | 221 | case eColorID_inactivecaptiontext: |
michael@0 | 222 | idx = COLOR_INACTIVECAPTIONTEXT; |
michael@0 | 223 | break; |
michael@0 | 224 | case eColorID_infobackground: |
michael@0 | 225 | idx = COLOR_INFOBK; |
michael@0 | 226 | break; |
michael@0 | 227 | case eColorID_infotext: |
michael@0 | 228 | idx = COLOR_INFOTEXT; |
michael@0 | 229 | break; |
michael@0 | 230 | case eColorID_menu: |
michael@0 | 231 | idx = COLOR_MENU; |
michael@0 | 232 | break; |
michael@0 | 233 | case eColorID_menutext: |
michael@0 | 234 | case eColorID__moz_menubartext: |
michael@0 | 235 | idx = COLOR_MENUTEXT; |
michael@0 | 236 | break; |
michael@0 | 237 | case eColorID_scrollbar: |
michael@0 | 238 | idx = COLOR_SCROLLBAR; |
michael@0 | 239 | break; |
michael@0 | 240 | case eColorID_threeddarkshadow: |
michael@0 | 241 | idx = COLOR_3DDKSHADOW; |
michael@0 | 242 | break; |
michael@0 | 243 | case eColorID_threedface: |
michael@0 | 244 | idx = COLOR_3DFACE; |
michael@0 | 245 | break; |
michael@0 | 246 | case eColorID_threedhighlight: |
michael@0 | 247 | idx = COLOR_3DHIGHLIGHT; |
michael@0 | 248 | break; |
michael@0 | 249 | case eColorID_threedlightshadow: |
michael@0 | 250 | idx = COLOR_3DLIGHT; |
michael@0 | 251 | break; |
michael@0 | 252 | case eColorID_threedshadow: |
michael@0 | 253 | idx = COLOR_3DSHADOW; |
michael@0 | 254 | break; |
michael@0 | 255 | case eColorID_window: |
michael@0 | 256 | idx = COLOR_WINDOW; |
michael@0 | 257 | break; |
michael@0 | 258 | case eColorID_windowframe: |
michael@0 | 259 | idx = COLOR_WINDOWFRAME; |
michael@0 | 260 | break; |
michael@0 | 261 | case eColorID_windowtext: |
michael@0 | 262 | idx = COLOR_WINDOWTEXT; |
michael@0 | 263 | break; |
michael@0 | 264 | case eColorID__moz_eventreerow: |
michael@0 | 265 | case eColorID__moz_oddtreerow: |
michael@0 | 266 | case eColorID__moz_field: |
michael@0 | 267 | case eColorID__moz_combobox: |
michael@0 | 268 | idx = COLOR_WINDOW; |
michael@0 | 269 | break; |
michael@0 | 270 | case eColorID__moz_fieldtext: |
michael@0 | 271 | case eColorID__moz_comboboxtext: |
michael@0 | 272 | idx = COLOR_WINDOWTEXT; |
michael@0 | 273 | break; |
michael@0 | 274 | case eColorID__moz_dialog: |
michael@0 | 275 | case eColorID__moz_cellhighlight: |
michael@0 | 276 | idx = COLOR_3DFACE; |
michael@0 | 277 | break; |
michael@0 | 278 | case eColorID__moz_win_mediatext: |
michael@0 | 279 | if (IsVistaOrLater() && IsAppThemed()) { |
michael@0 | 280 | res = ::GetColorFromTheme(eUXMediaToolbar, |
michael@0 | 281 | TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor); |
michael@0 | 282 | if (NS_SUCCEEDED(res)) |
michael@0 | 283 | return res; |
michael@0 | 284 | } |
michael@0 | 285 | // if we've gotten here just return -moz-dialogtext instead |
michael@0 | 286 | idx = COLOR_WINDOWTEXT; |
michael@0 | 287 | break; |
michael@0 | 288 | case eColorID__moz_win_communicationstext: |
michael@0 | 289 | if (IsVistaOrLater() && IsAppThemed()) |
michael@0 | 290 | { |
michael@0 | 291 | res = ::GetColorFromTheme(eUXCommunicationsToolbar, |
michael@0 | 292 | TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor); |
michael@0 | 293 | if (NS_SUCCEEDED(res)) |
michael@0 | 294 | return res; |
michael@0 | 295 | } |
michael@0 | 296 | // if we've gotten here just return -moz-dialogtext instead |
michael@0 | 297 | idx = COLOR_WINDOWTEXT; |
michael@0 | 298 | break; |
michael@0 | 299 | case eColorID__moz_dialogtext: |
michael@0 | 300 | case eColorID__moz_cellhighlighttext: |
michael@0 | 301 | idx = COLOR_WINDOWTEXT; |
michael@0 | 302 | break; |
michael@0 | 303 | case eColorID__moz_dragtargetzone: |
michael@0 | 304 | idx = COLOR_HIGHLIGHTTEXT; |
michael@0 | 305 | break; |
michael@0 | 306 | case eColorID__moz_buttondefault: |
michael@0 | 307 | idx = COLOR_3DDKSHADOW; |
michael@0 | 308 | break; |
michael@0 | 309 | case eColorID__moz_nativehyperlinktext: |
michael@0 | 310 | idx = COLOR_HOTLIGHT; |
michael@0 | 311 | break; |
michael@0 | 312 | default: |
michael@0 | 313 | idx = COLOR_WINDOW; |
michael@0 | 314 | break; |
michael@0 | 315 | } |
michael@0 | 316 | |
michael@0 | 317 | DWORD color = ::GetSysColor(idx); |
michael@0 | 318 | aColor = COLOREF_2_NSRGB(color); |
michael@0 | 319 | |
michael@0 | 320 | return res; |
michael@0 | 321 | } |
michael@0 | 322 | |
michael@0 | 323 | nsresult |
michael@0 | 324 | nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult) |
michael@0 | 325 | { |
michael@0 | 326 | nsresult res = nsXPLookAndFeel::GetIntImpl(aID, aResult); |
michael@0 | 327 | if (NS_SUCCEEDED(res)) |
michael@0 | 328 | return res; |
michael@0 | 329 | res = NS_OK; |
michael@0 | 330 | |
michael@0 | 331 | switch (aID) { |
michael@0 | 332 | case eIntID_CaretBlinkTime: |
michael@0 | 333 | aResult = (int32_t)::GetCaretBlinkTime(); |
michael@0 | 334 | break; |
michael@0 | 335 | case eIntID_CaretWidth: |
michael@0 | 336 | aResult = 1; |
michael@0 | 337 | break; |
michael@0 | 338 | case eIntID_ShowCaretDuringSelection: |
michael@0 | 339 | aResult = 0; |
michael@0 | 340 | break; |
michael@0 | 341 | case eIntID_SelectTextfieldsOnKeyFocus: |
michael@0 | 342 | // Select textfield content when focused by kbd |
michael@0 | 343 | // used by EventStateManager::sTextfieldSelectModel |
michael@0 | 344 | aResult = 1; |
michael@0 | 345 | break; |
michael@0 | 346 | case eIntID_SubmenuDelay: |
michael@0 | 347 | // This will default to the Windows' default |
michael@0 | 348 | // (400ms) on error. |
michael@0 | 349 | aResult = GetSystemParam(SPI_GETMENUSHOWDELAY, 400); |
michael@0 | 350 | break; |
michael@0 | 351 | case eIntID_TooltipDelay: |
michael@0 | 352 | aResult = 500; |
michael@0 | 353 | break; |
michael@0 | 354 | case eIntID_MenusCanOverlapOSBar: |
michael@0 | 355 | // we want XUL popups to be able to overlap the task bar. |
michael@0 | 356 | aResult = 1; |
michael@0 | 357 | break; |
michael@0 | 358 | case eIntID_DragThresholdX: |
michael@0 | 359 | // The system metric is the number of pixels at which a drag should |
michael@0 | 360 | // start. Our look and feel metric is the number of pixels you can |
michael@0 | 361 | // move before starting a drag, so subtract 1. |
michael@0 | 362 | |
michael@0 | 363 | aResult = ::GetSystemMetrics(SM_CXDRAG) - 1; |
michael@0 | 364 | break; |
michael@0 | 365 | case eIntID_DragThresholdY: |
michael@0 | 366 | aResult = ::GetSystemMetrics(SM_CYDRAG) - 1; |
michael@0 | 367 | break; |
michael@0 | 368 | case eIntID_UseAccessibilityTheme: |
michael@0 | 369 | // High contrast is a misnomer under Win32 -- any theme can be used with it, |
michael@0 | 370 | // e.g. normal contrast with large fonts, low contrast, etc. |
michael@0 | 371 | // The high contrast flag really means -- use this theme and don't override it. |
michael@0 | 372 | aResult = nsUXThemeData::IsHighContrastOn(); |
michael@0 | 373 | break; |
michael@0 | 374 | case eIntID_ScrollArrowStyle: |
michael@0 | 375 | aResult = eScrollArrowStyle_Single; |
michael@0 | 376 | break; |
michael@0 | 377 | case eIntID_ScrollSliderStyle: |
michael@0 | 378 | aResult = eScrollThumbStyle_Proportional; |
michael@0 | 379 | break; |
michael@0 | 380 | case eIntID_TreeOpenDelay: |
michael@0 | 381 | aResult = 1000; |
michael@0 | 382 | break; |
michael@0 | 383 | case eIntID_TreeCloseDelay: |
michael@0 | 384 | aResult = 0; |
michael@0 | 385 | break; |
michael@0 | 386 | case eIntID_TreeLazyScrollDelay: |
michael@0 | 387 | aResult = 150; |
michael@0 | 388 | break; |
michael@0 | 389 | case eIntID_TreeScrollDelay: |
michael@0 | 390 | aResult = 100; |
michael@0 | 391 | break; |
michael@0 | 392 | case eIntID_TreeScrollLinesMax: |
michael@0 | 393 | aResult = 3; |
michael@0 | 394 | break; |
michael@0 | 395 | case eIntID_WindowsClassic: |
michael@0 | 396 | aResult = !IsAppThemed(); |
michael@0 | 397 | break; |
michael@0 | 398 | case eIntID_TouchEnabled: |
michael@0 | 399 | aResult = IsTouchDeviceSupportPresent(); |
michael@0 | 400 | break; |
michael@0 | 401 | case eIntID_WindowsDefaultTheme: |
michael@0 | 402 | aResult = nsUXThemeData::IsDefaultWindowTheme(); |
michael@0 | 403 | break; |
michael@0 | 404 | case eIntID_WindowsThemeIdentifier: |
michael@0 | 405 | aResult = nsUXThemeData::GetNativeThemeId(); |
michael@0 | 406 | break; |
michael@0 | 407 | |
michael@0 | 408 | case eIntID_OperatingSystemVersionIdentifier: |
michael@0 | 409 | { |
michael@0 | 410 | aResult = GetOperatingSystemVersion(); |
michael@0 | 411 | break; |
michael@0 | 412 | } |
michael@0 | 413 | |
michael@0 | 414 | case eIntID_MacGraphiteTheme: |
michael@0 | 415 | case eIntID_MacLionTheme: |
michael@0 | 416 | aResult = 0; |
michael@0 | 417 | res = NS_ERROR_NOT_IMPLEMENTED; |
michael@0 | 418 | break; |
michael@0 | 419 | case eIntID_DWMCompositor: |
michael@0 | 420 | aResult = nsUXThemeData::CheckForCompositor(); |
michael@0 | 421 | break; |
michael@0 | 422 | case eIntID_WindowsGlass: |
michael@0 | 423 | // Aero Glass is only available prior to Windows 8 when DWM is used. |
michael@0 | 424 | aResult = (nsUXThemeData::CheckForCompositor() && !IsWin8OrLater()); |
michael@0 | 425 | break; |
michael@0 | 426 | case eIntID_AlertNotificationOrigin: |
michael@0 | 427 | aResult = 0; |
michael@0 | 428 | { |
michael@0 | 429 | // Get task bar window handle |
michael@0 | 430 | HWND shellWindow = FindWindowW(L"Shell_TrayWnd", nullptr); |
michael@0 | 431 | |
michael@0 | 432 | if (shellWindow != nullptr) |
michael@0 | 433 | { |
michael@0 | 434 | // Determine position |
michael@0 | 435 | APPBARDATA appBarData; |
michael@0 | 436 | appBarData.hWnd = shellWindow; |
michael@0 | 437 | appBarData.cbSize = sizeof(appBarData); |
michael@0 | 438 | if (SHAppBarMessage(ABM_GETTASKBARPOS, &appBarData)) |
michael@0 | 439 | { |
michael@0 | 440 | // Set alert origin as a bit field - see LookAndFeel.h |
michael@0 | 441 | // 0 represents bottom right, sliding vertically. |
michael@0 | 442 | switch(appBarData.uEdge) |
michael@0 | 443 | { |
michael@0 | 444 | case ABE_LEFT: |
michael@0 | 445 | aResult = NS_ALERT_HORIZONTAL | NS_ALERT_LEFT; |
michael@0 | 446 | break; |
michael@0 | 447 | case ABE_RIGHT: |
michael@0 | 448 | aResult = NS_ALERT_HORIZONTAL; |
michael@0 | 449 | break; |
michael@0 | 450 | case ABE_TOP: |
michael@0 | 451 | aResult = NS_ALERT_TOP; |
michael@0 | 452 | // fall through for the right-to-left handling. |
michael@0 | 453 | case ABE_BOTTOM: |
michael@0 | 454 | // If the task bar is right-to-left, |
michael@0 | 455 | // move the origin to the left |
michael@0 | 456 | if (::GetWindowLong(shellWindow, GWL_EXSTYLE) & |
michael@0 | 457 | WS_EX_LAYOUTRTL) |
michael@0 | 458 | aResult |= NS_ALERT_LEFT; |
michael@0 | 459 | break; |
michael@0 | 460 | } |
michael@0 | 461 | } |
michael@0 | 462 | } |
michael@0 | 463 | } |
michael@0 | 464 | break; |
michael@0 | 465 | case eIntID_IMERawInputUnderlineStyle: |
michael@0 | 466 | case eIntID_IMEConvertedTextUnderlineStyle: |
michael@0 | 467 | aResult = NS_STYLE_TEXT_DECORATION_STYLE_DASHED; |
michael@0 | 468 | break; |
michael@0 | 469 | case eIntID_IMESelectedRawTextUnderlineStyle: |
michael@0 | 470 | case eIntID_IMESelectedConvertedTextUnderline: |
michael@0 | 471 | aResult = NS_STYLE_TEXT_DECORATION_STYLE_NONE; |
michael@0 | 472 | break; |
michael@0 | 473 | case eIntID_SpellCheckerUnderlineStyle: |
michael@0 | 474 | aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY; |
michael@0 | 475 | break; |
michael@0 | 476 | case eIntID_ScrollbarButtonAutoRepeatBehavior: |
michael@0 | 477 | aResult = 0; |
michael@0 | 478 | break; |
michael@0 | 479 | case eIntID_SwipeAnimationEnabled: |
michael@0 | 480 | aResult = 0; |
michael@0 | 481 | break; |
michael@0 | 482 | case eIntID_ColorPickerAvailable: |
michael@0 | 483 | // We don't have a color picker implemented on Metro yet (bug 895464) |
michael@0 | 484 | aResult = (XRE_GetWindowsEnvironment() != WindowsEnvironmentType_Metro); |
michael@0 | 485 | break; |
michael@0 | 486 | case eIntID_UseOverlayScrollbars: |
michael@0 | 487 | aResult = (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro); |
michael@0 | 488 | break; |
michael@0 | 489 | case eIntID_AllowOverlayScrollbarsOverlap: |
michael@0 | 490 | aResult = 0; |
michael@0 | 491 | break; |
michael@0 | 492 | case eIntID_ScrollbarDisplayOnMouseMove: |
michael@0 | 493 | aResult = 1; |
michael@0 | 494 | break; |
michael@0 | 495 | case eIntID_ScrollbarFadeBeginDelay: |
michael@0 | 496 | aResult = 2500; |
michael@0 | 497 | break; |
michael@0 | 498 | case eIntID_ScrollbarFadeDuration: |
michael@0 | 499 | aResult = 350; |
michael@0 | 500 | break; |
michael@0 | 501 | default: |
michael@0 | 502 | aResult = 0; |
michael@0 | 503 | res = NS_ERROR_FAILURE; |
michael@0 | 504 | } |
michael@0 | 505 | return res; |
michael@0 | 506 | } |
michael@0 | 507 | |
michael@0 | 508 | nsresult |
michael@0 | 509 | nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult) |
michael@0 | 510 | { |
michael@0 | 511 | nsresult res = nsXPLookAndFeel::GetFloatImpl(aID, aResult); |
michael@0 | 512 | if (NS_SUCCEEDED(res)) |
michael@0 | 513 | return res; |
michael@0 | 514 | res = NS_OK; |
michael@0 | 515 | |
michael@0 | 516 | switch (aID) { |
michael@0 | 517 | case eFloatID_IMEUnderlineRelativeSize: |
michael@0 | 518 | aResult = 1.0f; |
michael@0 | 519 | break; |
michael@0 | 520 | case eFloatID_SpellCheckerUnderlineRelativeSize: |
michael@0 | 521 | aResult = 1.0f; |
michael@0 | 522 | break; |
michael@0 | 523 | default: |
michael@0 | 524 | aResult = -1.0; |
michael@0 | 525 | res = NS_ERROR_FAILURE; |
michael@0 | 526 | } |
michael@0 | 527 | return res; |
michael@0 | 528 | } |
michael@0 | 529 | |
michael@0 | 530 | static bool |
michael@0 | 531 | GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID, |
michael@0 | 532 | nsString &aFontName, |
michael@0 | 533 | gfxFontStyle &aFontStyle) |
michael@0 | 534 | { |
michael@0 | 535 | LOGFONTW* ptrLogFont = nullptr; |
michael@0 | 536 | LOGFONTW logFont; |
michael@0 | 537 | NONCLIENTMETRICSW ncm; |
michael@0 | 538 | HGDIOBJ hGDI; |
michael@0 | 539 | char16_t name[LF_FACESIZE]; |
michael@0 | 540 | |
michael@0 | 541 | // Depending on which stock font we want, there are three different |
michael@0 | 542 | // places we might have to look it up. |
michael@0 | 543 | switch (anID) { |
michael@0 | 544 | case LookAndFeel::eFont_Icon: |
michael@0 | 545 | if (!::SystemParametersInfoW(SPI_GETICONTITLELOGFONT, |
michael@0 | 546 | sizeof(logFont), (PVOID)&logFont, 0)) |
michael@0 | 547 | return false; |
michael@0 | 548 | |
michael@0 | 549 | ptrLogFont = &logFont; |
michael@0 | 550 | break; |
michael@0 | 551 | |
michael@0 | 552 | case LookAndFeel::eFont_Menu: |
michael@0 | 553 | case LookAndFeel::eFont_MessageBox: |
michael@0 | 554 | case LookAndFeel::eFont_SmallCaption: |
michael@0 | 555 | case LookAndFeel::eFont_StatusBar: |
michael@0 | 556 | case LookAndFeel::eFont_Tooltips: |
michael@0 | 557 | ncm.cbSize = sizeof(NONCLIENTMETRICSW); |
michael@0 | 558 | if (!::SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, |
michael@0 | 559 | sizeof(ncm), (PVOID)&ncm, 0)) |
michael@0 | 560 | return false; |
michael@0 | 561 | |
michael@0 | 562 | switch (anID) { |
michael@0 | 563 | case LookAndFeel::eFont_Menu: |
michael@0 | 564 | ptrLogFont = &ncm.lfMenuFont; |
michael@0 | 565 | break; |
michael@0 | 566 | case LookAndFeel::eFont_MessageBox: |
michael@0 | 567 | ptrLogFont = &ncm.lfMessageFont; |
michael@0 | 568 | break; |
michael@0 | 569 | case LookAndFeel::eFont_SmallCaption: |
michael@0 | 570 | ptrLogFont = &ncm.lfSmCaptionFont; |
michael@0 | 571 | break; |
michael@0 | 572 | case LookAndFeel::eFont_StatusBar: |
michael@0 | 573 | case LookAndFeel::eFont_Tooltips: |
michael@0 | 574 | ptrLogFont = &ncm.lfStatusFont; |
michael@0 | 575 | break; |
michael@0 | 576 | } |
michael@0 | 577 | break; |
michael@0 | 578 | |
michael@0 | 579 | case LookAndFeel::eFont_Widget: |
michael@0 | 580 | case LookAndFeel::eFont_Window: // css3 |
michael@0 | 581 | case LookAndFeel::eFont_Document: |
michael@0 | 582 | case LookAndFeel::eFont_Workspace: |
michael@0 | 583 | case LookAndFeel::eFont_Desktop: |
michael@0 | 584 | case LookAndFeel::eFont_Info: |
michael@0 | 585 | case LookAndFeel::eFont_Dialog: |
michael@0 | 586 | case LookAndFeel::eFont_Button: |
michael@0 | 587 | case LookAndFeel::eFont_PullDownMenu: |
michael@0 | 588 | case LookAndFeel::eFont_List: |
michael@0 | 589 | case LookAndFeel::eFont_Field: |
michael@0 | 590 | case LookAndFeel::eFont_Caption: |
michael@0 | 591 | hGDI = ::GetStockObject(DEFAULT_GUI_FONT); |
michael@0 | 592 | if (!hGDI) |
michael@0 | 593 | return false; |
michael@0 | 594 | |
michael@0 | 595 | if (::GetObjectW(hGDI, sizeof(logFont), &logFont) <= 0) |
michael@0 | 596 | return false; |
michael@0 | 597 | |
michael@0 | 598 | ptrLogFont = &logFont; |
michael@0 | 599 | break; |
michael@0 | 600 | } |
michael@0 | 601 | |
michael@0 | 602 | // Get scaling factor from physical to logical pixels |
michael@0 | 603 | float pixelScale = 1.0f / gfxWindowsPlatform::GetPlatform()->GetDPIScale(); |
michael@0 | 604 | |
michael@0 | 605 | // The lfHeight is in pixels, and it needs to be adjusted for the |
michael@0 | 606 | // device it will be displayed on. |
michael@0 | 607 | // Screens and Printers will differ in DPI |
michael@0 | 608 | // |
michael@0 | 609 | // So this accounts for the difference in the DeviceContexts |
michael@0 | 610 | // The pixelScale will typically be 1.0 for the screen |
michael@0 | 611 | // (though larger for hi-dpi screens where the Windows resolution |
michael@0 | 612 | // scale factor is 125% or 150% or even more), and could be |
michael@0 | 613 | // any value when going to a printer, for example pixelScale is |
michael@0 | 614 | // 6.25 when going to a 600dpi printer. |
michael@0 | 615 | float pixelHeight = -ptrLogFont->lfHeight; |
michael@0 | 616 | if (pixelHeight < 0) { |
michael@0 | 617 | HFONT hFont = ::CreateFontIndirectW(ptrLogFont); |
michael@0 | 618 | if (!hFont) |
michael@0 | 619 | return false; |
michael@0 | 620 | HGDIOBJ hObject = ::SelectObject(aHDC, hFont); |
michael@0 | 621 | TEXTMETRIC tm; |
michael@0 | 622 | ::GetTextMetrics(aHDC, &tm); |
michael@0 | 623 | ::SelectObject(aHDC, hObject); |
michael@0 | 624 | ::DeleteObject(hFont); |
michael@0 | 625 | pixelHeight = tm.tmAscent; |
michael@0 | 626 | } |
michael@0 | 627 | pixelHeight *= pixelScale; |
michael@0 | 628 | |
michael@0 | 629 | // we have problem on Simplified Chinese system because the system |
michael@0 | 630 | // report the default font size is 8 points. but if we use 8, the text |
michael@0 | 631 | // display very ugly. force it to be at 9 points (12 pixels) on that |
michael@0 | 632 | // system (cp936), but leave other sizes alone. |
michael@0 | 633 | if (pixelHeight < 12 && ::GetACP() == 936) |
michael@0 | 634 | pixelHeight = 12; |
michael@0 | 635 | |
michael@0 | 636 | aFontStyle.size = pixelHeight; |
michael@0 | 637 | |
michael@0 | 638 | // FIXME: What about oblique? |
michael@0 | 639 | aFontStyle.style = |
michael@0 | 640 | (ptrLogFont->lfItalic) ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL; |
michael@0 | 641 | |
michael@0 | 642 | // FIXME: Other weights? |
michael@0 | 643 | aFontStyle.weight = |
michael@0 | 644 | (ptrLogFont->lfWeight == FW_BOLD ? |
michael@0 | 645 | NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL); |
michael@0 | 646 | |
michael@0 | 647 | // FIXME: Set aFontStyle->stretch correctly! |
michael@0 | 648 | aFontStyle.stretch = NS_FONT_STRETCH_NORMAL; |
michael@0 | 649 | |
michael@0 | 650 | aFontStyle.systemFont = true; |
michael@0 | 651 | |
michael@0 | 652 | name[0] = 0; |
michael@0 | 653 | memcpy(name, ptrLogFont->lfFaceName, LF_FACESIZE*sizeof(char16_t)); |
michael@0 | 654 | aFontName = name; |
michael@0 | 655 | |
michael@0 | 656 | return true; |
michael@0 | 657 | } |
michael@0 | 658 | |
michael@0 | 659 | bool |
michael@0 | 660 | nsLookAndFeel::GetFontImpl(FontID anID, nsString &aFontName, |
michael@0 | 661 | gfxFontStyle &aFontStyle, |
michael@0 | 662 | float aDevPixPerCSSPixel) |
michael@0 | 663 | { |
michael@0 | 664 | HDC tdc = GetDC(nullptr); |
michael@0 | 665 | bool status = GetSysFontInfo(tdc, anID, aFontName, aFontStyle); |
michael@0 | 666 | ReleaseDC(nullptr, tdc); |
michael@0 | 667 | // now convert the logical font size from GetSysFontInfo into device pixels for layout |
michael@0 | 668 | aFontStyle.size *= aDevPixPerCSSPixel; |
michael@0 | 669 | return status; |
michael@0 | 670 | } |
michael@0 | 671 | |
michael@0 | 672 | /* virtual */ |
michael@0 | 673 | char16_t |
michael@0 | 674 | nsLookAndFeel::GetPasswordCharacterImpl() |
michael@0 | 675 | { |
michael@0 | 676 | #define UNICODE_BLACK_CIRCLE_CHAR 0x25cf |
michael@0 | 677 | return UNICODE_BLACK_CIRCLE_CHAR; |
michael@0 | 678 | } |