Use Project's EntityId as the "window id" for Alacritty PTYs (#35876)

It's unfortunate to need to have access to a GPUI window in order to
create a terminal, because it forces to take a `Window` parameter in
entities that otherwise would have been pure models.

This pull request changes it so that we pass the `Project`'s entity id,
which is equally stable as the window id.

Release Notes:

- N/A

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
This commit is contained in:
Antonio Scandurra 2025-08-08 16:30:49 +02:00 committed by GitHub
parent 95547f099c
commit 51298b6912
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 17 additions and 39 deletions

View file

@ -225,7 +225,6 @@ impl Tool for TerminalTool {
env, env,
..Default::default() ..Default::default()
}), }),
window,
cx, cx,
) )
})? })?

View file

@ -1014,10 +1014,9 @@ impl RunningState {
..task.resolved.clone() ..task.resolved.clone()
}; };
let terminal = project let terminal = project
.update_in(cx, |project, window, cx| { .update(cx, |project, cx| {
project.create_terminal( project.create_terminal(
TerminalKind::Task(task_with_shell.clone()), TerminalKind::Task(task_with_shell.clone()),
window.window_handle(),
cx, cx,
) )
})? })?
@ -1189,9 +1188,7 @@ impl RunningState {
let workspace = self.workspace.clone(); let workspace = self.workspace.clone();
let weak_project = project.downgrade(); let weak_project = project.downgrade();
let terminal_task = project.update(cx, |project, cx| { let terminal_task = project.update(cx, |project, cx| project.create_terminal(kind, cx));
project.create_terminal(kind, window.window_handle(), cx)
});
let terminal_task = cx.spawn_in(window, async move |_, cx| { let terminal_task = cx.spawn_in(window, async move |_, cx| {
let terminal = terminal_task.await?; let terminal = terminal_task.await?;

View file

@ -1,7 +1,7 @@
use crate::{Project, ProjectPath}; use crate::{Project, ProjectPath};
use anyhow::{Context as _, Result}; use anyhow::{Context as _, Result};
use collections::HashMap; use collections::HashMap;
use gpui::{AnyWindowHandle, App, AppContext as _, Context, Entity, Task, WeakEntity}; use gpui::{App, AppContext as _, Context, Entity, Task, WeakEntity};
use itertools::Itertools; use itertools::Itertools;
use language::LanguageName; use language::LanguageName;
use remote::ssh_session::SshArgs; use remote::ssh_session::SshArgs;
@ -98,7 +98,6 @@ impl Project {
pub fn create_terminal( pub fn create_terminal(
&mut self, &mut self,
kind: TerminalKind, kind: TerminalKind,
window: AnyWindowHandle,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> Task<Result<Entity<Terminal>>> { ) -> Task<Result<Entity<Terminal>>> {
let path: Option<Arc<Path>> = match &kind { let path: Option<Arc<Path>> = match &kind {
@ -134,7 +133,7 @@ impl Project {
None None
}; };
project.update(cx, |project, cx| { project.update(cx, |project, cx| {
project.create_terminal_with_venv(kind, python_venv_directory, window, cx) project.create_terminal_with_venv(kind, python_venv_directory, cx)
})? })?
}) })
} }
@ -209,7 +208,6 @@ impl Project {
&mut self, &mut self,
kind: TerminalKind, kind: TerminalKind,
python_venv_directory: Option<PathBuf>, python_venv_directory: Option<PathBuf>,
window: AnyWindowHandle,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> Result<Entity<Terminal>> { ) -> Result<Entity<Terminal>> {
let this = &mut *self; let this = &mut *self;
@ -396,7 +394,7 @@ impl Project {
settings.alternate_scroll, settings.alternate_scroll,
settings.max_scroll_history_lines, settings.max_scroll_history_lines,
is_ssh_terminal, is_ssh_terminal,
window, cx.entity_id().as_u64(),
completion_tx, completion_tx,
cx, cx,
) )

View file

@ -63,9 +63,9 @@ use std::{
use thiserror::Error; use thiserror::Error;
use gpui::{ use gpui::{
AnyWindowHandle, App, AppContext as _, Bounds, ClipboardItem, Context, EventEmitter, Hsla, App, AppContext as _, Bounds, ClipboardItem, Context, EventEmitter, Hsla, Keystroke, Modifiers,
Keystroke, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, Point, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, Point, Rgba,
Rgba, ScrollWheelEvent, SharedString, Size, Task, TouchPhase, Window, actions, black, px, ScrollWheelEvent, SharedString, Size, Task, TouchPhase, Window, actions, black, px,
}; };
use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str}; use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str};
@ -351,7 +351,7 @@ impl TerminalBuilder {
alternate_scroll: AlternateScroll, alternate_scroll: AlternateScroll,
max_scroll_history_lines: Option<usize>, max_scroll_history_lines: Option<usize>,
is_ssh_terminal: bool, is_ssh_terminal: bool,
window: AnyWindowHandle, window_id: u64,
completion_tx: Sender<Option<ExitStatus>>, completion_tx: Sender<Option<ExitStatus>>,
cx: &App, cx: &App,
) -> Result<TerminalBuilder> { ) -> Result<TerminalBuilder> {
@ -463,11 +463,7 @@ impl TerminalBuilder {
let term = Arc::new(FairMutex::new(term)); let term = Arc::new(FairMutex::new(term));
//Setup the pty... //Setup the pty...
let pty = match tty::new( let pty = match tty::new(&pty_options, TerminalBounds::default().into(), window_id) {
&pty_options,
TerminalBounds::default().into(),
window.window_id().as_u64(),
) {
Ok(pty) => pty, Ok(pty) => pty,
Err(error) => { Err(error) => {
bail!(TerminalError { bail!(TerminalError {

View file

@ -245,9 +245,8 @@ async fn deserialize_pane_group(
let kind = TerminalKind::Shell( let kind = TerminalKind::Shell(
working_directory.as_deref().map(Path::to_path_buf), working_directory.as_deref().map(Path::to_path_buf),
); );
let window = window.window_handle(); let terminal =
let terminal = project project.update(cx, |project, cx| project.create_terminal(kind, cx));
.update(cx, |project, cx| project.create_terminal(kind, window, cx));
Some(Some(terminal)) Some(Some(terminal))
} else { } else {
Some(None) Some(None)

View file

@ -432,10 +432,9 @@ impl TerminalPanel {
}) })
.unwrap_or((None, None)); .unwrap_or((None, None));
let kind = TerminalKind::Shell(working_directory); let kind = TerminalKind::Shell(working_directory);
let window_handle = window.window_handle();
let terminal = project let terminal = project
.update(cx, |project, cx| { .update(cx, |project, cx| {
project.create_terminal_with_venv(kind, python_venv_directory, window_handle, cx) project.create_terminal_with_venv(kind, python_venv_directory, cx)
}) })
.ok()?; .ok()?;
@ -666,13 +665,10 @@ impl TerminalPanel {
"terminal not yet supported for remote projects" "terminal not yet supported for remote projects"
))); )));
} }
let window_handle = window.window_handle();
let project = workspace.project().downgrade(); let project = workspace.project().downgrade();
cx.spawn_in(window, async move |workspace, cx| { cx.spawn_in(window, async move |workspace, cx| {
let terminal = project let terminal = project
.update(cx, |project, cx| { .update(cx, |project, cx| project.create_terminal(kind, cx))?
project.create_terminal(kind, window_handle, cx)
})?
.await?; .await?;
workspace.update_in(cx, |workspace, window, cx| { workspace.update_in(cx, |workspace, window, cx| {
@ -709,11 +705,8 @@ impl TerminalPanel {
terminal_panel.active_pane.clone() terminal_panel.active_pane.clone()
})?; })?;
let project = workspace.read_with(cx, |workspace, _| workspace.project().clone())?; let project = workspace.read_with(cx, |workspace, _| workspace.project().clone())?;
let window_handle = cx.window_handle();
let terminal = project let terminal = project
.update(cx, |project, cx| { .update(cx, |project, cx| project.create_terminal(kind, cx))?
project.create_terminal(kind, window_handle, cx)
})?
.await?; .await?;
let result = workspace.update_in(cx, |workspace, window, cx| { let result = workspace.update_in(cx, |workspace, window, cx| {
let terminal_view = Box::new(cx.new(|cx| { let terminal_view = Box::new(cx.new(|cx| {
@ -814,7 +807,6 @@ impl TerminalPanel {
) -> Task<Result<WeakEntity<Terminal>>> { ) -> Task<Result<WeakEntity<Terminal>>> {
let reveal = spawn_task.reveal; let reveal = spawn_task.reveal;
let reveal_target = spawn_task.reveal_target; let reveal_target = spawn_task.reveal_target;
let window_handle = window.window_handle();
let task_workspace = self.workspace.clone(); let task_workspace = self.workspace.clone();
cx.spawn_in(window, async move |terminal_panel, cx| { cx.spawn_in(window, async move |terminal_panel, cx| {
let project = terminal_panel.update(cx, |this, cx| { let project = terminal_panel.update(cx, |this, cx| {
@ -823,7 +815,7 @@ impl TerminalPanel {
})??; })??;
let new_terminal = project let new_terminal = project
.update(cx, |project, cx| { .update(cx, |project, cx| {
project.create_terminal(TerminalKind::Task(spawn_task), window_handle, cx) project.create_terminal(TerminalKind::Task(spawn_task), cx)
})? })?
.await?; .await?;
terminal_to_replace.update_in(cx, |terminal_to_replace, window, cx| { terminal_to_replace.update_in(cx, |terminal_to_replace, window, cx| {

View file

@ -1654,7 +1654,6 @@ impl Item for TerminalView {
window: &mut Window, window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> Option<Entity<Self>> { ) -> Option<Entity<Self>> {
let window_handle = window.window_handle();
let terminal = self let terminal = self
.project .project
.update(cx, |project, cx| { .update(cx, |project, cx| {
@ -1666,7 +1665,6 @@ impl Item for TerminalView {
project.create_terminal_with_venv( project.create_terminal_with_venv(
TerminalKind::Shell(working_directory), TerminalKind::Shell(working_directory),
python_venv_directory, python_venv_directory,
window_handle,
cx, cx,
) )
}) })
@ -1802,7 +1800,6 @@ impl SerializableItem for TerminalView {
window: &mut Window, window: &mut Window,
cx: &mut App, cx: &mut App,
) -> Task<anyhow::Result<Entity<Self>>> { ) -> Task<anyhow::Result<Entity<Self>>> {
let window_handle = window.window_handle();
window.spawn(cx, async move |cx| { window.spawn(cx, async move |cx| {
let cwd = cx let cwd = cx
.update(|_window, cx| { .update(|_window, cx| {
@ -1826,7 +1823,7 @@ impl SerializableItem for TerminalView {
let terminal = project let terminal = project
.update(cx, |project, cx| { .update(cx, |project, cx| {
project.create_terminal(TerminalKind::Shell(cwd), window_handle, cx) project.create_terminal(TerminalKind::Shell(cwd), cx)
})? })?
.await?; .await?;
cx.update(|window, cx| { cx.update(|window, cx| {