michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim:expandtab:shiftwidth=4:tabstop=4: michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // for strtod() michael@0: #include michael@0: michael@0: #include "nsLookAndFeel.h" michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include michael@0: #include "gfxPlatformGtk.h" michael@0: michael@0: #include "gtkdrawing.h" michael@0: #include "nsStyleConsts.h" michael@0: #include "gfxFontConstants.h" michael@0: #include "mozilla/gfx/2D.h" michael@0: michael@0: using mozilla::LookAndFeel; michael@0: michael@0: #define GDK_COLOR_TO_NS_RGB(c) \ michael@0: ((nscolor) NS_RGB(c.red>>8, c.green>>8, c.blue>>8)) michael@0: #define GDK_RGBA_TO_NS_RGBA(c) \ michael@0: ((nscolor) NS_RGBA((int)((c).red*255), (int)((c).green*255), \ michael@0: (int)((c).blue*255), (int)((c).alpha*255))) michael@0: michael@0: nsLookAndFeel::nsLookAndFeel() michael@0: : nsXPLookAndFeel(), michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: mStyle(nullptr), michael@0: #else michael@0: mBackgroundStyle(nullptr), michael@0: mViewStyle(nullptr), michael@0: mButtonStyle(nullptr), michael@0: #endif michael@0: mDefaultFontCached(false), mButtonFontCached(false), michael@0: mFieldFontCached(false), mMenuFontCached(false) michael@0: { michael@0: Init(); michael@0: } michael@0: michael@0: nsLookAndFeel::~nsLookAndFeel() michael@0: { michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: g_object_unref(mStyle); michael@0: #else michael@0: g_object_unref(mBackgroundStyle); michael@0: g_object_unref(mViewStyle); michael@0: g_object_unref(mButtonStyle); michael@0: #endif michael@0: } michael@0: michael@0: nsresult michael@0: nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor) michael@0: { michael@0: #if (MOZ_WIDGET_GTK == 3) michael@0: GdkRGBA gdk_color; michael@0: #endif michael@0: nsresult res = NS_OK; michael@0: michael@0: switch (aID) { michael@0: // These colors don't seem to be used for anything anymore in Mozilla michael@0: // (except here at least TextSelectBackground and TextSelectForeground) michael@0: // The CSS2 colors below are used. michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: case eColorID_WindowBackground: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_WindowForeground: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_WidgetBackground: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_WidgetForeground: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_WidgetSelectBackground: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]); michael@0: break; michael@0: case eColorID_WidgetSelectForeground: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_SELECTED]); michael@0: break; michael@0: #else michael@0: case eColorID_WindowBackground: michael@0: case eColorID_WidgetBackground: michael@0: case eColorID_TextBackground: michael@0: case eColorID_activecaption: // active window caption background michael@0: case eColorID_appworkspace: // MDI background color michael@0: case eColorID_background: // desktop background michael@0: case eColorID_window: michael@0: case eColorID_windowframe: michael@0: case eColorID__moz_dialog: michael@0: aColor = sMozWindowBackground; michael@0: break; michael@0: case eColorID_WindowForeground: michael@0: case eColorID_WidgetForeground: michael@0: case eColorID_TextForeground: michael@0: case eColorID_captiontext: // text in active window caption, size box, and scrollbar arrow box (!) michael@0: case eColorID_windowtext: michael@0: case eColorID__moz_dialogtext: michael@0: aColor = sMozWindowText; michael@0: break; michael@0: case eColorID_WidgetSelectBackground: michael@0: case eColorID_TextSelectBackground: michael@0: case eColorID_IMESelectedRawTextBackground: michael@0: case eColorID_IMESelectedConvertedTextBackground: michael@0: case eColorID__moz_dragtargetzone: michael@0: aColor = sMozWindowSelectedBackground; michael@0: break; michael@0: case eColorID_WidgetSelectForeground: michael@0: case eColorID_TextSelectForeground: michael@0: case eColorID_IMESelectedRawTextForeground: michael@0: case eColorID_IMESelectedConvertedTextForeground: michael@0: aColor = sMozWindowSelectedText; michael@0: break; michael@0: #endif michael@0: case eColorID_Widget3DHighlight: michael@0: aColor = NS_RGB(0xa0,0xa0,0xa0); michael@0: break; michael@0: case eColorID_Widget3DShadow: michael@0: aColor = NS_RGB(0x40,0x40,0x40); michael@0: break; michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: case eColorID_TextBackground: michael@0: // not used? michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_TextForeground: michael@0: // not used? michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_TextSelectBackground: michael@0: case eColorID_IMESelectedRawTextBackground: michael@0: case eColorID_IMESelectedConvertedTextBackground: michael@0: // still used michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_SELECTED]); michael@0: break; michael@0: case eColorID_TextSelectForeground: michael@0: case eColorID_IMESelectedRawTextForeground: michael@0: case eColorID_IMESelectedConvertedTextForeground: michael@0: // still used michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_SELECTED]); michael@0: break; michael@0: #endif michael@0: case eColorID_IMERawInputBackground: michael@0: case eColorID_IMEConvertedTextBackground: michael@0: aColor = NS_TRANSPARENT; michael@0: break; michael@0: case eColorID_IMERawInputForeground: michael@0: case eColorID_IMEConvertedTextForeground: michael@0: aColor = NS_SAME_AS_FOREGROUND_COLOR; michael@0: break; michael@0: case eColorID_IMERawInputUnderline: michael@0: case eColorID_IMEConvertedTextUnderline: michael@0: aColor = NS_SAME_AS_FOREGROUND_COLOR; michael@0: break; michael@0: case eColorID_IMESelectedRawTextUnderline: michael@0: case eColorID_IMESelectedConvertedTextUnderline: michael@0: aColor = NS_TRANSPARENT; michael@0: break; michael@0: case eColorID_SpellCheckerUnderline: michael@0: aColor = NS_RGB(0xff, 0, 0); michael@0: break; michael@0: michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors michael@0: case eColorID_activeborder: michael@0: // active window border michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_activecaption: michael@0: // active window caption background michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_appworkspace: michael@0: // MDI background color michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_background: michael@0: // desktop background michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_captiontext: michael@0: // text in active window caption, size box, and scrollbar arrow box (!) michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_graytext: michael@0: // disabled text in windows, menus, etc. michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_INSENSITIVE]); michael@0: break; michael@0: case eColorID_highlight: michael@0: // background of selected item michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_SELECTED]); michael@0: break; michael@0: case eColorID_highlighttext: michael@0: // text of selected item michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_SELECTED]); michael@0: break; michael@0: case eColorID_inactiveborder: michael@0: // inactive window border michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID_inactivecaption: michael@0: // inactive window caption michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_INSENSITIVE]); michael@0: break; michael@0: case eColorID_inactivecaptiontext: michael@0: // text in inactive window caption michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_INSENSITIVE]); michael@0: break; michael@0: #else michael@0: // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors michael@0: case eColorID_activeborder: michael@0: // active window border michael@0: gtk_style_context_get_border_color(mBackgroundStyle, michael@0: GTK_STATE_FLAG_NORMAL, &gdk_color); michael@0: aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); michael@0: break; michael@0: case eColorID_inactiveborder: michael@0: // inactive window border michael@0: gtk_style_context_get_border_color(mBackgroundStyle, michael@0: GTK_STATE_FLAG_INSENSITIVE, michael@0: &gdk_color); michael@0: aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); michael@0: break; michael@0: case eColorID_graytext: // disabled text in windows, menus, etc. michael@0: case eColorID_inactivecaptiontext: // text in inactive window caption michael@0: gtk_style_context_get_color(mBackgroundStyle, michael@0: GTK_STATE_FLAG_INSENSITIVE, &gdk_color); michael@0: aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); michael@0: break; michael@0: case eColorID_highlight: // preference selected item, michael@0: // background of selected item michael@0: gtk_style_context_get_background_color(mViewStyle, michael@0: GTK_STATE_FLAG_SELECTED, michael@0: &gdk_color); michael@0: aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); michael@0: break; michael@0: case eColorID_highlighttext: michael@0: // text of selected item michael@0: gtk_style_context_get_color(mViewStyle, michael@0: GTK_STATE_FLAG_SELECTED, &gdk_color); michael@0: aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); michael@0: break; michael@0: case eColorID_inactivecaption: michael@0: // inactive window caption michael@0: gtk_style_context_get_background_color(mBackgroundStyle, michael@0: GTK_STATE_FLAG_INSENSITIVE, michael@0: &gdk_color); michael@0: aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); michael@0: break; michael@0: #endif michael@0: case eColorID_infobackground: michael@0: // tooltip background color michael@0: aColor = sInfoBackground; michael@0: break; michael@0: case eColorID_infotext: michael@0: // tooltip text color michael@0: aColor = sInfoText; michael@0: break; michael@0: case eColorID_menu: michael@0: // menu background michael@0: aColor = sMenuBackground; michael@0: break; michael@0: case eColorID_menutext: michael@0: // menu text michael@0: aColor = sMenuText; michael@0: break; michael@0: case eColorID_scrollbar: michael@0: // scrollbar gray area michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_ACTIVE]); michael@0: #else michael@0: aColor = sMozScrollbar; michael@0: #endif michael@0: break; michael@0: michael@0: case eColorID_threedface: michael@0: case eColorID_buttonface: michael@0: // 3-D face color michael@0: aColor = sButtonBackground; michael@0: break; michael@0: michael@0: case eColorID_buttontext: michael@0: // text on push buttons michael@0: aColor = sButtonText; michael@0: break; michael@0: michael@0: case eColorID_buttonhighlight: michael@0: // 3-D highlighted edge color michael@0: case eColorID_threedhighlight: michael@0: // 3-D highlighted outer edge color michael@0: aColor = sButtonOuterLightBorder; michael@0: break; michael@0: michael@0: case eColorID_threedlightshadow: michael@0: // 3-D highlighted inner edge color michael@0: aColor = sButtonBackground; // always same as background in GTK code michael@0: break; michael@0: michael@0: case eColorID_buttonshadow: michael@0: // 3-D shadow edge color michael@0: case eColorID_threedshadow: michael@0: // 3-D shadow inner edge color michael@0: aColor = sButtonInnerDarkBorder; michael@0: break; michael@0: michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: case eColorID_threeddarkshadow: michael@0: // 3-D shadow outer edge color michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->black); michael@0: break; michael@0: michael@0: case eColorID_window: michael@0: case eColorID_windowframe: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]); michael@0: break; michael@0: michael@0: case eColorID_windowtext: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]); michael@0: break; michael@0: michael@0: case eColorID__moz_eventreerow: michael@0: case eColorID__moz_field: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID__moz_fieldtext: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID__moz_dialog: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID__moz_dialogtext: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_NORMAL]); michael@0: break; michael@0: case eColorID__moz_dragtargetzone: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_SELECTED]); michael@0: break; michael@0: case eColorID__moz_buttondefault: michael@0: // default button border color michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->black); michael@0: break; michael@0: case eColorID__moz_buttonhoverface: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->bg[GTK_STATE_PRELIGHT]); michael@0: break; michael@0: case eColorID__moz_buttonhovertext: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->fg[GTK_STATE_PRELIGHT]); michael@0: break; michael@0: case eColorID__moz_cellhighlight: michael@0: case eColorID__moz_html_cellhighlight: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->base[GTK_STATE_ACTIVE]); michael@0: break; michael@0: case eColorID__moz_cellhighlighttext: michael@0: case eColorID__moz_html_cellhighlighttext: michael@0: aColor = GDK_COLOR_TO_NS_RGB(mStyle->text[GTK_STATE_ACTIVE]); michael@0: break; michael@0: #else michael@0: case eColorID_threeddarkshadow: michael@0: // Hardcode to black michael@0: aColor = NS_RGB(0x00,0x00,0x00);; michael@0: break; michael@0: michael@0: case eColorID__moz_eventreerow: michael@0: case eColorID__moz_field: michael@0: aColor = sMozFieldBackground; michael@0: break; michael@0: case eColorID__moz_fieldtext: michael@0: aColor = sMozFieldText; michael@0: break; michael@0: case eColorID__moz_buttondefault: michael@0: // default button border color michael@0: gtk_style_context_get_border_color(mButtonStyle, michael@0: GTK_STATE_FLAG_NORMAL, &gdk_color); michael@0: aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); michael@0: break; michael@0: case eColorID__moz_buttonhoverface: michael@0: gtk_style_context_get_background_color(mButtonStyle, michael@0: GTK_STATE_FLAG_PRELIGHT, michael@0: &gdk_color); michael@0: aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); michael@0: break; michael@0: case eColorID__moz_buttonhovertext: michael@0: aColor = sButtonHoverText; michael@0: break; michael@0: case eColorID__moz_cellhighlight: michael@0: case eColorID__moz_html_cellhighlight: michael@0: gtk_style_context_get_background_color(mViewStyle, michael@0: GTK_STATE_FLAG_SELECTED, michael@0: &gdk_color); michael@0: aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); michael@0: break; michael@0: case eColorID__moz_cellhighlighttext: michael@0: case eColorID__moz_html_cellhighlighttext: michael@0: gtk_style_context_get_color(mViewStyle, michael@0: GTK_STATE_FLAG_SELECTED, &gdk_color); michael@0: aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); michael@0: break; michael@0: #endif michael@0: case eColorID__moz_menuhover: michael@0: aColor = sMenuHover; michael@0: break; michael@0: case eColorID__moz_menuhovertext: michael@0: aColor = sMenuHoverText; michael@0: break; michael@0: case eColorID__moz_oddtreerow: michael@0: aColor = sOddCellBackground; michael@0: break; michael@0: case eColorID__moz_nativehyperlinktext: michael@0: aColor = sNativeHyperLinkText; michael@0: break; michael@0: case eColorID__moz_comboboxtext: michael@0: aColor = sComboBoxText; michael@0: break; michael@0: case eColorID__moz_combobox: michael@0: aColor = sComboBoxBackground; michael@0: break; michael@0: case eColorID__moz_menubartext: michael@0: aColor = sMenuBarText; michael@0: break; michael@0: case eColorID__moz_menubarhovertext: michael@0: aColor = sMenuBarHoverText; michael@0: break; michael@0: default: michael@0: /* default color is BLACK */ michael@0: aColor = 0; michael@0: res = NS_ERROR_FAILURE; michael@0: break; michael@0: } michael@0: michael@0: return res; michael@0: } michael@0: michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: static void darken_gdk_color(GdkColor *src, GdkColor *dest) michael@0: { michael@0: gdouble red; michael@0: gdouble green; michael@0: gdouble blue; michael@0: michael@0: red = (gdouble) src->red / 65535.0; michael@0: green = (gdouble) src->green / 65535.0; michael@0: blue = (gdouble) src->blue / 65535.0; michael@0: michael@0: red *= 0.93; michael@0: green *= 0.93; michael@0: blue *= 0.93; michael@0: michael@0: dest->red = red * 65535.0; michael@0: dest->green = green * 65535.0; michael@0: dest->blue = blue * 65535.0; michael@0: } michael@0: #endif michael@0: michael@0: static int32_t CheckWidgetStyle(GtkWidget* aWidget, const char* aStyle, int32_t aResult) { michael@0: gboolean value = FALSE; michael@0: gtk_widget_style_get(aWidget, aStyle, &value, nullptr); michael@0: return value ? aResult : 0; michael@0: } michael@0: michael@0: static int32_t ConvertGTKStepperStyleToMozillaScrollArrowStyle(GtkWidget* aWidget) michael@0: { michael@0: if (!aWidget) michael@0: return mozilla::LookAndFeel::eScrollArrowStyle_Single; michael@0: michael@0: return michael@0: CheckWidgetStyle(aWidget, "has-backward-stepper", michael@0: mozilla::LookAndFeel::eScrollArrow_StartBackward) | michael@0: CheckWidgetStyle(aWidget, "has-forward-stepper", michael@0: mozilla::LookAndFeel::eScrollArrow_EndForward) | michael@0: CheckWidgetStyle(aWidget, "has-secondary-backward-stepper", michael@0: mozilla::LookAndFeel::eScrollArrow_EndBackward) | michael@0: CheckWidgetStyle(aWidget, "has-secondary-forward-stepper", michael@0: mozilla::LookAndFeel::eScrollArrow_StartForward); michael@0: } michael@0: michael@0: nsresult michael@0: nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult) michael@0: { michael@0: nsresult res = NS_OK; michael@0: michael@0: // Set these before they can get overrided in the nsXPLookAndFeel. michael@0: switch (aID) { michael@0: case eIntID_ScrollButtonLeftMouseButtonAction: michael@0: aResult = 0; michael@0: return NS_OK; michael@0: case eIntID_ScrollButtonMiddleMouseButtonAction: michael@0: aResult = 1; michael@0: return NS_OK; michael@0: case eIntID_ScrollButtonRightMouseButtonAction: michael@0: aResult = 2; michael@0: return NS_OK; michael@0: default: michael@0: break; michael@0: } michael@0: michael@0: res = nsXPLookAndFeel::GetIntImpl(aID, aResult); michael@0: if (NS_SUCCEEDED(res)) michael@0: return res; michael@0: res = NS_OK; michael@0: michael@0: switch (aID) { michael@0: case eIntID_CaretBlinkTime: michael@0: { michael@0: GtkSettings *settings; michael@0: gint blink_time; michael@0: gboolean blink; michael@0: michael@0: settings = gtk_settings_get_default (); michael@0: g_object_get (settings, michael@0: "gtk-cursor-blink-time", &blink_time, michael@0: "gtk-cursor-blink", &blink, michael@0: nullptr); michael@0: michael@0: if (blink) michael@0: aResult = (int32_t) blink_time; michael@0: else michael@0: aResult = 0; michael@0: break; michael@0: } michael@0: case eIntID_CaretWidth: michael@0: aResult = 1; michael@0: break; michael@0: case eIntID_ShowCaretDuringSelection: michael@0: aResult = 0; michael@0: break; michael@0: case eIntID_SelectTextfieldsOnKeyFocus: michael@0: { michael@0: GtkWidget *entry; michael@0: GtkSettings *settings; michael@0: gboolean select_on_focus; michael@0: michael@0: entry = gtk_entry_new(); michael@0: g_object_ref_sink(entry); michael@0: settings = gtk_widget_get_settings(entry); michael@0: g_object_get(settings, michael@0: "gtk-entry-select-on-focus", michael@0: &select_on_focus, michael@0: nullptr); michael@0: michael@0: if(select_on_focus) michael@0: aResult = 1; michael@0: else michael@0: aResult = 0; michael@0: michael@0: gtk_widget_destroy(entry); michael@0: g_object_unref(entry); michael@0: } michael@0: break; michael@0: case eIntID_SubmenuDelay: michael@0: { michael@0: GtkSettings *settings; michael@0: gint delay; michael@0: michael@0: settings = gtk_settings_get_default (); michael@0: g_object_get (settings, "gtk-menu-popup-delay", &delay, nullptr); michael@0: aResult = (int32_t) delay; michael@0: break; michael@0: } michael@0: case eIntID_TooltipDelay: michael@0: { michael@0: aResult = 500; michael@0: break; michael@0: } michael@0: case eIntID_MenusCanOverlapOSBar: michael@0: // we want XUL popups to be able to overlap the task bar. michael@0: aResult = 1; michael@0: break; michael@0: case eIntID_SkipNavigatingDisabledMenuItem: michael@0: aResult = 1; michael@0: break; michael@0: case eIntID_DragThresholdX: michael@0: case eIntID_DragThresholdY: michael@0: { michael@0: GtkWidget* box = gtk_hbox_new(FALSE, 5); michael@0: gint threshold = 0; michael@0: g_object_get(gtk_widget_get_settings(box), michael@0: "gtk-dnd-drag-threshold", &threshold, michael@0: nullptr); michael@0: g_object_ref_sink(box); michael@0: michael@0: aResult = threshold; michael@0: } michael@0: break; michael@0: case eIntID_ScrollArrowStyle: michael@0: moz_gtk_init(); michael@0: aResult = michael@0: ConvertGTKStepperStyleToMozillaScrollArrowStyle(moz_gtk_get_scrollbar_widget()); michael@0: break; michael@0: case eIntID_ScrollSliderStyle: michael@0: aResult = eScrollThumbStyle_Proportional; michael@0: break; michael@0: case eIntID_TreeOpenDelay: michael@0: aResult = 1000; michael@0: break; michael@0: case eIntID_TreeCloseDelay: michael@0: aResult = 1000; michael@0: break; michael@0: case eIntID_TreeLazyScrollDelay: michael@0: aResult = 150; michael@0: break; michael@0: case eIntID_TreeScrollDelay: michael@0: aResult = 100; michael@0: break; michael@0: case eIntID_TreeScrollLinesMax: michael@0: aResult = 3; michael@0: break; michael@0: case eIntID_DWMCompositor: michael@0: case eIntID_WindowsClassic: michael@0: case eIntID_WindowsDefaultTheme: michael@0: case eIntID_WindowsThemeIdentifier: michael@0: case eIntID_OperatingSystemVersionIdentifier: michael@0: aResult = 0; michael@0: res = NS_ERROR_NOT_IMPLEMENTED; michael@0: break; michael@0: case eIntID_TouchEnabled: michael@0: aResult = 0; michael@0: res = NS_ERROR_NOT_IMPLEMENTED; michael@0: break; michael@0: case eIntID_MacGraphiteTheme: michael@0: case eIntID_MacLionTheme: michael@0: aResult = 0; michael@0: res = NS_ERROR_NOT_IMPLEMENTED; michael@0: break; michael@0: case eIntID_AlertNotificationOrigin: michael@0: aResult = NS_ALERT_TOP; michael@0: break; michael@0: case eIntID_IMERawInputUnderlineStyle: michael@0: case eIntID_IMEConvertedTextUnderlineStyle: michael@0: aResult = NS_STYLE_TEXT_DECORATION_STYLE_SOLID; michael@0: break; michael@0: case eIntID_IMESelectedRawTextUnderlineStyle: michael@0: case eIntID_IMESelectedConvertedTextUnderline: michael@0: aResult = NS_STYLE_TEXT_DECORATION_STYLE_NONE; michael@0: break; michael@0: case eIntID_SpellCheckerUnderlineStyle: michael@0: aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY; michael@0: break; michael@0: case eIntID_ImagesInMenus: michael@0: aResult = moz_gtk_images_in_menus(); michael@0: break; michael@0: case eIntID_ImagesInButtons: michael@0: aResult = moz_gtk_images_in_buttons(); michael@0: break; michael@0: case eIntID_MenuBarDrag: michael@0: aResult = sMenuSupportsDrag; michael@0: break; michael@0: case eIntID_ScrollbarButtonAutoRepeatBehavior: michael@0: aResult = 1; michael@0: break; michael@0: case eIntID_SwipeAnimationEnabled: michael@0: aResult = 0; michael@0: break; michael@0: case eIntID_ColorPickerAvailable: michael@0: aResult = 1; michael@0: break; michael@0: default: michael@0: aResult = 0; michael@0: res = NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: return res; michael@0: } michael@0: michael@0: nsresult michael@0: nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult) michael@0: { michael@0: nsresult res = NS_OK; michael@0: res = nsXPLookAndFeel::GetFloatImpl(aID, aResult); michael@0: if (NS_SUCCEEDED(res)) michael@0: return res; michael@0: res = NS_OK; michael@0: michael@0: switch (aID) { michael@0: case eFloatID_IMEUnderlineRelativeSize: michael@0: aResult = 1.0f; michael@0: break; michael@0: case eFloatID_SpellCheckerUnderlineRelativeSize: michael@0: aResult = 1.0f; michael@0: break; michael@0: case eFloatID_CaretAspectRatio: michael@0: aResult = sCaretRatio; michael@0: break; michael@0: default: michael@0: aResult = -1.0; michael@0: res = NS_ERROR_FAILURE; michael@0: } michael@0: return res; michael@0: } michael@0: michael@0: static void michael@0: GetSystemFontInfo(GtkWidget *aWidget, michael@0: nsString *aFontName, michael@0: gfxFontStyle *aFontStyle) michael@0: { michael@0: GtkSettings *settings = gtk_widget_get_settings(aWidget); michael@0: michael@0: aFontStyle->style = NS_FONT_STYLE_NORMAL; michael@0: michael@0: gchar *fontname; michael@0: g_object_get(settings, "gtk-font-name", &fontname, nullptr); michael@0: michael@0: PangoFontDescription *desc; michael@0: desc = pango_font_description_from_string(fontname); michael@0: michael@0: aFontStyle->systemFont = true; michael@0: michael@0: g_free(fontname); michael@0: michael@0: NS_NAMED_LITERAL_STRING(quote, "\""); michael@0: NS_ConvertUTF8toUTF16 family(pango_font_description_get_family(desc)); michael@0: *aFontName = quote + family + quote; michael@0: michael@0: aFontStyle->weight = pango_font_description_get_weight(desc); michael@0: michael@0: // FIXME: Set aFontStyle->stretch correctly! michael@0: aFontStyle->stretch = NS_FONT_STRETCH_NORMAL; michael@0: michael@0: float size = float(pango_font_description_get_size(desc)) / PANGO_SCALE; michael@0: michael@0: // |size| is now either pixels or pango-points (not Mozilla-points!) michael@0: michael@0: if (!pango_font_description_get_size_is_absolute(desc)) { michael@0: // |size| is in pango-points, so convert to pixels. michael@0: size *= float(gfxPlatformGtk::GetDPI()) / POINTS_PER_INCH_FLOAT; michael@0: } michael@0: michael@0: // |size| is now pixels michael@0: michael@0: aFontStyle->size = size; michael@0: michael@0: pango_font_description_free(desc); michael@0: } michael@0: michael@0: static void michael@0: GetSystemFontInfo(LookAndFeel::FontID aID, michael@0: nsString *aFontName, michael@0: gfxFontStyle *aFontStyle) michael@0: { michael@0: if (aID == LookAndFeel::eFont_Widget) { michael@0: GtkWidget *label = gtk_label_new("M"); michael@0: GtkWidget *parent = gtk_fixed_new(); michael@0: GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP); michael@0: michael@0: gtk_container_add(GTK_CONTAINER(parent), label); michael@0: gtk_container_add(GTK_CONTAINER(window), parent); michael@0: michael@0: gtk_widget_ensure_style(label); michael@0: GetSystemFontInfo(label, aFontName, aFontStyle); michael@0: gtk_widget_destroy(window); // no unref, windows are different michael@0: michael@0: } else if (aID == LookAndFeel::eFont_Button) { michael@0: GtkWidget *label = gtk_label_new("M"); michael@0: GtkWidget *parent = gtk_fixed_new(); michael@0: GtkWidget *button = gtk_button_new(); michael@0: GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP); michael@0: michael@0: gtk_container_add(GTK_CONTAINER(button), label); michael@0: gtk_container_add(GTK_CONTAINER(parent), button); michael@0: gtk_container_add(GTK_CONTAINER(window), parent); michael@0: michael@0: gtk_widget_ensure_style(label); michael@0: GetSystemFontInfo(label, aFontName, aFontStyle); michael@0: gtk_widget_destroy(window); // no unref, windows are different michael@0: michael@0: } else if (aID == LookAndFeel::eFont_Field) { michael@0: GtkWidget *entry = gtk_entry_new(); michael@0: GtkWidget *parent = gtk_fixed_new(); michael@0: GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP); michael@0: michael@0: gtk_container_add(GTK_CONTAINER(parent), entry); michael@0: gtk_container_add(GTK_CONTAINER(window), parent); michael@0: michael@0: gtk_widget_ensure_style(entry); michael@0: GetSystemFontInfo(entry, aFontName, aFontStyle); michael@0: gtk_widget_destroy(window); // no unref, windows are different michael@0: michael@0: } else { michael@0: NS_ABORT_IF_FALSE(aID == LookAndFeel::eFont_Menu, "unexpected font ID"); michael@0: GtkWidget *accel_label = gtk_accel_label_new("M"); michael@0: GtkWidget *menuitem = gtk_menu_item_new(); michael@0: GtkWidget *menu = gtk_menu_new(); michael@0: g_object_ref_sink(menu); michael@0: michael@0: gtk_container_add(GTK_CONTAINER(menuitem), accel_label); michael@0: gtk_menu_shell_append((GtkMenuShell *)GTK_MENU(menu), menuitem); michael@0: michael@0: gtk_widget_ensure_style(accel_label); michael@0: GetSystemFontInfo(accel_label, aFontName, aFontStyle); michael@0: g_object_unref(menu); michael@0: } michael@0: } michael@0: michael@0: bool michael@0: nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName, michael@0: gfxFontStyle& aFontStyle, michael@0: float aDevPixPerCSSPixel) michael@0: { michael@0: nsString *cachedFontName = nullptr; michael@0: gfxFontStyle *cachedFontStyle = nullptr; michael@0: bool *isCached = nullptr; michael@0: michael@0: switch (aID) { michael@0: case eFont_Menu: // css2 michael@0: case eFont_PullDownMenu: // css3 michael@0: cachedFontName = &mMenuFontName; michael@0: cachedFontStyle = &mMenuFontStyle; michael@0: isCached = &mMenuFontCached; michael@0: aID = eFont_Menu; michael@0: break; michael@0: michael@0: case eFont_Field: // css3 michael@0: case eFont_List: // css3 michael@0: cachedFontName = &mFieldFontName; michael@0: cachedFontStyle = &mFieldFontStyle; michael@0: isCached = &mFieldFontCached; michael@0: aID = eFont_Field; michael@0: break; michael@0: michael@0: case eFont_Button: // css3 michael@0: cachedFontName = &mButtonFontName; michael@0: cachedFontStyle = &mButtonFontStyle; michael@0: isCached = &mButtonFontCached; michael@0: break; michael@0: michael@0: case eFont_Caption: // css2 michael@0: case eFont_Icon: // css2 michael@0: case eFont_MessageBox: // css2 michael@0: case eFont_SmallCaption: // css2 michael@0: case eFont_StatusBar: // css2 michael@0: case eFont_Window: // css3 michael@0: case eFont_Document: // css3 michael@0: case eFont_Workspace: // css3 michael@0: case eFont_Desktop: // css3 michael@0: case eFont_Info: // css3 michael@0: case eFont_Dialog: // css3 michael@0: case eFont_Tooltips: // moz michael@0: case eFont_Widget: // moz michael@0: cachedFontName = &mDefaultFontName; michael@0: cachedFontStyle = &mDefaultFontStyle; michael@0: isCached = &mDefaultFontCached; michael@0: aID = eFont_Widget; michael@0: break; michael@0: } michael@0: michael@0: if (!*isCached) { michael@0: GetSystemFontInfo(aID, cachedFontName, cachedFontStyle); michael@0: *isCached = true; michael@0: } michael@0: michael@0: aFontName = *cachedFontName; michael@0: aFontStyle = *cachedFontStyle; michael@0: return true; michael@0: } michael@0: michael@0: #if (MOZ_WIDGET_GTK == 3) michael@0: static GtkStyleContext* michael@0: create_context(GtkWidgetPath *path) michael@0: { michael@0: GtkStyleContext *style = gtk_style_context_new(); michael@0: gtk_style_context_set_path(style, path); michael@0: return(style); michael@0: } michael@0: #endif michael@0: michael@0: void michael@0: nsLookAndFeel::Init() michael@0: { michael@0: GdkColor colorValue; michael@0: GdkColor *colorValuePtr; michael@0: michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: NS_ASSERTION(!mStyle, "already initialized"); michael@0: // GtkInvisibles come with a refcount that is not floating michael@0: // (since their initialization code calls g_object_ref_sink) and michael@0: // their destroy code releases that reference (which means they michael@0: // have to be explicitly destroyed, since calling unref enough michael@0: // to cause destruction would lead to *another* unref). michael@0: // However, this combination means that it's actually still ok michael@0: // to use the normal pattern, which is to g_object_ref_sink michael@0: // after construction, and then destroy *and* unref when we're michael@0: // done. (Though we could skip the g_object_ref_sink and the michael@0: // corresponding g_object_unref, but that's particular to michael@0: // GtkInvisibles and GtkWindows.) michael@0: GtkWidget *widget = gtk_invisible_new(); michael@0: g_object_ref_sink(widget); // effectively g_object_ref (see above) michael@0: michael@0: gtk_widget_ensure_style(widget); michael@0: mStyle = gtk_style_copy(gtk_widget_get_style(widget)); michael@0: michael@0: gtk_widget_destroy(widget); michael@0: g_object_unref(widget); michael@0: michael@0: // tooltip foreground and background michael@0: GtkStyle *style = gtk_rc_get_style_by_paths(gtk_settings_get_default(), michael@0: "gtk-tooltips", "GtkWindow", michael@0: GTK_TYPE_WINDOW); michael@0: if (style) { michael@0: sInfoBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]); michael@0: sInfoText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]); michael@0: } michael@0: michael@0: // menu foreground & menu background michael@0: GtkWidget *accel_label = gtk_accel_label_new("M"); michael@0: GtkWidget *menuitem = gtk_menu_item_new(); michael@0: GtkWidget *menu = gtk_menu_new(); michael@0: michael@0: g_object_ref_sink(menu); michael@0: michael@0: gtk_container_add(GTK_CONTAINER(menuitem), accel_label); michael@0: gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); michael@0: michael@0: gtk_widget_set_style(accel_label, nullptr); michael@0: gtk_widget_set_style(menu, nullptr); michael@0: gtk_widget_realize(menu); michael@0: gtk_widget_realize(accel_label); michael@0: michael@0: style = gtk_widget_get_style(accel_label); michael@0: if (style) { michael@0: sMenuText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]); michael@0: } michael@0: michael@0: style = gtk_widget_get_style(menu); michael@0: if (style) { michael@0: sMenuBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]); michael@0: } michael@0: michael@0: style = gtk_widget_get_style(menuitem); michael@0: if (style) { michael@0: sMenuHover = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_PRELIGHT]); michael@0: sMenuHoverText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_PRELIGHT]); michael@0: } michael@0: michael@0: g_object_unref(menu); michael@0: #else michael@0: GdkRGBA color; michael@0: GtkStyleContext *style; michael@0: michael@0: // Gtk manages a screen's CSS in the settings object so we michael@0: // ask Gtk to create it explicitly. Otherwise we may end up michael@0: // with wrong color theme, see Bug 972382 michael@0: (void)gtk_settings_get_for_screen(gdk_screen_get_default()); michael@0: michael@0: GtkWidgetPath *path = gtk_widget_path_new(); michael@0: gtk_widget_path_append_type(path, GTK_TYPE_WINDOW); michael@0: michael@0: mBackgroundStyle = create_context(path); michael@0: gtk_style_context_add_class(mBackgroundStyle, GTK_STYLE_CLASS_BACKGROUND); michael@0: michael@0: mViewStyle = create_context(path); michael@0: gtk_style_context_add_class(mViewStyle, GTK_STYLE_CLASS_VIEW); michael@0: michael@0: mButtonStyle = create_context(path); michael@0: gtk_style_context_add_class(mButtonStyle, GTK_STYLE_CLASS_BUTTON); michael@0: michael@0: // Scrollbar colors michael@0: style = create_context(path); michael@0: gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR); michael@0: gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH); michael@0: gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color); michael@0: g_object_unref(style); michael@0: michael@0: // Text colors michael@0: gtk_style_context_get_background_color(mViewStyle, GTK_STATE_FLAG_NORMAL, &color); michael@0: sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color); michael@0: gtk_style_context_get_color(mViewStyle, GTK_STATE_FLAG_NORMAL, &color); michael@0: sMozFieldText = GDK_RGBA_TO_NS_RGBA(color); michael@0: michael@0: // Window colors michael@0: style = create_context(path); michael@0: gtk_style_context_save(style); michael@0: gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); michael@0: gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color); michael@0: gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sMozWindowText = GDK_RGBA_TO_NS_RGBA(color); michael@0: michael@0: // Selected text and background michael@0: gtk_style_context_get_background_color(style, GTK_STATE_FLAG_SELECTED, &color); michael@0: sMozWindowSelectedBackground = GDK_RGBA_TO_NS_RGBA(color); michael@0: gtk_style_context_get_color(style, GTK_STATE_FLAG_SELECTED, &color); michael@0: sMozWindowSelectedText = GDK_RGBA_TO_NS_RGBA(color); michael@0: gtk_style_context_restore(style); michael@0: michael@0: // tooltip foreground and background michael@0: gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP); michael@0: gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sInfoBackground = GDK_RGBA_TO_NS_RGBA(color); michael@0: gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sInfoText = GDK_RGBA_TO_NS_RGBA(color); michael@0: g_object_unref(style); michael@0: michael@0: // menu foreground & menu background michael@0: GtkWidget *accel_label = gtk_accel_label_new("M"); michael@0: GtkWidget *menuitem = gtk_menu_item_new(); michael@0: GtkWidget *menu = gtk_menu_new(); michael@0: michael@0: g_object_ref_sink(menu); michael@0: michael@0: gtk_container_add(GTK_CONTAINER(menuitem), accel_label); michael@0: gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); michael@0: michael@0: style = gtk_widget_get_style_context(accel_label); michael@0: gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sMenuText = GDK_RGBA_TO_NS_RGBA(color); michael@0: michael@0: style = gtk_widget_get_style_context(menu); michael@0: gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sMenuBackground = GDK_RGBA_TO_NS_RGBA(color); michael@0: michael@0: style = gtk_widget_get_style_context(menuitem); michael@0: gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color); michael@0: sMenuHover = GDK_RGBA_TO_NS_RGBA(color); michael@0: gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); michael@0: sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color); michael@0: michael@0: g_object_unref(menu); michael@0: #endif michael@0: michael@0: // button styles michael@0: GtkWidget *parent = gtk_fixed_new(); michael@0: GtkWidget *button = gtk_button_new(); michael@0: GtkWidget *label = gtk_label_new("M"); michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: GtkWidget *combobox = gtk_combo_box_new(); michael@0: GtkWidget *comboboxLabel = gtk_label_new("M"); michael@0: gtk_container_add(GTK_CONTAINER(combobox), comboboxLabel); michael@0: #else michael@0: GtkWidget *combobox = gtk_combo_box_new_with_entry(); michael@0: GtkWidget *comboboxLabel = gtk_bin_get_child(GTK_BIN(combobox)); michael@0: #endif michael@0: GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP); michael@0: GtkWidget *treeView = gtk_tree_view_new(); michael@0: GtkWidget *linkButton = gtk_link_button_new("http://example.com/"); michael@0: GtkWidget *menuBar = gtk_menu_bar_new(); michael@0: GtkWidget *entry = gtk_entry_new(); michael@0: michael@0: gtk_container_add(GTK_CONTAINER(button), label); michael@0: gtk_container_add(GTK_CONTAINER(parent), button); michael@0: gtk_container_add(GTK_CONTAINER(parent), treeView); michael@0: gtk_container_add(GTK_CONTAINER(parent), linkButton); michael@0: gtk_container_add(GTK_CONTAINER(parent), combobox); michael@0: gtk_container_add(GTK_CONTAINER(parent), menuBar); michael@0: gtk_container_add(GTK_CONTAINER(window), parent); michael@0: gtk_container_add(GTK_CONTAINER(parent), entry); michael@0: michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: gtk_widget_set_style(button, nullptr); michael@0: gtk_widget_set_style(label, nullptr); michael@0: gtk_widget_set_style(treeView, nullptr); michael@0: gtk_widget_set_style(linkButton, nullptr); michael@0: gtk_widget_set_style(combobox, nullptr); michael@0: gtk_widget_set_style(comboboxLabel, nullptr); michael@0: gtk_widget_set_style(menuBar, nullptr); michael@0: gtk_widget_set_style(entry, nullptr); michael@0: michael@0: gtk_widget_realize(button); michael@0: gtk_widget_realize(label); michael@0: gtk_widget_realize(treeView); michael@0: gtk_widget_realize(linkButton); michael@0: gtk_widget_realize(combobox); michael@0: gtk_widget_realize(comboboxLabel); michael@0: gtk_widget_realize(menuBar); michael@0: gtk_widget_realize(entry); michael@0: michael@0: style = gtk_widget_get_style(label); michael@0: if (style) { michael@0: sButtonText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]); michael@0: } michael@0: michael@0: style = gtk_widget_get_style(comboboxLabel); michael@0: if (style) { michael@0: sComboBoxText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]); michael@0: } michael@0: style = gtk_widget_get_style(combobox); michael@0: if (style) { michael@0: sComboBoxBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]); michael@0: } michael@0: michael@0: style = gtk_widget_get_style(menuBar); michael@0: if (style) { michael@0: sMenuBarText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_NORMAL]); michael@0: sMenuBarHoverText = GDK_COLOR_TO_NS_RGB(style->fg[GTK_STATE_SELECTED]); michael@0: } michael@0: michael@0: // GTK's guide to fancy odd row background colors: michael@0: // 1) Check if a theme explicitly defines an odd row color michael@0: // 2) If not, check if it defines an even row color, and darken it michael@0: // slightly by a hardcoded value (gtkstyle.c) michael@0: // 3) If neither are defined, take the base background color and michael@0: // darken that by a hardcoded value michael@0: colorValuePtr = nullptr; michael@0: gtk_widget_style_get(treeView, michael@0: "odd-row-color", &colorValuePtr, michael@0: nullptr); michael@0: michael@0: if (colorValuePtr) { michael@0: colorValue = *colorValuePtr; michael@0: } else { michael@0: gtk_widget_style_get(treeView, michael@0: "even-row-color", &colorValuePtr, michael@0: nullptr); michael@0: if (colorValuePtr) michael@0: darken_gdk_color(colorValuePtr, &colorValue); michael@0: else michael@0: darken_gdk_color(&treeView->style->base[GTK_STATE_NORMAL], &colorValue); michael@0: } michael@0: michael@0: sOddCellBackground = GDK_COLOR_TO_NS_RGB(colorValue); michael@0: if (colorValuePtr) michael@0: gdk_color_free(colorValuePtr); michael@0: michael@0: style = gtk_widget_get_style(button); michael@0: if (style) { michael@0: sButtonBackground = GDK_COLOR_TO_NS_RGB(style->bg[GTK_STATE_NORMAL]); michael@0: sButtonOuterLightBorder = michael@0: GDK_COLOR_TO_NS_RGB(style->light[GTK_STATE_NORMAL]); michael@0: sButtonInnerDarkBorder = michael@0: GDK_COLOR_TO_NS_RGB(style->dark[GTK_STATE_NORMAL]); michael@0: } michael@0: #else michael@0: // Button text, background, border michael@0: style = gtk_widget_get_style_context(label); michael@0: gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sButtonText = GDK_RGBA_TO_NS_RGBA(color); michael@0: gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); michael@0: sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color); michael@0: michael@0: // Combobox label and background colors michael@0: style = gtk_widget_get_style_context(comboboxLabel); michael@0: gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sComboBoxText = GDK_RGBA_TO_NS_RGBA(color); michael@0: michael@0: style = gtk_widget_get_style_context(combobox); michael@0: gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sComboBoxBackground = GDK_RGBA_TO_NS_RGBA(color); michael@0: michael@0: // Menubar text and hover text colors michael@0: style = gtk_widget_get_style_context(menuBar); michael@0: gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sMenuBarText = GDK_RGBA_TO_NS_RGBA(color); michael@0: gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); michael@0: sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color); michael@0: michael@0: // GTK's guide to fancy odd row background colors: michael@0: // 1) Check if a theme explicitly defines an odd row color michael@0: // 2) If not, check if it defines an even row color, and darken it michael@0: // slightly by a hardcoded value (gtkstyle.c) michael@0: // 3) If neither are defined, take the base background color and michael@0: // darken that by a hardcoded value michael@0: style = gtk_widget_get_style_context(treeView); michael@0: michael@0: // Get odd row background color michael@0: gtk_style_context_save(style); michael@0: gtk_style_context_add_region(style, GTK_STYLE_REGION_ROW, GTK_REGION_ODD); michael@0: gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color); michael@0: gtk_style_context_restore(style); michael@0: michael@0: style = gtk_widget_get_style_context(button); michael@0: gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sButtonBackground = GDK_RGBA_TO_NS_RGBA(color); michael@0: michael@0: gtk_style_context_get_border_color(style, GTK_STATE_FLAG_PRELIGHT, &color); michael@0: sButtonInnerDarkBorder = GDK_RGBA_TO_NS_RGBA(color); michael@0: gtk_style_context_get_border_color(style, GTK_STATE_FLAG_NORMAL, &color); michael@0: sButtonOuterLightBorder = GDK_RGBA_TO_NS_RGBA(color); michael@0: #endif michael@0: // Some themes have a unified menu bar, and support window dragging on it michael@0: gboolean supports_menubar_drag = FALSE; michael@0: GParamSpec *param_spec = michael@0: gtk_widget_class_find_style_property(GTK_WIDGET_GET_CLASS(menuBar), michael@0: "window-dragging"); michael@0: if (param_spec) { michael@0: if (g_type_is_a(G_PARAM_SPEC_VALUE_TYPE(param_spec), G_TYPE_BOOLEAN)) { michael@0: gtk_widget_style_get(menuBar, michael@0: "window-dragging", &supports_menubar_drag, michael@0: nullptr); michael@0: } michael@0: } michael@0: sMenuSupportsDrag = supports_menubar_drag; michael@0: michael@0: colorValuePtr = nullptr; michael@0: gtk_widget_style_get(linkButton, "link-color", &colorValuePtr, nullptr); michael@0: if (colorValuePtr) { michael@0: colorValue = *colorValuePtr; // we can't pass deref pointers to GDK_COLOR_TO_NS_RGB michael@0: sNativeHyperLinkText = GDK_COLOR_TO_NS_RGB(colorValue); michael@0: gdk_color_free(colorValuePtr); michael@0: } else { michael@0: sNativeHyperLinkText = NS_RGB(0x00,0x00,0xEE); michael@0: } michael@0: michael@0: // invisible character styles michael@0: guint value; michael@0: g_object_get (entry, "invisible-char", &value, nullptr); michael@0: sInvisibleCharacter = char16_t(value); michael@0: michael@0: // caret styles michael@0: gtk_widget_style_get(entry, michael@0: "cursor-aspect-ratio", &sCaretRatio, michael@0: nullptr); michael@0: michael@0: gtk_widget_destroy(window); michael@0: } michael@0: michael@0: // virtual michael@0: char16_t michael@0: nsLookAndFeel::GetPasswordCharacterImpl() michael@0: { michael@0: return sInvisibleCharacter; michael@0: } michael@0: michael@0: void michael@0: nsLookAndFeel::RefreshImpl() michael@0: { michael@0: nsXPLookAndFeel::RefreshImpl(); michael@0: michael@0: mDefaultFontCached = false; michael@0: mButtonFontCached = false; michael@0: mFieldFontCached = false; michael@0: mMenuFontCached = false; michael@0: michael@0: #if (MOZ_WIDGET_GTK == 2) michael@0: g_object_unref(mStyle); michael@0: mStyle = nullptr; michael@0: #else michael@0: g_object_unref(mBackgroundStyle); michael@0: g_object_unref(mViewStyle); michael@0: g_object_unref(mButtonStyle); michael@0: michael@0: mBackgroundStyle = nullptr; michael@0: mViewStyle = nullptr; michael@0: mButtonStyle = nullptr; michael@0: #endif michael@0: michael@0: Init(); michael@0: } michael@0: michael@0: bool michael@0: nsLookAndFeel::GetEchoPasswordImpl() { michael@0: return false; michael@0: }