/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "HeadlessThemeGTK.h" #include "mozilla/StaticPrefs_layout.h" #include "nsStyleConsts.h" #include "nsIFrame.h" namespace mozilla { namespace widget { NS_IMPL_ISUPPORTS_INHERITED(HeadlessThemeGTK, nsNativeTheme, nsITheme) NS_IMETHODIMP HeadlessThemeGTK::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame, StyleAppearance aAppearance, const nsRect& aRect, const nsRect& aDirtyRect) { return NS_OK; } LayoutDeviceIntMargin HeadlessThemeGTK::GetWidgetBorder( nsDeviceContext* aContext, nsIFrame* aFrame, StyleAppearance aAppearance) { if (aAppearance == StyleAppearance::MenulistButton && StaticPrefs::layout_css_webkit_appearance_enabled()) { aAppearance = StyleAppearance::Menulist; } LayoutDeviceIntMargin result; // The following values are generated from the Ubuntu GTK theme. switch (aAppearance) { case StyleAppearance::Button: case StyleAppearance::Toolbarbutton: result.top = 6; result.right = 7; result.bottom = 6; result.left = 7; break; case StyleAppearance::FocusOutline: case StyleAppearance::MenulistTextfield: case StyleAppearance::NumberInput: case StyleAppearance::Textfield: result.top = 5; result.right = 7; result.bottom = 5; result.left = 7; break; case StyleAppearance::Statusbarpanel: case StyleAppearance::Resizerpanel: case StyleAppearance::Listbox: case StyleAppearance::Treeview: case StyleAppearance::Treeheadersortarrow: case StyleAppearance::ProgressBar: case StyleAppearance::ProgressbarVertical: case StyleAppearance::SpinnerUpbutton: case StyleAppearance::SpinnerDownbutton: case StyleAppearance::SpinnerTextfield: case StyleAppearance::Textarea: case StyleAppearance::Menupopup: case StyleAppearance::MozGtkInfoBar: result.top = 1; result.right = 1; result.bottom = 1; result.left = 1; break; case StyleAppearance::Treeheadercell: result.top = 5; result.right = 7; result.bottom = 6; result.left = 6; break; case StyleAppearance::Tab: result.top = 4; result.right = 7; result.bottom = 2; result.left = 7; break; case StyleAppearance::Tooltip: result.top = 6; result.right = 6; result.bottom = 6; result.left = 6; break; case StyleAppearance::Menulist: result.top = 6; result.right = 22; result.bottom = 6; result.left = 7; break; case StyleAppearance::MenulistButton: case StyleAppearance::MozMenulistButton: result.top = 1; result.right = 1; result.bottom = 1; result.left = 0; break; case StyleAppearance::Menuitem: case StyleAppearance::Checkmenuitem: case StyleAppearance::Radiomenuitem: if (IsRegularMenuItem(aFrame)) { break; } result.top = 3; result.right = 5; result.bottom = 3; result.left = 5; break; default: break; } return result; } bool HeadlessThemeGTK::GetWidgetPadding(nsDeviceContext* aContext, nsIFrame* aFrame, StyleAppearance aAppearance, LayoutDeviceIntMargin* aResult) { if (aAppearance == StyleAppearance::MenulistButton && StaticPrefs::layout_css_webkit_appearance_enabled()) { aAppearance = StyleAppearance::Menulist; } // The following values are generated from the Ubuntu GTK theme. switch (aAppearance) { case StyleAppearance::Radio: case StyleAppearance::Checkbox: case StyleAppearance::Toolbarbutton: case StyleAppearance::Dualbutton: case StyleAppearance::ToolbarbuttonDropdown: case StyleAppearance::ButtonArrowUp: case StyleAppearance::ButtonArrowDown: case StyleAppearance::ButtonArrowNext: case StyleAppearance::ButtonArrowPrevious: case StyleAppearance::TabScrollArrowBack: case StyleAppearance::TabScrollArrowForward: case StyleAppearance::MenulistButton: case StyleAppearance::MozMenulistButton: case StyleAppearance::RangeThumb: case StyleAppearance::ButtonFocus: aResult->top = 0; aResult->right = 0; aResult->bottom = 0; aResult->left = 0; return true; case StyleAppearance::Menuitem: case StyleAppearance::Checkmenuitem: case StyleAppearance::Radiomenuitem: if (!IsRegularMenuItem(aFrame)) { return false; } aResult->top = 3; aResult->right = 5; aResult->bottom = 3; aResult->left = 5; return true; default: break; } return false; } NS_IMETHODIMP HeadlessThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aFrame, StyleAppearance aAppearance, LayoutDeviceIntSize* aResult, bool* aIsOverridable) { aResult->width = aResult->height = 0; *aIsOverridable = true; if (aAppearance == StyleAppearance::MenulistButton && StaticPrefs::layout_css_webkit_appearance_enabled()) { aAppearance = StyleAppearance::Menulist; } // The following values are generated from the Ubuntu GTK theme. switch (aAppearance) { case StyleAppearance::Splitter: if (IsHorizontal(aFrame)) { aResult->width = 6; aResult->height = 0; } else { aResult->width = 0; aResult->height = 6; } *aIsOverridable = false; break; case StyleAppearance::Button: case StyleAppearance::Toolbarbutton: aResult->width = 14; aResult->height = 12; break; case StyleAppearance::Radio: case StyleAppearance::Checkbox: aResult->width = 18; aResult->height = 18; break; case StyleAppearance::ToolbarbuttonDropdown: case StyleAppearance::ButtonArrowUp: case StyleAppearance::ButtonArrowDown: case StyleAppearance::ButtonArrowNext: case StyleAppearance::ButtonArrowPrevious: case StyleAppearance::Resizer: aResult->width = 15; aResult->height = 15; *aIsOverridable = false; break; case StyleAppearance::Separator: aResult->width = 12; aResult->height = 0; break; case StyleAppearance::Treetwisty: case StyleAppearance::Treetwistyopen: aResult->width = 8; aResult->height = 8; *aIsOverridable = false; break; case StyleAppearance::Treeheadercell: aResult->width = 13; aResult->height = 11; break; case StyleAppearance::Treeheadersortarrow: case StyleAppearance::SpinnerUpbutton: case StyleAppearance::SpinnerDownbutton: aResult->width = 14; aResult->height = 13; break; case StyleAppearance::TabScrollArrowBack: case StyleAppearance::TabScrollArrowForward: aResult->width = 16; aResult->height = 16; *aIsOverridable = false; break; case StyleAppearance::InnerSpinButton: case StyleAppearance::Spinner: aResult->width = 14; aResult->height = 26; break; case StyleAppearance::MenulistTextfield: case StyleAppearance::NumberInput: case StyleAppearance::Textfield: aResult->width = 0; aResult->height = 12; break; case StyleAppearance::ScrollbarHorizontal: aResult->width = 31; aResult->height = 10; break; case StyleAppearance::ScrollbarVertical: aResult->width = 10; aResult->height = 31; break; case StyleAppearance::ScrollbarbuttonUp: case StyleAppearance::ScrollbarbuttonDown: aResult->width = 10; aResult->height = 13; *aIsOverridable = false; break; case StyleAppearance::ScrollbarbuttonLeft: case StyleAppearance::ScrollbarbuttonRight: aResult->width = 13; aResult->height = 10; *aIsOverridable = false; break; case StyleAppearance::ScrollbarthumbHorizontal: aResult->width = 31; aResult->height = 10; *aIsOverridable = false; break; case StyleAppearance::ScrollbarthumbVertical: aResult->width = 10; aResult->height = 31; *aIsOverridable = false; break; case StyleAppearance::Menulist: aResult->width = 44; aResult->height = 27; break; case StyleAppearance::MenulistButton: case StyleAppearance::MozMenulistButton: aResult->width = 29; aResult->height = 28; *aIsOverridable = false; break; case StyleAppearance::ScalethumbHorizontal: case StyleAppearance::RangeThumb: aResult->width = 14; aResult->height = 18; *aIsOverridable = false; break; case StyleAppearance::ScalethumbVertical: aResult->width = 18; aResult->height = 13; *aIsOverridable = false; break; case StyleAppearance::Menuseparator: aResult->width = 0; aResult->height = 8; *aIsOverridable = false; break; default: break; } return NS_OK; } NS_IMETHODIMP HeadlessThemeGTK::WidgetStateChanged(nsIFrame* aFrame, StyleAppearance aAppearance, nsAtom* aAttribute, bool* aShouldRepaint, const nsAttrValue* aOldValue) { return NS_OK; } NS_IMETHODIMP HeadlessThemeGTK::ThemeChanged() { return NS_OK; } static bool IsFrameContentNodeInNamespace(nsIFrame* aFrame, uint32_t aNamespace) { nsIContent* content = aFrame ? aFrame->GetContent() : nullptr; if (!content) return false; return content->IsInNamespace(aNamespace); } NS_IMETHODIMP_(bool) HeadlessThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame, StyleAppearance aAppearance) { if (aAppearance == StyleAppearance::MenulistButton && StaticPrefs::layout_css_webkit_appearance_enabled()) { aAppearance = StyleAppearance::Menulist; } switch (aAppearance) { case StyleAppearance::Button: case StyleAppearance::Radio: case StyleAppearance::Checkbox: case StyleAppearance::FocusOutline: case StyleAppearance::Toolbox: case StyleAppearance::Toolbar: case StyleAppearance::Toolbarbutton: case StyleAppearance::Dualbutton: case StyleAppearance::ToolbarbuttonDropdown: case StyleAppearance::ButtonArrowUp: case StyleAppearance::ButtonArrowDown: case StyleAppearance::ButtonArrowNext: case StyleAppearance::ButtonArrowPrevious: case StyleAppearance::Separator: case StyleAppearance::Toolbargripper: case StyleAppearance::Splitter: case StyleAppearance::Statusbar: case StyleAppearance::Statusbarpanel: case StyleAppearance::Resizerpanel: case StyleAppearance::Resizer: case StyleAppearance::Listbox: case StyleAppearance::Treeview: case StyleAppearance::Treetwisty: case StyleAppearance::Treeheadercell: case StyleAppearance::Treeheadersortarrow: case StyleAppearance::Treetwistyopen: case StyleAppearance::ProgressBar: case StyleAppearance::Progresschunk: case StyleAppearance::ProgressbarVertical: case StyleAppearance::Tab: case StyleAppearance::Tabpanels: case StyleAppearance::TabScrollArrowBack: case StyleAppearance::TabScrollArrowForward: case StyleAppearance::Tooltip: case StyleAppearance::InnerSpinButton: case StyleAppearance::Spinner: case StyleAppearance::SpinnerUpbutton: case StyleAppearance::SpinnerDownbutton: case StyleAppearance::SpinnerTextfield: case StyleAppearance::NumberInput: case StyleAppearance::ScrollbarHorizontal: case StyleAppearance::ScrollbarVertical: case StyleAppearance::ScrollbarbuttonUp: case StyleAppearance::ScrollbarbuttonDown: case StyleAppearance::ScrollbarbuttonLeft: case StyleAppearance::ScrollbarbuttonRight: case StyleAppearance::ScrollbartrackHorizontal: case StyleAppearance::ScrollbartrackVertical: case StyleAppearance::ScrollbarthumbHorizontal: case StyleAppearance::ScrollbarthumbVertical: case StyleAppearance::Textfield: case StyleAppearance::Textarea: case StyleAppearance::Menulist: case StyleAppearance::MenulistText: case StyleAppearance::MenulistTextfield: case StyleAppearance::ScaleHorizontal: case StyleAppearance::ScaleVertical: case StyleAppearance::ScalethumbHorizontal: case StyleAppearance::ScalethumbVertical: case StyleAppearance::Range: case StyleAppearance::RangeThumb: case StyleAppearance::CheckboxContainer: case StyleAppearance::RadioContainer: case StyleAppearance::CheckboxLabel: case StyleAppearance::RadioLabel: case StyleAppearance::ButtonFocus: case StyleAppearance::Window: case StyleAppearance::Dialog: case StyleAppearance::Menubar: case StyleAppearance::Menupopup: case StyleAppearance::Menuitem: case StyleAppearance::Checkmenuitem: case StyleAppearance::Radiomenuitem: case StyleAppearance::Menuseparator: case StyleAppearance::Menuarrow: case StyleAppearance::MozGtkInfoBar: return !IsWidgetStyled(aPresContext, aFrame, aAppearance); case StyleAppearance::MenulistButton: case StyleAppearance::MozMenulistButton: return (!aFrame || IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) && !IsWidgetStyled(aPresContext, aFrame, aAppearance); default: break; } return false; } NS_IMETHODIMP_(bool) HeadlessThemeGTK::WidgetIsContainer(StyleAppearance aAppearance) { if (aAppearance == StyleAppearance::MenulistButton && StaticPrefs::layout_css_webkit_appearance_enabled()) { aAppearance = StyleAppearance::Menulist; } if (aAppearance == StyleAppearance::MenulistButton || aAppearance == StyleAppearance::MozMenulistButton || aAppearance == StyleAppearance::Radio || aAppearance == StyleAppearance::RangeThumb || aAppearance == StyleAppearance::Checkbox || aAppearance == StyleAppearance::TabScrollArrowBack || aAppearance == StyleAppearance::TabScrollArrowForward || aAppearance == StyleAppearance::ButtonArrowUp || aAppearance == StyleAppearance::ButtonArrowDown || aAppearance == StyleAppearance::ButtonArrowNext || aAppearance == StyleAppearance::ButtonArrowPrevious) { return false; } return true; } bool HeadlessThemeGTK::ThemeDrawsFocusForWidget(StyleAppearance aAppearance) { if (aAppearance == StyleAppearance::Menulist || aAppearance == StyleAppearance::Button || aAppearance == StyleAppearance::Treeheadercell) { return true; } return false; } bool HeadlessThemeGTK::ThemeNeedsComboboxDropmarker() { return false; } } // namespace widget } // namespace mozilla