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 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-09-27 01:35:56 +12:00
parent d7036ad807
commit 6bcdb87524
2 changed files with 30 additions and 0 deletions
+26
View File
@@ -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);
}
}
+4
View File
@@ -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<QAction *> 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;