Photoshop Scripting: How to add an event listener to the ScriptUI windowObj

1.6k views Asked by At

I want to add an event listener to the windowObj that on keydown, calls a function. I can not get this to work on the window object; however, I can get it working after a child of the window object (a button for example), has been clicked. I've also tried clicking on the window area around the button, thinking that maybe the window needed to be active, but this did not work. Oddly enough, this test worked when I changed "keydown" to "click".

The way I want it to work: When the ScriptUI window displays, on keydown, a function is called.

Below is code of a simplified example of what I want to happen:

#target Photoshop

var w = new Window ("dialog");
var buttonPositions = w.add ("group");
var top = buttonPositions.add ("button", undefined, "Button");

w.addEventListener ("keydown", function (k) {handle(k)});

function handle (k) {
    alert (k.keyName);
}

w.show ();

Displays when script runs

Displays when script is run

Alert box with key name displays on keydown Alert box with key name displays on keydown

1

There are 1 answers

0
Stelio Kontos On

tl;dr: Set the active property of any control that accepts keystrokes and is a descendent in the registered element's hierarchy to true:

btn.active = true;
win.addEventListener("keydown", function (e) { alert(e.keyName); });

The Window object isn't designed to detect keydown events. This can be demonstrated by intermingling panel, statictext, and group elements with controls such as radiobutton, button, and checkbox. Pressing the tab key skips any elements that ignore keydown events, and sets the focus to the first control in line that accepts keydown events. The first control residing in the listener's hierarchy that receives focus will trigger your callback on the next keypress.

enter image description here

Per the Photoshop Scripting Reference (emphasis mine):

An active control is the one with keyboard focus - that is, the one that accepts keystrokes, or in the case of a Button, is selected when the user types Return or Enter in Windows, or the space bar in Mac OS.

Keydown events can propagate through a Window (or Panel, or Group element, for that matter) as part of the event registration and capture phase, but to trigger a keydown event, the actual target needs to accept that type of event.

function showDialog() {
    var win = new Window("dialog");
    var btn = win.add("button", undefined, "Cancel");

    // Sets initial focus to a control that accepts `ev: KeyboardEvent`,
    // and is a descendent in the registered `this: Window` hierarchy.
    btn.active = true;

    win.addEventListener("keydown", function (e) { alert(e.keyName); });

    return win.show() ? 0 : 1;
}

More info at: event callbacks/listeners and control objects.