ロック背景と解除オーバーレイ
セッションがロックされている間、ShojiWM は通常、ロッカーの ext-session-lock-v1
サーフェスしか描きません。この API を使うと、設定で選んだウィンドウやレイヤーシェルの
サーフェスを、透明なロック画面の後ろに表示し続けられます(動く壁紙やスクリーンセーバー
など)。また、ロック解除に成功したあと、アニメーション付きのオーバーレイでロック画面から
デスクトップへ切り替えることもできます。
この API はロッカーではなく、パスワード入力や認証は行いません。何も選ばなければ、 ロックの動作は今までと同じです。
背景の選択
const locked = COMPOSITOR.session.configureLockBackground({
windowIds: [wallpaperWindow.id],
layerIds: [wallpaperLayer.id],
});
- 引数には現在の
WaylandWindow.id/WaylandLayer.idを渡します。設定の中で (たとえばCOMPOSITOR.event.onOpenで)目的のクライアントを見つけて選び、 そのインスタンスが変わったら呼び直してください。空の配列を渡すと背景を消します。 - ID は最大 64 個までです。それぞれ空でなく、512 バイト以下で、制御文字を含まない必要が あります。知らないフィールドはエラーになります。
- 戻り値は「今ロックされているかどうか」です。この呼び出し自体がロックや解除を することはありません。
- 選択はいつでも(ロック中でも)変えられ、次のフレームから反映されます。モジュールの
トップレベルではなく、設定の読み込み後(イベント・タイマー・
onEnable)に呼んでください。
描かれるもの:
- 選んだルートサーフェスのツリーと、そのクライアントのサブサーフェスだけです。別管理の ポップアップ、SSD、エフェクト、選ばれていないウィンドウやレイヤーは表示されません。 ウィンドウはクライアント矩形の位置に描かれ、ウィンドウの composition は使われません。
- 重なり順は通常のウィンドウ・レイヤーの順に従いますが、選んだウィンドウは常に選んだ レイヤーより上になります。
- 入力は変わりません。キーボードとポインターはロッカーにしか届きません。
選択が無効になるとき:
- 選択は設定ランタイムに属します。ランタイムが停止・リロードすると外れるので、
必要なら
onEnableで選び直してください。 - 出力にバッファ付きのロックサーフェスが現れるまでは何も描きません。ロッカーが落ちると、 その出力は背景も含めて空のロック画面に戻ります。
設定は信頼される前提です。クライアントを選ぶと、そのサーフェスツリーに描かれた UI も 含めて、ロック中にその画素が見えるようになります。個人情報を表示しうるアプリではなく、 背景専用のクライアントを選んでください。これはサンドボックスではありません。
解除時の受け渡し
COMPOSITOR.effect.overlay は placement: "unlock" を受け付けます。ロック中に作れる
唯一のオーバーレイで、ロッカーが解除したあともデスクトップの上に残ります。作成には
次の条件があります。
- ロック中であること
- 入力が
snapshotSource()であること persistent: falseであることmaxDurationが 3000 ms 以下であること
ほかの placement はロックされると閉じられ、ロック中は作れません。新しくロックされると それまでのオーバーレイは閉じられます。セッションの一時停止(VT 切り替え)と電源オフの 出力でもオーバーレイは閉じられます。有効なロックサーフェスが無い間、解除オーバーレイは 描かれません。
スナップショットに入るのはロック画面の内容(ロックサーフェスと選んだ背景。カーソルは
含まない)です。どちらにも覆われていない部分は透明になるため、解除した瞬間から
その部分には実際のデスクトップが透けて見えます。背景で出力全体を覆うか、シェーダーで
不透明な色を返してください(例: vec4(frozen.rgb, 1.0))。
受け渡しは認証に成功してから始めてください。
- まだロックされている間に、切り離したタスクからオーバーレイを作ります。コンポジタが 完了を待つコールバックから await しないでください(出力オーバーレイ を参照)。
- オーバーレイの準備ができる(Promise が解決する)まで待ちます。これでスナップショットが 撮られています。
- ロッカーの通常の認証済みの経路で解除します。
- 実際のデスクトップの上で、シェーダーの uniform を動かします。
- 終わったらハンドルを dispose します。失敗に備えて、
closedPromise・ネイティブの 期限・自前のタイムアウトを使ってください。
async function revealDesktop(output: string, unlock: () => void) {
const progress = signal(0);
const handle = await COMPOSITOR.effect.overlay(output, {
placement: "unlock",
maxDuration: 3_000,
effect: compileOverlayEffect({
input: snapshotSource(),
alpha: "preserve",
pipeline: [shaderStage(dissolve, { uniforms: { progress } })],
}),
});
try {
unlock(); // ロッカーにロックの解除を伝える
const start = Date.now();
while (progress.value < 1) {
progress.value = Math.min(1, (Date.now() - start) / 600);
await new Promise<void>((resolve) => setTimeout(resolve, 8));
}
} finally {
handle.dispose();
}
}
アニメーションは組み込まれていません。シェーダーと、動きを減らす設定向けの代替は 設定側で用意してください。
Rust
Rust SDK にも同じ API があります。
COMPOSITOR.session.configure_lock_background(LockBackground {
window_ids: vec![window.id()],
layer_ids: vec![],
})?;
let overlay = Overlay::new(effect)
.placement(OverlayPlacement::Unlock)
.max_duration_ms(3_000.0);
現状
新しい API です。選択、ロッカーが落ちたとき、リロード、受け渡しの動作は、ネスト(Winit)の セッションで確認済みです。実際の TTY セッションでの本物のロッカー、VT 切り替え、DPMS、 複数・回転出力はまだ試していません。