update dock

This commit is contained in:
2026-08-23 10:03:10 +07:00
parent 7fb7275233
commit 8da48bdc4a
25 changed files with 1583 additions and 5471 deletions
+25 -5
View File
@@ -91,17 +91,37 @@ impl LruImageCache {
}
}
/// Drop a cache entry from the sprite atlas and remove its resource from the
/// asset system, so both the decoded image and the raw fetched bytes are
/// freed. `window` restricts the atlas removal to the current window; `None`
/// removes it from all windows.
/// Drop a cache entry's decoded data and remove its resource from the asset
/// system, so both the decoded image and the raw fetched bytes are freed.
///
/// The atlas texture is freed **on the next frame, before it paints**, never
/// in the middle of one: the release that empties the cache can run at the
/// end of a frame's draw — after the scene was built, before it is presented
/// — and eviction runs while a frame is painting (`load` is called from
/// paint). The next frame also has to repaint every view instead of replaying
/// their recorded paint commands: `cached()` views reuse recorded commands
/// across frames, and those commands reference the atlas tiles being freed,
/// so a replay would hand the renderer a scene full of freed texture ids.
/// `window.refresh()` disables that reuse for exactly one frame.
///
/// `window` restricts the atlas removal to the current window; `None` removes
/// it from all windows (the cache entity is being released at shutdown, when
/// no scene is in flight).
fn unload(
(mut item, resource): (ImageCacheItem, Resource),
window: Option<&mut Window>,
cx: &mut App,
) {
if let Some(Ok(image)) = item.get() {
cx.drop_image(image, window);
match window {
Some(window) => {
window.on_next_frame(move |window, cx| {
window.refresh();
cx.drop_image(image, Some(window));
});
}
None => cx.drop_image(image, None),
}
}
ImageSource::Resource(resource).remove_asset(cx);
}
@@ -1,7 +1,7 @@
use std::path::PathBuf;
use std::rc::Rc;
use dock::{Panel, PanelEvent};
use dock::{BasePanel, Panel, PanelEvent};
use gpui::prelude::*;
use gpui::{
AnyElement, App, Context, Entity, EventEmitter, FocusHandle, Focusable, Pixels, Render,
@@ -455,11 +455,13 @@ impl CommitDiffView {
}
}
impl Panel for CommitDiffView {
impl BasePanel for CommitDiffView {
fn panel_name(&self) -> &'static str {
"commit_diff"
}
}
impl Panel for CommitDiffView {
fn title(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div().text_sm().child(SharedString::from(format!(
"{}/{}",
@@ -1,4 +1,4 @@
use dock::{Panel, PanelEvent};
use dock::{BasePanel, Panel, PanelEvent};
use gpui::prelude::*;
use gpui::{
App, Context, Entity, EventEmitter, FocusHandle, Focusable, Render, SharedString, Window, div,
@@ -131,11 +131,13 @@ impl IssueDetailView {
}
}
impl Panel for IssueDetailView {
impl BasePanel for IssueDetailView {
fn panel_name(&self) -> &'static str {
"issue_detail"
}
}
impl Panel for IssueDetailView {
fn title(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let short_id = self
.store
@@ -3,10 +3,9 @@
//! the header's All/Open/Closed filter.
use std::rc::Rc;
use std::sync::Arc;
use assets::CustomIconName;
use dock::{DockArea, DockPlacement, Panel, PanelEvent};
use dock::{BasePanel, DockArea, DockPlacement, Panel, PanelEvent, panel_handle};
use gpui::prelude::*;
use gpui::{
AnyElement, App, Context, Entity, EventEmitter, FocusHandle, Focusable, Pixels, Render,
@@ -123,7 +122,7 @@ impl IssuesView {
let panel = cx.new(|cx| IssueDetailView::new(self.store.clone(), issue_id, window, cx));
dock_area.update(cx, |dock_area, cx| {
dock_area.add_panel(Arc::new(panel), DockPlacement::Bottom, window, cx);
dock_area.add_panel_view(panel_handle(panel), DockPlacement::Bottom, None, window, cx);
});
}
@@ -417,11 +416,13 @@ fn open_new_issue_dialog(store: Entity<RepoStore>, window: &mut Window, cx: &mut
});
}
impl Panel for IssuesView {
impl BasePanel for IssuesView {
fn panel_name(&self) -> &'static str {
"issues"
}
}
impl Panel for IssuesView {
fn title(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div().child(SharedString::from(format!("{}/issues", self.repo_name)))
}
@@ -1,11 +1,10 @@
use std::collections::{HashMap, HashSet, VecDeque};
use std::path::{Component, Path, PathBuf};
use std::rc::Rc;
use std::sync::Arc;
use anyhow::Error;
use assets::CustomIconName;
use dock::{DockArea, DockPlacement, Panel, PanelEvent};
use dock::{BasePanel, DockArea, DockPlacement, Panel, PanelEvent, panel_handle};
use gix::Repository;
use gpui::prelude::*;
use gpui::{
@@ -653,7 +652,7 @@ impl RepoDetailView {
cx.new(|cx| CommitDiffView::new(worktree, repo_name, commit_id.into(), window, cx));
dock_area.update(cx, |dock_area, cx| {
dock_area.add_panel(Arc::new(panel), DockPlacement::Center, window, cx);
dock_area.add_panel_view(panel_handle(panel), DockPlacement::Center, None, window, cx);
});
}
@@ -674,7 +673,7 @@ impl RepoDetailView {
});
dock_area.update(cx, |dock_area, cx| {
dock_area.add_panel(Arc::new(panel), DockPlacement::Center, window, cx);
dock_area.add_panel_view(panel_handle(panel), DockPlacement::Center, None, window, cx);
});
}
@@ -695,7 +694,7 @@ impl RepoDetailView {
});
dock_area.update(cx, |dock_area, cx| {
dock_area.add_panel(Arc::new(panel), DockPlacement::Center, window, cx);
dock_area.add_panel_view(panel_handle(panel), DockPlacement::Center, None, window, cx);
});
}
@@ -1203,11 +1202,13 @@ impl RepoDetailView {
}
}
impl Panel for RepoDetailView {
impl BasePanel for RepoDetailView {
fn panel_name(&self) -> &'static str {
"repo_detail"
}
}
impl Panel for RepoDetailView {
fn title(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
self.display_name(cx)
}
@@ -1,7 +1,7 @@
use std::path::PathBuf;
use std::rc::Rc;
use dock::{Panel, PanelEvent};
use dock::{BasePanel, Panel, PanelEvent};
use gpui::prelude::*;
use gpui::{
AnyElement, App, Context, Entity, EventEmitter, FocusHandle, Focusable, Pixels, Render,
@@ -819,11 +819,13 @@ fn commit_meta(commit: &FileCommit) -> String {
}
}
impl Panel for PullRequestDetailView {
impl BasePanel for PullRequestDetailView {
fn panel_name(&self) -> &'static str {
"pull-request-detail"
}
}
impl Panel for PullRequestDetailView {
fn title(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let subject = self
.store
@@ -1,8 +1,7 @@
use std::rc::Rc;
use std::sync::Arc;
use assets::CustomIconName;
use dock::{DockArea, DockPlacement, Panel, PanelEvent};
use dock::{BasePanel, DockArea, DockPlacement, Panel, PanelEvent, panel_handle};
use gpui::prelude::*;
use gpui::{
AnyElement, App, Context, Entity, EventEmitter, FocusHandle, Focusable, Pixels, Render,
@@ -126,7 +125,7 @@ impl PullRequestsView {
let panel = cx.new(|cx| PullRequestDetailView::new(self.store.clone(), pr_id, window, cx));
dock_area.update(cx, |dock_area, cx| {
dock_area.add_panel(Arc::new(panel), DockPlacement::Bottom, window, cx);
dock_area.add_panel_view(panel_handle(panel), DockPlacement::Bottom, None, window, cx);
});
}
@@ -504,11 +503,13 @@ fn open_new_pull_request_dialog(store: Entity<RepoStore>, window: &mut Window, c
});
}
impl Panel for PullRequestsView {
impl BasePanel for PullRequestsView {
fn panel_name(&self) -> &'static str {
"pull-requests"
}
}
impl Panel for PullRequestsView {
fn title(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div().child(SharedString::from(format!(
"{}/pull-requests",
+11 -4
View File
@@ -1,13 +1,12 @@
use std::rc::Rc;
use std::sync::Arc;
use dock::{BasePanel, DockArea, DockPlacement, Panel, PanelEvent, panel_handle};
use gpui::prelude::*;
use gpui::{
AnyElement, App, Context, Entity, EventEmitter, FocusHandle, Focusable, Pixels, Render,
SharedString, Size, Subscription, WeakEntity, Window, div, px, size,
};
use gpui_component::avatar::Avatar;
use dock::{DockArea, DockPlacement, Panel, PanelEvent};
use gpui_component::scroll::Scrollbar;
use gpui_component::{
ActiveTheme, Sizable, StyledExt, VirtualListScrollHandle, h_flex, v_flex, v_virtual_list,
@@ -68,7 +67,13 @@ impl RepoListView {
if let Some(dock_area) = dock_area.upgrade() {
dock_area.update(cx, |dock_area, cx| {
dock_area.add_panel(Arc::new(detail), DockPlacement::Center, window, cx);
dock_area.add_panel_view(
panel_handle(detail),
DockPlacement::Center,
None,
window,
cx,
);
});
}
}
@@ -166,11 +171,13 @@ impl RepoListView {
}
}
impl Panel for RepoListView {
impl BasePanel for RepoListView {
fn panel_name(&self) -> &'static str {
"repo_list"
}
}
impl Panel for RepoListView {
fn title(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div().text_sm().child(SharedString::from("Explore"))
}
+12 -9
View File
@@ -1,7 +1,8 @@
use std::sync::Arc;
use assets::CustomIconName;
use dock::{DockArea, DockPlacement, Panel, PanelEvent, TAB_BAR_HEIGHT, title_bar_drag_handlers};
use dock::{
BasePanel, DockArea, DockPlacement, Panel, PanelEvent, TAB_BAR_HEIGHT, panel_handle,
title_bar_drag_handlers,
};
use gpui::prelude::*;
use gpui::{
App, ClickEvent, Context, ElementId, EventEmitter, FocusHandle, Focusable, Render,
@@ -74,7 +75,7 @@ impl SidebarPanel {
self.explore = Some(panel.downgrade());
let _ = self.dock_area.update(cx, |dock_area, cx| {
dock_area.add_panel(Arc::new(panel), DockPlacement::Center, window, cx);
dock_area.add_panel_view(panel_handle(panel), DockPlacement::Center, None, window, cx);
});
}
@@ -138,20 +139,22 @@ impl SidebarPanel {
}
}
impl Panel for SidebarPanel {
impl BasePanel for SidebarPanel {
fn panel_name(&self) -> &'static str {
"sidebar"
}
fn title(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
}
fn closable(&self, _cx: &App) -> bool {
false
}
}
impl Panel for SidebarPanel {
fn title(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
}
}
impl EventEmitter<PanelEvent> for SidebarPanel {}
impl Focusable for SidebarPanel {
+9 -8
View File
@@ -1,6 +1,4 @@
use std::sync::Arc;
use dock::{DockArea, DockItem};
use dock::{DockArea, DockLayout, DockPlacement, SignedDockSkin, panel_handle};
use gpui::prelude::*;
use gpui::{Context, Entity, Render, Subscription, Window, div, px};
use gpui_component::{Root, StyledExt, Theme};
@@ -19,20 +17,23 @@ pub struct Workspace {
impl Workspace {
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
let dock = cx.new(|cx| DockArea::new("dock", Some(1), window, cx));
let dock = cx.new(|cx| {
let skin = SignedDockSkin::new(cx);
DockArea::new("dock", Some(1), window, cx).with_renderer(skin)
});
let weak_dock = dock.downgrade();
let sidebar = cx.new(|cx| SidebarPanel::new(weak_dock.clone(), cx));
let weak_sidebar = sidebar.downgrade();
dock.update(cx, |dock_area, cx| {
dock_area.set_left_dock(
DockItem::panel(Arc::new(sidebar)),
Some(px(240.)),
true,
dock_area.set_dock(
DockPlacement::Left,
DockLayout::tabs().panel_view(panel_handle(sidebar), cx),
window,
cx,
);
dock_area.set_dock_size(DockPlacement::Left, px(240.), window, cx);
});
let backend = Backend::global(cx);