Bug 419281

Summary: Krita Actions - Copy Paste Layer Script
Product: [Applications] krita Reporter: keyth_qcfx2 <keyth2363214>
Component: ScriptingAssignee: Krita Bugs <krita-bugs-null>
Status: RESOLVED NOT A BUG    
Severity: normal CC: dimula73, ghevan, griffinvalley, halla
Priority: NOR Keywords: triaged
Version First Reported In: 4.2.8   
Target Milestone: ---   
Platform: Other   
OS: Other   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description keyth_qcfx2 2020-03-27 04:14:18 UTC
SUMMARY
Making a selection on a layer and using the 

STEPS TO REPRODUCE
scenarioA
1. Make a Selection
2. use "copy_selection_to_new_layer" action for a new layer (becomes locked to layer)
3. try using "activateNextLayer" to select the new layer (will not work, originally I tried without it since it moves up but it has the same effect this being here or not)
4. try to use any action on the new layer but it will Always affect the original layer.

scenarioB
1. Make a Selection
2. use "copy_selection_to_new_layer" action for a new layer
3. Create another script/button to do the rest of the actions
4. now "activateNextLayer" is not needed since the pause allows the layer selection to be Concrete.
5. try to use any action on the new layer but now it will work.

OBSERVED RESULT
Creating a new layer with a paste of any kind blocks any operation to the new layer, even layers changes. But if you part the same code in two parts it works.

EXPECTED RESULT
Ability to change layer after a paste command.

SOFTWARE/OS VERSIONS
Windows: 10

ADDITIONAL INFORMATION
As you can see the commands actually work if they are applied individually but they should be able to work along side each other.
I was making a small copy paste and mirror script and I noticed this odd behavior, I will be posting my code to this link if it is quicker to take a look and test. My code considers if you have a selection or not active and if you don't it creates a selection, currently you need to press M1 and then M2 for it to execute whole.
code:
https://github.com/EyeOdin/mirror_tools

Hopefully I could merge "Mirror_1" and "Mirror_2" into a single function without resorting to a break.
Comment 1 Halla Rempt 2020-05-06 14:18:43 UTC
Yes, please do attach a minimal script I can run from scripter to this bug report.
Comment 2 keyth_qcfx2 2020-05-09 05:28:44 UTC
# Import Krita
from krita import *

# Krita Instance Objects
ki = Krita.instance()
ad = ki.activeDocument()
an = ad.activeNode()
root = ad.rootNode()
# Read document size
width = ad.width() / 2
height = ad.height()

# Force the Mirror Axis to Center
ki.action('mirrorX-moveToCenter').trigger()

# Is there a Selection from the User?
sel = ad.selection()
# Selection Sensitive
if sel == None:  # Create a Selection
    # Place Selection
    ss = Selection()
    ss.select(0.0, 0.0, width, height, 255)
    ad.setSelection(ss)

    # Copy Selection
    ki.action('copy_selection_to_new_layer').trigger()

    # Deselect
    ki.action('deselect').trigger()

    # Point of Error that needs to be Broken to Work

    # Since there is a Selection from the user do Mirror Flip like this instead
    Krita.instance().action('mirrorNodeX').trigger()

    # Mirror_2 with the layer below
    Krita.instance().action('merge_layer').trigger()

print("Copy Paste Done")
Comment 3 keyth_qcfx2 2020-05-09 05:31:09 UTC
I just copy pasted the code from the mirror tools add-on I made and sized it a bit down so it has less lines because there is no need for so many variables. you can open any image and just run it. it will automatically select the left side of the image and try to mirror it to the right side.
Comment 4 Bug Janitor Service 2020-05-10 04:33:19 UTC
Thanks for your comment!

Automatically switching the status of this bug to REPORTED so that the KDE team
knows that the bug is ready to get confirmed.

In the future you may also do this yourself when providing needed information.
Comment 5 vanyossi 2020-05-11 01:42:47 UTC
This probably means the operation "copy_selection_to_new_layer" is asyncronous, or it needs the gui to finalize some events. In any case this is not a bug in krita, but perhaps a missing documentation on doxygen.

Add "ad.waitForDone()" after the action "copy_selection_to_new_layer" and the script will work as expected.
Comment 6 vanyossi 2020-05-11 01:51:28 UTC
after a quick test. ad.waitForDone() should be put after "deselect" action. Sorry for the confusion.
Comment 7 keyth_qcfx2 2020-05-13 05:01:05 UTC
That does not WORK at all!......How do you set this is as "RESOLVED NOT A BUG"? 

the ad.waitForDone() does nothing that I can see to solve this issue. I think it might give the time to rest and do something but there is no LAYER SWAP just the same. Considering your advice I tried to place wait where you told me and also too on every step of the process in case i was placing it on the wrong spot. I should mention I have tested asynchronization before making this Report, I tryed again and not to my surprise it does not work also *sighs*
Because it is NOT asynchronization for I can tell, it feels more like a LAYER LOCK.

"""
EXPECTED RESULT
Ability to change layer after a paste command.
"""

I don't know what else more to explain this:
-I made a sample script that "Does NOT" work
-An addon with the same EXACT code that "Does" work

I know the rest is working because you did not look at the end result of the code. You even had the addon to compared it too. place a layer above and below and note their names and see the end result, the merge will eat the layer below and not the new layer it created because it thinks it is still on the layer below.

the wait of the 2 buttons method gives allows for the selected layer to be in fact be the one that is HIGHLIGHTED and NOT keep python acting from the ORIGINAL layer below it where it started using its original commands. because there is disparity from where the actions act and where they show to be acting according to the layer stack, by the end of a simply copy paste procedure.

I talked about the "activateNextLayer" command too that was not used because the 2 button setup literally ignored it and had no need for it. But I had it marked on the code (addon) and spoke how useless it was too. Because if you use that command isolated it will work but NOT if you surround it with other commands. it will be locked and not change regardless.

Also making a action does not allow you to create a layer and input names to be saved in variables to be used later so you can use it's name to change its layer because that works.

As an Alternative you could say, "why not create a node manually and use the name it so you can swap instead of using actions to copy paste?"
Also a bug there but instead on the Paste process, the information is correct on the clipboard but does not lay it on the layer correctly, that I have reported, I even made video demonstrating how it did not work. Also no one gives a shit on that one it seems.



...I am Sorry to say but everything Python in Krita is especially aggravating. I made a damn Color Picker in Krita and I felt like I should punch myself because of even having stupid ideas. But this Copy Paste Thing? it is even worse seriously... If you guys don't believe me, I am okays, I think I did what I could do. I reported both. I had my responses that both are not bugs. I am just gonna use my stupid work around call it a day and not bother anymore.
Comment 8 keyth_qcfx2 2020-05-13 07:50:16 UTC
Does this code explain the issue better?

# Import Krita
from krita import *

# Krita
ki = Krita.instance()
ad = ki.activeDocument()

# Make a Selection
ss = Selection()
ss.select(50, 50, 1000, 1000, 255)
ad.setSelection(ss)

# Stupid bug example
ki.action('add_new_paint_layer').trigger()
ki.action('activateNextLayer').trigger()  # should swap layer with this command
ki.action('clear').trigger()
ki.action('deselect').trigger()
Comment 9 wolthera 2020-05-13 08:25:57 UTC
I tried to reproduce this, but the provided scripts work here?

In fact, if I comment out 'ki.action('activateNextLayer').trigger()', then it still works as expected, Krita selects the topmost layer because it was the last one added...

Someone needs to try and reproduce this on windows...
Comment 10 wolthera 2020-05-13 08:28:56 UTC
BTW, that last comment was for the first script, the second script indeed needs a 'waitForDone':
--------------------------------------------

# Import Krita
from krita import *

# Krita Instance Objects
ki = Krita.instance()
ad = ki.activeDocument()
an = ad.activeNode()
root = ad.rootNode()
# Read document size
width = ad.width() / 2
height = ad.height()

# Force the Mirror Axis to Center
ki.action('mirrorX-moveToCenter').trigger()

# Is there a Selection from the User?
sel = ad.selection()
# Selection Sensitive
if sel == None:  # Create a Selection
    # Place Selection
    ss = Selection()
    ss.select(0.0, 0.0, width, height, 255)
    ad.setSelection(ss)

    # Copy Selection
    ki.action('copy_selection_to_new_layer').trigger()
    ad.waitForDone()

    # Deselect
    ki.action('deselect').trigger()

    # Point of Error that needs to be Broken to Work

    # Since there is a Selection from the user do Mirror Flip like this instead
    Krita.instance().action('mirrorNodeX').trigger()

    # Mirror_2 with the layer below
    Krita.instance().action('merge_layer').trigger()

print("Copy Paste Done")
Comment 11 keyth_qcfx2 2020-05-13 08:40:25 UTC
this is one of my tests after asking for advice, the code is on the side and i just placed the suggestion everywhere to make sure because I did not even know where it should be yet.
https://gyazo.com/a455e2bcbc147fa06b7fa931120b9b8b
I am sorry to bother everyone.
Comment 12 Dmitry Kazakov 2020-05-13 09:00:07 UTC
The problem was in using width = ad.width() / 2 for mirroring instead of the full rect. I'll close the bug then.
Comment 13 keyth_qcfx2 2020-05-15 05:39:20 UTC
then how do you explain the same behaviour with no mirroring?
https://pasteall.org/media/9/c/9c6451a6126988fb67ecd773912c053e.png

As you can see it has the same exact behaviour and:
-there is no mirror command (even though the width/2 was to make a manual selection for when there is no user selection beforehand)
-it is not multi-threading. I tested with extreme usage of waitForDone() and refreshProjection() as suggested and that has no impact on outcome.
-it is not the operating system. I tested this same code on 3 windows machines and 1 linux machine (kde version) and the behaviour is consistent on all machines, I don't understand how it works on your end both linux and windows.

However if you execute this code by hand or with commands individually the image will never be deleted. Is not a python actions not meant to literally mimic the same action done by a user? how does it have different results if you execute the same sequence of commands?
Comment 14 vanyossi 2020-05-16 01:51:05 UTC
For the sake of clarity, could you attach a screenshot of the script with the correct output in oneside and the incorrect output on the other side? I am at least a bit confused now.