Fix orphaned arrows when the draw shortcut repeats (#6789)

Holding or spamming the draw-arrow shortcut fires the action again
before the previous local arrow has been placed. Every new arrow takes
the mouse grab from the previous one, so the previous arrow never
receives the release that deletes it. If the cursor had passed over a
card meanwhile, the orphan stayed visible on the board.

Track the in-progress arrow on the CardItem that started it and cancel
it, together with any child arrows, before starting a new one. The
attach-arrow shortcut (Ctrl+Alt+A) uses the same path, so it no longer
leaks arrows either.

Fixes #4329.

Co-authored-by: mb <mbaecker@unforce.de>
This commit is contained in:
unf0rce 2026-11-07 16:53:53 +01:00 • committed by GitHub
parent 01572bfce2
commit 80986266b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 78 additions and 23 deletions

View file

@ -294,6 +294,13 @@ void CardItem::drawArrow(const QColor &arrowColor)
return;
}
// A held shortcut repeats the action before the previous arrow is placed.
// That arrow has lost the mouse grab to the new one, so it would never
// receive the release that deletes it; discard it (and its children).
if (pendingArrow) {
pendingArrow->cancel();
}
auto *game = owner->getGame();
PlayerLogic *arrowOwner = game->getPlayerManager()->getActiveLocalPlayer(game->getGameState()->getActivePlayer());
int phase = 0; // 0 means to not set the phase
@ -303,6 +310,7 @@ void CardItem::drawArrow(const QColor &arrowColor)
}
ArrowDragItem *arrow = new ArrowDragItem(arrowOwner, this, arrowColor, phase);
scene()->addItem(arrow);
pendingArrow = arrow;
arrow->grabMouse();
for (const auto &item : scene()->selectedItems()) {
@ -326,8 +334,14 @@ void CardItem::drawAttachArrow()
return;
}
// See drawArrow(): a repeated trigger must not orphan the previous arrow.
if (pendingArrow) {
pendingArrow->cancel();
}
auto *arrow = new ArrowAttachItem(this);
scene()->addItem(arrow);
pendingArrow = arrow;
arrow->grabMouse();
for (const auto &item : scene()->selectedItems()) {