diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 0ac282d199..d94d82487a 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -24,6 +24,7 @@ use settings::Settings; use smallvec::SmallVec; use std::{ any::{Any, TypeId}, + borrow::Cow, cmp::Ordering, ops::Range, path::PathBuf, @@ -531,6 +532,10 @@ impl Item for ProjectDiagnosticsEditor { .update(cx, |editor, cx| editor.navigate(data, cx)) } + fn tab_tooltip_text<'a>(&'a self, _: &'a AppContext) -> Option> { + Some("Project Diagnostics".into()) + } + fn is_dirty(&self, cx: &AppContext) -> bool { self.excerpts.read(cx).is_dirty(cx) } diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 0f2a98dfe9..630b900e27 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -514,6 +514,23 @@ impl Item for Editor { } } + fn tab_tooltip_text<'a>(&self, cx: &'a AppContext) -> Option> { + let file_path = self + .buffer() + .read(cx) + .as_singleton()? + .read(cx) + .file() + .and_then(|f| f.as_local())? + .abs_path(cx); + + let file_path = util::paths::compact(&file_path) + .to_string_lossy() + .to_string(); + + Some(file_path.into()) + } + fn tab_description<'a>(&'a self, detail: usize, cx: &'a AppContext) -> Option> { match path_for_buffer(&self.buffer, detail, true, cx)? { Cow::Borrowed(path) => Some(path.to_string_lossy()), diff --git a/crates/feedback/src/feedback_editor.rs b/crates/feedback/src/feedback_editor.rs index 15334138db..c45c29c989 100644 --- a/crates/feedback/src/feedback_editor.rs +++ b/crates/feedback/src/feedback_editor.rs @@ -1,5 +1,6 @@ use std::{ any::TypeId, + borrow::Cow, ops::{Range, RangeInclusive}, sync::Arc, }; @@ -248,6 +249,10 @@ impl Entity for FeedbackEditor { } impl Item for FeedbackEditor { + fn tab_tooltip_text<'a>(&'a self, _: &'a AppContext) -> Option> { + Some("Send Feedback".into()) + } + fn tab_content(&self, _: Option, style: &theme::Tab, _: &AppContext) -> ElementBox { Flex::row() .with_child( diff --git a/crates/gpui/src/elements/tooltip.rs b/crates/gpui/src/elements/tooltip.rs index 562f12295c..2f26ee116d 100644 --- a/crates/gpui/src/elements/tooltip.rs +++ b/crates/gpui/src/elements/tooltip.rs @@ -39,7 +39,7 @@ pub struct TooltipStyle { pub container: ContainerStyle, pub text: TextStyle, keystroke: KeystrokeStyle, - pub max_text_width: f32, + pub max_text_width: Option, } #[derive(Clone, Deserialize, Default)] @@ -140,9 +140,14 @@ impl Tooltip { ) -> impl Element { Flex::row() .with_child({ - let text = Text::new(text, style.text) - .constrained() - .with_max_width(style.max_text_width); + let text = if let Some(max_text_width) = style.max_text_width { + Text::new(text, style.text) + .constrained() + .with_max_width(max_text_width) + } else { + Text::new(text, style.text).constrained() + }; + if measure { text.flex(1., false).boxed() } else { diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index c7660aa336..b57561a4cc 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -22,6 +22,7 @@ use settings::Settings; use smallvec::SmallVec; use std::{ any::{Any, TypeId}, + borrow::Cow, mem, ops::Range, path::PathBuf, @@ -225,6 +226,10 @@ impl View for ProjectSearchView { } impl Item for ProjectSearchView { + fn tab_tooltip_text<'a>(&'a self, cx: &'a AppContext) -> Option> { + Some(self.query_editor.read(cx).text(cx).into()) + } + fn act_as_type<'a>( &'a self, type_id: TypeId, diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 3af147b9ff..99f15c126e 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -3,6 +3,7 @@ pub mod terminal_button; pub mod terminal_element; use std::{ + borrow::Cow, ops::RangeInclusive, path::{Path, PathBuf}, time::Duration, @@ -543,6 +544,10 @@ impl View for TerminalView { } impl Item for TerminalView { + fn tab_tooltip_text<'a>(&'a self, cx: &'a AppContext) -> Option> { + Some(self.terminal().read(cx).title().into()) + } + fn tab_content( &self, _detail: Option, diff --git a/crates/welcome/src/welcome.rs b/crates/welcome/src/welcome.rs index 28b0e43c57..114f3eb88e 100644 --- a/crates/welcome/src/welcome.rs +++ b/crates/welcome/src/welcome.rs @@ -1,6 +1,6 @@ mod base_keymap_picker; -use std::sync::Arc; +use std::{borrow::Cow, sync::Arc}; use db::kvp::KEY_VALUE_STORE; use gpui::{ @@ -198,6 +198,10 @@ impl WelcomePage { } impl Item for WelcomePage { + fn tab_tooltip_text<'a>(&'a self, _: &'a AppContext) -> Option> { + Some("Welcome to Zed!".into()) + } + fn tab_content( &self, _detail: Option, diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs index f7ffe64f97..347a0022cc 100644 --- a/crates/workspace/src/item.rs +++ b/crates/workspace/src/item.rs @@ -44,6 +44,9 @@ pub trait Item: View { fn navigate(&mut self, _: Box, _: &mut ViewContext) -> bool { false } + fn tab_tooltip_text<'a>(&'a self, _: &'a AppContext) -> Option> { + None + } fn tab_description<'a>(&'a self, _: usize, _: &'a AppContext) -> Option> { None } @@ -162,6 +165,7 @@ pub trait ItemHandle: 'static + fmt::Debug { cx: &mut AppContext, handler: Box, ) -> gpui::Subscription; + fn tab_tooltip_text<'a>(&self, cx: &'a AppContext) -> Option>; fn tab_description<'a>(&self, detail: usize, cx: &'a AppContext) -> Option>; fn tab_content(&self, detail: Option, style: &theme::Tab, cx: &AppContext) -> ElementBox; @@ -248,6 +252,10 @@ impl ItemHandle for ViewHandle { }) } + fn tab_tooltip_text<'a>(&self, cx: &'a AppContext) -> Option> { + self.read(cx).tab_tooltip_text(cx) + } + fn tab_description<'a>(&self, detail: usize, cx: &'a AppContext) -> Option> { self.read(cx).tab_description(detail, cx) } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index a54aed96f4..c394ae4631 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -1386,6 +1386,9 @@ impl Pane { let detail = detail.clone(); let theme = cx.global::().theme.clone(); + let mut tooltip_theme = theme.tooltip.clone(); + tooltip_theme.max_text_width = None; + let tab_tooltip_text = item.tab_tooltip_text(cx).map(|a| a.to_string()); move |mouse_state, cx| { let tab_style = @@ -1393,39 +1396,56 @@ impl Pane { let hovered = mouse_state.hovered(); enum Tab {} - MouseEventHandler::::new(ix, cx, |_, cx| { - Self::render_tab( - &item, - pane.clone(), - ix == 0, - detail, - hovered, - tab_style, - cx, - ) - }) - .on_down(MouseButton::Left, move |_, cx| { - cx.dispatch_action(ActivateItem(ix)); - }) - .on_click(MouseButton::Middle, { - let item = item.clone(); - let pane = pane.clone(); - move |_, cx: &mut EventContext| { - cx.dispatch_action(CloseItemById { - item_id: item.id(), - pane: pane.clone(), - }) - } - }) - .on_down(MouseButton::Right, move |e, cx| { - let item = item.clone(); - cx.dispatch_action(DeployTabContextMenu { - position: e.position, - item_id: item.id(), - pane: pane.clone(), - }); - }) - .boxed() + let mouse_event_handler = + MouseEventHandler::::new(ix, cx, |_, cx| { + Self::render_tab( + &item, + pane.clone(), + ix == 0, + detail, + hovered, + tab_style, + cx, + ) + }) + .on_down(MouseButton::Left, move |_, cx| { + cx.dispatch_action(ActivateItem(ix)); + }) + .on_click(MouseButton::Middle, { + let item = item.clone(); + let pane = pane.clone(); + move |_, cx: &mut EventContext| { + cx.dispatch_action(CloseItemById { + item_id: item.id(), + pane: pane.clone(), + }) + } + }) + .on_down( + MouseButton::Right, + move |e, cx| { + let item = item.clone(); + cx.dispatch_action(DeployTabContextMenu { + position: e.position, + item_id: item.id(), + pane: pane.clone(), + }); + }, + ); + + if let Some(tab_tooltip_text) = tab_tooltip_text { + return mouse_event_handler + .with_tooltip::( + ix, + tab_tooltip_text, + None, + tooltip_theme, + cx, + ) + .boxed(); + } + + mouse_event_handler.boxed() } }); diff --git a/crates/workspace/src/shared_screen.rs b/crates/workspace/src/shared_screen.rs index 7f7bf3b25f..a1dcb89e44 100644 --- a/crates/workspace/src/shared_screen.rs +++ b/crates/workspace/src/shared_screen.rs @@ -13,7 +13,10 @@ use gpui::{ }; use settings::Settings; use smallvec::SmallVec; -use std::sync::{Arc, Weak}; +use std::{ + borrow::Cow, + sync::{Arc, Weak}, +}; pub enum Event { Close, @@ -92,6 +95,9 @@ impl View for SharedScreen { } impl Item for SharedScreen { + fn tab_tooltip_text<'a>(&'a self, _: &'a AppContext) -> Option> { + Some(format!("{}'s screen", self.user.github_login).into()) + } fn deactivated(&mut self, cx: &mut ViewContext) { if let Some(nav_history) = self.nav_history.as_ref() { nav_history.push::<()>(None, cx);