Eventとは?
イベントはPhotoshopのExtendScript,CEPの頃からある概念ですがユーザーのアクションに対して 登録した関数を発火させる概念です。例えばユーザーがドキュメントを編集する度保存処理をさせる、といった 事を実現するために使います。Web APIで言うところのaddEventListenerですね。PhotoshopUXPにも CEPから受け継がれているのでイベントの登録ができます。ただ以下のようにイベントには幾つか種類があります。
ブラウザーのイベント
HTMLの要素に対してのイベントです。パネル上に構築したHTMLのインターフェイスに対するイベント、つまりブラウザー上の JavaScriptと全く同じです。addEventListenerメソッドでイベントを追加できます。但しブラウザーと環境が異なるので 一部振る舞いも変わる事もあり得るので注意してください。Panelのイベント
プラグインのパネルのイベントです。パネルが表示したりメニューコマンドがクリックされた時に発火されるイベントです。 詳しくは記事UXP Panelの概念をご覧ください。ホストアプリケーションのイベント
今回扱うのがこホストアプリケーションのイベント、つまりPhotoshop上でドキュメントが保存された時やレイヤーが作成された時に発火するような アプリケーションの変化を感知して発火するイベントです。CEPではPhotoshopしか標準ではありませんでしたがUXPでどうなるかは不明です。 どちらにせよUXPでは既にPhotoshop向けに実装されています。
以上になります。以下、Photoshop上のイベントについて解説します。
どうやって登録するの?
まずは登録のやり方です。これに関してはCEPの時に比べてかなりシンプルになりました。addNotificationListener メソッドの引数に登録するイベントの内容、登録する関数を渡すだけです。大体addEventListenerと同じですね。
Photoshop.actionモジュールのaddNotificationListenerメソッドでイベントの追加ができます。 openはドキュメントを開いた時のイベントです。第一引数にイベント文字列を渡しますがArray型で複数のイベントを 一度に追加できます。第二引数に登録する関数です。removeNotificationListenerでイベントの削除ができるので まんまWebAPIと同じですね。またイベントが発火した際にはコールバックで第一引数からイベントの文字列、第二引数にイベントの内容のオブジェクト を受け取れます。

イベントの文字列を取得する
イベントの文字列をそのまま渡すだけでイベントの登録ができるのはわかりました。しかしどうやってイベントの文字列を 取得すれば良いのでしょうか。まずapi1の場合eventNotifierであらゆるイベント下でコールバック関数が発火するようになります。 console.logで内容を受け取ればイベントの詳細及び登録に必要な文字列も取得できます。api2からはeventNotifierは使えないので通常のaddNotificationListenerメソッドに allのイベントを登録します。ただしあらゆるイベント下で発火するので本番環境下では使わないようにしましょう。

取得したイベントの内容をjsonデータとして残したい場合はアクションコマンドを記録(詳しくはbatchPlayの記事参照)でも文字列を取得できます。以下そのjsonの一例。
その他何度も取り上げているPlugin Alchemistでもイベントの文字列の取得ができます。

その他のイベント
上記以外のイベント以外にも特殊なイベントがUXPには存在します。
load and launch
これはPhotoshop23.1からの機能ですが今回取り上げます。 使う場合はmanifestのバージョンを5にしてdataプロパティの”loadEvent”に”startup”を設定することでPhotoshopが立ち上がった後にそのままプラグインもバックで立ち上がるようになります。 Photoshopが立ち上がった時にそのままイベントを登録したい時などは便利ですがユーザーの意思とは無関係にプラグインが立ち上がるので慎重に使用すべきでしょう。 詳しくはmanifestの記事を参照してください。
userIdle
ユーザーのアイドル状態、ユーザーがPhotoshop上で何もしない状態が一定時間続いた時のイベントです。 addNotificationListenerでイベントの登録をします。 登録時に渡す値に関しては公式のドキュメントにサンプルが載っていたのでそのまま使います。
三つ目の引数onUserIdleはコールバック関数を渡します。 これだけでidleイベントを待ち受けしてくれるようになりますがidleイベント発火に至る時間も設定したいです。ユーザーが操作を停止してからコールバックが発火するまでの時間はsetUserIdleTimeメソッドを使います。 引数にnumber型の値を渡せば渡した値の時間だけidleが経過した後にコールバックが発火します。 これも公式のドキュメントのサンプルをそのまま使います。
idleを停止したい場合はsetUserIdleTimeメソッドに0を渡します。 一連の流れをサンプルとして書き出すと以下のようになります。
時間経過でアラートを表示する関数が発火します。 コールバック関数の引数にeventNameとdescriptorがあるのに気づくでしょう。 eventNameはまんまイベントの名前、この時はuserIdle、descriptorでイベントの状態のオブジェクトを受け取ります。 ユーザーがidle状態から離脱すると{"idleEnd":true}が返ってくるらしいのですがおそらくidle時間が経過した時、 ユーザーがidle状態から離脱した時に感知するせいか二度コールバックが発火しました。 なのでdescriptorのidleEndプロパティがtrueでない時のみにアラートが出るようにして条件分岐しています。 (この部分のifを取り除くとアラートが二度発火する)
