fix(tabs): renommer l'onglet du bon panneau en multi-panneaux

Le renommage d'onglet visait le panneau actif au moment de la validation
et non celui ou le renommage avait ete ouvert. L'ouverture appelle
unfocus_all_terminals(), si bien que `pane_model.active()` pouvait
designer un autre panneau au moment du commit : en configuration
scindee, le nouveau titre atterrissait sur l'onglet d'un panneau voisin.

`rename_tab` memorise desormais le panneau : (Pane, Entity, String) au
lieu de (Entity, String). L'ouverture le capture via focused(), et
commit, annulation et remise a zero le retrouvent par
panes.get(pane) au lieu de active_mut(). Le focus est rendu au panneau
d'origine via set_focus(pane) plutot que par update_terminal_focus(),
qui le laissait au petit bonheur.

Reprend le stash de 2026-06-13, fait sur 39d3d01. Le seul conflit
portait sur dialog(), ou la branche a gagne depuis le dialogue de
chargement de disposition : les deux sont conserves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lionel DARNIS 2026-08-07 19:39:48 +02:00
parent d6a398411e
commit abd415723c

View file

@ -665,7 +665,7 @@ pub struct App {
color_scheme_expanded: Option<(ColorSchemeKind, Option<ColorSchemeId>)>,
color_scheme_renaming: Option<(ColorSchemeKind, ColorSchemeId, String)>,
color_scheme_rename_id: widget::Id,
rename_tab: Option<(segmented_button::Entity, String)>,
rename_tab: Option<(pane_grid::Pane, segmented_button::Entity, String)>,
rename_tab_id: widget::Id,
layout_load_pending: Option<LayoutNode>,
ssh_hosts: Vec<String>,
@ -3591,26 +3591,28 @@ impl Application for App {
return self.update(Message::TabRenameOpen(Some(entity)));
}
Message::TabRenameOpen(entity_opt) => {
if let Some(tab_model) = self.pane_model.active() {
let pane = self.pane_model.focused();
if let Some(tab_model) = self.pane_model.panes.get(pane) {
let entity = entity_opt.unwrap_or_else(|| tab_model.active());
let initial = tab_model
.text(entity)
.map(|s| s.to_string())
.unwrap_or_default();
self.rename_tab = Some((entity, initial));
self.rename_tab = Some((pane, entity, initial));
self.pane_model.unfocus_all_terminals();
return self.update_focus();
}
}
Message::TabRenameInput(value) => {
if let Some((_, buffer)) = self.rename_tab.as_mut() {
if let Some((_, _, buffer)) = self.rename_tab.as_mut() {
*buffer = value;
}
}
Message::TabRenameCommit => {
if let Some((entity, value)) = self.rename_tab.take() {
if let Some((pane, entity, value)) = self.rename_tab.take() {
let trimmed = value.trim().to_string();
if let Some(tab_model) = self.pane_model.active_mut() {
let mut renamed = false;
if let Some(tab_model) = self.pane_model.panes.get_mut(pane) {
if trimmed.is_empty() {
if let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity) {
terminal.lock().unwrap().tab_title_override = None;
@ -3622,25 +3624,37 @@ impl Application for App {
}
tab_model.text_set(entity, trimmed);
}
renamed = true;
}
if renamed {
self.pane_model.set_focus(pane);
}
self.pane_model.update_terminal_focus();
return self.update_title(None);
}
}
Message::TabRenameCancel => {
self.rename_tab = None;
if let Some((pane, _, _)) = self.rename_tab.take()
&& self.pane_model.panes.get(pane).is_some()
{
self.pane_model.set_focus(pane);
return self.update_title(None);
}
self.pane_model.update_terminal_focus();
}
Message::TabRenameResetToDefault => {
if let Some((entity, _)) = self.rename_tab.take()
&& let Some(tab_model) = self.pane_model.active_mut()
{
if let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity) {
terminal.lock().unwrap().tab_title_override = None;
if let Some((pane, entity, _)) = self.rename_tab.take() {
let mut reset = false;
if let Some(tab_model) = self.pane_model.panes.get_mut(pane) {
if let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity) {
terminal.lock().unwrap().tab_title_override = None;
}
tab_model.text_set(entity, fl!("new-terminal"));
reset = true;
}
if reset {
self.pane_model.set_focus(pane);
return self.update_title(None);
}
tab_model.text_set(entity, fl!("new-terminal"));
self.pane_model.update_terminal_focus();
return self.update_title(None);
}
self.pane_model.update_terminal_focus();
}
@ -3712,7 +3726,7 @@ impl Application for App {
tab_title_override.unwrap_or_else(|| fl!("new-terminal")),
);
}
return self.update_title(Some(pane));
return self.update_title(None);
}
TermEvent::TextAreaSizeRequest(f) => {
if let Some(tab_model) = self.pane_model.panes.get(pane)
@ -3736,7 +3750,7 @@ impl Application for App {
tab_model.text_set(entity, title);
}
}
return self.update_title(Some(pane));
return self.update_title(None);
}
TermEvent::MouseCursorDirty => {
if let Some(tab_model) = self.pane_model.panes.get(pane)
@ -4011,7 +4025,7 @@ impl Application for App {
);
}
if let Some((_, buffer)) = self.rename_tab.as_ref() {
if let Some((_, _, buffer)) = self.rename_tab.as_ref() {
let input = widget::text_input(fl!("tab-name-placeholder"), buffer)
.id(self.rename_tab_id.clone())
.on_input(Message::TabRenameInput)
@ -4132,6 +4146,7 @@ impl Application for App {
.button_spacing(space_xxs)
.on_activate(Message::TabActivate)
.on_close(|entity| Message::TabClose(Some(entity)))
.on_double_click(move |entity| Message::TabRenameOpenForPane(pane, entity))
.on_context(move |entity| Message::TabRenameOpenForPane(pane, entity)),
)
.class(style::Container::Custom(Box::new(|theme| {