メインコンテンツまでスキップ

ウィンドウの合成

COMPOSITOR.window.composition は ShojiWM のカスタマイズの心臓部です。ウィンドウを 受け取り、それをどう配置・装飾するかを表す TSX ツリーを返す関数を割り当てます。 コンポジターはすべてのトップレベルウィンドウに対してこれを呼び、読み取った値が 変化するたびに(差分的に)再実行します。

COMPOSITOR.window.composition = (window) => (
<ManagedWindow rect={window.position} zIndex={1}>
<WindowBorder
style={{borderRadius: 10, border: {px: 2, color: window.isFocused((f) => (f ? '#d7ba7d' : '#4f5666'))}}}
>
<Box direction="column">
<Box direction="row" style={{height: 28, paddingX: 8, gap: 8, alignItems: 'center'}}>
<AppIcon icon={window.icon} style={{width: 16, height: 16}} />
<Label text={window.title} style={{flexGrow: 1, fontSize: 13}} />
</Box>
<ClientWindow />
</Box>
</WindowBorder>
</ManagedWindow>
);

ツリーには必ず、ちょうど1つの <ManagedWindow/> が、ちょうど1つの <ClientWindow/> を包む形で含まれている必要があります。その間にある もの――ボーダー・タイトルバー・ボタン――があなたの装飾で、SSD コンポーネント で組み立てます。

window オブジェクト

引数は WaylandWindow、つまり1つのウィンドウへのライブでリアクティブなハンドルです。 合成内でそのシグナルを読むと、変更に自動的に購読されます。

リアクティブなプロパティ

それぞれ ReadonlySignal です――window.title()window.title.value のように 読むか、window.isFocused((f) => f ? 'a' : 'b') のようにマップします。

プロパティ意味
titlestringウィンドウタイトル
appIdstring | undefinedアプリケーション id(例: "org.gnome.Nautilus"
iconWindowIcon | undefinedアプリケーションアイコン
isFocusedbooleanキーボードフォーカスを持つ
isFloatingbooleanフローティング(非タイル)
isMaximizedboolean最大化
isFullscreenbooleanフルスクリーン
isResizablebooleanクライアントがインタラクティブリサイズを許可
isTransientboolean別ウィンドウの子(ダイアログ)
parentIdstring | undefinedトランジェントの場合の親ウィンドウ id
sizeConstraintsWindowSizeConstraintsクライアントの最小/最大サイズ
interactionスナップショット現在のポインター/ドラッグの状態

非リアクティブなヘルパー: id(安定した文字列)、position / rect(現在の論理 ジオメトリ)、state(ウィンドウごとのストア。状態とシグナル を参照)、transform(GPU トランスフォーム)、animationアニメーション を参照)。

メソッド

メソッド効果
close()クライアントに閉じるよう要求
maximize() / unmaximize()最大化の切り替え
minimize()最小化
fullscreen() / unfullscreen()フルスクリーンの切り替え
focus()キーボードフォーカスを与え前面に出す
scheduleAnimation(options)マネージドウィンドウのジオメトリをアニメーション
cancelAnimation(channel?)実行中のアニメーションをキャンセル
setCloseAnimationDuration(ms)閉じるアニメーションに合わせてサーフェス破棄を遅延
isXWayland()XWayland 上で動作中なら true

ManagedWindow

<ManagedWindow/> はウィンドウをレイアウトシステムに結びつけるアンカーです。 ウィンドウごとに1つ置きます。

Prop意味
rectManagedWindowRectウィンドウの論理的な {x, y, width, height}
zIndexnumber重なり順(大きいほど上)
workspacestring | numberワークスペース割り当て
visibleOutputsstring[] | null指定出力に限定(null で全出力)
visiblebooleanアンマップせずに表示/非表示
idlebooleanフォーカス巡回から除外。背景として扱う
interactivebooleanfalse のときポインター入力を無視
forceRectSizebooleanクライアントを rect のサイズに強制
tiledbooleanタイル状態をクライアントに送る
opacitynumber0.01.0
transformManagedWindowTransform追加の GPU トランスフォーム
allowTearingbooleanフルスクリーン+ダイレクトスキャンアウト時のテアリングを許可(ゲーム向け)

すべての prop はリアクティブなレイアウトのためにシグナルを受け付けます。rectzIndex などは通常、あなたのウィンドウマネージャのロジックが駆動します。

ClientWindow

<ClientWindow/> はクライアントの実際のサーフェスバッファを描画します。リーフノードで 子要素は持ちません。別名: <Window/>

<ClientWindow style={{borderRadius: 8}} />

任意の style はサーフェスをクリップ/装飾します(通常は borderRadius のみ)。

フルスクリーンのファストパス

フルスクリーンのウィンドウでは、<ManagedWindow/> の中に素の <ClientWindow/> だけを返します(ボーダーもタイトルバーもなし)。他に何も描画しないことで、TTY バックエンドがクライアントバッファをプライマリプレーンに昇格(ダイレクトスキャンアウト) でき、最小のレイテンシになります。デフォルト設定はまさにこれを行っています。