Bug 495811

Summary: Safe Assert with addChildNode followed by setActiveNode
Product: [Applications] krita Reporter: Evan Lee <evan.lee.v0>
Component: ScriptingAssignee: Krita Bugs <krita-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: halla
Priority: NOR    
Version: nightly build (please specify the git hash!)   
Target Milestone: ---   
Platform: Microsoft Windows   
OS: Microsoft Windows   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Evan Lee 2024-11-05 03:27:26 UTC
Version: 5.3.0-prealpha (git e031c83)

Following code causes an internal error:
```python
from krita import *

doc = Krita.instance().activeDocument()
node = doc.createNode('test', 'paintlayer')
root = doc.rootNode()
root.addChildNode(node, None)
doc.setActiveNode(node)
doc.refreshProjection()
```

Krita has encountered an internal error:
SAFE ASSERT (krita): "shape" in file C:/builds/graphics/krita/libs/ui/kis_node_manager.cpp, line 162

If node for setActiveNode is different from addChildNode, setActiveNode is somehow overridden by addChildNode so the new child node is always the active node instead of the specified node. There is no internal error in this case.

Related: https://bugs.kde.org/show_bug.cgi?id=482315
Comment 1 Evan Lee 2024-11-05 04:03:43 UTC
I tried to find a workaround with setChildNodes but it resulted in a similar internal error.

I ran this script on the default document which consists of two layers: "Paint Layer 1" and "Background".

```python
from krita import *

doc = Krita.instance().activeDocument()
activeNode = doc.activeNode()
parentNode = activeNode.parentNode()
node = doc.createNode('test', 'paintlayer')
childNodes = parentNode.childNodes()
i = childNodes.index(activeNode)
childNodes.insert(i+1, node)
print([node.name() for node in childNodes])
parentNode.setChildNodes([])
parentNode.setChildNodes(childNodes)
doc.setActiveNode(node)
doc.refreshProjection()
```

Krita has encountered an internal error:
SAFE ASSERT (krita): "shape" in file C:/builds/graphics/krita/libs/ui/kis_node_manager.cpp, line 162

If the node for setActiveNode is different from the one inserted, setActiveNode is ignored and the active node is set to the top child.

When `parentNode.setChildNodes([])` is commented, we get the below error followed by the one from above.

Krita has encountered an internal error:
SAFE ASSERT (krita): "!newNode->parent()" in file C:/builds/graphics/krita/libs/image/kis_node.cpp, line 473
Comment 2 Halla Rempt 2024-11-05 14:05:38 UTC
I can confirm the issue. Thanks for the report. A safe assert is a warning that is only displayed in nightlies and usually fine to ignore, but we should look into this problem.
Comment 3 Dmitry Kazakov 2024-11-07 16:20:48 UTC
Git commit b1994c61454a3448a0a2b619db28f21e8bcd8edb by Dmitry Kazakov.
Committed on 07/11/2024 at 16:20.
Pushed by dkazakov into branch 'master'.

Fix accessing active node state from the Python scripts

M  +6    -0    libs/global/KisSynchronizedConnection.cpp
M  +1    -0    libs/global/KisSynchronizedConnection.h
M  +13   -1    libs/libkis/Document.cpp

https://invent.kde.org/graphics/krita/-/commit/b1994c61454a3448a0a2b619db28f21e8bcd8edb