diff --git a/crates/terminal/src/pty_info.rs b/crates/terminal/src/pty_info.rs index 559d022fda8a0..6478cb4ad87c9 100644 --- a/crates/terminal/src/pty_info.rs +++ b/crates/terminal/src/pty_info.rs @@ -10,7 +10,7 @@ use windows::Win32::{Foundation::HANDLE, System::Threading::GetProcessId}; use sysinfo::{Pid, Process, ProcessRefreshKind, RefreshKind, System, UpdateKind}; -struct ProcessIdGetter { +pub struct ProcessIdGetter { handle: i32, fallback_pid: u32, } @@ -31,6 +31,10 @@ impl ProcessIdGetter { } Some(Pid::from_u32(pid as u32)) } + + pub fn fallback_pid(&self) -> u32 { + self.fallback_pid + } } #[cfg(windows)] @@ -62,6 +66,10 @@ impl ProcessIdGetter { } Some(Pid::from_u32(pid)) } + + pub fn fallback_pid(&self) -> u32 { + self.fallback_pid + } } #[derive(Clone, Debug)] @@ -96,6 +104,10 @@ impl PtyProcessInfo { } } + pub fn pid_getter(&self) -> &ProcessIdGetter { + &self.pid_getter + } + fn refresh(&mut self) -> Option<&Process> { let pid = self.pid_getter.pid()?; if self.system.refresh_processes_specifics( diff --git a/crates/terminal_view/src/terminal_tab_tooltip.rs b/crates/terminal_view/src/terminal_tab_tooltip.rs new file mode 100644 index 0000000000000..69150f0b9a513 --- /dev/null +++ b/crates/terminal_view/src/terminal_tab_tooltip.rs @@ -0,0 +1,36 @@ +use gpui::{IntoElement, Render, ViewContext}; +use ui::{prelude::*, tooltip_container, Divider}; + +pub struct TerminalTooltip { + title: SharedString, + pid: u32, +} + +impl TerminalTooltip { + pub fn new(title: impl Into, pid: u32) -> Self { + Self { + title: title.into(), + pid, + } + } +} + +impl Render for TerminalTooltip { + fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { + tooltip_container(cx, move |this, _cx| { + this.occlude() + .on_mouse_move(|_, cx| cx.stop_propagation()) + .child( + v_flex() + .gap_1() + .child(Label::new(self.title.clone())) + .child(Divider::horizontal()) + .child( + Label::new(format!("Process ID (PID): {}", self.pid)) + .color(Color::Muted) + .size(LabelSize::Small), + ), + ) + }) + } +} diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 5a55cf6e81a90..63958bd839040 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -1,6 +1,7 @@ mod persistence; pub mod terminal_element; pub mod terminal_panel; +pub mod terminal_tab_tooltip; use collections::HashSet; use editor::{actions::SelectAll, scroll::Autoscroll, Editor}; @@ -26,13 +27,16 @@ use terminal::{ }; use terminal_element::{is_blank, TerminalElement}; use terminal_panel::TerminalPanel; +use terminal_tab_tooltip::TerminalTooltip; use ui::{h_flex, prelude::*, ContextMenu, Icon, IconName, Label, Tooltip}; use util::{ paths::{PathWithPosition, SanitizedPath}, ResultExt, }; use workspace::{ - item::{BreadcrumbText, Item, ItemEvent, SerializableItem, TabContentParams}, + item::{ + BreadcrumbText, Item, ItemEvent, SerializableItem, TabContentParams, TabTooltipContent, + }, register_serializable_item, searchable::{SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle}, CloseActiveItem, NewCenterTerminal, NewTerminal, OpenVisible, ToolbarItemLocation, Workspace, @@ -996,8 +1000,17 @@ impl Render for TerminalView { impl Item for TerminalView { type Event = ItemEvent; - fn tab_tooltip_text(&self, cx: &AppContext) -> Option { - Some(self.terminal().read(cx).title(false).into()) + fn tab_tooltip_content(&self, cx: &AppContext) -> Option { + let terminal = self.terminal().read(cx); + let title = terminal.title(false); + let pid = terminal.pty_info.pid_getter().fallback_pid(); + + Some(TabTooltipContent::Custom(Box::new( + move |cx: &mut WindowContext| { + cx.new_view(|_| TerminalTooltip::new(title.clone(), pid)) + .into() + }, + ))) } fn tab_content(&self, params: TabContentParams, cx: &WindowContext) -> AnyElement {