Is there any way to turn off document refresh while code makes changes?

I’m writing a plugin that makes a few little changes to several layers in each of several documents. As a result the document display flashes and jumps in a very annoying way for a few seconds. Is there any way to turn off the document refresh, or just to limit which events it responds to?

Both the document itself and all the background of the pasteboard flash (I usually run in dark mode and it switches between that and white).

FWIW, I’ve tried:

  • making the changes in a document created with core.createTemporaryDocument. The description does say “This document does not appear in the UI, and there are limitations with some editing features.” I have yet to figure out what you can actually do with one; most of the Document object returned is empty, not even access to its layers property.

  • fiddling with the action playback options, because there are some threads around that say that could help in similar situations with ExtendScript. I can’t see any effect on UXP and BatchPlay.

  • I looked for a way to zoom right out or right in on a document to reduce the visual impact of refreshes, but couldn’t find one.

  • I tried core.redrawDocument at strategic moments, but couldn’t see any difference.

Chunks of the work are done with batchPlay, but I’ve steered clear of chaining batchPlay calls into one because there seem to be enough comments about problems with that!

FWIW, I do suspend history on each doc as I work on it, but that doesn’t seem to have any impact on redraw frequency.

Any other thoughts?

I assume you execute all within “single execute as modal” state since you suspend history, right?

Yes, that’s correct, most of the code is in one big modal execution context.

I’ve never been sure whether it’s worth breaking those into smaller units but it’s easier to make one big blob …

I’ve just been experimenting with multi-action batchPlay calls, but so far it’s not making much, if any, difference.

I was surprised to see the Photoshop ‘home’ screen when I stopped on some breakpoints. If I waited for a few seconds the active document would then get shown. At other times the response is instantaneous and flickering fast.

Even without the debugger I can now see that the home screen keeps appearing and disappearing; the big blue ‘new file’ and the white ‘read article’ buttons are very visible, now that I know what I’m looking at,

The sequence I’m following is:

  1. Create new document

  2. For each source document:

  • Make a temporary duplicate of the doc

  • Massage it a bit, e.g. changing colour mode, converting all layers into a smart object etc. I now have all of this in a single, multi-step batchPlay

  • Copy the contents of the temporary document (usually only one layer) into the new document at the top of the layer list (I tried the bottom as well, and it doesn’t make any visible difference).

  • Close the temporary file without saving


You could disable homescreen if there is nothing better you could do. At least for the time of modal state. Not sure if this one requires PS restart.

I just tried disabling the home screen manually, and it does look as if you need to restart Photoshop. When I turned it off and on around my code with batchPlay it had no effect. Shame, because it did make a small improvement.

I’m seeing that there are a lot of factors that have an impact; making sure that the history and layers palettes aren’t showing improves things a little bit as well.

The biggest improvement comes from setting up with all windows arranged as, for example, “tile all vertically”. If I do that then only one of those tiles flickers at a time, which is much less annoying.

But although I could see the commands to do that through Alchemist*, if I try to call them in my code I get “must be in modal execution” if it’s outside, and “command not currently available” if it’s inside the modal scope. I did try putting each of those batchPlay calls into its own modal execution context, before and after the one that encapsulates most of the code, but still get “command not available”.

const bpres = await batchPlay([{
          _obj: "invokeCommand",
          commandID: 5933,
          kcanDispatchWhileModal: true,
          _options: {
            dialogOptions: "dontDisplay",
            modalBehavior: "execute"
      ], {});

But then I tried the same thing using core.performMenuCommand, and that works!

I had been starting to wonder if I would have to put a warning on my plugin description with a list of mitigations that anyone who is sensitive to flashing lights can do when using it. But this looks like a good workround.

Now, I wonder how I can discover the initial arrangement that the user has set up so I can restore that at the end instead of just consolidating to tabs …

But that will have to wait till later


  • I’m not sure if I offered my deep thanks for Alchemist; I don’t think I could put together a plugin that does useful things without it!

This message is pretty much useless in any scenario. It usually means, that some pre-requisites are not met. For example, if you try to delete an active layer without actually having selected any, IIRC you would get this message. There were more similar cases, but can’t recall exactly what. Basically you need to do something first to make that command available

You can’t have fine control over all document windows. You can use menu commands… but that will give you basic control.

Also sometimes you can have multiple windows for the same document but as far I know this is impossible to detect in scripting. And if don’t know about it, you cannot recreate it.

Thanks. So I’m just going with tiling all open images to start with and then switching to tabs at the end. I’ve added a checkbox for people to use if they don’t want me to mess with their window settings. I think that’ll be enough.

Not sure of the proper etiquette here.

I’m happy with the solution described above. Well, maybe not happy, but it’s useable.

Should I mark the original question as answered?

That is good idea. I think you can change once there is the better solution. Or even add your own reply with the solution and mark your own reply as the correct answer.

1 Like