Commit 10653411 authored by Tusooa Zhu's avatar Tusooa Zhu 🔼

Fix a crash when undoing with DefaultTool active

DefaultTool::updateActions() might be executed in the
gui thread when the layer has gone through changes in
the image thread. Old shapes might have already be
deleted, which causes use-after-free. We fixed this by
locking the shape layer canvas in updateActions().
parent 4f2bafc5
......@@ -1600,51 +1600,55 @@ void DefaultTool::updateActions()
{
QList<KoShape*> editableShapes;
if (koSelection()) {
editableShapes = koSelection()->selectedEditableShapes();
}
{
QScopedPointer<KisLockableCanvas::Locker> lock(shapeManager()->obtainLock());
if (koSelection()) {
editableShapes = koSelection()->selectedEditableShapes();
}
const bool hasEditableShapes = !editableShapes.isEmpty();
const bool hasEditableShapes = !editableShapes.isEmpty();
action("object_order_front")->setEnabled(hasEditableShapes);
action("object_order_raise")->setEnabled(hasEditableShapes);
action("object_order_lower")->setEnabled(hasEditableShapes);
action("object_order_back")->setEnabled(hasEditableShapes);
action("object_order_front")->setEnabled(hasEditableShapes);
action("object_order_raise")->setEnabled(hasEditableShapes);
action("object_order_lower")->setEnabled(hasEditableShapes);
action("object_order_back")->setEnabled(hasEditableShapes);
action("object_transform_rotate_90_cw")->setEnabled(hasEditableShapes);
action("object_transform_rotate_90_ccw")->setEnabled(hasEditableShapes);
action("object_transform_rotate_180")->setEnabled(hasEditableShapes);
action("object_transform_mirror_horizontally")->setEnabled(hasEditableShapes);
action("object_transform_mirror_vertically")->setEnabled(hasEditableShapes);
action("object_transform_reset")->setEnabled(hasEditableShapes);
action("object_transform_rotate_90_cw")->setEnabled(hasEditableShapes);
action("object_transform_rotate_90_ccw")->setEnabled(hasEditableShapes);
action("object_transform_rotate_180")->setEnabled(hasEditableShapes);
action("object_transform_mirror_horizontally")->setEnabled(hasEditableShapes);
action("object_transform_mirror_vertically")->setEnabled(hasEditableShapes);
action("object_transform_reset")->setEnabled(hasEditableShapes);
const bool multipleSelected = editableShapes.size() > 1;
const bool multipleSelected = editableShapes.size() > 1;
const bool alignmentEnabled =
multipleSelected ||
(!editableShapes.isEmpty() &&
canvas()->resourceManager()->hasResource(KoCanvasResourceProvider::PageSize));
const bool alignmentEnabled =
multipleSelected ||
(!editableShapes.isEmpty() &&
canvas()->resourceManager()->hasResource(KoCanvasResourceProvider::PageSize));
action("object_align_horizontal_left")->setEnabled(alignmentEnabled);
action("object_align_horizontal_center")->setEnabled(alignmentEnabled);
action("object_align_horizontal_right")->setEnabled(alignmentEnabled);
action("object_align_vertical_top")->setEnabled(alignmentEnabled);
action("object_align_vertical_center")->setEnabled(alignmentEnabled);
action("object_align_vertical_bottom")->setEnabled(alignmentEnabled);
action("object_align_horizontal_left")->setEnabled(alignmentEnabled);
action("object_align_horizontal_center")->setEnabled(alignmentEnabled);
action("object_align_horizontal_right")->setEnabled(alignmentEnabled);
action("object_align_vertical_top")->setEnabled(alignmentEnabled);
action("object_align_vertical_center")->setEnabled(alignmentEnabled);
action("object_align_vertical_bottom")->setEnabled(alignmentEnabled);
const bool distributionEnabled = editableShapes.size() > 2;
const bool distributionEnabled = editableShapes.size() > 2;
action("object_distribute_horizontal_left")->setEnabled(distributionEnabled);
action("object_distribute_horizontal_center")->setEnabled(distributionEnabled);
action("object_distribute_horizontal_right")->setEnabled(distributionEnabled);
action("object_distribute_horizontal_gaps")->setEnabled(distributionEnabled);
action("object_distribute_horizontal_left")->setEnabled(distributionEnabled);
action("object_distribute_horizontal_center")->setEnabled(distributionEnabled);
action("object_distribute_horizontal_right")->setEnabled(distributionEnabled);
action("object_distribute_horizontal_gaps")->setEnabled(distributionEnabled);
action("object_distribute_vertical_top")->setEnabled(distributionEnabled);
action("object_distribute_vertical_center")->setEnabled(distributionEnabled);
action("object_distribute_vertical_bottom")->setEnabled(distributionEnabled);
action("object_distribute_vertical_gaps")->setEnabled(distributionEnabled);
action("object_distribute_vertical_top")->setEnabled(distributionEnabled);
action("object_distribute_vertical_center")->setEnabled(distributionEnabled);
action("object_distribute_vertical_bottom")->setEnabled(distributionEnabled);
action("object_distribute_vertical_gaps")->setEnabled(distributionEnabled);
updateDistinctiveActions(editableShapes);
updateDistinctiveActions(editableShapes);
}
emit selectionChanged(editableShapes.size());
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment