Skip to content

fix(ui): stop the leftover xterm viewport painting a strip under the terminal (src/styles.css, docs) - #79

Merged
smileygames merged 1 commit into
mainfrom
77-fix-ui-terminal-scrollbar
Aug 24, 2026
Merged

fix(ui): stop the leftover xterm viewport painting a strip under the terminal (src/styles.css, docs)#79
smileygames merged 1 commit into
mainfrom
77-fix-ui-terminal-scrollbar

Conversation

@smileygames

Copy link
Copy Markdown
Member

Closes #77

端末の下辺に出ていた横方向の帯と、右端のスクロールバーの矢印を消す。原因は実測で特定した。実際の src/styles.cssindex.html の DOM からブラウザ上に採寸用のページを組み、そこで箱を測っている。

原因は .xterm-viewport である。xterm 6 のスクロールは .xterm-scrollable-element が持ち、この要素は誰も測らない空の div として残っているが、xterm 自身のスタイルシートは保守されていない二つの指定を当てたままである——テーマの届かない #000 の塗りと、ネイティブのスクロールバーを 15px 分確保する overflow-y: scroll である。端末の箱は height: 100% で面いっぱいへ伸ばしてあり、xterm が描くのは行の整数倍であるから、行数 × 行の高さ を引いた余りが下辺に残る。そこをこの空の要素が黒で塗っていた。

帯は割り算の余りであり、面の高さとともに動く(実測、600〜900px の窓で 4.44px 〜 14.44px)。新しく生まれたものではなく、#68 が 800px の窓で 6.63px から 14.44px へ動かした。

前提に書かれていた仮説(.xterm-screen.xterm-viewport より広くなって横のバーが出る)は実測で否定された。.xterm-screen.xterm-scrollable-element の中にあり、横方向の溢れは無い。補正も壊れていない——fit が測るのは .term であり、桁数と行数は実際に描かれている面と一致する(修正の前後どちらでも 1280×800 の窓に対して 126×23、画面は 960×345)。

制約の確認:

未確認: WebView2 上の見た目。採寸はブラウザ上の計測ページで行っている。

…terminal

端末の下辺に出ていた横方向の帯と、右端のスクロールバーの矢印を消す。原因は
実測で特定した。実際のスタイルシートと index.html の DOM からブラウザ上に
採寸用のページを組み、そこで箱を測っている。

xterm 6 のスクロールは `.xterm-scrollable-element` が持ち、`.xterm-viewport`
は誰も測らない空の `div` として残っている。それでも xterm 自身のスタイル
シートはこの要素へ二つの指定を当てたままであり、どちらも保守されていない
——テーマの届かない `#000` の塗りと、ネイティブのスクロールバーを 15px 分
確保する `overflow-y: scroll` である。端末の箱は `height: 100%` で面いっぱい
へ伸ばしてあり、xterm が描くのは行の整数倍であるから、`行数 × 行の高さ` を
引いた余りは誰も描かない帯として下辺に残る。そこをこの空の要素が黒で塗り、
右端にはネイティブのスクロールバーの下向き矢印が出ていた。

帯は割り算の余りであり、面の高さとともに動く。実測で 600〜900px の窓に対して
4.44px から 14.44px である。新しく生まれたものではなく、#68 が 800px の窓で
6.63px から 14.44px へ動かした。矢印の高さに届かなかったものがちょうど一つ分
になった時点で、縁ではなくスクロールバーとして読まれる。

補正の側は壊れていない。`fit` が測るのは `.term` であり、そこから出る桁数と
行数は実際に描かれている面と一致する。修正の前後どちらでも 126×23 に対して
960×345(1280×800 の窓)であり、`fitShown` の呼び出し口にも触れていない。
端末の使える面積も変えていない。直すのは何も描かない要素であるため、
`.xterm-viewport` へ `display: none` を当てる。塗りや `overflow` を上書き
する形は採らない。その形では次の面の高さが作る余りの上に帯がまた立つ。

同じ規則に並んでいた `.xterm-viewport` と `.xterm-screen` の `height: 100%`
も外す。前者は四辺で位置指定済み、後者はレンダラのインライン `height` が
勝つため、どちらも何も変えていなかった。

#77

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@smileygames smileygames linked an issue Aug 24, 2026 that may be closed by this pull request
@smileygames smileygames self-assigned this Aug 24, 2026

@smileygames smileygames left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

自己レビュー結果: PASS

#77 の受け入れ基準に対して差分を確認し、原因の主張を独立に裏取りした。

原因の裏取り

issue の前提に書いた仮説(.xterm-screen が viewport より広くなる)は外れており、実装者が実測で否定している。仮説を潰した上で別の原因に到達しているので、その筋を追認する。

node_modules/@xterm/xterm/css/xterm.css を直接読んで確認した。.xterm .xterm-viewportbackground-color: #000(ハードコード)と overflow-y: scroll、そして position: absolute + top/right/bottom/left: 0 が乗っている。.xterm の箱いっぱいに黒い層が敷かれ、その右端に native のスクロールバーが確保される。

.xterm-screen はこの中ではなく兄弟である(lib/xterm.js の生成箇所で、viewport と screen が同じ fragment へ別々に append されている)。したがって screen が描く rows × cell height の下に残る帯だけが黒く見える。実機の見え方と一致する。

インストール済みは @xterm/xterm 6.0.0。スクロールは .xterm-scrollable-element 側にあり、xterm-viewport のクラス名は JS 中に生成箇所の一度しか出てこない。display: none で壊れる経路が無いことを、以下まで見て確認した。

  • OverviewRulerRendereroverviewRuler オプション未使用。かつ canvas は viewport の前に兄弟として挿入されるので、隠しても消えない。
  • DomRenderer_viewportElement.style.height(インラインスタイル)を読む。CSS の display はインラインスタイルを書き換えないため、前後で読み値は変わらない。
  • ホイールスクロール — viewport にリスナは付いていない。handleMouseWheel は scrollable element 側。

受け入れ基準

  • 測定してから直している — 当て推量の CSS ではない。#68 で 6.63px → 14.44px(800px 窓)へ動いたという数字まで出ており、「#68 以降に見え始めた」という観察と符合する。
  • 端末の面積を減らしていない#77 の制約)— .term は 980.44×359.44 のまま。
  • 補正の仕組みを壊していないfitShown の呼び出し口は無改変。resize_pty の桁数と行数は描かれている面と一致(126×7.617=960、23×15=345)。
  • 三軸の独立#60 / #66 / #68)は無改変。

ついでの掃除

height: 100% のセレクタから .xterm-viewport.xterm-screen が落ちている。どちらも効いていなかったという理由が書かれており(screen は renderer のインライン height を持つためスタイルシートが届かない、viewport は四辺に位置指定済み)、妥当。

実機未確認

  • WebView2 での見え方。実測はブラウザで行っており、実機の webview ではない(docs に記録済み)。
  • scrollback のホイールスクロール。 経路上は壊れないことを上記で確認したが、動きそのものは未確認。実機で端末を流したときに追随するかを見ておくのが安全。

次の一手

実行モード auto。この自己レビュー通過をもって squash merge する。リリース種別は patch 相当(観測可能だが、CSS 一行の修正であり構造変更ではない)。

@smileygames
smileygames merged commit 4e53ffc into main Aug 24, 2026
2 checks passed
@smileygames
smileygames deleted the 77-fix-ui-terminal-scrollbar branch August 24, 2026 02:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ui): a scrollbar appears in the terminal after the header landed

1 participant