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