Reland "Remove cx from ThemeSettings" (#39720)
- **Reapply "Remove cx from ThemeSettings (#38836)" (#39691)** - **Fix theme loading races** Closes #ISSUE Release Notes: - N/A
This commit is contained in:
+23
-82
@@ -12,7 +12,6 @@ use crashes::InitCrashHandler;
|
||||
use db::kvp::{GLOBAL_KEY_VALUE_STORE, KEY_VALUE_STORE};
|
||||
use editor::Editor;
|
||||
use extension::ExtensionHostProxy;
|
||||
use extension_host::ExtensionStore;
|
||||
use fs::{Fs, RealFs};
|
||||
use futures::{StreamExt, channel::oneshot, future};
|
||||
use git::GitHostingProviderRegistry;
|
||||
@@ -40,10 +39,7 @@ use std::{
|
||||
process,
|
||||
sync::Arc,
|
||||
};
|
||||
use theme::{
|
||||
ActiveTheme, IconThemeNotFoundError, SystemAppearance, ThemeNotFoundError, ThemeRegistry,
|
||||
ThemeSettings,
|
||||
};
|
||||
use theme::{ActiveTheme, GlobalTheme, ThemeRegistry};
|
||||
use util::{ResultExt, TryFutureExt, maybe};
|
||||
use uuid::Uuid;
|
||||
use workspace::{
|
||||
@@ -57,7 +53,7 @@ use zed::{
|
||||
initialize_workspace, open_paths_with_positions,
|
||||
};
|
||||
|
||||
use crate::zed::OpenRequestKind;
|
||||
use crate::zed::{OpenRequestKind, eager_load_active_theme_and_icon_theme};
|
||||
|
||||
#[cfg(feature = "mimalloc")]
|
||||
#[global_allocator]
|
||||
@@ -543,11 +539,18 @@ pub fn main() {
|
||||
system_id.as_ref().map(|id| id.to_string()),
|
||||
cx,
|
||||
);
|
||||
|
||||
SystemAppearance::init(cx);
|
||||
theme::init(theme::LoadThemes::All(Box::new(Assets)), cx);
|
||||
theme_extension::init(
|
||||
extension_host::init(
|
||||
extension_host_proxy.clone(),
|
||||
app_state.fs.clone(),
|
||||
app_state.client.clone(),
|
||||
app_state.node_runtime.clone(),
|
||||
cx,
|
||||
);
|
||||
|
||||
theme::init(theme::LoadThemes::All(Box::new(Assets)), cx);
|
||||
eager_load_active_theme_and_icon_theme(fs.clone(), cx);
|
||||
theme_extension::init(
|
||||
extension_host_proxy,
|
||||
ThemeRegistry::global(cx),
|
||||
cx.background_executor().clone(),
|
||||
);
|
||||
@@ -581,18 +584,10 @@ pub fn main() {
|
||||
);
|
||||
assistant_tools::init(app_state.client.http_client(), cx);
|
||||
repl::init(app_state.fs.clone(), cx);
|
||||
extension_host::init(
|
||||
extension_host_proxy,
|
||||
app_state.fs.clone(),
|
||||
app_state.client.clone(),
|
||||
app_state.node_runtime.clone(),
|
||||
cx,
|
||||
);
|
||||
recent_projects::init(cx);
|
||||
|
||||
load_embedded_fonts(cx);
|
||||
|
||||
app_state.languages.set_theme(cx.theme().clone());
|
||||
editor::init(cx);
|
||||
image_viewer::init(cx);
|
||||
repl::notebook::init(cx);
|
||||
@@ -638,8 +633,6 @@ pub fn main() {
|
||||
json_schema_store::init(cx);
|
||||
|
||||
cx.observe_global::<SettingsStore>({
|
||||
let fs = fs.clone();
|
||||
let languages = app_state.languages.clone();
|
||||
let http = app_state.client.http_client();
|
||||
let client = app_state.client.clone();
|
||||
move |cx| {
|
||||
@@ -652,9 +645,6 @@ pub fn main() {
|
||||
.ok();
|
||||
}
|
||||
|
||||
eager_load_active_theme_and_icon_theme(fs.clone(), cx);
|
||||
|
||||
languages.set_theme(cx.theme().clone());
|
||||
let new_host = &client::ClientSettings::get_global(cx).server_url;
|
||||
if &http.base_url() != new_host {
|
||||
http.set_base_url(new_host);
|
||||
@@ -665,6 +655,14 @@ pub fn main() {
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
app_state.languages.set_theme(cx.theme().clone());
|
||||
cx.observe_global::<GlobalTheme>({
|
||||
let languages = app_state.languages.clone();
|
||||
move |cx| {
|
||||
languages.set_theme(cx.theme().clone());
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
telemetry::event!(
|
||||
"Settings Changed",
|
||||
setting = "theme",
|
||||
@@ -1354,63 +1352,6 @@ fn load_embedded_fonts(cx: &App) {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Eagerly loads the active theme and icon theme based on the selections in the
|
||||
/// theme settings.
|
||||
///
|
||||
/// This fast path exists to load these themes as soon as possible so the user
|
||||
/// doesn't see the default themes while waiting on extensions to load.
|
||||
fn eager_load_active_theme_and_icon_theme(fs: Arc<dyn Fs>, cx: &App) {
|
||||
let extension_store = ExtensionStore::global(cx);
|
||||
let theme_registry = ThemeRegistry::global(cx);
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let appearance = SystemAppearance::global(cx).0;
|
||||
|
||||
if let Some(theme_selection) = theme_settings.theme_selection.as_ref() {
|
||||
let theme_name = theme_selection.theme(appearance);
|
||||
if matches!(theme_registry.get(theme_name), Err(ThemeNotFoundError(_)))
|
||||
&& let Some(theme_path) = extension_store.read(cx).path_to_extension_theme(theme_name)
|
||||
{
|
||||
cx.spawn({
|
||||
let theme_registry = theme_registry.clone();
|
||||
let fs = fs.clone();
|
||||
async move |cx| {
|
||||
theme_registry.load_user_theme(&theme_path, fs).await?;
|
||||
|
||||
cx.update(|cx| {
|
||||
ThemeSettings::reload_current_theme(cx);
|
||||
})
|
||||
}
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(icon_theme_selection) = theme_settings.icon_theme_selection.as_ref() {
|
||||
let icon_theme_name = icon_theme_selection.icon_theme(appearance);
|
||||
if matches!(
|
||||
theme_registry.get_icon_theme(icon_theme_name),
|
||||
Err(IconThemeNotFoundError(_))
|
||||
) && let Some((icon_theme_path, icons_root_path)) = extension_store
|
||||
.read(cx)
|
||||
.path_to_extension_icon_theme(icon_theme_name)
|
||||
{
|
||||
cx.spawn({
|
||||
let fs = fs.clone();
|
||||
async move |cx| {
|
||||
theme_registry
|
||||
.load_icon_theme(&icon_theme_path, &icons_root_path, fs)
|
||||
.await?;
|
||||
|
||||
cx.update(|cx| {
|
||||
ThemeSettings::reload_current_icon_theme(cx);
|
||||
})
|
||||
}
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Spawns a background task to load the user themes from the themes directory.
|
||||
fn load_user_themes_in_background(fs: Arc<dyn fs::Fs>, cx: &mut App) {
|
||||
cx.spawn({
|
||||
@@ -1435,7 +1376,7 @@ fn load_user_themes_in_background(fs: Arc<dyn fs::Fs>, cx: &mut App) {
|
||||
}
|
||||
}
|
||||
theme_registry.load_user_themes(themes_dir, fs).await?;
|
||||
cx.update(ThemeSettings::reload_current_theme)?;
|
||||
cx.update(GlobalTheme::reload_theme)?;
|
||||
}
|
||||
anyhow::Ok(())
|
||||
}
|
||||
@@ -1461,7 +1402,7 @@ fn watch_themes(fs: Arc<dyn fs::Fs>, cx: &mut App) {
|
||||
.await
|
||||
.log_err()
|
||||
{
|
||||
cx.update(ThemeSettings::reload_current_theme).log_err();
|
||||
cx.update(GlobalTheme::reload_theme).log_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+61
-4
@@ -20,7 +20,9 @@ use collections::VecDeque;
|
||||
use debugger_ui::debugger_panel::DebugPanel;
|
||||
use editor::ProposedChangesEditorToolbar;
|
||||
use editor::{Editor, MultiBuffer};
|
||||
use extension_host::ExtensionStore;
|
||||
use feature_flags::{FeatureFlagAppExt, PanicFeatureFlag};
|
||||
use fs::Fs;
|
||||
use futures::future::Either;
|
||||
use futures::{StreamExt, channel::mpsc, select_biased};
|
||||
use git_ui::git_panel::GitPanel;
|
||||
@@ -68,7 +70,10 @@ use std::{
|
||||
sync::atomic::{self, AtomicBool},
|
||||
};
|
||||
use terminal_view::terminal_panel::{self, TerminalPanel};
|
||||
use theme::{ActiveTheme, ThemeSettings};
|
||||
use theme::{
|
||||
ActiveTheme, GlobalTheme, IconThemeNotFoundError, SystemAppearance, ThemeNotFoundError,
|
||||
ThemeRegistry, ThemeSettings,
|
||||
};
|
||||
use ui::{PopoverMenuHandle, prelude::*};
|
||||
use util::markdown::MarkdownString;
|
||||
use util::rel_path::RelPath;
|
||||
@@ -2012,6 +2017,55 @@ fn capture_recent_audio(workspace: &mut Workspace, _: &mut Window, cx: &mut Cont
|
||||
);
|
||||
}
|
||||
|
||||
/// Eagerly loads the active theme and icon theme based on the selections in the
|
||||
/// theme settings.
|
||||
///
|
||||
/// This fast path exists to load these themes as soon as possible so the user
|
||||
/// doesn't see the default themes while waiting on extensions to load.
|
||||
pub(crate) fn eager_load_active_theme_and_icon_theme(fs: Arc<dyn Fs>, cx: &mut App) {
|
||||
let extension_store = ExtensionStore::global(cx);
|
||||
let theme_registry = ThemeRegistry::global(cx);
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let appearance = SystemAppearance::global(cx).0;
|
||||
|
||||
let theme_name = theme_settings.theme.name(appearance);
|
||||
if matches!(
|
||||
theme_registry.get(&theme_name.0),
|
||||
Err(ThemeNotFoundError(_))
|
||||
) && let Some(theme_path) = extension_store
|
||||
.read(cx)
|
||||
.path_to_extension_theme(&theme_name.0)
|
||||
{
|
||||
if cx
|
||||
.background_executor()
|
||||
.block(theme_registry.load_user_theme(&theme_path, fs.clone()))
|
||||
.log_err()
|
||||
.is_some()
|
||||
{
|
||||
GlobalTheme::reload_theme(cx);
|
||||
}
|
||||
}
|
||||
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
let icon_theme_name = theme_settings.icon_theme.name(appearance);
|
||||
if matches!(
|
||||
theme_registry.get_icon_theme(&icon_theme_name.0),
|
||||
Err(IconThemeNotFoundError(_))
|
||||
) && let Some((icon_theme_path, icons_root_path)) = extension_store
|
||||
.read(cx)
|
||||
.path_to_extension_icon_theme(&icon_theme_name.0)
|
||||
{
|
||||
if cx
|
||||
.background_executor()
|
||||
.block(theme_registry.load_icon_theme(&icon_theme_path, &icons_root_path, fs))
|
||||
.log_err()
|
||||
.is_some()
|
||||
{
|
||||
GlobalTheme::reload_icon_theme(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -2031,8 +2085,11 @@ mod tests {
|
||||
path::{Path, PathBuf},
|
||||
time::Duration,
|
||||
};
|
||||
use theme::{ThemeRegistry, ThemeSettings};
|
||||
use util::{path, rel_path::rel_path};
|
||||
use theme::ThemeRegistry;
|
||||
use util::{
|
||||
path,
|
||||
rel_path::{RelPath, rel_path},
|
||||
};
|
||||
use workspace::{
|
||||
NewFile, OpenOptions, OpenVisible, SERIALIZATION_THROTTLE_TIME, SaveIntent, SplitDirection,
|
||||
WorkspaceHandle,
|
||||
@@ -4632,7 +4689,7 @@ mod tests {
|
||||
for theme_name in themes.list().into_iter().map(|meta| meta.name) {
|
||||
let theme = themes.get(&theme_name).unwrap();
|
||||
assert_eq!(theme.name, theme_name);
|
||||
if theme.name == ThemeSettings::get(None, cx).active_theme.name {
|
||||
if theme.name.as_ref() == "One Dark" {
|
||||
has_default_theme = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user