yoda: copie a la selection vers le presse-papiers, a la Ghostty

La selection n'allait que dans la selection primaire (clic du milieu) ;
pour la coller avec Ctrl+V ailleurs, il fallait Ctrl+Shift+C. Reprise de
copy-on-select = clipboard de Ghostty, le reglage de l'ancienne config
Ghostty de Lionel.

- Config copy_on_select_clipboard (desactive par defaut, comme l'amont) ;
  case dans Reglages > Avance.
- terminal_box::on_selection_done : publie a la fin d'un geste de
  selection fait dans le panneau (glisser, double/triple clic, Shift+
  clic), pas a chaque relachement du bouton gauche. La copie primaire
  existante part elle a tout relachement dans la fenetre : la recopier
  dans le presse-papiers ecraserait, au simple clic sur un onglet, ce
  qu'on vient de copier ailleurs avec une vieille selection.
- Message::SelectionDone : copie la selection de cet onglet ; une
  selection vide (simple clic) ne donne pas de texte (range_simple).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lionel DARNIS 2026-10-01 14:38:17 +02:00
parent a035b47e98
commit 9b10e98ab1
5 changed files with 56 additions and 0 deletions

View file

@ -600,6 +600,8 @@ pub enum Message {
SyntaxTheme(ColorSchemeKind, usize),
SystemThemeChange,
TabNewInheritWorkingDirectory(bool),
CopyOnSelectClipboard(bool),
SelectionDone(pane_grid::Pane, segmented_button::Entity),
TabActivate(segmented_button::Entity),
TabActivateJump(usize),
TabClose(Option<segmented_button::Entity>),
@ -1759,6 +1761,14 @@ impl App {
self.config.tab_new_inherit_working_directory,
Message::TabNewInheritWorkingDirectory,
),
)
.add(
widget::settings::item::builder(fl!("copy-on-select-clipboard"))
.description(fl!("copy-on-select-clipboard-description"))
.toggler(
self.config.copy_on_select_clipboard,
Message::CopyOnSelectClipboard,
),
);
widget::settings::view_column(vec![
@ -3404,6 +3414,24 @@ impl Application for App {
return self.update_config();
}
}
Message::CopyOnSelectClipboard(copy_on_select_clipboard) => {
if copy_on_select_clipboard != self.config.copy_on_select_clipboard {
config_set!(copy_on_select_clipboard, copy_on_select_clipboard);
}
}
Message::SelectionDone(pane, entity) => {
// [yoda] Copie à la sélection vers le presse-papiers ; la
// sélection primaire, elle, suit le relâchement du bouton.
if self.config.copy_on_select_clipboard
&& let Some(tab_model) = self.pane_model.panes.get(pane)
&& let Some(terminal) = tab_model.data::<Mutex<Terminal>>(entity)
{
let text = terminal.lock().unwrap().term.lock().selection_to_string();
if let Some(text) = text.filter(|text| !text.is_empty()) {
return clipboard::write(text);
}
}
}
Message::TabNewInheritWorkingDirectory(tab_new_inherit_working_directory) => {
config_set!(
tab_new_inherit_working_directory,
@ -4298,6 +4326,11 @@ impl Application for App {
terminal_box = terminal_box.on_mouse_enter(move || Message::MouseEnter(pane));
}
if self.config.copy_on_select_clipboard {
terminal_box =
terminal_box.on_selection_done(move || Message::SelectionDone(pane, entity));
}
// [yoda] Voile sur les panneaux non focalisés (à la Ghostty), seulement
// quand il y en a plusieurs : on voit d'un coup d'œil où l'on tape.
if let Some(dim) = self.config.unfocused_pane_dim_ratio()