From 6bcdb875244b2bd57e795ec68e24bb0c6ea0e1f3 Mon Sep 17 00:00:00 2001 From: ispyisail Date: Sun, 27 Sep 2026 01:35:56 +1200 Subject: [PATCH] Fix the folio staying in pan mode after a Ctrl+Shift shortcut Holding Ctrl+Shift over a folio pans it, and only a key release seen by the view ends that. A Ctrl+Shift shortcut that opens a window -- the command search, Ctrl+Shift+M -- takes the keyboard before Ctrl and Shift are released, so the view never sees the release. On Windows, where the Shift press itself already reports Ctrl+Shift, the folio then stayed in pan mode after a command was chosen: a hand cursor, and clicks ignored, so a drawing tool picked from the search did nothing. On Linux the Enter key's release happened to reach the view and end it. The view now remembers that it pans because of Ctrl+Shift (not because the hand tool was chosen) and stops when it loses the focus, or at a click made without Ctrl+Shift, instead of waiting for a release it may never get. Reproduced on Linux by holding back Enter's release, as Windows does: the line drawn after "Ctrl+Shift+M, une ligne, Enter" is not saved on master and is with this change. Ctrl+Shift+drag and the hand tool still pan (a dragged step does not move), as on master. Co-Authored-By: Claude Opus 5.5 --- sources/diagramview.cpp | 26 ++++++++++++++++++++++++++ sources/diagramview.h | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index 2ccb6daa7..1cd5b5721 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -316,6 +316,7 @@ void DiagramView::handleTextDrop(QDropEvent *e) { */ void DiagramView::setVisualisationMode() { + m_ctrl_shift_panning = false; setDragMode(ScrollHandDrag); applyReadOnly(); setInteractive(false); @@ -327,6 +328,7 @@ void DiagramView::setVisualisationMode() */ void DiagramView::setSelectionMode() { + m_ctrl_shift_panning = false; setDragMode(RubberBandDrag); setInteractive(true); applyReadOnly(); @@ -557,6 +559,12 @@ void DiagramView::mousePressEvent(QMouseEvent *e) { e->ignore(); + //Ctrl+Shift panning whose key release was missed (see + //focusOutEvent()): a click without them ends it + if (m_ctrl_shift_panning && !isCtrlShifting(e)) { + setSelectionMode(); + } + if (m_fresh_focus_in) { switchToVisualisationModeIfNeeded(e); @@ -801,6 +809,23 @@ void DiagramView::focusInEvent(QFocusEvent *e) { } } +/** + @brief DiagramView::focusOutEvent + Leave the Ctrl+Shift panning: without the focus, the view will not see + Ctrl or Shift being released, which is what normally ends it. A + Ctrl+Shift shortcut that opens a window (Ctrl+Shift+M, the command + search) left the view panning, ignoring clicks on the folio, on Windows, + where no other key release reached the view to end it. + @param e +*/ +void DiagramView::focusOutEvent(QFocusEvent *e) +{ + if (m_ctrl_shift_panning) { + setSelectionMode(); + } + PaletteGraphicsView::focusOutEvent(e); +} + /** @brief DiagramView::focusNextPrevChild By default, QWidget intercepts Tab/Shift+Tab to move keyboard focus to @@ -1396,6 +1421,7 @@ bool DiagramView::switchToVisualisationModeIfNeeded(QInputEvent *e) { if (isCtrlShifting(e) && !selectedItemHasFocus()) { if (dragMode() != QGraphicsView::ScrollHandDrag) { setVisualisationMode(); + m_ctrl_shift_panning = true; return(true); } } diff --git a/sources/diagramview.h b/sources/diagramview.h index f2abdd505..1b641d72f 100644 --- a/sources/diagramview.h +++ b/sources/diagramview.h @@ -60,6 +60,9 @@ class DiagramView : public PaletteGraphicsView QPointF m_drag_last_pos; bool m_fresh_focus_in, m_first_activation = true; + /// True while the view pans because Ctrl+Shift is held, as opposed + /// to the visualisation mode chosen from the toolbar. + bool m_ctrl_shift_panning = false; QList m_separators; QPolygonF m_free_rubberband; bool m_free_rubberbanding = false; @@ -93,6 +96,7 @@ class DiagramView : public PaletteGraphicsView void contextMenuEvent(QContextMenuEvent *) override; void wheelEvent(QWheelEvent *) override; void focusInEvent(QFocusEvent *) override; + void focusOutEvent(QFocusEvent *) override; void keyPressEvent(QKeyEvent *) override; void keyReleaseEvent(QKeyEvent *) override; bool event(QEvent *) override;