Copier-coller a la souris comme dans un terminal Unix

Selectionner copie aussitot au relachement du bouton, et le clic droit colle
directement. Plus de menu contextuel ni de raccourci a connaitre : c'est le
comportement des terminaux Unix et de PuTTY.

- selection relachee, et double-clic sur un mot, copient dans la foulee
- clic droit et clic molette collent immediatement
- un simple clic sans deplacement se contente d'annuler la selection, sans
  toucher au presse-papiers : sinon il ecraserait ce qu'on s'apprete a coller
- le menu contextuel est supprime, le clic droit etant desormais un collage
- "Tout selectionner" passe sur Ctrl+Maj+A, Ctrl+A restant "debut de ligne"
  pour le shell

Les raccourcis clavier restent disponibles pour qui les prefere.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
snoopy
2026-09-04 16:30:17 +02:00
parent fbf7f580bc
commit f641357073
3 changed files with 58 additions and 25 deletions

View File

@@ -11,9 +11,9 @@ from __future__ import annotations
import pyte
from PySide6.QtCore import QRect, Qt, Signal
from PySide6.QtGui import (
QColor, QFont, QFontMetrics, QPainter, QKeyEvent, QWheelEvent, QKeySequence,
QColor, QFont, QFontMetrics, QPainter, QKeyEvent, QWheelEvent,
)
from PySide6.QtWidgets import QWidget, QMenu, QApplication, QScrollBar
from PySide6.QtWidgets import QWidget, QApplication, QScrollBar
from app import theme as app_theme
@@ -478,6 +478,10 @@ class TerminalWidget(QWidget):
if key == Qt.Key_V:
self.paste_clipboard()
return
if key == Qt.Key_A:
# Ctrl+A seul reste "debut de ligne" pour le shell
self.select_all()
return
if key == Qt.Key_Insert and (modifiers & Qt.ShiftModifier):
self.paste_clipboard()
return
@@ -551,8 +555,10 @@ class TerminalWidget(QWidget):
self._sel_anchor = self._sel_focus = self._cell_at(event.position().toPoint())
self._selecting = True
self.update()
elif event.button() == Qt.MiddleButton:
self.paste_clipboard() # habitude Unix : clic molette = coller
elif event.button() in (Qt.RightButton, Qt.MiddleButton):
# Comportement des terminaux Unix (et de PuTTY) : le clic droit colle
# directement, sans passer par un menu.
self.paste_clipboard()
super().mousePressEvent(event)
def mouseMoveEvent(self, event) -> None:
@@ -564,9 +570,14 @@ class TerminalWidget(QWidget):
def mouseReleaseEvent(self, event) -> None:
if event.button() == Qt.LeftButton:
self._selecting = False
# un simple clic (sans deplacement) annule la selection
if self._sel_anchor == self._sel_focus:
# simple clic sans deplacement : on annule la selection sans toucher
# au presse-papiers, qui contient peut-etre ce qu'on s'apprete a coller
self.clear_selection()
else:
# Comportement des terminaux Unix : relacher la souris apres une
# selection copie immediatement, sans raccourci ni menu.
self.copy_selection()
super().mouseReleaseEvent(event)
def mouseDoubleClickEvent(self, event) -> None:
@@ -584,22 +595,9 @@ class TerminalWidget(QWidget):
end += 1
self._sel_anchor, self._sel_focus = (start, row), (end, row)
self.update()
self.copy_selection() # comme la selection a la souris : copie immediate
def contextMenuEvent(self, event) -> None:
menu = QMenu(self)
copy_action = menu.addAction("Copier")
copy_action.setShortcut(QKeySequence("Ctrl+Shift+C"))
copy_action.setEnabled(self.has_selection())
paste_action = menu.addAction("Coller")
paste_action.setShortcut(QKeySequence("Ctrl+Shift+V"))
paste_action.setEnabled(bool(QApplication.clipboard().text()))
menu.addSeparator()
select_all_action = menu.addAction("Tout selectionner")
action = menu.exec(event.globalPos())
if action == copy_action:
self.copy_selection()
elif action == paste_action:
self.paste_clipboard()
elif action == select_all_action:
self.select_all()
# Pas de menu contextuel : dans un terminal Unix le clic droit colle,
# et il est traite dans mousePressEvent.
event.ignore()