Weird Layer.moveBelow() behavior

Was struggling with React, so thought I’d give a try with a simple JS UXP plugin, but again ran into a weird issue with layer ordering.

In my index.js (main in manifest) I have two simple commands:

app.activeDocument.layerTree[1].moveAbove(
  app.activeDocument.layerTree[0]
);
app.activeDocument.layerTree[2].moveBelow(
  app.activeDocument.layerTree[0]
);

This is how layers look like before these two are executed:
image

And this is how it looks after:
image

In this case app.activeDocument.layerTree[1] is the “On top 1” layer and app.activeDocument.layerTree[2] - “On top 2”. First command moves “On top 1” above the zero-index layer (to the very top). Second one should move “On top 2” below the new zero-index (first) layer, but instead in moves to the top again.

Thought maybe .layerTree doesn’t get reindexed or something, but it also doesn’t make sense, because indexes still doesn’t match. And moving below shouldn’t move up anyway.

Noticed this with more layers while looping in a forEach, but managed to simplify to just these two commands to reproduce the issue. Even if this happens almost all of the time, sometimes layers are ordered even more randomly after these two commands :confused:

Spent probably around 8 hours trying to figure out why, how and what is happening with no luck at all. Any help is appreciated.

Just thought this might be more clear (although it does exactly the same)

const topLayer = app.activeDocument.layerTree[0];
const layerOnTop1 = app.activeDocument.layerTree[1];
const layerOnTop2 = app.activeDocument.layerTree[2];

layerOnTop1.moveAbove(topLayer);
layerOnTop2.moveBelow(layerOnTop1);

And layerOnTop2 never gets moved below layerOnTop1 :frowning: Somehow it goes to the very top.

What I actually want to achieve is to move all selected layers to top by moving first selected layer to top and the next ones below the previously moved.

I haven’t tried out your code example, but if that’s all you want to do, can’t you just flip/invert the array of selected layers and add push them to the top in reverse order? That should give you the result you’re looking for

1 Like

Tried that :slight_smile: It works, but…

Situation is… I store these selected layers and later, on layer tree change, I move these layers back to top if needed. Pushing to top in reverse, makes every move visible and it distracts. Looks like something is flickering in layers panel and that’s not really a good UX :slight_smile: If all selected layers are already at the top, I don’t want them to move from their places on tree change

So definitely the issue is on Adobes side. Both moveAbove() and moveBelow() behave exactly the same. The issue appears if you try to move layer to the position it is already at.

const layer0 = app.activeDocument.layerTree[0];
const layer1 = app.activeDocument.layerTree[1];
layer0.moveAbove(layer1);

and

const layer0 = app.activeDocument.layerTree[0];
const layer1 = app.activeDocument.layerTree[1];
layer1.moveBelow(layer0);

Both snippets switch layers places, but they shouldn’t. If I want to move 0 above 1, it shouldn’t actually do anything, but somehow it moves 0 below 1. Same with the opposite method.

Layer move methods are pretty unpredictable when moving layers next to each other or at the beginning or the end of the layer set.

@kerrishotts, maybe some good news on this issue too?