mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-16 17:07:14 +03:00
Make tests less noisy (#12463)
When running the tests for linux, I found a lot of benign errors getting logged. This PR cuts down some of the noise from unnecessary workspace serialization and SVG renders Release Notes: - N/A
This commit is contained in:
parent
bdf627ce07
commit
5a149b970c
@ -16,9 +16,9 @@ use rust_embed::RustEmbed;
|
|||||||
pub struct Assets;
|
pub struct Assets;
|
||||||
|
|
||||||
impl AssetSource for Assets {
|
impl AssetSource for Assets {
|
||||||
fn load(&self, path: &str) -> Result<std::borrow::Cow<'static, [u8]>> {
|
fn load(&self, path: &str) -> Result<Option<std::borrow::Cow<'static, [u8]>>> {
|
||||||
Self::get(path)
|
Self::get(path)
|
||||||
.map(|f| f.data)
|
.map(|f| Some(f.data))
|
||||||
.ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
|
.ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,10 @@ impl Assets {
|
|||||||
let mut embedded_fonts = Vec::new();
|
let mut embedded_fonts = Vec::new();
|
||||||
for font_path in font_paths {
|
for font_path in font_paths {
|
||||||
if font_path.ends_with(".ttf") {
|
if font_path.ends_with(".ttf") {
|
||||||
let font_bytes = cx.asset_source().load(&font_path)?;
|
let font_bytes = cx
|
||||||
|
.asset_source()
|
||||||
|
.load(&font_path)?
|
||||||
|
.expect("Assets should never return None");
|
||||||
embedded_fonts.push(font_bytes);
|
embedded_fonts.push(font_bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,12 @@ impl SoundRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let path = format!("sounds/{}.wav", name);
|
let path = format!("sounds/{}.wav", name);
|
||||||
let bytes = self.assets.load(&path)?.into_owned();
|
let bytes = self
|
||||||
|
.assets
|
||||||
|
.load(&path)?
|
||||||
|
.map(|asset| Ok(asset))
|
||||||
|
.unwrap_or_else(|| Err(anyhow::anyhow!("No such asset available")))?
|
||||||
|
.into_owned();
|
||||||
let cursor = Cursor::new(bytes);
|
let cursor = Cursor::new(bytes);
|
||||||
let source = Decoder::new(cursor)?.convert_samples::<f32>().buffered();
|
let source = Decoder::new(cursor)?.convert_samples::<f32>().buffered();
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ use std::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use text::Point;
|
use text::Point;
|
||||||
use workspace::{Workspace, WorkspaceId};
|
use workspace::Workspace;
|
||||||
|
|
||||||
#[gpui::test(iterations = 10)]
|
#[gpui::test(iterations = 10)]
|
||||||
async fn test_host_disconnect(
|
async fn test_host_disconnect(
|
||||||
@ -85,14 +85,8 @@ async fn test_host_disconnect(
|
|||||||
|
|
||||||
assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared()));
|
assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared()));
|
||||||
|
|
||||||
let workspace_b = cx_b.add_window(|cx| {
|
let workspace_b = cx_b
|
||||||
Workspace::new(
|
.add_window(|cx| Workspace::new(None, project_b.clone(), client_b.app_state.clone(), cx));
|
||||||
WorkspaceId::default(),
|
|
||||||
project_b.clone(),
|
|
||||||
client_b.app_state.clone(),
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
let cx_b = &mut VisualTestContext::from_window(*workspace_b, cx_b);
|
let cx_b = &mut VisualTestContext::from_window(*workspace_b, cx_b);
|
||||||
let workspace_b_view = workspace_b.root_view(cx_b).unwrap();
|
let workspace_b_view = workspace_b.root_view(cx_b).unwrap();
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ use std::{
|
|||||||
Arc,
|
Arc,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use workspace::{Workspace, WorkspaceId, WorkspaceStore};
|
use workspace::{Workspace, WorkspaceStore};
|
||||||
|
|
||||||
pub struct TestServer {
|
pub struct TestServer {
|
||||||
pub app_state: Arc<AppState>,
|
pub app_state: Arc<AppState>,
|
||||||
@ -906,12 +906,7 @@ impl TestClient {
|
|||||||
) -> (View<Workspace>, &'a mut VisualTestContext) {
|
) -> (View<Workspace>, &'a mut VisualTestContext) {
|
||||||
cx.add_window_view(|cx| {
|
cx.add_window_view(|cx| {
|
||||||
cx.activate_window();
|
cx.activate_window();
|
||||||
Workspace::new(
|
Workspace::new(None, project.clone(), self.app_state.clone(), cx)
|
||||||
WorkspaceId::default(),
|
|
||||||
project.clone(),
|
|
||||||
self.app_state.clone(),
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -922,12 +917,7 @@ impl TestClient {
|
|||||||
let project = self.build_test_project(cx).await;
|
let project = self.build_test_project(cx).await;
|
||||||
cx.add_window_view(|cx| {
|
cx.add_window_view(|cx| {
|
||||||
cx.activate_window();
|
cx.activate_window();
|
||||||
Workspace::new(
|
Workspace::new(None, project.clone(), self.app_state.clone(), cx)
|
||||||
WorkspaceId::default(),
|
|
||||||
project.clone(),
|
|
||||||
self.app_state.clone(),
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +400,11 @@ impl Item for ChannelView {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_on_split(&self, _: WorkspaceId, cx: &mut ViewContext<Self>) -> Option<View<Self>> {
|
fn clone_on_split(
|
||||||
|
&self,
|
||||||
|
_: Option<WorkspaceId>,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> Option<View<Self>> {
|
||||||
Some(cx.new_view(|cx| {
|
Some(cx.new_view(|cx| {
|
||||||
Self::new(
|
Self::new(
|
||||||
self.project.clone(),
|
self.project.clone(),
|
||||||
|
@ -704,7 +704,7 @@ impl Item for ProjectDiagnosticsEditor {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: workspace::WorkspaceId,
|
_workspace_id: Option<workspace::WorkspaceId>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>>
|
) -> Option<View<Self>>
|
||||||
where
|
where
|
||||||
|
@ -484,7 +484,7 @@ pub struct Editor {
|
|||||||
current_line_highlight: CurrentLineHighlight,
|
current_line_highlight: CurrentLineHighlight,
|
||||||
collapse_matches: bool,
|
collapse_matches: bool,
|
||||||
autoindent_mode: Option<AutoindentMode>,
|
autoindent_mode: Option<AutoindentMode>,
|
||||||
workspace: Option<(WeakView<Workspace>, WorkspaceId)>,
|
workspace: Option<(WeakView<Workspace>, Option<WorkspaceId>)>,
|
||||||
keymap_context_layers: BTreeMap<TypeId, KeyContext>,
|
keymap_context_layers: BTreeMap<TypeId, KeyContext>,
|
||||||
input_enabled: bool,
|
input_enabled: bool,
|
||||||
use_modal_editing: bool,
|
use_modal_editing: bool,
|
||||||
|
@ -657,7 +657,7 @@ impl Item for Editor {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: Option<WorkspaceId>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Editor>>
|
) -> Option<View<Editor>>
|
||||||
where
|
where
|
||||||
@ -846,9 +846,12 @@ impl Item for Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
|
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
|
||||||
let workspace_id = workspace.database_id();
|
|
||||||
let item_id = cx.view().item_id().as_u64() as ItemId;
|
|
||||||
self.workspace = Some((workspace.weak_handle(), workspace.database_id()));
|
self.workspace = Some((workspace.weak_handle(), workspace.database_id()));
|
||||||
|
let Some(workspace_id) = workspace.database_id() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_id = cx.view().item_id().as_u64() as ItemId;
|
||||||
|
|
||||||
fn serialize(
|
fn serialize(
|
||||||
buffer: Model<Buffer>,
|
buffer: Model<Buffer>,
|
||||||
@ -873,7 +876,7 @@ impl Item for Editor {
|
|||||||
serialize(buffer.clone(), workspace_id, item_id, cx);
|
serialize(buffer.clone(), workspace_id, item_id, cx);
|
||||||
|
|
||||||
cx.subscribe(&buffer, |this, buffer, event, cx| {
|
cx.subscribe(&buffer, |this, buffer, event, cx| {
|
||||||
if let Some((_, workspace_id)) = this.workspace.as_ref() {
|
if let Some((_, Some(workspace_id))) = this.workspace.as_ref() {
|
||||||
if let language::Event::FileHandleChanged = event {
|
if let language::Event::FileHandleChanged = event {
|
||||||
serialize(
|
serialize(
|
||||||
buffer,
|
buffer,
|
||||||
|
@ -389,7 +389,8 @@ impl Editor {
|
|||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
hide_hover(self, cx);
|
hide_hover(self, cx);
|
||||||
let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1);
|
let workspace_id = self.workspace.as_ref().and_then(|workspace| workspace.1);
|
||||||
|
|
||||||
self.scroll_manager.set_scroll_position(
|
self.scroll_manager.set_scroll_position(
|
||||||
scroll_position,
|
scroll_position,
|
||||||
&display_map,
|
&display_map,
|
||||||
@ -409,7 +410,7 @@ impl Editor {
|
|||||||
|
|
||||||
pub fn set_scroll_anchor(&mut self, scroll_anchor: ScrollAnchor, cx: &mut ViewContext<Self>) {
|
pub fn set_scroll_anchor(&mut self, scroll_anchor: ScrollAnchor, cx: &mut ViewContext<Self>) {
|
||||||
hide_hover(self, cx);
|
hide_hover(self, cx);
|
||||||
let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1);
|
let workspace_id = self.workspace.as_ref().and_then(|workspace| workspace.1);
|
||||||
let top_row = scroll_anchor
|
let top_row = scroll_anchor
|
||||||
.anchor
|
.anchor
|
||||||
.to_point(&self.buffer().read(cx).snapshot(cx))
|
.to_point(&self.buffer().read(cx).snapshot(cx))
|
||||||
@ -424,7 +425,7 @@ impl Editor {
|
|||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
hide_hover(self, cx);
|
hide_hover(self, cx);
|
||||||
let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1);
|
let workspace_id = self.workspace.as_ref().and_then(|workspace| workspace.1);
|
||||||
let snapshot = &self.buffer().read(cx).snapshot(cx);
|
let snapshot = &self.buffer().read(cx).snapshot(cx);
|
||||||
if !scroll_anchor.anchor.is_valid(snapshot) {
|
if !scroll_anchor.anchor.is_valid(snapshot) {
|
||||||
log::warn!("Invalid scroll anchor: {:?}", scroll_anchor);
|
log::warn!("Invalid scroll anchor: {:?}", scroll_anchor);
|
||||||
|
@ -992,7 +992,7 @@ impl Item for ExtensionsPage {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: Option<WorkspaceId>,
|
||||||
_: &mut ViewContext<Self>,
|
_: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>> {
|
) -> Option<View<Self>> {
|
||||||
None
|
None
|
||||||
|
@ -38,11 +38,10 @@ impl FileIcons {
|
|||||||
pub fn new(assets: impl AssetSource) -> Self {
|
pub fn new(assets: impl AssetSource) -> Self {
|
||||||
assets
|
assets
|
||||||
.load("icons/file_icons/file_types.json")
|
.load("icons/file_icons/file_types.json")
|
||||||
.and_then(|file| {
|
.ok()
|
||||||
serde_json::from_str::<FileIcons>(str::from_utf8(&file).unwrap())
|
.flatten()
|
||||||
.map_err(Into::into)
|
.and_then(|file| serde_json::from_str::<FileIcons>(str::from_utf8(&file).unwrap()).ok())
|
||||||
})
|
.unwrap_or_else(|| FileIcons {
|
||||||
.unwrap_or_else(|_| FileIcons {
|
|
||||||
stems: HashMap::default(),
|
stems: HashMap::default(),
|
||||||
suffixes: HashMap::default(),
|
suffixes: HashMap::default(),
|
||||||
types: HashMap::default(),
|
types: HashMap::default(),
|
||||||
|
@ -5,8 +5,11 @@ use gpui::*;
|
|||||||
struct Assets {}
|
struct Assets {}
|
||||||
|
|
||||||
impl AssetSource for Assets {
|
impl AssetSource for Assets {
|
||||||
fn load(&self, path: &str) -> Result<std::borrow::Cow<'static, [u8]>> {
|
fn load(&self, path: &str) -> Result<Option<std::borrow::Cow<'static, [u8]>>> {
|
||||||
std::fs::read(path).map(Into::into).map_err(Into::into)
|
std::fs::read(path)
|
||||||
|
.map(Into::into)
|
||||||
|
.map_err(Into::into)
|
||||||
|
.map(|result| Some(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{size, DevicePixels, Result, SharedString, Size};
|
use crate::{size, DevicePixels, Result, SharedString, Size};
|
||||||
use anyhow::anyhow;
|
|
||||||
use image::{Bgra, ImageBuffer};
|
use image::{Bgra, ImageBuffer};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
@ -11,18 +11,15 @@ use std::{
|
|||||||
/// A source of assets for this app to use.
|
/// A source of assets for this app to use.
|
||||||
pub trait AssetSource: 'static + Send + Sync {
|
pub trait AssetSource: 'static + Send + Sync {
|
||||||
/// Load the given asset from the source path.
|
/// Load the given asset from the source path.
|
||||||
fn load(&self, path: &str) -> Result<Cow<'static, [u8]>>;
|
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>>;
|
||||||
|
|
||||||
/// List the assets at the given path.
|
/// List the assets at the given path.
|
||||||
fn list(&self, path: &str) -> Result<Vec<SharedString>>;
|
fn list(&self, path: &str) -> Result<Vec<SharedString>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AssetSource for () {
|
impl AssetSource for () {
|
||||||
fn load(&self, path: &str) -> Result<Cow<'static, [u8]>> {
|
fn load(&self, _path: &str) -> Result<Option<Cow<'static, [u8]>>> {
|
||||||
Err(anyhow!(
|
Ok(None)
|
||||||
"load called on empty asset provider with \"{}\"",
|
|
||||||
path
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list(&self, _path: &str) -> Result<Vec<SharedString>> {
|
fn list(&self, _path: &str) -> Result<Vec<SharedString>> {
|
||||||
|
@ -344,8 +344,8 @@ pub(crate) trait PlatformAtlas: Send + Sync {
|
|||||||
fn get_or_insert_with<'a>(
|
fn get_or_insert_with<'a>(
|
||||||
&self,
|
&self,
|
||||||
key: &AtlasKey,
|
key: &AtlasKey,
|
||||||
build: &mut dyn FnMut() -> Result<(Size<DevicePixels>, Cow<'a, [u8]>)>,
|
build: &mut dyn FnMut() -> Result<Option<(Size<DevicePixels>, Cow<'a, [u8]>)>>,
|
||||||
) -> Result<AtlasTile>;
|
) -> Result<Option<AtlasTile>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -114,18 +114,20 @@ impl PlatformAtlas for BladeAtlas {
|
|||||||
fn get_or_insert_with<'a>(
|
fn get_or_insert_with<'a>(
|
||||||
&self,
|
&self,
|
||||||
key: &AtlasKey,
|
key: &AtlasKey,
|
||||||
build: &mut dyn FnMut() -> Result<(Size<DevicePixels>, Cow<'a, [u8]>)>,
|
build: &mut dyn FnMut() -> Result<Option<(Size<DevicePixels>, Cow<'a, [u8]>)>>,
|
||||||
) -> Result<AtlasTile> {
|
) -> Result<Option<AtlasTile>> {
|
||||||
let mut lock = self.0.lock();
|
let mut lock = self.0.lock();
|
||||||
if let Some(tile) = lock.tiles_by_key.get(key) {
|
if let Some(tile) = lock.tiles_by_key.get(key) {
|
||||||
Ok(tile.clone())
|
Ok(Some(tile.clone()))
|
||||||
} else {
|
} else {
|
||||||
profiling::scope!("new tile");
|
profiling::scope!("new tile");
|
||||||
let (size, bytes) = build()?;
|
let Some((size, bytes)) = build()? else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
let tile = lock.allocate(size, key.texture_kind());
|
let tile = lock.allocate(size, key.texture_kind());
|
||||||
lock.upload_texture(tile.texture_id, tile.bounds, &bytes);
|
lock.upload_texture(tile.texture_id, tile.bounds, &bytes);
|
||||||
lock.tiles_by_key.insert(key.clone(), tile.clone());
|
lock.tiles_by_key.insert(key.clone(), tile.clone());
|
||||||
Ok(tile)
|
Ok(Some(tile))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,20 +60,22 @@ impl PlatformAtlas for MetalAtlas {
|
|||||||
fn get_or_insert_with<'a>(
|
fn get_or_insert_with<'a>(
|
||||||
&self,
|
&self,
|
||||||
key: &AtlasKey,
|
key: &AtlasKey,
|
||||||
build: &mut dyn FnMut() -> Result<(Size<DevicePixels>, Cow<'a, [u8]>)>,
|
build: &mut dyn FnMut() -> Result<Option<(Size<DevicePixels>, Cow<'a, [u8]>)>>,
|
||||||
) -> Result<AtlasTile> {
|
) -> Result<Option<AtlasTile>> {
|
||||||
let mut lock = self.0.lock();
|
let mut lock = self.0.lock();
|
||||||
if let Some(tile) = lock.tiles_by_key.get(key) {
|
if let Some(tile) = lock.tiles_by_key.get(key) {
|
||||||
Ok(tile.clone())
|
Ok(Some(tile.clone()))
|
||||||
} else {
|
} else {
|
||||||
let (size, bytes) = build()?;
|
let Some((size, bytes)) = build()? else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
let tile = lock
|
let tile = lock
|
||||||
.allocate(size, key.texture_kind())
|
.allocate(size, key.texture_kind())
|
||||||
.ok_or_else(|| anyhow!("failed to allocate"))?;
|
.ok_or_else(|| anyhow!("failed to allocate"))?;
|
||||||
let texture = lock.texture(tile.texture_id);
|
let texture = lock.texture(tile.texture_id);
|
||||||
texture.upload(tile.bounds, &bytes);
|
texture.upload(tile.bounds, &bytes);
|
||||||
lock.tiles_by_key.insert(key.clone(), tile.clone());
|
lock.tiles_by_key.insert(key.clone(), tile.clone());
|
||||||
Ok(tile)
|
Ok(Some(tile))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,25 +291,26 @@ impl PlatformAtlas for TestAtlas {
|
|||||||
fn get_or_insert_with<'a>(
|
fn get_or_insert_with<'a>(
|
||||||
&self,
|
&self,
|
||||||
key: &crate::AtlasKey,
|
key: &crate::AtlasKey,
|
||||||
build: &mut dyn FnMut() -> anyhow::Result<(
|
build: &mut dyn FnMut() -> anyhow::Result<
|
||||||
Size<crate::DevicePixels>,
|
Option<(Size<crate::DevicePixels>, std::borrow::Cow<'a, [u8]>)>,
|
||||||
std::borrow::Cow<'a, [u8]>,
|
>,
|
||||||
)>,
|
) -> anyhow::Result<Option<crate::AtlasTile>> {
|
||||||
) -> anyhow::Result<crate::AtlasTile> {
|
|
||||||
let mut state = self.0.lock();
|
let mut state = self.0.lock();
|
||||||
if let Some(tile) = state.tiles.get(key) {
|
if let Some(tile) = state.tiles.get(key) {
|
||||||
return Ok(tile.clone());
|
return Ok(Some(tile.clone()));
|
||||||
}
|
}
|
||||||
|
drop(state);
|
||||||
|
|
||||||
|
let Some((size, _)) = build()? else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut state = self.0.lock();
|
||||||
state.next_id += 1;
|
state.next_id += 1;
|
||||||
let texture_id = state.next_id;
|
let texture_id = state.next_id;
|
||||||
state.next_id += 1;
|
state.next_id += 1;
|
||||||
let tile_id = state.next_id;
|
let tile_id = state.next_id;
|
||||||
|
|
||||||
drop(state);
|
|
||||||
let (size, _) = build()?;
|
|
||||||
let mut state = self.0.lock();
|
|
||||||
|
|
||||||
state.tiles.insert(
|
state.tiles.insert(
|
||||||
key.clone(),
|
key.clone(),
|
||||||
crate::AtlasTile {
|
crate::AtlasTile {
|
||||||
@ -326,6 +327,6 @@ impl PlatformAtlas for TestAtlas {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(state.tiles[key].clone())
|
Ok(Some(state.tiles[key].clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,15 @@ impl SvgRenderer {
|
|||||||
Self { asset_source }
|
Self { asset_source }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, params: &RenderSvgParams) -> Result<Vec<u8>> {
|
pub fn render(&self, params: &RenderSvgParams) -> Result<Option<Vec<u8>>> {
|
||||||
if params.size.is_zero() {
|
if params.size.is_zero() {
|
||||||
return Err(anyhow!("can't render at a zero size"));
|
return Err(anyhow!("can't render at a zero size"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the tree.
|
// Load the tree.
|
||||||
let bytes = self.asset_source.load(¶ms.path)?;
|
let Some(bytes) = self.asset_source.load(¶ms.path)? else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
let pixmap = self.render_pixmap(&bytes, SvgSize::Size(params.size))?;
|
let pixmap = self.render_pixmap(&bytes, SvgSize::Size(params.size))?;
|
||||||
|
|
||||||
@ -40,7 +42,7 @@ impl SvgRenderer {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|p| p.alpha())
|
.map(|p| p.alpha())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
Ok(alpha_mask)
|
Ok(Some(alpha_mask))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_pixmap(&self, bytes: &[u8], size: SvgSize) -> Result<Pixmap, usvg::Error> {
|
pub fn render_pixmap(&self, bytes: &[u8], size: SvgSize) -> Result<Pixmap, usvg::Error> {
|
||||||
|
@ -2347,13 +2347,14 @@ impl<'a> WindowContext<'a> {
|
|||||||
|
|
||||||
let raster_bounds = self.text_system().raster_bounds(¶ms)?;
|
let raster_bounds = self.text_system().raster_bounds(¶ms)?;
|
||||||
if !raster_bounds.is_zero() {
|
if !raster_bounds.is_zero() {
|
||||||
let tile =
|
let tile = self
|
||||||
self.window
|
.window
|
||||||
.sprite_atlas
|
.sprite_atlas
|
||||||
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
||||||
let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
|
let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
|
||||||
Ok((size, Cow::Owned(bytes)))
|
Ok(Some((size, Cow::Owned(bytes))))
|
||||||
})?;
|
})?
|
||||||
|
.expect("Callback above only errors or returns Some");
|
||||||
let bounds = Bounds {
|
let bounds = Bounds {
|
||||||
origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
|
origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
|
||||||
size: tile.bounds.size.map(Into::into),
|
size: tile.bounds.size.map(Into::into),
|
||||||
@ -2410,13 +2411,15 @@ impl<'a> WindowContext<'a> {
|
|||||||
|
|
||||||
let raster_bounds = self.text_system().raster_bounds(¶ms)?;
|
let raster_bounds = self.text_system().raster_bounds(¶ms)?;
|
||||||
if !raster_bounds.is_zero() {
|
if !raster_bounds.is_zero() {
|
||||||
let tile =
|
let tile = self
|
||||||
self.window
|
.window
|
||||||
.sprite_atlas
|
.sprite_atlas
|
||||||
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
||||||
let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
|
let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
|
||||||
Ok((size, Cow::Owned(bytes)))
|
Ok(Some((size, Cow::Owned(bytes))))
|
||||||
})?;
|
})?
|
||||||
|
.expect("Callback above only errors or returns Some");
|
||||||
|
|
||||||
let bounds = Bounds {
|
let bounds = Bounds {
|
||||||
origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
|
origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
|
||||||
size: tile.bounds.size.map(Into::into),
|
size: tile.bounds.size.map(Into::into),
|
||||||
@ -2464,13 +2467,18 @@ impl<'a> WindowContext<'a> {
|
|||||||
.map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
|
.map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let tile =
|
let Some(tile) =
|
||||||
self.window
|
self.window
|
||||||
.sprite_atlas
|
.sprite_atlas
|
||||||
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
||||||
let bytes = self.svg_renderer.render(¶ms)?;
|
let Some(bytes) = self.svg_renderer.render(¶ms)? else {
|
||||||
Ok((params.size, Cow::Owned(bytes)))
|
return Ok(None);
|
||||||
})?;
|
};
|
||||||
|
Ok(Some((params.size, Cow::Owned(bytes))))
|
||||||
|
})?
|
||||||
|
else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
let content_mask = self.content_mask().scale(scale_factor);
|
let content_mask = self.content_mask().scale(scale_factor);
|
||||||
|
|
||||||
self.window
|
self.window
|
||||||
@ -2513,8 +2521,9 @@ impl<'a> WindowContext<'a> {
|
|||||||
.window
|
.window
|
||||||
.sprite_atlas
|
.sprite_atlas
|
||||||
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
||||||
Ok((data.size(), Cow::Borrowed(data.as_bytes())))
|
Ok(Some((data.size(), Cow::Borrowed(data.as_bytes()))))
|
||||||
})?;
|
})?
|
||||||
|
.expect("Callback above only returns Some");
|
||||||
let content_mask = self.content_mask().scale(scale_factor);
|
let content_mask = self.content_mask().scale(scale_factor);
|
||||||
let corner_radii = corner_radii.scale(scale_factor);
|
let corner_radii = corner_radii.scale(scale_factor);
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ impl Item for ImageView {
|
|||||||
let workspace_id = workspace.database_id();
|
let workspace_id = workspace.database_id();
|
||||||
let image_path = self.path.clone();
|
let image_path = self.path.clone();
|
||||||
|
|
||||||
|
if let Some(workspace_id) = workspace_id {
|
||||||
cx.background_executor()
|
cx.background_executor()
|
||||||
.spawn({
|
.spawn({
|
||||||
let image_path = image_path.clone();
|
let image_path = image_path.clone();
|
||||||
@ -107,6 +108,7 @@ impl Item for ImageView {
|
|||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn serialized_item_kind() -> Option<&'static str> {
|
fn serialized_item_kind() -> Option<&'static str> {
|
||||||
Some(IMAGE_VIEWER_KIND)
|
Some(IMAGE_VIEWER_KIND)
|
||||||
@ -133,7 +135,7 @@ impl Item for ImageView {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: Option<WorkspaceId>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>>
|
) -> Option<View<Self>>
|
||||||
where
|
where
|
||||||
|
@ -407,7 +407,7 @@ impl Item for SyntaxTreeView {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_: workspace::WorkspaceId,
|
_: Option<workspace::WorkspaceId>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>>
|
) -> Option<View<Self>>
|
||||||
where
|
where
|
||||||
|
@ -287,7 +287,7 @@ impl PickerDelegate for RecentProjectsDelegate {
|
|||||||
};
|
};
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
if workspace.database_id() == *candidate_workspace_id {
|
if workspace.database_id() == Some(*candidate_workspace_id) {
|
||||||
Task::ready(Ok(()))
|
Task::ready(Ok(()))
|
||||||
} else {
|
} else {
|
||||||
match candidate_workspace_location {
|
match candidate_workspace_location {
|
||||||
@ -675,7 +675,7 @@ impl RecentProjectsDelegate {
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
if let Some(workspace) = self.workspace.upgrade() {
|
if let Some(workspace) = self.workspace.upgrade() {
|
||||||
let workspace = workspace.read(cx);
|
let workspace = workspace.read(cx);
|
||||||
if workspace_id == workspace.database_id() {
|
if Some(workspace_id) == workspace.database_id() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,7 +456,7 @@ impl Item for ProjectSearchView {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: Option<WorkspaceId>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>>
|
) -> Option<View<Self>>
|
||||||
where
|
where
|
||||||
|
@ -283,7 +283,7 @@ impl Item for ProjectIndexDebugView {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_: workspace::WorkspaceId,
|
_: Option<workspace::WorkspaceId>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>>
|
) -> Option<View<Self>>
|
||||||
where
|
where
|
||||||
|
@ -15,10 +15,11 @@ use rust_embed::RustEmbed;
|
|||||||
pub struct Assets;
|
pub struct Assets;
|
||||||
|
|
||||||
impl AssetSource for Assets {
|
impl AssetSource for Assets {
|
||||||
fn load(&self, path: &str) -> Result<Cow<'static, [u8]>> {
|
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>> {
|
||||||
Self::get(path)
|
Self::get(path)
|
||||||
.map(|f| f.data)
|
.map(|f| f.data)
|
||||||
.ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
|
.ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
|
||||||
|
.map(|data| Some(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
||||||
|
@ -128,7 +128,10 @@ fn load_embedded_fonts(cx: &AppContext) -> gpui::Result<()> {
|
|||||||
let mut embedded_fonts = Vec::new();
|
let mut embedded_fonts = Vec::new();
|
||||||
for font_path in font_paths {
|
for font_path in font_paths {
|
||||||
if font_path.ends_with(".ttf") {
|
if font_path.ends_with(".ttf") {
|
||||||
let font_bytes = cx.asset_source().load(&font_path)?;
|
let font_bytes = cx
|
||||||
|
.asset_source()
|
||||||
|
.load(&font_path)?
|
||||||
|
.expect("Should never be None in the storybook");
|
||||||
embedded_fonts.push(font_bytes);
|
embedded_fonts.push(font_bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,9 @@ impl TerminalPanel {
|
|||||||
|
|
||||||
let (panel, pane, items) = workspace.update(&mut cx, |workspace, cx| {
|
let (panel, pane, items) = workspace.update(&mut cx, |workspace, cx| {
|
||||||
let panel = cx.new_view(|cx| TerminalPanel::new(workspace, cx));
|
let panel = cx.new_view(|cx| TerminalPanel::new(workspace, cx));
|
||||||
let items = if let Some(serialized_panel) = serialized_panel.as_ref() {
|
let items = if let Some((serialized_panel, database_id)) =
|
||||||
|
serialized_panel.as_ref().zip(workspace.database_id())
|
||||||
|
{
|
||||||
panel.update(cx, |panel, cx| {
|
panel.update(cx, |panel, cx| {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
panel.height = serialized_panel.height.map(|h| h.round());
|
panel.height = serialized_panel.height.map(|h| h.round());
|
||||||
@ -234,7 +236,7 @@ impl TerminalPanel {
|
|||||||
TerminalView::deserialize(
|
TerminalView::deserialize(
|
||||||
workspace.project().clone(),
|
workspace.project().clone(),
|
||||||
workspace.weak_handle(),
|
workspace.weak_handle(),
|
||||||
workspace.database_id(),
|
database_id,
|
||||||
*item_id,
|
*item_id,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
|
@ -91,7 +91,7 @@ pub struct TerminalView {
|
|||||||
blinking_paused: bool,
|
blinking_paused: bool,
|
||||||
blink_epoch: usize,
|
blink_epoch: usize,
|
||||||
can_navigate_to_selected_word: bool,
|
can_navigate_to_selected_word: bool,
|
||||||
workspace_id: WorkspaceId,
|
workspace_id: Option<WorkspaceId>,
|
||||||
show_title: bool,
|
show_title: bool,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
_terminal_subscriptions: Vec<Subscription>,
|
_terminal_subscriptions: Vec<Subscription>,
|
||||||
@ -142,7 +142,7 @@ impl TerminalView {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
terminal: Model<Terminal>,
|
terminal: Model<Terminal>,
|
||||||
workspace: WeakView<Workspace>,
|
workspace: WeakView<Workspace>,
|
||||||
workspace_id: WorkspaceId,
|
workspace_id: Option<WorkspaceId>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let workspace_handle = workspace.clone();
|
let workspace_handle = workspace.clone();
|
||||||
@ -458,7 +458,7 @@ fn subscribe_for_terminal_events(
|
|||||||
if terminal.task().is_none() {
|
if terminal.task().is_none() {
|
||||||
if let Some(cwd) = terminal.get_cwd() {
|
if let Some(cwd) = terminal.get_cwd() {
|
||||||
let item_id = cx.entity_id();
|
let item_id = cx.entity_id();
|
||||||
let workspace_id = this.workspace_id;
|
if let Some(workspace_id) = this.workspace_id {
|
||||||
cx.background_executor()
|
cx.background_executor()
|
||||||
.spawn(async move {
|
.spawn(async move {
|
||||||
TERMINAL_DB
|
TERMINAL_DB
|
||||||
@ -470,6 +470,7 @@ fn subscribe_for_terminal_events(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Event::NewNavigationTarget(maybe_navigation_target) => {
|
Event::NewNavigationTarget(maybe_navigation_target) => {
|
||||||
this.can_navigate_to_selected_word = match maybe_navigation_target {
|
this.can_navigate_to_selected_word = match maybe_navigation_target {
|
||||||
@ -853,7 +854,7 @@ impl Item for TerminalView {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: Option<WorkspaceId>,
|
||||||
_cx: &mut ViewContext<Self>,
|
_cx: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>> {
|
) -> Option<View<Self>> {
|
||||||
//From what I can tell, there's no way to tell the current working
|
//From what I can tell, there's no way to tell the current working
|
||||||
@ -941,20 +942,18 @@ impl Item for TerminalView {
|
|||||||
project.create_terminal(cwd, None, window, cx)
|
project.create_terminal(cwd, None, window, cx)
|
||||||
})??;
|
})??;
|
||||||
pane.update(&mut cx, |_, cx| {
|
pane.update(&mut cx, |_, cx| {
|
||||||
cx.new_view(|cx| TerminalView::new(terminal, workspace, workspace_id, cx))
|
cx.new_view(|cx| TerminalView::new(terminal, workspace, Some(workspace_id), cx))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
|
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
|
||||||
if self.terminal().read(cx).task().is_none() {
|
if self.terminal().read(cx).task().is_none() {
|
||||||
|
if let Some((new_id, old_id)) = workspace.database_id().zip(self.workspace_id) {
|
||||||
cx.background_executor()
|
cx.background_executor()
|
||||||
.spawn(TERMINAL_DB.update_workspace_id(
|
.spawn(TERMINAL_DB.update_workspace_id(new_id, old_id, cx.entity_id().as_u64()))
|
||||||
workspace.database_id(),
|
|
||||||
self.workspace_id,
|
|
||||||
cx.entity_id().as_u64(),
|
|
||||||
))
|
|
||||||
.detach();
|
.detach();
|
||||||
|
}
|
||||||
self.workspace_id = workspace.database_id();
|
self.workspace_id = workspace.database_id();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::path::Path;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::{fmt::Debug, path::Path};
|
||||||
|
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
@ -226,7 +226,7 @@ impl ThemeRegistry {
|
|||||||
.filter(|path| path.ends_with(".json"));
|
.filter(|path| path.ends_with(".json"));
|
||||||
|
|
||||||
for path in theme_paths {
|
for path in theme_paths {
|
||||||
let Some(theme) = self.assets.load(&path).log_err() else {
|
let Some(theme) = self.assets.load(&path).log_err().flatten() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,10 +11,11 @@ use rust_embed::RustEmbed;
|
|||||||
pub struct Assets;
|
pub struct Assets;
|
||||||
|
|
||||||
impl AssetSource for Assets {
|
impl AssetSource for Assets {
|
||||||
fn load(&self, path: &str) -> Result<Cow<'static, [u8]>> {
|
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>> {
|
||||||
Self::get(path)
|
Self::get(path)
|
||||||
.map(|f| f.data)
|
.map(|f| f.data)
|
||||||
.ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
|
.ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
|
||||||
|
.map(|result| Some(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
||||||
|
@ -313,7 +313,7 @@ impl Item for WelcomePage {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: Option<WorkspaceId>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>> {
|
) -> Option<View<Self>> {
|
||||||
Some(cx.new_view(|cx| WelcomePage {
|
Some(cx.new_view(|cx| WelcomePage {
|
||||||
|
@ -172,7 +172,7 @@ pub trait Item: FocusableView + EventEmitter<Self::Event> {
|
|||||||
fn set_nav_history(&mut self, _: ItemNavHistory, _: &mut ViewContext<Self>) {}
|
fn set_nav_history(&mut self, _: ItemNavHistory, _: &mut ViewContext<Self>) {}
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: Option<WorkspaceId>,
|
||||||
_: &mut ViewContext<Self>,
|
_: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>>
|
) -> Option<View<Self>>
|
||||||
where
|
where
|
||||||
@ -287,7 +287,7 @@ pub trait ItemHandle: 'static + Send {
|
|||||||
fn boxed_clone(&self) -> Box<dyn ItemHandle>;
|
fn boxed_clone(&self) -> Box<dyn ItemHandle>;
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
workspace_id: WorkspaceId,
|
workspace_id: Option<WorkspaceId>,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
) -> Option<Box<dyn ItemHandle>>;
|
) -> Option<Box<dyn ItemHandle>>;
|
||||||
fn added_to_pane(
|
fn added_to_pane(
|
||||||
@ -437,7 +437,7 @@ impl<T: Item> ItemHandle for View<T> {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
workspace_id: WorkspaceId,
|
workspace_id: Option<WorkspaceId>,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
) -> Option<Box<dyn ItemHandle>> {
|
) -> Option<Box<dyn ItemHandle>> {
|
||||||
self.update(cx, |item, cx| item.clone_on_split(workspace_id, cx))
|
self.update(cx, |item, cx| item.clone_on_split(workspace_id, cx))
|
||||||
@ -528,7 +528,6 @@ impl<T: Item> ItemHandle for View<T> {
|
|||||||
{
|
{
|
||||||
pane
|
pane
|
||||||
} else {
|
} else {
|
||||||
log::error!("unexpected item event after pane was dropped");
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -883,7 +882,7 @@ pub mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct TestItem {
|
pub struct TestItem {
|
||||||
pub workspace_id: WorkspaceId,
|
pub workspace_id: Option<WorkspaceId>,
|
||||||
pub state: String,
|
pub state: String,
|
||||||
pub label: String,
|
pub label: String,
|
||||||
pub save_count: usize,
|
pub save_count: usize,
|
||||||
@ -964,7 +963,7 @@ pub mod test {
|
|||||||
|
|
||||||
pub fn new_deserialized(id: WorkspaceId, cx: &mut ViewContext<Self>) -> Self {
|
pub fn new_deserialized(id: WorkspaceId, cx: &mut ViewContext<Self>) -> Self {
|
||||||
let mut this = Self::new(cx);
|
let mut this = Self::new(cx);
|
||||||
this.workspace_id = id;
|
this.workspace_id = Some(id);
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1081,7 +1080,7 @@ pub mod test {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: Option<WorkspaceId>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>>
|
) -> Option<View<Self>>
|
||||||
where
|
where
|
||||||
|
@ -119,7 +119,7 @@ impl Item for SharedScreen {
|
|||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: Option<WorkspaceId>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<View<Self>> {
|
) -> Option<View<Self>> {
|
||||||
let track = self.track.upgrade()?;
|
let track = self.track.upgrade()?;
|
||||||
|
@ -588,7 +588,7 @@ pub struct Workspace {
|
|||||||
window_edited: bool,
|
window_edited: bool,
|
||||||
active_call: Option<(Model<ActiveCall>, Vec<Subscription>)>,
|
active_call: Option<(Model<ActiveCall>, Vec<Subscription>)>,
|
||||||
leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
|
leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
|
||||||
database_id: WorkspaceId,
|
database_id: Option<WorkspaceId>,
|
||||||
app_state: Arc<AppState>,
|
app_state: Arc<AppState>,
|
||||||
dispatching_keystrokes: Rc<RefCell<Vec<Keystroke>>>,
|
dispatching_keystrokes: Rc<RefCell<Vec<Keystroke>>>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
@ -622,7 +622,7 @@ impl Workspace {
|
|||||||
const MAX_PADDING: f32 = 0.4;
|
const MAX_PADDING: f32 = 0.4;
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
workspace_id: WorkspaceId,
|
workspace_id: Option<WorkspaceId>,
|
||||||
project: Model<Project>,
|
project: Model<Project>,
|
||||||
app_state: Arc<AppState>,
|
app_state: Arc<AppState>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
@ -795,15 +795,17 @@ impl Workspace {
|
|||||||
if let Some(display) = cx.display() {
|
if let Some(display) = cx.display() {
|
||||||
if let Some(display_uuid) = display.uuid().log_err() {
|
if let Some(display_uuid) = display.uuid().log_err() {
|
||||||
let window_bounds = cx.window_bounds();
|
let window_bounds = cx.window_bounds();
|
||||||
|
if let Some(database_id) = workspace_id {
|
||||||
cx.background_executor()
|
cx.background_executor()
|
||||||
.spawn(DB.set_window_open_status(
|
.spawn(DB.set_window_open_status(
|
||||||
workspace_id,
|
database_id,
|
||||||
SerializedWindowBounds(window_bounds),
|
SerializedWindowBounds(window_bounds),
|
||||||
display_uuid,
|
display_uuid,
|
||||||
))
|
))
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.bounds_save_task_queued.take();
|
this.bounds_save_task_queued.take();
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
@ -956,7 +958,12 @@ impl Workspace {
|
|||||||
let window = if let Some(window) = requesting_window {
|
let window = if let Some(window) = requesting_window {
|
||||||
cx.update_window(window.into(), |_, cx| {
|
cx.update_window(window.into(), |_, cx| {
|
||||||
cx.replace_root_view(|cx| {
|
cx.replace_root_view(|cx| {
|
||||||
Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx)
|
Workspace::new(
|
||||||
|
Some(workspace_id),
|
||||||
|
project_handle.clone(),
|
||||||
|
app_state.clone(),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
})?;
|
})?;
|
||||||
window
|
window
|
||||||
@ -994,7 +1001,7 @@ impl Workspace {
|
|||||||
move |cx| {
|
move |cx| {
|
||||||
cx.new_view(|cx| {
|
cx.new_view(|cx| {
|
||||||
let mut workspace =
|
let mut workspace =
|
||||||
Workspace::new(workspace_id, project_handle, app_state, cx);
|
Workspace::new(Some(workspace_id), project_handle, app_state, cx);
|
||||||
workspace.centered_layout = centered_layout;
|
workspace.centered_layout = centered_layout;
|
||||||
workspace
|
workspace
|
||||||
})
|
})
|
||||||
@ -3464,9 +3471,12 @@ impl Workspace {
|
|||||||
pub fn on_window_activation_changed(&mut self, cx: &mut ViewContext<Self>) {
|
pub fn on_window_activation_changed(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
if cx.is_window_active() {
|
if cx.is_window_active() {
|
||||||
self.update_active_view_for_followers(cx);
|
self.update_active_view_for_followers(cx);
|
||||||
|
|
||||||
|
if let Some(database_id) = self.database_id {
|
||||||
cx.background_executor()
|
cx.background_executor()
|
||||||
.spawn(persistence::DB.update_timestamp(self.database_id()))
|
.spawn(persistence::DB.update_timestamp(database_id))
|
||||||
.detach();
|
.detach();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for pane in &self.panes {
|
for pane in &self.panes {
|
||||||
pane.update(cx, |pane, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
@ -3506,7 +3516,7 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn database_id(&self) -> WorkspaceId {
|
pub fn database_id(&self) -> Option<WorkspaceId> {
|
||||||
self.database_id
|
self.database_id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3566,6 +3576,10 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_workspace_internal(&self, cx: &mut WindowContext) -> Task<()> {
|
fn serialize_workspace_internal(&self, cx: &mut WindowContext) -> Task<()> {
|
||||||
|
let Some(database_id) = self.database_id() else {
|
||||||
|
return Task::ready(());
|
||||||
|
};
|
||||||
|
|
||||||
fn serialize_pane_handle(pane_handle: &View<Pane>, cx: &WindowContext) -> SerializedPane {
|
fn serialize_pane_handle(pane_handle: &View<Pane>, cx: &WindowContext) -> SerializedPane {
|
||||||
let (items, active) = {
|
let (items, active) = {
|
||||||
let pane = pane_handle.read(cx);
|
let pane = pane_handle.read(cx);
|
||||||
@ -3701,7 +3715,7 @@ impl Workspace {
|
|||||||
let docks = build_serialized_docks(self, cx);
|
let docks = build_serialized_docks(self, cx);
|
||||||
let window_bounds = Some(SerializedWindowBounds(cx.window_bounds()));
|
let window_bounds = Some(SerializedWindowBounds(cx.window_bounds()));
|
||||||
let serialized_workspace = SerializedWorkspace {
|
let serialized_workspace = SerializedWorkspace {
|
||||||
id: self.database_id,
|
id: database_id,
|
||||||
location,
|
location,
|
||||||
center_group,
|
center_group,
|
||||||
window_bounds,
|
window_bounds,
|
||||||
@ -3944,9 +3958,11 @@ impl Workspace {
|
|||||||
|
|
||||||
pub fn toggle_centered_layout(&mut self, _: &ToggleCenteredLayout, cx: &mut ViewContext<Self>) {
|
pub fn toggle_centered_layout(&mut self, _: &ToggleCenteredLayout, cx: &mut ViewContext<Self>) {
|
||||||
self.centered_layout = !self.centered_layout;
|
self.centered_layout = !self.centered_layout;
|
||||||
|
if let Some(database_id) = self.database_id() {
|
||||||
cx.background_executor()
|
cx.background_executor()
|
||||||
.spawn(DB.set_centered_layout(self.database_id, self.centered_layout))
|
.spawn(DB.set_centered_layout(database_id, self.centered_layout))
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
|
}
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,7 +832,7 @@ fn load_embedded_fonts(cx: &AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scope.spawn(async {
|
scope.spawn(async {
|
||||||
let font_bytes = asset_source.load(font_path).unwrap();
|
let font_bytes = asset_source.load(font_path).unwrap().unwrap();
|
||||||
embedded_fonts.lock().push(font_bytes);
|
embedded_fonts.lock().push(font_bytes);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3043,8 +3043,14 @@ mod tests {
|
|||||||
fn test_bundled_settings_and_themes(cx: &mut AppContext) {
|
fn test_bundled_settings_and_themes(cx: &mut AppContext) {
|
||||||
cx.text_system()
|
cx.text_system()
|
||||||
.add_fonts(vec![
|
.add_fonts(vec![
|
||||||
Assets.load("fonts/zed-sans/zed-sans-extended.ttf").unwrap(),
|
Assets
|
||||||
Assets.load("fonts/zed-mono/zed-mono-extended.ttf").unwrap(),
|
.load("fonts/zed-sans/zed-sans-extended.ttf")
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
Assets
|
||||||
|
.load("fonts/zed-mono/zed-mono-extended.ttf")
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
])
|
])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let themes = ThemeRegistry::default();
|
let themes = ThemeRegistry::default();
|
||||||
|
Loading…
Reference in New Issue
Block a user