feat: add native material backgrounds

This commit is contained in:
2026-11-09 09:52:29 +07:00
parent 8c438ed8a6
commit 7784e8d570
14 changed files with 279 additions and 36 deletions
+1
View File
@@ -93,6 +93,7 @@ impl KdeScheme {
titlebar_height: Some(px(44.)),
root_font_size: Some(self.root_font_size.unwrap_or(px(13.33))),
accessibility,
window_background: None,
source: SourceKind::Kde,
}
}
+19 -3
View File
@@ -38,6 +38,12 @@ fn home_dir() -> Option<PathBuf> {
std::env::var_os("HOME").map(PathBuf::from)
}
/// Whether the session runs on Wayland, where compositors state blur protocols.
fn wayland_session() -> bool {
std::env::var_os("WAYLAND_DISPLAY").is_some()
|| std::env::var("XDG_SESSION_TYPE").is_ok_and(|session| session == "wayland")
}
fn detect(home: &Path, portal_reachable: bool, gsettings_reachable: bool) -> Backend {
let omarchy_marker = home
.join(".local/state/omarchy/current/theme.name")
@@ -164,6 +170,7 @@ impl LinuxSource {
.unwrap_or(gpui::px(14.67)),
),
accessibility,
window_background: None,
source: SourceKind::Gnome,
}
}
@@ -203,15 +210,24 @@ impl ThemeSource for LinuxSource {
match self.backend {
Backend::Omarchy => omarchy::io::read_current()
.map(|theme| theme.into_system(accessibility))
.map(|theme| {
let mut system = theme.into_system(accessibility);
// Hyprland blurs transparent surfaces on its own.
system.window_background = Some(gpui::WindowBackgroundAppearance::Blurred);
system
})
.unwrap_or_else(|| SystemTheme::fallback(variant)),
Backend::Kde => kde::io::read_current()
.map(|scheme| {
scheme.into_system(
let mut system = scheme.into_system(
accessibility,
portal_appearance.and_then(|appearance| appearance.accent),
portal_appearance.map(|appearance| appearance.variant(variant)),
)
);
// KWin states the blur protocols; X11 compositors do not.
system.window_background =
wayland_session().then_some(gpui::WindowBackgroundAppearance::Blurred);
system
})
.unwrap_or_else(|| SystemTheme::fallback(variant)),
Backend::Portal => self.portal_snapshot(variant, portal_appearance, accessibility),
+2
View File
@@ -121,6 +121,8 @@ impl ThemeSource for MacosSource {
variant,
accent: Self::color_to_hsla(&NSColor::controlAccentColor()),
palette,
// macOS blurs what is behind the window natively.
window_background: Some(gpui::WindowBackgroundAppearance::Blurred),
control_radius: Some(gpui::px(CONTROL_RADIUS_PTS)),
overlay_radius: None,
sm_radius: None,
+1
View File
@@ -72,6 +72,7 @@ impl OmarchyTheme {
titlebar_height: None,
root_font_size: None,
accessibility,
window_background: None,
source: SourceKind::Omarchy,
}
}
+21 -2
View File
@@ -31,12 +31,12 @@ const TITLEBAR_HEIGHT_PX: f32 = 32.0;
/// WinUI 11's default body text size, in pixels at 100% scaling.
const ROOT_FONT_SIZE_PX: f32 = 14.0;
/// The `Personalize` registry values, read once at startup as the fallback
/// when the WinRT surface is unavailable.
/// The `Personalize` registry values and the OS build number.
#[derive(Clone, Copy, Debug, Default)]
struct RegistrySettings {
apps_use_light_theme: Option<bool>,
enable_transparency: Option<bool>,
current_build: Option<u32>,
}
impl RegistrySettings {
@@ -45,6 +45,9 @@ impl RegistrySettings {
windows_registry::CURRENT_USER
.open(r"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize")
};
let current_version = || {
windows_registry::LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Windows NT\CurrentVersion")
};
Self {
apps_use_light_theme: personalize()
.and_then(|key| key.get_u32("AppsUseLightTheme"))
@@ -54,6 +57,10 @@ impl RegistrySettings {
.and_then(|key| key.get_u32("EnableTransparency"))
.ok()
.map(|value| value != 0),
current_build: current_version()
.and_then(|key| key.get_string("CurrentBuildNumber"))
.ok()
.and_then(|build| build.parse::<u32>().ok()),
}
}
}
@@ -130,6 +137,17 @@ impl WindowsSource {
.unwrap_or(false),
}
}
/// The native backdrop: Mica on Windows 11, acrylic on Windows 10 1809+.
fn window_material(&self) -> Option<gpui::WindowBackgroundAppearance> {
match self.registry.current_build {
// 22621: Windows 11 22H2, where the DWM backdrop types exist.
Some(build) if build >= 22621 => Some(gpui::WindowBackgroundAppearance::MicaBackdrop),
// 17763: Windows 10 1809, where acrylic blur-behind exists.
Some(build) if build >= 17763 => Some(gpui::WindowBackgroundAppearance::Blurred),
_ => None,
}
}
}
impl ThemeSource for WindowsSource {
@@ -180,6 +198,7 @@ impl ThemeSource for WindowsSource {
titlebar_height: Some(gpui::px(TITLEBAR_HEIGHT_PX)),
root_font_size: Some(gpui::px(ROOT_FONT_SIZE_PX * text_scale as f32)),
accessibility: self.accessibility(),
window_background: self.window_material(),
source: SourceKind::Windows,
}
}