[1.0 Review] rendering / window / font の config と platform 例外の凍結 #7

Closed
opened 2026-09-03 16:03:46 +09:00 by natsukium · 1 comment
Owner

背景

felis の rendering は daemon が RowDelta(row 粒度の damage)と画像配置を送り、client が felis-render-wgpu で毎フレーム全グリッドを再描画する。explanation/rendering/pipeline.md に cell pass(bg→fg→decoration→image の4 pipeline)+ optional post-process(shader.post)が仕様化。フォントは felis-shaping(swash)で font.size は logical px。

現状の問題 / 凍結前に決めるべき点

1. window.opacitywindow.backdrop の結合

  • opacity は background opacity(kitty background_opacity モデル)で、明示的 bg を持つ cell は不透明のまま。OS compositor が合成。
  • backdrop は OS-native material(none/blur/acrylic/mica/tabbed)で、各値が特定 OS にのみ有効。

現行: bluropacity < 1.0 でないと window 背面に隠れて無効、Windows material は opacity によらず title bar に効く(body は wgpu DX12 swapchain が opaque のため常に不透明)。backlog.md に「Windows body transparency は wgpu の CreateSwapChainForHwndOpaque のみのため不可」と明記。

問い: 1.0 で opacitybackdrop を独立したキーとして凍結するか、将来の Linux compositor blur 対応で backdrop に Linux 値が追加された時に値集合が OS ごとに分岐し続けることを許容するか。代替: window.transparency = {opacity, backdrop} のようにまとめる。

2. shader.post の契約

shader.post = {builtin="trail"} | {file="..."} で、WGSL の fs_post entry point と uniform 契約(reference/shaders.md)が append-only で versioned。shader.animate = "never" | "focused" で continuous redraw を制御。

  • 現行は post が単一値(1つの post-process pass)。将来複数 pass(blur→trail のチェーン)を許すなら post = [{...}, {...}] の配列に破壊的変更が必要。今しか配列化できない。
  • animate = "focused" は idle CPU を犠牲にする opt-in。"always"(unfocused でも回す)を意図的に持たない。1.0 でこの「unfocused では回さない」制約を凍結するか。

3. font size の単位と範囲

font.size = 14.0 は logical px(window scale を掛ける前の値)で、4.0..=72.0 に clamp、非正・非有限は built-in default に fallback。MIN_FONT_SIZE_LOGICAL_PX / MAX_FONT_SIZE_LOGICAL_PXfelis-client-core に定数。Ctrl+Wheel / font_size action でも同じ band。

_logical_px_physical_px の命名分離は DPI 境界での bug を防ぐ意図。1.0 でこの命名と clamp 範囲を凍結するか、将来的に font.size = "14pt" のような単位付き文字列を許すか。

4. font.fallback の auto-discover

空配列時に CJK 1 face + symbol 全 face + emoji 1 face + nerd 1 face を auto-discover。非空なら宣言順に append し auto-discover は走らない。family 必須、features 省略で font.features を継承。

auto-discover が暗黙に大量の font を mmap する(Apple Color Emoji 183MiB 等)点は explanation/rendering/text-shaping.md に記載。1.0 で auto-discover の対象集合(現行の4グループ)を凍結するか、将来的にユーザがグループごとに on/off できる font.fallback.auto のような opt-out を追加する余地を残すか。

5. damage tracking と render-on-dirty

Daemon が row 粒度で damage を追い、client は redraw flag で全グリッドを再描画(client-side damage なし)。explanation/rendering/damage-tracking.md に「underdraw なし」が仕様。felis-gridScreenBuffer vs Grid の seam もこのためにある。

1.0 で「client は damage を読まない」ことを凍結するか、将来 client-side damage 消費者(例: 部分再描画で省電力)が現れた時の Revisit trigger を architecture/overview.md に記録するか。

6. platform 均一性 vs 例外

explanation/non-goals.md で「macOS/Linux/Windows で均一に実装できない機能は省略」が原則だが、window.backdrop と ConPTY の t=f/t/s 制限は例外として carve-out。1.0 でこの「例外は shim であり gated feature ではない」線引きをより厳密にし、新しい OS 依存機能の追加基準を non-goals.md に明記すべき。

提案

  • window.opacity / backdrop / shader.post / font.* の各キーについて、1.0 での凍結値集合を reference/config.md に「1.0 凍結」ラベル付きで明記し、将来の追加が additive(新 backdrop 値、新 shader.builtin)であることを control-surfaces.md の lenient parsing 契約と紐づけ。
  • shader.post を将来配列化する可能性があるなら、今のうちに post = {builtin=...}post = [{builtin=...}] に破壊的変更するか、現行単一値を 1.0 として凍結し、将来は post_list のような別キーで拡張する方針を決める。
  • rendering の platform 例外(Windows body transparency 不可、ConPTY t=f/t/sENOTSUP)を reference/protocols/support-matrix.mdreference/workspace.md の Build matrix に 1.0 の既知制限として再掲。

判定基準

  • config.tomlwindow / shader / font 節だけを見て、どの値が live reload でどれが要 relaunch か、どの値がどの OS で効くかが推測できること。
  • 1.0 の felis-config.schema.json が、将来の minor 追加を additionalProperties non-strict で許容しつつ、typo を editor 上で検出できること。

cc @natsukium

## 背景 felis の rendering は daemon が `RowDelta`(row 粒度の damage)と画像配置を送り、client が `felis-render-wgpu` で毎フレーム全グリッドを再描画する。`explanation/rendering/pipeline.md` に cell pass(bg→fg→decoration→image の4 pipeline)+ optional post-process(`shader.post`)が仕様化。フォントは `felis-shaping`(swash)で `font.size` は logical px。 ## 現状の問題 / 凍結前に決めるべき点 ### 1. `window.opacity` と `window.backdrop` の結合 - `opacity` は background opacity(kitty `background_opacity` モデル)で、明示的 bg を持つ cell は不透明のまま。OS compositor が合成。 - `backdrop` は OS-native material(`none/blur/acrylic/mica/tabbed`)で、各値が特定 OS にのみ有効。 現行: `blur` は `opacity < 1.0` でないと window 背面に隠れて無効、Windows material は `opacity` によらず title bar に効く(body は wgpu DX12 swapchain が opaque のため常に不透明)。`backlog.md` に「Windows body transparency は wgpu の `CreateSwapChainForHwnd` が `Opaque` のみのため不可」と明記。 **問い:** 1.0 で `opacity` と `backdrop` を独立したキーとして凍結するか、将来の Linux compositor blur 対応で `backdrop` に Linux 値が追加された時に値集合が OS ごとに分岐し続けることを許容するか。代替: `window.transparency = {opacity, backdrop}` のようにまとめる。 ### 2. `shader.post` の契約 `shader.post = {builtin="trail"} | {file="..."}` で、WGSL の `fs_post` entry point と uniform 契約(`reference/shaders.md`)が append-only で versioned。`shader.animate = "never" | "focused"` で continuous redraw を制御。 - 現行は `post` が単一値(1つの post-process pass)。将来複数 pass(blur→trail のチェーン)を許すなら `post = [{...}, {...}]` の配列に破壊的変更が必要。今しか配列化できない。 - `animate = "focused"` は idle CPU を犠牲にする opt-in。`"always"`(unfocused でも回す)を意図的に持たない。1.0 でこの「unfocused では回さない」制約を凍結するか。 ### 3. font size の単位と範囲 `font.size = 14.0` は logical px(window scale を掛ける前の値)で、`4.0..=72.0` に clamp、非正・非有限は built-in default に fallback。`MIN_FONT_SIZE_LOGICAL_PX` / `MAX_FONT_SIZE_LOGICAL_PX` が `felis-client-core` に定数。`Ctrl+Wheel` / `font_size` action でも同じ band。 `_logical_px` と `_physical_px` の命名分離は DPI 境界での bug を防ぐ意図。1.0 でこの命名と clamp 範囲を凍結するか、将来的に `font.size = "14pt"` のような単位付き文字列を許すか。 ### 4. `font.fallback` の auto-discover 空配列時に CJK 1 face + symbol 全 face + emoji 1 face + nerd 1 face を auto-discover。非空なら宣言順に append し auto-discover は走らない。`family` 必須、`features` 省略で `font.features` を継承。 auto-discover が暗黙に大量の font を mmap する(Apple Color Emoji 183MiB 等)点は `explanation/rendering/text-shaping.md` に記載。1.0 で auto-discover の対象集合(現行の4グループ)を凍結するか、将来的にユーザがグループごとに on/off できる `font.fallback.auto` のような opt-out を追加する余地を残すか。 ### 5. damage tracking と render-on-dirty Daemon が row 粒度で damage を追い、client は redraw flag で全グリッドを再描画(client-side damage なし)。`explanation/rendering/damage-tracking.md` に「underdraw なし」が仕様。`felis-grid` の `ScreenBuffer` vs `Grid` の seam もこのためにある。 1.0 で「client は damage を読まない」ことを凍結するか、将来 client-side damage 消費者(例: 部分再描画で省電力)が現れた時の Revisit trigger を `architecture/overview.md` に記録するか。 ### 6. platform 均一性 vs 例外 `explanation/non-goals.md` で「macOS/Linux/Windows で均一に実装できない機能は省略」が原則だが、`window.backdrop` と ConPTY の `t=f/t/s` 制限は例外として carve-out。1.0 でこの「例外は shim であり gated feature ではない」線引きをより厳密にし、新しい OS 依存機能の追加基準を `non-goals.md` に明記すべき。 ## 提案 - `window.opacity` / `backdrop` / `shader.post` / `font.*` の各キーについて、1.0 での凍結値集合を `reference/config.md` に「1.0 凍結」ラベル付きで明記し、将来の追加が additive(新 `backdrop` 値、新 `shader.builtin`)であることを `control-surfaces.md` の lenient parsing 契約と紐づけ。 - `shader.post` を将来配列化する可能性があるなら、今のうちに `post = {builtin=...}` を `post = [{builtin=...}]` に破壊的変更するか、現行単一値を 1.0 として凍結し、将来は `post_list` のような別キーで拡張する方針を決める。 - rendering の platform 例外(Windows body transparency 不可、ConPTY `t=f/t/s` は `ENOTSUP`)を `reference/protocols/support-matrix.md` と `reference/workspace.md` の Build matrix に 1.0 の既知制限として再掲。 ## 判定基準 - `config.toml` の `window` / `shader` / `font` 節だけを見て、どの値が live reload でどれが要 relaunch か、どの値がどの OS で効くかが推測できること。 - 1.0 の `felis-config.schema.json` が、将来の minor 追加を `additionalProperties` non-strict で許容しつつ、typo を editor 上で検出できること。 cc @natsukium
Author
Owner

Superseded by the concrete unit rename in #28. The later review retained the existing rendering/window architecture and platform boundary recorded in #12; other speculative redesign questions are not v0.1.0 work.

Superseded by the concrete unit rename in #28. The later review retained the existing rendering/window architecture and platform boundary recorded in #12; other speculative redesign questions are not v0.1.0 work.
Sign in to join this conversation.
No description provided.