Fix #3818: the chosen brightness holds when the system theme differs

The theme's colors went into egui's style for the current system theme
only. When the system's light or dark setting differed from it or
changed while the app ran, egui switched to its other style, which held
egui's defaults: tool tips became a white box with gray text, or with
the theme's light text. Applying a brightness now sets egui's theme to
match, starting from the current style so settings such as the tool tip
delay carry over.
This commit is contained in:
dotCooCoo
2026-11-01 13:30:34 -08:00
parent 639c9d6ce9
commit a055ebcbc7
+60
View File
@@ -587,6 +587,15 @@ pub fn apply(ctx: &egui::Context, b: Brightness) {
pub fn apply_with(ctx: &egui::Context, b: Brightness, accent: Accent, scheme: Scheme) {
let t = Tokens::for_scheme(scheme, b, accent);
ctx.data_mut(|d| d.insert_temp(egui::Id::NULL, t));
// egui keeps a style for each system theme and by default follows the system's setting. The
// chosen brightness sets egui's theme, so these colors stay in force when the system's setting
// differs or changes. A change of theme starts from the current style, which keeps settings
// such as the tool tip delay.
let theme = if t.dark { egui::Theme::Dark } else { egui::Theme::Light };
if ctx.theme() != theme {
ctx.set_style_of(theme, ctx.global_style());
}
ctx.set_theme(theme);
let mut v = if t.dark { Visuals::dark() } else { Visuals::light() };
v.panel_fill = t.panel;
v.window_fill = t.panel;
@@ -669,4 +678,55 @@ mod tests {
assert_eq!(Scheme::parse(Scheme::Classic.id()), Some(Scheme::Classic));
}
}
/// #3818: the brightness chosen in Preferences stays in force when the system's light or dark
/// setting differs from it or changes while the app runs. Tool tips keep the theme's panel fill
/// and text color instead of egui's own white box and gray text.
#[test]
fn the_theme_holds_whatever_the_system_theme() {
let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(400.0, 400.0));
for b in Brightness::ALL {
for scheme in Scheme::ALL {
for (first, then) in [(egui::Theme::Dark, egui::Theme::Light), (egui::Theme::Light, egui::Theme::Dark)] {
let t = Tokens::for_scheme(scheme, b, Accent::default());
let ctx = egui::Context::default();
let mut time = 0.0;
let mut tip = None;
for i in 0..5 {
time += 0.5;
let system_theme = Some(if i == 0 { first } else { then });
let events = if i == 1 { vec![egui::Event::PointerMoved(egui::pos2(30.0, 15.0))] } else { vec![] };
let input = egui::RawInput { time: Some(time), screen_rect: Some(screen), events, system_theme, ..Default::default() };
let mut out = ctx.run_ui(input, |ui| {
if i == 0 {
apply_with(ui.ctx(), b, Accent::default(), scheme);
ui.ctx().global_style_mut(|s| s.interaction.tooltip_delay = 0.0);
}
ui.button("Hover me").on_hover_text("Tip text");
});
out.textures_delta.clear();
tip = out.shapes.iter().find_map(|c| match &c.shape {
egui::Shape::Text(s) if s.galley.text() == "Tip text" => Some(s.fallback_color),
_ => None,
});
}
let v = ctx.global_style().visuals.clone();
assert_eq!((v.window_fill, v.override_text_color), (t.panel, Some(t.text)), "{scheme:?} {b:?}, system {first:?} then {then:?}");
assert_eq!(tip, Some(t.text), "{scheme:?} {b:?}, system {first:?} then {then:?}: the tool tip's text");
}
}
}
}
/// Changing brightness keeps the interface settings made after the theme was applied, such as
/// General › Show Tool Tips' delay.
#[test]
fn changing_brightness_keeps_other_interface_settings() {
let ctx = egui::Context::default();
apply(&ctx, Brightness::Dark);
ctx.global_style_mut(|s| s.interaction.tooltip_delay = f32::INFINITY);
apply(&ctx, Brightness::Light);
assert_eq!(ctx.global_style().interaction.tooltip_delay, f32::INFINITY);
assert_eq!(ctx.global_style().visuals.window_fill, Tokens::for_brightness(Brightness::Light).panel);
}
}