linux: Fix sync_system_appearance on Linux. (#796)

Close #104
This commit is contained in:
Jason Lee 2025-04-16 14:55:01 +08:00 committed by GitHub
parent 3fb0c41fad
commit e2463bbdcf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 24 additions and 17 deletions

View file

@ -4,10 +4,8 @@ use gpui_component::{
button::{Button, ButtonVariants as _},
dock::{DockArea, DockAreaState, DockEvent, DockItem, DockPlacement},
popup_menu::PopupMenuExt,
IconName, Root, Sizable,
IconName, Root, Sizable, Theme,
};
#[cfg(not(target_os = "linux"))]
use gpui_component::{Theme, TitleBar};
use serde::Deserialize;
use std::{sync::Arc, time::Duration};
@ -61,9 +59,6 @@ struct DockAreaTab {
impl StoryWorkspace {
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
// There will crash on Linux.
// https://github.com/longbridge/gpui-component/issues/104
#[cfg(not(target_os = "linux"))]
window
.observe_window_appearance(|window, cx| {
Theme::sync_system_appearance(Some(window), cx);
@ -395,7 +390,7 @@ impl StoryWorkspace {
let options = WindowOptions {
window_bounds: Some(WindowBounds::Windowed(window_bounds)),
#[cfg(not(target_os = "linux"))]
titlebar: Some(TitleBar::title_bar_options()),
titlebar: Some(gpui_component::TitleBar::title_bar_options()),
window_min_size: Some(gpui::Size {
width: px(640.),
height: px(480.),

View file

@ -3,6 +3,7 @@ use std::ops::{Deref, DerefMut};
use gpui::{
hsla, point, px, App, BoxShadow, Global, Hsla, Pixels, SharedString, Window, WindowAppearance,
};
use serde::{Deserialize, Serialize};
use crate::{scroll::ScrollbarShow, Colorize as _};
@ -563,14 +564,14 @@ impl Theme {
/// Sync the theme with the system appearance
pub fn sync_system_appearance(window: Option<&mut Window>, cx: &mut App) {
match cx.window_appearance() {
WindowAppearance::Dark | WindowAppearance::VibrantDark => {
Self::change(ThemeMode::Dark, window, cx)
}
WindowAppearance::Light | WindowAppearance::VibrantLight => {
Self::change(ThemeMode::Light, window, cx)
}
}
// Better use window.appearance() for avoid error on Linux.
// https://github.com/longbridge/gpui-component/issues/104
let appearance = window
.as_ref()
.map(|window| window.appearance())
.unwrap_or_else(|| cx.window_appearance());
Self::change(appearance, window, cx);
}
/// Sync the Scrollbar showing behavior with the system
@ -582,7 +583,8 @@ impl Theme {
}
}
pub fn change(mode: ThemeMode, window: Option<&mut Window>, cx: &mut App) {
pub fn change(mode: impl Into<ThemeMode>, window: Option<&mut Window>, cx: &mut App) {
let mode = mode.into();
let colors = match mode {
ThemeMode::Light => ThemeColor::light(),
ThemeMode::Dark => ThemeColor::dark(),
@ -628,7 +630,8 @@ impl From<ThemeColor> for Theme {
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, PartialOrd, Eq)]
#[derive(Debug, Clone, Copy, Default, PartialEq, PartialOrd, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ThemeMode {
Light,
#[default]
@ -641,3 +644,12 @@ impl ThemeMode {
matches!(self, Self::Dark)
}
}
impl From<WindowAppearance> for ThemeMode {
fn from(appearance: WindowAppearance) -> Self {
match appearance {
WindowAppearance::Dark | WindowAppearance::VibrantDark => Self::Dark,
WindowAppearance::Light | WindowAppearance::VibrantLight => Self::Light,
}
}
}