Keep mouse gestures working while a tool is running

Most commands on the empty-folio ring start a drawing tool, and the view
left the right button alone while a tool ran, so the gesture after one
that started a tool only cancelled the tool: every other gesture opened
the context menu instead of the ring.

Now a right drag always shows the ring. A running tool is ended when the
drag starts, as picking another tool from the toolbar would. A plain
right click still goes to the tool, which cancels or finishes it as
before.

Discussion #1033.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G2d2Zi8BfrYRPX88zhaoFG
This commit is contained in:
ispyisail
2026-09-27 01:34:55 +12:00
parent 501379def2
commit f850d0bee8
2 changed files with 47 additions and 18 deletions
+45 -18
View File
@@ -640,33 +640,43 @@ void DiagramView::mousePressEvent(QMouseEvent *e)
} }
//Right button: a click opens the context menu on release, a drag is //Right button: a click opens the context menu on release, a drag is
//a gesture (DiagramGestureOverlay). Left alone while a tool runs -- //a gesture (DiagramGestureOverlay). Left alone while a text is edited.
//a right click cancels or finishes it -- and while a text is edited.
m_swallow_native_menu = false; m_swallow_native_menu = false;
m_gesture_over_tool = false;
if (e->button() == Qt::RightButton if (e->button() == Qt::RightButton
&& DiagramGestureOverlay::isEnabled() && DiagramGestureOverlay::isEnabled()
&& !m_diagram->eventInterfaceIsRunning()
&& !m_diagram->focusItem()) && !m_diagram->focusItem())
{ {
m_gesture_tracking = true; m_gesture_tracking = true;
m_swallow_native_menu = true;
m_gesture_origin = e->position().toPoint(); m_gesture_origin = e->position().toPoint();
m_context_toolbar->hide(); m_context_toolbar->hide();
//Select what is under the mouse, as the context menu does, so //A tool is running, often one a gesture just started. A right
//a gesture acts on it //click still goes to it -- it cancels or finishes the tool -- so
if (QGraphicsItem *item = m_diagram->itemAt(mapToScene(m_gesture_origin), transform())) { //the press carries on to the scene. A drag ends the tool and
if (!item->isSelected()) { //shows the ring (see mouseMoveEvent).
m_diagram->clearSelection(); if (m_diagram->eventInterfaceIsRunning()) {
//Clearing the selection can delete handler items, so m_gesture_over_tool = true;
//look the item up again (see contextMenuEvent) }
if (QGraphicsItem *again = m_diagram->itemAt(mapToScene(m_gesture_origin), transform())) { else
again->setSelected(true); {
m_swallow_native_menu = true;
//Select what is under the mouse, as the context menu does, so
//a gesture acts on it
if (QGraphicsItem *item = m_diagram->itemAt(mapToScene(m_gesture_origin), transform())) {
if (!item->isSelected()) {
m_diagram->clearSelection();
//Clearing the selection can delete handler items, so
//look the item up again (see contextMenuEvent)
if (QGraphicsItem *again = m_diagram->itemAt(mapToScene(m_gesture_origin), transform())) {
again->setSelected(true);
}
} }
} }
e->accept();
return;
} }
e->accept();
return;
} }
//Start drag view when hold the middle button //Start drag view when hold the middle button
@@ -725,13 +735,24 @@ void DiagramView::mouseMoveEvent(QMouseEvent *e)
const QPoint pos = e->position().toPoint(); const QPoint pos = e->position().toPoint();
if (!m_gesture_overlay->isVisible() if (!m_gesture_overlay->isVisible()
&& (pos - m_gesture_origin).manhattanLength() > 2 * QApplication::startDragDistance()) { && (pos - m_gesture_origin).manhattanLength() > 2 * QApplication::startDragDistance()) {
if (m_gesture_over_tool) {
//The drag is a gesture: end the tool, and ignore the
//platform's right-click menu like any other gesture
m_diagram->clearEventInterface();
m_swallow_native_menu = true;
}
m_gesture_overlay->showAt(m_gesture_origin, selectionCommands()); m_gesture_overlay->showAt(m_gesture_origin, selectionCommands());
} }
if (m_gesture_overlay->isVisible()) { if (m_gesture_overlay->isVisible()) {
m_gesture_overlay->setPointer(pos); m_gesture_overlay->setPointer(pos);
e->accept();
return;
}
//Not a drag yet: a running tool keeps following the mouse
if (!m_gesture_over_tool) {
e->accept();
return;
} }
e->accept();
return;
} }
// Drag the view // Drag the view
@@ -795,7 +816,10 @@ void DiagramView::mouseReleaseEvent(QMouseEvent *e)
{ {
if (m_event_interface && m_event_interface->mouseReleaseEvent(e)) return; if (m_event_interface && m_event_interface->mouseReleaseEvent(e)) return;
if (m_gesture_tracking && e->button() == Qt::RightButton) //A plain right click on a running tool falls through: the tool
//handles it, as it always has
if (m_gesture_tracking && e->button() == Qt::RightButton
&& !(m_gesture_over_tool && !m_gesture_overlay->isVisible()))
{ {
m_gesture_tracking = false; m_gesture_tracking = false;
const QPoint pos = e->position().toPoint(); const QPoint pos = e->position().toPoint();
@@ -822,6 +846,9 @@ void DiagramView::mouseReleaseEvent(QMouseEvent *e)
e->accept(); e->accept();
return; return;
} }
if (e->button() == Qt::RightButton) {
m_gesture_tracking = false;
}
// Stop drag view // Stop drag view
if (e->button() == Qt::MiddleButton) if (e->button() == Qt::MiddleButton)
+2
View File
@@ -66,6 +66,8 @@ class DiagramView : public PaletteGraphicsView
/// the view opens the menu itself on release /// the view opens the menu itself on release
bool m_swallow_native_menu = false; bool m_swallow_native_menu = false;
bool m_menu_from_gesture = false; bool m_menu_from_gesture = false;
/// The right press went to a running tool; a drag ends the tool
bool m_gesture_over_tool = false;
QPoint m_gesture_origin; QPoint m_gesture_origin;
DiagramGestureOverlay *m_gesture_overlay = nullptr; DiagramGestureOverlay *m_gesture_overlay = nullptr;
QPoint m_last_mouse_pos = QPoint(-1, -1); QPoint m_last_mouse_pos = QPoint(-1, -1);