I’m developing a Photoshop UXP panel that allows users to quickly switch between two layers and set the corresponding tool (e.g. Clone Stamp for one, Mixer Brush for the other).
Expected behavior:
Click one button → switches to target layer and sets the correct tool
What I’ve tried:
Switching layer via batchPlay inside executeAsModal
Switching tool via:
A second executeAsModal call
setTimeout and async delays
app.currentTool (DOM-based switch)
Combined batchPlay calls inside a single executeAsModal
Layer and tool switches in separate buttons
Introducing artificial pauses and dummy commands to reset Photoshop state
Observed issues:
When layer and tool switching are triggered in sequence (even with delays), Photoshop frequently enters a broken state:
Tool switch fails silently
Keyboard shortcuts for tools stop working entirely
Photoshop doesn’t recover until another native modal is opened (e.g. Image Size)
No errors appear in the console
This happens even when tool switching is separated into a second button click, and the layer switch alone seems to trigger it
Has anyone found a reliable, UXP-compliant way to trigger both layer and tool switching from a single button press — without triggering Photoshop’s broken modal state or disabling keyboard input?
Yes. I have this working in on one of the panels in production and have no issues. You can do that in single modal call. Timeout work only within your plugin. It ignores other plugin modal states and also PS modal dialogs.
It sounds like PS enters modal state and does not leave it. That would block keyboard shortcuts.
Could I ask for a bit more detail on how you structure the executeAsModal call?
In my case, I’m trying to switch to a specific layer by name (using batchPlay) and then switch to a specific tool (e.g. cloneStampTool). I’ve tried combining those two operations in a single executeAsModal, but it seems like Photoshop sometimes enters that stuck modal state — the tool switch silently fails, and keyboard shortcuts become unresponsive until I manually open a native modal like Image Size.
I’d love to understand:
Are both select commands (layer + tool) part of the same batchPlay array?
Do you include both events inside the same object, or two objects in sequence?
Are there any special _options or flags that make the tool switch succeed reliably inside executeAsModal?
If you’re able to share even a stripped-down example of the structure, it would be incredibly helpful.
Thanks again — this has been the one blocker preventing a clean implementation!