Skip to content

Commit

Permalink
style: Move system colors to values::specified::color.
Browse files Browse the repository at this point in the history
This should be an idempotent patch. The way to come up with this patch has been:

 * Run the first script attached to the bug and pipe it to xclip, then paste it
   in color.rs
 * Add the relevant #[derive] annotations and remove the color.mako.rs
   definition.
 * Reorder the values to match the ColorID definition, on which some widget
   prefs and caching stuff relies on.
 * Manually port some documentation from nsLookAndFeel.h
 * Run `rg 'eColorID_' | cut -d : -f 1 | sort | uniq >files`
 * Run the second script attached to the bug.
 * Manually fix usage of `LAST_COLOR` (adding the `End` variant), and adding
   casts to integer as needed.
 * Add an static assert so that people remember to update the prefs, rather than
   a comment on the definition :)

Differential Revision: https://phabricator.services.mozilla.com/D32610
  • Loading branch information
emilio committed Jun 4, 2019
1 parent 3a2705f commit 729bf19
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 131 deletions.
111 changes: 0 additions & 111 deletions components/style/properties/longhands/color.mako.rs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -17,114 +17,3 @@ ${helpers.predefined_type(
ignored_when_colors_disabled="True", ignored_when_colors_disabled="True",
spec="https://drafts.csswg.org/css-color/#color", spec="https://drafts.csswg.org/css-color/#color",
)} )}

// FIXME(#15973): Add servo support for system colors
//
// FIXME(emilio): Move outside of mako.
% if product == "gecko":
pub mod system_colors {
<%
# These are actually parsed. See nsCSSProps::kColorKTable
system_colors = """activeborder activecaption appworkspace background buttonface
buttonhighlight buttonshadow buttontext captiontext graytext highlight
highlighttext inactiveborder inactivecaption inactivecaptiontext
infobackground infotext menu menutext scrollbar threeddarkshadow
threedface threedhighlight threedlightshadow threedshadow window
windowframe windowtext -moz-buttondefault -moz-buttonhoverface
-moz-buttonhovertext -moz-cellhighlight -moz-cellhighlighttext
-moz-eventreerow -moz-field -moz-fieldtext -moz-dialog -moz-dialogtext
-moz-dragtargetzone -moz-gtk-info-bar-text -moz-html-cellhighlight
-moz-html-cellhighlighttext -moz-mac-buttonactivetext
-moz-gtk-buttonactivetext
-moz-mac-chrome-active -moz-mac-chrome-inactive
-moz-mac-defaultbuttontext -moz-mac-focusring -moz-mac-menuselect
-moz-mac-menushadow -moz-mac-menutextdisable -moz-mac-menutextselect
-moz-mac-disabledtoolbartext -moz-mac-secondaryhighlight
-moz-mac-vibrancy-light -moz-mac-vibrancy-dark
-moz-mac-vibrant-titlebar-light -moz-mac-vibrant-titlebar-dark
-moz-mac-menupopup
-moz-mac-menuitem -moz-mac-active-menuitem -moz-mac-source-list
-moz-mac-source-list-selection -moz-mac-active-source-list-selection
-moz-mac-tooltip
-moz-menuhover -moz-menuhovertext -moz-menubartext -moz-menubarhovertext
-moz-oddtreerow -moz-win-mediatext -moz-win-communicationstext
-moz-win-accentcolor -moz-win-accentcolortext
-moz-nativehyperlinktext -moz-comboboxtext -moz-combobox""".split()

# These are not parsed but must be serialized
# They are only ever set directly by Gecko
extra_colors = """WindowBackground WindowForeground WidgetBackground WidgetForeground
WidgetSelectBackground WidgetSelectForeground Widget3DHighlight Widget3DShadow
TextBackground TextForeground TextSelectBackground TextSelectForeground
TextSelectForegroundCustom TextSelectBackgroundDisabled TextSelectBackgroundAttention
TextHighlightBackground TextHighlightForeground IMERawInputBackground
IMERawInputForeground IMERawInputUnderline IMESelectedRawTextBackground
IMESelectedRawTextForeground IMESelectedRawTextUnderline
IMEConvertedTextBackground IMEConvertedTextForeground IMEConvertedTextUnderline
IMESelectedConvertedTextBackground IMESelectedConvertedTextForeground
IMESelectedConvertedTextUnderline SpellCheckerUnderline""".split()
%>
use crate::gecko_bindings::bindings::Gecko_GetLookAndFeelSystemColor;
use crate::gecko_bindings::structs::root::mozilla::LookAndFeel_ColorID;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
use to_shmem::impl_trivial_to_shmem;
use crate::values::computed::{Context, ToComputedValue};

pub type SystemColor = LookAndFeel_ColorID;

// It's hard to implement MallocSizeOf for LookAndFeel_ColorID because it
// is a bindgen type. So we implement it on the typedef instead.
malloc_size_of_is_0!(SystemColor);

impl_trivial_to_shmem!(SystemColor);

impl ToCss for SystemColor {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
let s = match *self {
% for color in system_colors + extra_colors:
LookAndFeel_ColorID::eColorID_${to_rust_ident(color)} => "${color}",
% endfor
LookAndFeel_ColorID::eColorID_LAST_COLOR => unreachable!(),
};
dest.write_str(s)
}
}

impl ToComputedValue for SystemColor {
type ComputedValue = u32; // nscolor

#[inline]
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
unsafe {
Gecko_GetLookAndFeelSystemColor(
*self as i32,
cx.device().document(),
)
}
}

#[inline]
fn from_computed_value(_: &Self::ComputedValue) -> Self {
unreachable!()
}
}

impl SystemColor {
pub fn from_ident<'i, 't>(ident: &str) -> Result<Self, ()> {
ascii_case_insensitive_phf_map! {
color_name -> SystemColor = {
% for color in system_colors:
"${color}" => LookAndFeel_ColorID::eColorID_${to_rust_ident(color)},
% endfor
}
}

color_name(ident).cloned().ok_or(())
}
}
}
% endif
243 changes: 223 additions & 20 deletions components/style/values/specified/color.rs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use super::AllowQuirks;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use crate::gecko_bindings::structs::nscolor; use crate::gecko_bindings::structs::nscolor;
use crate::parser::{Parse, ParserContext}; use crate::parser::{Parse, ParserContext};
#[cfg(feature = "gecko")]
use crate::properties::longhands::system_colors::SystemColor;
use crate::values::computed::{Color as ComputedColor, Context, ToComputedValue}; use crate::values::computed::{Color as ComputedColor, Context, ToComputedValue};
use crate::values::generics::color::{Color as GenericColor, ColorOrAuto as GenericColorOrAuto}; use crate::values::generics::color::{Color as GenericColor, ColorOrAuto as GenericColorOrAuto};
use crate::values::specified::calc::CalcNode; use crate::values::specified::calc::CalcNode;
Expand All @@ -35,7 +33,6 @@ pub enum Color {
}, },
/// A complex color value from computed value /// A complex color value from computed value
Complex(ComputedColor), Complex(ComputedColor),

/// A system color /// A system color
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
System(SystemColor), System(SystemColor),
Expand All @@ -47,6 +44,215 @@ pub enum Color {
InheritFromBodyQuirk, InheritFromBodyQuirk,
} }


/// System colors.
#[allow(missing_docs)]
#[cfg(feature = "gecko")]
#[derive(Copy, Clone, Debug, MallocSizeOf, Parse, PartialEq, ToCss, ToShmem)]
#[repr(u8)]
pub enum SystemColor {
#[css(skip)]
WindowBackground,
#[css(skip)]
WindowForeground,
#[css(skip)]
WidgetBackground,
#[css(skip)]
WidgetForeground,
#[css(skip)]
WidgetSelectBackground,
#[css(skip)]
WidgetSelectForeground,
#[css(skip)]
Widget3DHighlight,
#[css(skip)]
Widget3DShadow,
#[css(skip)]
TextBackground,
#[css(skip)]
TextForeground,
#[css(skip)]
TextSelectBackground,
#[css(skip)]
TextSelectForeground,
#[css(skip)]
TextSelectForegroundCustom,
#[css(skip)]
TextSelectBackgroundDisabled,
#[css(skip)]
TextSelectBackgroundAttention,
#[css(skip)]
TextHighlightBackground,
#[css(skip)]
TextHighlightForeground,
#[css(skip)]
IMERawInputBackground,
#[css(skip)]
IMERawInputForeground,
#[css(skip)]
IMERawInputUnderline,
#[css(skip)]
IMESelectedRawTextBackground,
#[css(skip)]
IMESelectedRawTextForeground,
#[css(skip)]
IMESelectedRawTextUnderline,
#[css(skip)]
IMEConvertedTextBackground,
#[css(skip)]
IMEConvertedTextForeground,
#[css(skip)]
IMEConvertedTextUnderline,
#[css(skip)]
IMESelectedConvertedTextBackground,
#[css(skip)]
IMESelectedConvertedTextForeground,
#[css(skip)]
IMESelectedConvertedTextUnderline,
#[css(skip)]
SpellCheckerUnderline,
Activeborder,
Activecaption,
Appworkspace,
Background,
Buttonface,
Buttonhighlight,
Buttonshadow,
Buttontext,
Captiontext,
Graytext,
Highlight,
Highlighttext,
Inactiveborder,
Inactivecaption,
Inactivecaptiontext,
Infobackground,
Infotext,
Menu,
Menutext,
Scrollbar,
Threeddarkshadow,
Threedface,
Threedhighlight,
Threedlightshadow,
Threedshadow,
Window,
Windowframe,
Windowtext,
MozButtondefault,
MozField,
MozFieldtext,
MozDialog,
MozDialogtext,
/// Used to highlight valid regions to drop something onto.
MozDragtargetzone,
/// Used for selected but not focused cell backgrounds.
MozCellhighlight,
/// Used for selected but not focused cell text.
MozCellhighlighttext,
/// Used for selected but not focused html cell backgrounds.
MozHtmlCellhighlight,
/// Used for selected but not focused html cell text.
MozHtmlCellhighlighttext,
/// Used to button text background when hovered.
MozButtonhoverface,
/// Used to button text color when hovered.
MozButtonhovertext,
/// Used for menu item backgrounds when hovered.
MozMenuhover,
/// Used for menu item text when hovered.
MozMenuhovertext,
/// Used for menubar item text.
MozMenubartext,
/// Used for menubar item text when hovered.
MozMenubarhovertext,

/// On platforms where these colors are the same as -moz-field, use
/// -moz-fieldtext as foreground color
MozEventreerow,
MozOddtreerow,

/// Used for button text when pressed.
MozGtkButtonactivetext,

/// Used for button text when pressed.
MozMacButtonactivetext,
/// Background color of chrome toolbars in active windows.
MozMacChromeActive,
/// Background color of chrome toolbars in inactive windows.
MozMacChromeInactive,
/// Foreground color of default buttons.
MozMacDefaultbuttontext,
/// Ring color around text fields and lists.
MozMacFocusring,
/// Color used when mouse is over a menu item.
MozMacMenuselect,
/// Color used to do shadows on menu items.
MozMacMenushadow,
/// Color used to display text for disabled menu items.
MozMacMenutextdisable,
/// Color used to display text while mouse is over a menu item.
MozMacMenutextselect,
/// Text color of disabled text on toolbars.
MozMacDisabledtoolbartext,
/// Inactive light hightlight
MozMacSecondaryhighlight,

/// Font smoothing background colors needed by the Mac OS X theme, based on
/// -moz-appearance names.
MozMacVibrancyLight,
MozMacVibrancyDark,
MozMacVibrantTitlebarLight,
MozMacVibrantTitlebarDark,
MozMacMenupopup,
MozMacMenuitem,
MozMacActiveMenuitem,
MozMacSourceList,
MozMacSourceListSelection,
MozMacActiveSourceListSelection,
MozMacTooltip,

/// Accent color for title bar.
MozWinAccentcolor,
/// Color from drawing text over the accent color.
MozWinAccentcolortext,
/// Media rebar text.
MozWinMediatext,
/// Communications rebar text.
MozWinCommunicationstext,

/// Hyperlink color extracted from the system, not affected by the
/// browser.anchor_color user pref.
///
/// There is no OS-specified safe background color for this text, but it is
/// used regularly within Windows and the Gnome DE on Dialog and Window
/// colors.
MozNativehyperlinktext,

/// Combobox widgets
MozComboboxtext,
MozCombobox,

MozGtkInfoBarText,

#[css(skip)]
End, // Just for array-indexing purposes.
}

#[cfg(feature = "gecko")]
impl SystemColor {
#[inline]
fn compute(&self, cx: &Context) -> ComputedColor {
use crate::gecko_bindings::bindings;
unsafe {
convert_nscolor_to_computedcolor(bindings::Gecko_GetLookAndFeelSystemColor(
*self as i32,
cx.device().document(),
))
}
}
}


#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
mod gecko { mod gecko {
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss, ToShmem)] #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss, ToShmem)]
Expand Down Expand Up @@ -340,32 +546,29 @@ impl Color {
/// If `context` is `None`, and the specified color requires data from /// If `context` is `None`, and the specified color requires data from
/// the context to resolve, then `None` is returned. /// the context to resolve, then `None` is returned.
pub fn to_computed_color(&self, _context: Option<&Context>) -> Option<ComputedColor> { pub fn to_computed_color(&self, _context: Option<&Context>) -> Option<ComputedColor> {
match *self { Some(match *self {
Color::CurrentColor => Some(ComputedColor::currentcolor()), Color::CurrentColor => ComputedColor::currentcolor(),
Color::Numeric { ref parsed, .. } => Some(ComputedColor::rgba(*parsed)), Color::Numeric { ref parsed, .. } => ComputedColor::rgba(*parsed),
Color::Complex(ref complex) => Some(*complex), Color::Complex(ref complex) => *complex,
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
Color::System(system) => _context Color::System(system) => system.compute(_context?),
.map(|context| convert_nscolor_to_computedcolor(system.to_computed_value(context))),
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
Color::Special(special) => { Color::Special(special) => {
use self::gecko::SpecialColorKeyword as Keyword; use self::gecko::SpecialColorKeyword as Keyword;
_context.map(|context| { let prefs = _context?.device().pref_sheet_prefs();
let prefs = context.device().pref_sheet_prefs(); convert_nscolor_to_computedcolor(match special {
convert_nscolor_to_computedcolor(match special { Keyword::MozDefaultColor => prefs.mDefaultColor,
Keyword::MozDefaultColor => prefs.mDefaultColor, Keyword::MozDefaultBackgroundColor => prefs.mDefaultBackgroundColor,
Keyword::MozDefaultBackgroundColor => prefs.mDefaultBackgroundColor, Keyword::MozHyperlinktext => prefs.mLinkColor,
Keyword::MozHyperlinktext => prefs.mLinkColor, Keyword::MozActivehyperlinktext => prefs.mActiveLinkColor,
Keyword::MozActivehyperlinktext => prefs.mActiveLinkColor, Keyword::MozVisitedhyperlinktext => prefs.mVisitedLinkColor,
Keyword::MozVisitedhyperlinktext => prefs.mVisitedLinkColor,
})
}) })
}, },
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
Color::InheritFromBodyQuirk => { Color::InheritFromBodyQuirk => {
_context.map(|context| ComputedColor::rgba(context.device().body_text_color())) ComputedColor::rgba(_context?.device().body_text_color())
}, },
} })
} }
} }


Expand Down

0 comments on commit 729bf19

Please sign in to comment.