Bumping manifests a=b2g-bump
[gecko.git] / widget / gtk / nsLookAndFeel.cpp
blobea4cc0e2d35bf3acf4623d7fd4af1cc6338f6cbc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 // for strtod()
9 #include <stdlib.h>
11 #include "nsLookAndFeel.h"
13 #include <gtk/gtk.h>
14 #include <gdk/gdk.h>
16 #include <pango/pango.h>
17 #include <pango/pango-fontmap.h>
19 #include <fontconfig/fontconfig.h>
20 #include "gfxPlatformGtk.h"
22 #include "gtkdrawing.h"
23 #include "nsStyleConsts.h"
24 #include "gfxFontConstants.h"
25 #include "mozilla/gfx/2D.h"
27 using mozilla::LookAndFeel;
29 #define GDK_COLOR_TO_NS_RGB(c) \
30 ((nscolor) NS_RGB(c.red>>8, c.green>>8, c.blue>>8))
31 #define GDK_RGBA_TO_NS_RGBA(c) \
32 ((nscolor) NS_RGBA((int)((c).red*255), (int)((c).green*255), \
33 (int)((c).blue*255), (int)((c).alpha*255)))
35 nsLookAndFeel::nsLookAndFeel()
36 : nsXPLookAndFeel(),
37 #if (MOZ_WIDGET_GTK == 2)
38 mStyle(nullptr),
39 #else
40 mBackgroundStyle(nullptr),
41 mButtonStyle(nullptr),
42 #endif
43 mDefaultFontCached(false), mButtonFontCached(false),
44 mFieldFontCached(false), mMenuFontCached(false)
46 Init();
49 nsLookAndFeel::~nsLookAndFeel()
51 #if (MOZ_WIDGET_GTK == 2)
52 g_object_unref(mStyle);
53 #else
54 g_object_unref(mBackgroundStyle);
55 g_object_unref(mButtonStyle);
56 #endif
59 nsresult
60 nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
62 #if (MOZ_WIDGET_GTK == 3)
63 GdkRGBA gdk_color;
64 #endif
65 nsresult res = NS_OK;
67 switch (aID) {
68 // These colors don't seem to be used for anything anymore in Mozilla
69 // (except here at least TextSelectBackground and TextSelectForeground)
70 // The CSS2 colors below are used.
71 #if (MOZ_WIDGET_GTK == 2)
72 case eColorID_WindowBackground:
73 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]);
74 break;
75 case eColorID_WindowForeground:
76 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]);
77 break;
78 case eColorID_WidgetBackground:
79 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
80 break;
81 case eColorID_WidgetForeground:
82 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
83 break;
84 case eColorID_WidgetSelectBackground:
85 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]);
86 break;
87 case eColorID_WidgetSelectForeground:
88 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_SELECTED]);
89 break;
90 #else
91 case eColorID_WindowBackground:
92 case eColorID_WidgetBackground:
93 case eColorID_TextBackground:
94 case eColorID_activecaption: // active window caption background
95 case eColorID_appworkspace: // MDI background color
96 case eColorID_background: // desktop background
97 case eColorID_window:
98 case eColorID_windowframe:
99 case eColorID__moz_dialog:
100 aColor = sMozWindowBackground;
101 break;
102 case eColorID_WindowForeground:
103 case eColorID_WidgetForeground:
104 case eColorID_TextForeground:
105 case eColorID_captiontext: // text in active window caption, size box, and scrollbar arrow box (!)
106 case eColorID_windowtext:
107 case eColorID__moz_dialogtext:
108 aColor = sMozWindowText;
109 break;
110 case eColorID_WidgetSelectBackground:
111 case eColorID_TextSelectBackground:
112 case eColorID_IMESelectedRawTextBackground:
113 case eColorID_IMESelectedConvertedTextBackground:
114 case eColorID__moz_dragtargetzone:
115 case eColorID__moz_cellhighlight:
116 case eColorID__moz_html_cellhighlight:
117 case eColorID_highlight: // preference selected item,
118 aColor = sTextSelectedBackground;
119 break;
120 case eColorID_WidgetSelectForeground:
121 case eColorID_TextSelectForeground:
122 case eColorID_IMESelectedRawTextForeground:
123 case eColorID_IMESelectedConvertedTextForeground:
124 case eColorID_highlighttext:
125 case eColorID__moz_cellhighlighttext:
126 case eColorID__moz_html_cellhighlighttext:
127 aColor = sTextSelectedText;
128 break;
129 #endif
130 case eColorID_Widget3DHighlight:
131 aColor = NS_RGB(0xa0,0xa0,0xa0);
132 break;
133 case eColorID_Widget3DShadow:
134 aColor = NS_RGB(0x40,0x40,0x40);
135 break;
136 #if (MOZ_WIDGET_GTK == 2)
137 case eColorID_TextBackground:
138 // not used?
139 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]);
140 break;
141 case eColorID_TextForeground:
142 // not used?
143 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]);
144 break;
145 case eColorID_TextSelectBackground:
146 case eColorID_IMESelectedRawTextBackground:
147 case eColorID_IMESelectedConvertedTextBackground:
148 // still used
149 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_SELECTED]);
150 break;
151 case eColorID_TextSelectForeground:
152 case eColorID_IMESelectedRawTextForeground:
153 case eColorID_IMESelectedConvertedTextForeground:
154 // still used
155 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_SELECTED]);
156 break;
157 #endif
158 case eColorID_IMERawInputBackground:
159 case eColorID_IMEConvertedTextBackground:
160 aColor = NS_TRANSPARENT;
161 break;
162 case eColorID_IMERawInputForeground:
163 case eColorID_IMEConvertedTextForeground:
164 aColor = NS_SAME_AS_FOREGROUND_COLOR;
165 break;
166 case eColorID_IMERawInputUnderline:
167 case eColorID_IMEConvertedTextUnderline:
168 aColor = NS_SAME_AS_FOREGROUND_COLOR;
169 break;
170 case eColorID_IMESelectedRawTextUnderline:
171 case eColorID_IMESelectedConvertedTextUnderline:
172 aColor = NS_TRANSPARENT;
173 break;
174 case eColorID_SpellCheckerUnderline:
175 aColor = NS_RGB(0xff, 0, 0);
176 break;
178 #if (MOZ_WIDGET_GTK == 2)
179 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
180 case eColorID_activeborder:
181 // active window border
182 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
183 break;
184 case eColorID_activecaption:
185 // active window caption background
186 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
187 break;
188 case eColorID_appworkspace:
189 // MDI background color
190 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
191 break;
192 case eColorID_background:
193 // desktop background
194 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
195 break;
196 case eColorID_captiontext:
197 // text in active window caption, size box, and scrollbar arrow box (!)
198 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
199 break;
200 case eColorID_graytext:
201 // disabled text in windows, menus, etc.
202 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_INSENSITIVE]);
203 break;
204 case eColorID_highlight:
205 // background of selected item
206 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_SELECTED]);
207 break;
208 case eColorID_highlighttext:
209 // text of selected item
210 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_SELECTED]);
211 break;
212 case eColorID_inactiveborder:
213 // inactive window border
214 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
215 break;
216 case eColorID_inactivecaption:
217 // inactive window caption
218 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_INSENSITIVE]);
219 break;
220 case eColorID_inactivecaptiontext:
221 // text in inactive window caption
222 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_INSENSITIVE]);
223 break;
224 #else
225 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
226 case eColorID_activeborder:
227 // active window border
228 gtk_style_context_get_border_color(mBackgroundStyle,
229 GTK_STATE_FLAG_NORMAL, &gdk_color);
230 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
231 break;
232 case eColorID_inactiveborder:
233 // inactive window border
234 gtk_style_context_get_border_color(mBackgroundStyle,
235 GTK_STATE_FLAG_INSENSITIVE,
236 &gdk_color);
237 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
238 break;
239 case eColorID_graytext: // disabled text in windows, menus, etc.
240 case eColorID_inactivecaptiontext: // text in inactive window caption
241 gtk_style_context_get_color(mBackgroundStyle,
242 GTK_STATE_FLAG_INSENSITIVE, &gdk_color);
243 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
244 break;
245 case eColorID_inactivecaption:
246 // inactive window caption
247 gtk_style_context_get_background_color(mBackgroundStyle,
248 GTK_STATE_FLAG_INSENSITIVE,
249 &gdk_color);
250 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
251 break;
252 #endif
253 case eColorID_infobackground:
254 // tooltip background color
255 aColor = sInfoBackground;
256 break;
257 case eColorID_infotext:
258 // tooltip text color
259 aColor = sInfoText;
260 break;
261 case eColorID_menu:
262 // menu background
263 aColor = sMenuBackground;
264 break;
265 case eColorID_menutext:
266 // menu text
267 aColor = sMenuText;
268 break;
269 case eColorID_scrollbar:
270 // scrollbar gray area
271 #if (MOZ_WIDGET_GTK == 2)
272 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_ACTIVE]);
273 #else
274 aColor = sMozScrollbar;
275 #endif
276 break;
278 case eColorID_threedlightshadow:
279 // 3-D highlighted inner edge color
280 // always same as background in GTK code
281 case eColorID_threedface:
282 case eColorID_buttonface:
283 // 3-D face color
284 #if (MOZ_WIDGET_GTK == 3)
285 aColor = sMozWindowBackground;
286 #else
287 aColor = sButtonBackground;
288 #endif
289 break;
291 case eColorID_buttontext:
292 // text on push buttons
293 aColor = sButtonText;
294 break;
296 case eColorID_buttonhighlight:
297 // 3-D highlighted edge color
298 case eColorID_threedhighlight:
299 // 3-D highlighted outer edge color
300 aColor = sFrameOuterLightBorder;
301 break;
303 case eColorID_buttonshadow:
304 // 3-D shadow edge color
305 case eColorID_threedshadow:
306 // 3-D shadow inner edge color
307 aColor = sFrameInnerDarkBorder;
308 break;
310 #if (MOZ_WIDGET_GTK == 2)
311 case eColorID_threeddarkshadow:
312 // 3-D shadow outer edge color
313 aColor = GDK_COLOR_TO_NS_RGB(mStyle->black);
314 break;
316 case eColorID_window:
317 case eColorID_windowframe:
318 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
319 break;
321 case eColorID_windowtext:
322 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
323 break;
325 case eColorID__moz_eventreerow:
326 case eColorID__moz_field:
327 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]);
328 break;
329 case eColorID__moz_fieldtext:
330 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]);
331 break;
332 case eColorID__moz_dialog:
333 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]);
334 break;
335 case eColorID__moz_dialogtext:
336 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]);
337 break;
338 case eColorID__moz_dragtargetzone:
339 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]);
340 break;
341 case eColorID__moz_buttondefault:
342 // default button border color
343 aColor = GDK_COLOR_TO_NS_RGB(mStyle->black);
344 break;
345 case eColorID__moz_buttonhoverface:
346 aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_PRELIGHT]);
347 break;
348 case eColorID__moz_buttonhovertext:
349 aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_PRELIGHT]);
350 break;
351 case eColorID__moz_cellhighlight:
352 case eColorID__moz_html_cellhighlight:
353 aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_ACTIVE]);
354 break;
355 case eColorID__moz_cellhighlighttext:
356 case eColorID__moz_html_cellhighlighttext:
357 aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_ACTIVE]);
358 break;
359 #else
360 case eColorID_threeddarkshadow:
361 // Hardcode to black
362 aColor = NS_RGB(0x00,0x00,0x00);;
363 break;
365 case eColorID__moz_eventreerow:
366 case eColorID__moz_field:
367 aColor = sMozFieldBackground;
368 break;
369 case eColorID__moz_fieldtext:
370 aColor = sMozFieldText;
371 break;
372 case eColorID__moz_buttondefault:
373 // default button border color
374 gtk_style_context_get_border_color(mButtonStyle,
375 GTK_STATE_FLAG_NORMAL, &gdk_color);
376 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
377 break;
378 case eColorID__moz_buttonhoverface:
379 gtk_style_context_get_background_color(mButtonStyle,
380 GTK_STATE_FLAG_PRELIGHT,
381 &gdk_color);
382 aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
383 break;
384 case eColorID__moz_buttonhovertext:
385 aColor = sButtonHoverText;
386 break;
387 #endif
388 case eColorID__moz_menuhover:
389 aColor = sMenuHover;
390 break;
391 case eColorID__moz_menuhovertext:
392 aColor = sMenuHoverText;
393 break;
394 case eColorID__moz_oddtreerow:
395 aColor = sOddCellBackground;
396 break;
397 case eColorID__moz_nativehyperlinktext:
398 aColor = sNativeHyperLinkText;
399 break;
400 case eColorID__moz_comboboxtext:
401 aColor = sComboBoxText;
402 break;
403 case eColorID__moz_combobox:
404 aColor = sComboBoxBackground;
405 break;
406 case eColorID__moz_menubartext:
407 aColor = sMenuBarText;
408 break;
409 case eColorID__moz_menubarhovertext:
410 aColor = sMenuBarHoverText;
411 break;
412 default:
413 /* default color is BLACK */
414 aColor = 0;
415 res = NS_ERROR_FAILURE;
416 break;
419 return res;
422 #if (MOZ_WIDGET_GTK == 2)
423 static void darken_gdk_color(GdkColor *src, GdkColor *dest)
425 gdouble red;
426 gdouble green;
427 gdouble blue;
429 red = (gdouble) src->red / 65535.0;
430 green = (gdouble) src->green / 65535.0;
431 blue = (gdouble) src->blue / 65535.0;
433 red *= 0.93;
434 green *= 0.93;
435 blue *= 0.93;
437 dest->red = red * 65535.0;
438 dest->green = green * 65535.0;
439 dest->blue = blue * 65535.0;
441 #endif
443 static int32_t CheckWidgetStyle(GtkWidget* aWidget, const char* aStyle, int32_t aResult) {
444 gboolean value = FALSE;
445 gtk_widget_style_get(aWidget, aStyle, &value, nullptr);
446 return value ? aResult : 0;
449 static int32_t ConvertGTKStepperStyleToMozillaScrollArrowStyle(GtkWidget* aWidget)
451 if (!aWidget)
452 return mozilla::LookAndFeel::eScrollArrowStyle_Single;
454 return
455 CheckWidgetStyle(aWidget, "has-backward-stepper",
456 mozilla::LookAndFeel::eScrollArrow_StartBackward) |
457 CheckWidgetStyle(aWidget, "has-forward-stepper",
458 mozilla::LookAndFeel::eScrollArrow_EndForward) |
459 CheckWidgetStyle(aWidget, "has-secondary-backward-stepper",
460 mozilla::LookAndFeel::eScrollArrow_EndBackward) |
461 CheckWidgetStyle(aWidget, "has-secondary-forward-stepper",
462 mozilla::LookAndFeel::eScrollArrow_StartForward);
465 nsresult
466 nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
468 nsresult res = NS_OK;
470 // Set these before they can get overrided in the nsXPLookAndFeel.
471 switch (aID) {
472 case eIntID_ScrollButtonLeftMouseButtonAction:
473 aResult = 0;
474 return NS_OK;
475 case eIntID_ScrollButtonMiddleMouseButtonAction:
476 aResult = 1;
477 return NS_OK;
478 case eIntID_ScrollButtonRightMouseButtonAction:
479 aResult = 2;
480 return NS_OK;
481 default:
482 break;
485 res = nsXPLookAndFeel::GetIntImpl(aID, aResult);
486 if (NS_SUCCEEDED(res))
487 return res;
488 res = NS_OK;
490 switch (aID) {
491 case eIntID_CaretBlinkTime:
493 GtkSettings *settings;
494 gint blink_time;
495 gboolean blink;
497 settings = gtk_settings_get_default ();
498 g_object_get (settings,
499 "gtk-cursor-blink-time", &blink_time,
500 "gtk-cursor-blink", &blink,
501 nullptr);
503 if (blink)
504 aResult = (int32_t) blink_time;
505 else
506 aResult = 0;
507 break;
509 case eIntID_CaretWidth:
510 aResult = 1;
511 break;
512 case eIntID_ShowCaretDuringSelection:
513 aResult = 0;
514 break;
515 case eIntID_SelectTextfieldsOnKeyFocus:
517 GtkWidget *entry;
518 GtkSettings *settings;
519 gboolean select_on_focus;
521 entry = gtk_entry_new();
522 g_object_ref_sink(entry);
523 settings = gtk_widget_get_settings(entry);
524 g_object_get(settings,
525 "gtk-entry-select-on-focus",
526 &select_on_focus,
527 nullptr);
529 if(select_on_focus)
530 aResult = 1;
531 else
532 aResult = 0;
534 gtk_widget_destroy(entry);
535 g_object_unref(entry);
537 break;
538 case eIntID_ScrollToClick:
540 GtkSettings *settings;
541 gboolean warps_slider = FALSE;
543 settings = gtk_settings_get_default ();
544 if (g_object_class_find_property (G_OBJECT_GET_CLASS(settings),
545 "gtk-primary-button-warps-slider")) {
546 g_object_get (settings,
547 "gtk-primary-button-warps-slider",
548 &warps_slider,
549 nullptr);
552 if (warps_slider)
553 aResult = 1;
554 else
555 aResult = 0;
557 break;
558 case eIntID_SubmenuDelay:
560 GtkSettings *settings;
561 gint delay;
563 settings = gtk_settings_get_default ();
564 g_object_get (settings, "gtk-menu-popup-delay", &delay, nullptr);
565 aResult = (int32_t) delay;
566 break;
568 case eIntID_TooltipDelay:
570 aResult = 500;
571 break;
573 case eIntID_MenusCanOverlapOSBar:
574 // we want XUL popups to be able to overlap the task bar.
575 aResult = 1;
576 break;
577 case eIntID_SkipNavigatingDisabledMenuItem:
578 aResult = 1;
579 break;
580 case eIntID_DragThresholdX:
581 case eIntID_DragThresholdY:
583 GtkWidget* box = gtk_hbox_new(FALSE, 5);
584 gint threshold = 0;
585 g_object_get(gtk_widget_get_settings(box),
586 "gtk-dnd-drag-threshold", &threshold,
587 nullptr);
588 g_object_ref_sink(box);
590 aResult = threshold;
592 break;
593 case eIntID_ScrollArrowStyle:
594 moz_gtk_init();
595 aResult =
596 ConvertGTKStepperStyleToMozillaScrollArrowStyle(moz_gtk_get_scrollbar_widget());
597 break;
598 case eIntID_ScrollSliderStyle:
599 aResult = eScrollThumbStyle_Proportional;
600 break;
601 case eIntID_TreeOpenDelay:
602 aResult = 1000;
603 break;
604 case eIntID_TreeCloseDelay:
605 aResult = 1000;
606 break;
607 case eIntID_TreeLazyScrollDelay:
608 aResult = 150;
609 break;
610 case eIntID_TreeScrollDelay:
611 aResult = 100;
612 break;
613 case eIntID_TreeScrollLinesMax:
614 aResult = 3;
615 break;
616 case eIntID_DWMCompositor:
617 case eIntID_WindowsClassic:
618 case eIntID_WindowsDefaultTheme:
619 case eIntID_WindowsThemeIdentifier:
620 case eIntID_OperatingSystemVersionIdentifier:
621 aResult = 0;
622 res = NS_ERROR_NOT_IMPLEMENTED;
623 break;
624 case eIntID_TouchEnabled:
625 aResult = 0;
626 res = NS_ERROR_NOT_IMPLEMENTED;
627 break;
628 case eIntID_MacGraphiteTheme:
629 case eIntID_MacLionTheme:
630 aResult = 0;
631 res = NS_ERROR_NOT_IMPLEMENTED;
632 break;
633 case eIntID_AlertNotificationOrigin:
634 aResult = NS_ALERT_TOP;
635 break;
636 case eIntID_IMERawInputUnderlineStyle:
637 case eIntID_IMEConvertedTextUnderlineStyle:
638 aResult = NS_STYLE_TEXT_DECORATION_STYLE_SOLID;
639 break;
640 case eIntID_IMESelectedRawTextUnderlineStyle:
641 case eIntID_IMESelectedConvertedTextUnderline:
642 aResult = NS_STYLE_TEXT_DECORATION_STYLE_NONE;
643 break;
644 case eIntID_SpellCheckerUnderlineStyle:
645 aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY;
646 break;
647 case eIntID_ImagesInMenus:
648 aResult = moz_gtk_images_in_menus();
649 break;
650 case eIntID_ImagesInButtons:
651 aResult = moz_gtk_images_in_buttons();
652 break;
653 case eIntID_MenuBarDrag:
654 aResult = sMenuSupportsDrag;
655 break;
656 case eIntID_ScrollbarButtonAutoRepeatBehavior:
657 aResult = 1;
658 break;
659 case eIntID_SwipeAnimationEnabled:
660 aResult = 0;
661 break;
662 case eIntID_ColorPickerAvailable:
663 aResult = 1;
664 break;
665 default:
666 aResult = 0;
667 res = NS_ERROR_FAILURE;
670 return res;
673 nsresult
674 nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult)
676 nsresult res = NS_OK;
677 res = nsXPLookAndFeel::GetFloatImpl(aID, aResult);
678 if (NS_SUCCEEDED(res))
679 return res;
680 res = NS_OK;
682 switch (aID) {
683 case eFloatID_IMEUnderlineRelativeSize:
684 aResult = 1.0f;
685 break;
686 case eFloatID_SpellCheckerUnderlineRelativeSize:
687 aResult = 1.0f;
688 break;
689 case eFloatID_CaretAspectRatio:
690 aResult = sCaretRatio;
691 break;
692 default:
693 aResult = -1.0;
694 res = NS_ERROR_FAILURE;
696 return res;
699 static void
700 GetSystemFontInfo(GtkWidget *aWidget,
701 nsString *aFontName,
702 gfxFontStyle *aFontStyle)
704 GtkSettings *settings = gtk_widget_get_settings(aWidget);
706 aFontStyle->style = NS_FONT_STYLE_NORMAL;
708 gchar *fontname;
709 g_object_get(settings, "gtk-font-name", &fontname, nullptr);
711 PangoFontDescription *desc;
712 desc = pango_font_description_from_string(fontname);
714 aFontStyle->systemFont = true;
716 g_free(fontname);
718 NS_NAMED_LITERAL_STRING(quote, "\"");
719 NS_ConvertUTF8toUTF16 family(pango_font_description_get_family(desc));
720 *aFontName = quote + family + quote;
722 aFontStyle->weight = pango_font_description_get_weight(desc);
724 // FIXME: Set aFontStyle->stretch correctly!
725 aFontStyle->stretch = NS_FONT_STRETCH_NORMAL;
727 float size = float(pango_font_description_get_size(desc)) / PANGO_SCALE;
729 // |size| is now either pixels or pango-points (not Mozilla-points!)
731 if (!pango_font_description_get_size_is_absolute(desc)) {
732 // |size| is in pango-points, so convert to pixels.
733 size *= float(gfxPlatformGtk::GetDPI()) / POINTS_PER_INCH_FLOAT;
736 // |size| is now pixels
738 aFontStyle->size = size;
740 pango_font_description_free(desc);
743 static void
744 GetSystemFontInfo(LookAndFeel::FontID aID,
745 nsString *aFontName,
746 gfxFontStyle *aFontStyle)
748 if (aID == LookAndFeel::eFont_Widget) {
749 GtkWidget *label = gtk_label_new("M");
750 GtkWidget *parent = gtk_fixed_new();
751 GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
753 gtk_container_add(GTK_CONTAINER(parent), label);
754 gtk_container_add(GTK_CONTAINER(window), parent);
756 gtk_widget_ensure_style(label);
757 GetSystemFontInfo(label, aFontName, aFontStyle);
758 gtk_widget_destroy(window); // no unref, windows are different
760 } else if (aID == LookAndFeel::eFont_Button) {
761 GtkWidget *label = gtk_label_new("M");
762 GtkWidget *parent = gtk_fixed_new();
763 GtkWidget *button = gtk_button_new();
764 GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
766 gtk_container_add(GTK_CONTAINER(button), label);
767 gtk_container_add(GTK_CONTAINER(parent), button);
768 gtk_container_add(GTK_CONTAINER(window), parent);
770 gtk_widget_ensure_style(label);
771 GetSystemFontInfo(label, aFontName, aFontStyle);
772 gtk_widget_destroy(window); // no unref, windows are different
774 } else if (aID == LookAndFeel::eFont_Field) {
775 GtkWidget *entry = gtk_entry_new();
776 GtkWidget *parent = gtk_fixed_new();
777 GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
779 gtk_container_add(GTK_CONTAINER(parent), entry);
780 gtk_container_add(GTK_CONTAINER(window), parent);
782 gtk_widget_ensure_style(entry);
783 GetSystemFontInfo(entry, aFontName, aFontStyle);
784 gtk_widget_destroy(window); // no unref, windows are different
786 } else {
787 NS_ABORT_IF_FALSE(aID == LookAndFeel::eFont_Menu, "unexpected font ID");
788 GtkWidget *accel_label = gtk_accel_label_new("M");
789 GtkWidget *menuitem = gtk_menu_item_new();
790 GtkWidget *menu = gtk_menu_new();
791 g_object_ref_sink(menu);
793 gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
794 gtk_menu_shell_append((GtkMenuShell *)GTK_MENU(menu), menuitem);
796 gtk_widget_ensure_style(accel_label);
797 GetSystemFontInfo(accel_label, aFontName, aFontStyle);
798 g_object_unref(menu);
802 bool
803 nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName,
804 gfxFontStyle& aFontStyle,
805 float aDevPixPerCSSPixel)
807 nsString *cachedFontName = nullptr;
808 gfxFontStyle *cachedFontStyle = nullptr;
809 bool *isCached = nullptr;
811 switch (aID) {
812 case eFont_Menu: // css2
813 case eFont_PullDownMenu: // css3
814 cachedFontName = &mMenuFontName;
815 cachedFontStyle = &mMenuFontStyle;
816 isCached = &mMenuFontCached;
817 aID = eFont_Menu;
818 break;
820 case eFont_Field: // css3
821 case eFont_List: // css3
822 cachedFontName = &mFieldFontName;
823 cachedFontStyle = &mFieldFontStyle;
824 isCached = &mFieldFontCached;
825 aID = eFont_Field;
826 break;
828 case eFont_Button: // css3
829 cachedFontName = &mButtonFontName;
830 cachedFontStyle = &mButtonFontStyle;
831 isCached = &mButtonFontCached;
832 break;
834 case eFont_Caption: // css2
835 case eFont_Icon: // css2
836 case eFont_MessageBox: // css2
837 case eFont_SmallCaption: // css2
838 case eFont_StatusBar: // css2
839 case eFont_Window: // css3
840 case eFont_Document: // css3
841 case eFont_Workspace: // css3
842 case eFont_Desktop: // css3
843 case eFont_Info: // css3
844 case eFont_Dialog: // css3
845 case eFont_Tooltips: // moz
846 case eFont_Widget: // moz
847 cachedFontName = &mDefaultFontName;
848 cachedFontStyle = &mDefaultFontStyle;
849 isCached = &mDefaultFontCached;
850 aID = eFont_Widget;
851 break;
854 if (!*isCached) {
855 GetSystemFontInfo(aID, cachedFontName, cachedFontStyle);
856 *isCached = true;
859 aFontName = *cachedFontName;
860 aFontStyle = *cachedFontStyle;
861 return true;
864 #if (MOZ_WIDGET_GTK == 3)
865 static GtkStyleContext*
866 create_context(GtkWidgetPath *path)
868 GtkStyleContext *style = gtk_style_context_new();
869 gtk_style_context_set_path(style, path);
870 return(style);
872 #endif
874 void
875 nsLookAndFeel::Init()
877 GdkColor colorValue;
878 GdkColor *colorValuePtr;
880 #if (MOZ_WIDGET_GTK == 2)
881 NS_ASSERTION(!mStyle, "already initialized");
882 // GtkInvisibles come with a refcount that is not floating
883 // (since their initialization code calls g_object_ref_sink) and
884 // their destroy code releases that reference (which means they
885 // have to be explicitly destroyed, since calling unref enough
886 // to cause destruction would lead to *another* unref).
887 // However, this combination means that it's actually still ok
888 // to use the normal pattern, which is to g_object_ref_sink
889 // after construction, and then destroy *and* unref when we're
890 // done. (Though we could skip the g_object_ref_sink and the
891 // corresponding g_object_unref, but that's particular to
892 // GtkInvisibles and GtkWindows.)
893 GtkWidget *widget = gtk_invisible_new();
894 g_object_ref_sink(widget); // effectively g_object_ref (see above)
896 gtk_widget_ensure_style(widget);
897 mStyle = gtk_style_copy(gtk_widget_get_style(widget));
899 gtk_widget_destroy(widget);
900 g_object_unref(widget);
902 // tooltip foreground and background
903 GtkStyle *style = gtk_rc_get_style_by_paths(gtk_settings_get_default(),
904 "gtk-tooltips", "GtkWindow",
905 GTK_TYPE_WINDOW);
906 if (style) {
907 sInfoBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
908 sInfoText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
911 // menu foreground & menu background
912 GtkWidget *accel_label = gtk_accel_label_new("M");
913 GtkWidget *menuitem = gtk_menu_item_new();
914 GtkWidget *menu = gtk_menu_new();
916 g_object_ref_sink(menu);
918 gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
919 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
921 gtk_widget_set_style(accel_label, nullptr);
922 gtk_widget_set_style(menu, nullptr);
923 gtk_widget_realize(menu);
924 gtk_widget_realize(accel_label);
926 style = gtk_widget_get_style(accel_label);
927 if (style) {
928 sMenuText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
931 style = gtk_widget_get_style(menu);
932 if (style) {
933 sMenuBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
936 style = gtk_widget_get_style(menuitem);
937 if (style) {
938 sMenuHover = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_PRELIGHT]);
939 sMenuHoverText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_PRELIGHT]);
942 g_object_unref(menu);
943 #else
944 GdkRGBA color;
945 GtkStyleContext *style;
947 // Gtk manages a screen's CSS in the settings object so we
948 // ask Gtk to create it explicitly. Otherwise we may end up
949 // with wrong color theme, see Bug 972382
950 (void)gtk_settings_get_for_screen(gdk_screen_get_default());
952 GtkWidgetPath *path = gtk_widget_path_new();
953 gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
955 mBackgroundStyle = create_context(path);
956 gtk_style_context_add_class(mBackgroundStyle, GTK_STYLE_CLASS_BACKGROUND);
958 mButtonStyle = create_context(path);
959 gtk_style_context_add_class(mButtonStyle, GTK_STYLE_CLASS_BUTTON);
961 // Scrollbar colors
962 style = create_context(path);
963 gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR);
964 gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
965 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
966 sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color);
967 g_object_unref(style);
969 // Text colors
970 style = create_context(path);
971 gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW);
972 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
973 sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color);
974 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
975 sMozFieldText = GDK_RGBA_TO_NS_RGBA(color);
977 // Selected text and background
978 gtk_style_context_get_background_color(style,
979 static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
980 &color);
981 sTextSelectedBackground = GDK_RGBA_TO_NS_RGBA(color);
982 gtk_style_context_get_color(style,
983 static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
984 &color);
985 sTextSelectedText = GDK_RGBA_TO_NS_RGBA(color);
986 g_object_unref(style);
988 // Window colors
989 style = create_context(path);
990 gtk_style_context_save(style);
991 gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
992 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
993 sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color);
994 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
995 sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
996 gtk_style_context_restore(style);
998 // tooltip foreground and background
999 gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
1000 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
1001 sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
1002 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
1003 sInfoText = GDK_RGBA_TO_NS_RGBA(color);
1004 g_object_unref(style);
1006 // menu foreground & menu background
1007 GtkWidget *accel_label = gtk_accel_label_new("M");
1008 GtkWidget *menuitem = gtk_menu_item_new();
1009 GtkWidget *menu = gtk_menu_new();
1011 g_object_ref_sink(menu);
1013 gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
1014 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1016 style = gtk_widget_get_style_context(accel_label);
1017 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
1018 sMenuText = GDK_RGBA_TO_NS_RGBA(color);
1020 style = gtk_widget_get_style_context(menu);
1021 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
1022 sMenuBackground = GDK_RGBA_TO_NS_RGBA(color);
1024 style = gtk_widget_get_style_context(menuitem);
1025 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
1026 sMenuHover = GDK_RGBA_TO_NS_RGBA(color);
1027 gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
1028 sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color);
1030 g_object_unref(menu);
1031 #endif
1033 // button styles
1034 GtkWidget *parent = gtk_fixed_new();
1035 GtkWidget *button = gtk_button_new();
1036 GtkWidget *label = gtk_label_new("M");
1037 #if (MOZ_WIDGET_GTK == 2)
1038 GtkWidget *combobox = gtk_combo_box_new();
1039 GtkWidget *comboboxLabel = gtk_label_new("M");
1040 gtk_container_add(GTK_CONTAINER(combobox), comboboxLabel);
1041 #else
1042 GtkWidget *combobox = gtk_combo_box_new_with_entry();
1043 GtkWidget *comboboxLabel = gtk_bin_get_child(GTK_BIN(combobox));
1044 #endif
1045 GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
1046 GtkWidget *treeView = gtk_tree_view_new();
1047 GtkWidget *linkButton = gtk_link_button_new("http://example.com/");
1048 GtkWidget *menuBar = gtk_menu_bar_new();
1049 GtkWidget *entry = gtk_entry_new();
1051 gtk_container_add(GTK_CONTAINER(button), label);
1052 gtk_container_add(GTK_CONTAINER(parent), button);
1053 gtk_container_add(GTK_CONTAINER(parent), treeView);
1054 gtk_container_add(GTK_CONTAINER(parent), linkButton);
1055 gtk_container_add(GTK_CONTAINER(parent), combobox);
1056 gtk_container_add(GTK_CONTAINER(parent), menuBar);
1057 gtk_container_add(GTK_CONTAINER(window), parent);
1058 gtk_container_add(GTK_CONTAINER(parent), entry);
1060 #if (MOZ_WIDGET_GTK == 2)
1061 gtk_widget_set_style(button, nullptr);
1062 gtk_widget_set_style(label, nullptr);
1063 gtk_widget_set_style(treeView, nullptr);
1064 gtk_widget_set_style(linkButton, nullptr);
1065 gtk_widget_set_style(combobox, nullptr);
1066 gtk_widget_set_style(comboboxLabel, nullptr);
1067 gtk_widget_set_style(menuBar, nullptr);
1068 gtk_widget_set_style(entry, nullptr);
1070 gtk_widget_realize(button);
1071 gtk_widget_realize(label);
1072 gtk_widget_realize(treeView);
1073 gtk_widget_realize(linkButton);
1074 gtk_widget_realize(combobox);
1075 gtk_widget_realize(comboboxLabel);
1076 gtk_widget_realize(menuBar);
1077 gtk_widget_realize(entry);
1079 style = gtk_widget_get_style(label);
1080 if (style) {
1081 sButtonText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
1084 style = gtk_widget_get_style(comboboxLabel);
1085 if (style) {
1086 sComboBoxText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
1088 style = gtk_widget_get_style(combobox);
1089 if (style) {
1090 sComboBoxBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
1093 style = gtk_widget_get_style(menuBar);
1094 if (style) {
1095 sMenuBarText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]);
1096 sMenuBarHoverText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_SELECTED]);
1099 // GTK's guide to fancy odd row background colors:
1100 // 1) Check if a theme explicitly defines an odd row color
1101 // 2) If not, check if it defines an even row color, and darken it
1102 // slightly by a hardcoded value (gtkstyle.c)
1103 // 3) If neither are defined, take the base background color and
1104 // darken that by a hardcoded value
1105 colorValuePtr = nullptr;
1106 gtk_widget_style_get(treeView,
1107 "odd-row-color", &colorValuePtr,
1108 nullptr);
1110 if (colorValuePtr) {
1111 colorValue = *colorValuePtr;
1112 } else {
1113 gtk_widget_style_get(treeView,
1114 "even-row-color", &colorValuePtr,
1115 nullptr);
1116 if (colorValuePtr)
1117 darken_gdk_color(colorValuePtr, &colorValue);
1118 else
1119 darken_gdk_color(&treeView->style->base[GTK_STATE_NORMAL], &colorValue);
1122 sOddCellBackground = GDK_COLOR_TO_NS_RGB(colorValue);
1123 if (colorValuePtr)
1124 gdk_color_free(colorValuePtr);
1126 style = gtk_widget_get_style(button);
1127 if (style) {
1128 sButtonBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]);
1129 sFrameOuterLightBorder =
1130 GDK_COLOR_TO_NS_RGB(style->light[GTK_STATE_NORMAL]);
1131 sFrameInnerDarkBorder =
1132 GDK_COLOR_TO_NS_RGB(style->dark[GTK_STATE_NORMAL]);
1134 #else
1135 // Button text, background, border
1136 style = gtk_widget_get_style_context(label);
1137 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
1138 sButtonText = GDK_RGBA_TO_NS_RGBA(color);
1139 gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
1140 sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
1142 // Combobox label and background colors
1143 style = gtk_widget_get_style_context(comboboxLabel);
1144 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
1145 sComboBoxText = GDK_RGBA_TO_NS_RGBA(color);
1147 style = gtk_widget_get_style_context(combobox);
1148 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
1149 sComboBoxBackground = GDK_RGBA_TO_NS_RGBA(color);
1151 // Menubar text and hover text colors
1152 style = gtk_widget_get_style_context(menuBar);
1153 gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
1154 sMenuBarText = GDK_RGBA_TO_NS_RGBA(color);
1155 gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
1156 sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color);
1158 // GTK's guide to fancy odd row background colors:
1159 // 1) Check if a theme explicitly defines an odd row color
1160 // 2) If not, check if it defines an even row color, and darken it
1161 // slightly by a hardcoded value (gtkstyle.c)
1162 // 3) If neither are defined, take the base background color and
1163 // darken that by a hardcoded value
1164 style = gtk_widget_get_style_context(treeView);
1166 // Get odd row background color
1167 gtk_style_context_save(style);
1168 gtk_style_context_add_region(style, GTK_STYLE_REGION_ROW, GTK_REGION_ODD);
1169 gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
1170 sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color);
1171 gtk_style_context_restore(style);
1173 GtkWidget *frame = gtk_frame_new(nullptr);
1174 gtk_container_add(GTK_CONTAINER(parent), frame);
1176 // TODO GTK3 - update sFrameOuterLightBorder
1177 // for GTK_BORDER_STYLE_INSET/OUTSET/GROVE/RIDGE border styles (Bug 978172).
1178 style = gtk_widget_get_style_context(frame);
1179 gtk_style_context_get_border_color(style, GTK_STATE_FLAG_NORMAL, &color);
1180 sFrameInnerDarkBorder = sFrameOuterLightBorder = GDK_RGBA_TO_NS_RGBA(color);
1181 #endif
1182 // Some themes have a unified menu bar, and support window dragging on it
1183 gboolean supports_menubar_drag = FALSE;
1184 GParamSpec *param_spec =
1185 gtk_widget_class_find_style_property(GTK_WIDGET_GET_CLASS(menuBar),
1186 "window-dragging");
1187 if (param_spec) {
1188 if (g_type_is_a(G_PARAM_SPEC_VALUE_TYPE(param_spec), G_TYPE_BOOLEAN)) {
1189 gtk_widget_style_get(menuBar,
1190 "window-dragging", &supports_menubar_drag,
1191 nullptr);
1194 sMenuSupportsDrag = supports_menubar_drag;
1196 colorValuePtr = nullptr;
1197 gtk_widget_style_get(linkButton, "link-color", &colorValuePtr, nullptr);
1198 if (colorValuePtr) {
1199 colorValue = *colorValuePtr; // we can't pass deref pointers to GDK_COLOR_TO_NS_RGB
1200 sNativeHyperLinkText = GDK_COLOR_TO_NS_RGB(colorValue);
1201 gdk_color_free(colorValuePtr);
1202 } else {
1203 sNativeHyperLinkText = NS_RGB(0x00,0x00,0xEE);
1206 // invisible character styles
1207 guint value;
1208 g_object_get (entry, "invisible-char", &value, nullptr);
1209 sInvisibleCharacter = char16_t(value);
1211 // caret styles
1212 gtk_widget_style_get(entry,
1213 "cursor-aspect-ratio", &sCaretRatio,
1214 nullptr);
1216 gtk_widget_destroy(window);
1219 // virtual
1220 char16_t
1221 nsLookAndFeel::GetPasswordCharacterImpl()
1223 return sInvisibleCharacter;
1226 void
1227 nsLookAndFeel::RefreshImpl()
1229 nsXPLookAndFeel::RefreshImpl();
1231 mDefaultFontCached = false;
1232 mButtonFontCached = false;
1233 mFieldFontCached = false;
1234 mMenuFontCached = false;
1236 #if (MOZ_WIDGET_GTK == 2)
1237 g_object_unref(mStyle);
1238 mStyle = nullptr;
1239 #else
1240 g_object_unref(mBackgroundStyle);
1241 g_object_unref(mButtonStyle);
1243 mBackgroundStyle = nullptr;
1244 mButtonStyle = nullptr;
1245 #endif
1247 Init();
1250 bool
1251 nsLookAndFeel::GetEchoPasswordImpl() {
1252 return false;