Skip to content

Fix #192: collapsed Claude Code input in face-remapped popups#201

Merged
dakra merged 1 commit intomainfrom
size-init-with-screen-lines
Apr 28, 2026
Merged

Fix #192: collapsed Claude Code input in face-remapped popups#201
dakra merged 1 commit intomainfrom
size-init-with-screen-lines

Conversation

@dakra
Copy link
Copy Markdown
Owner

@dakra dakra commented Apr 27, 2026

Summary

  • Fixes Starting Claude with CLAUDE_CODE_NO_FLICKER=1 results in rendering defect #192. Aaronjensen's Claude Code /tui fullscreen sometimes renders with the input box missing/collapsed when ghostel runs in a Doom popup with a theme that remaps the default face height (e.g. nano-light).
  • Root cause: ghostel--init-buffer captured terminal height with window-body-height (units = frame char height) while the standard window-adjust-process-window-size-smallest uses window-screen-lines (units = default-line-height). When a theme remaps the default face height, the two disagree, init captures the wrong number, and the very next redisplay fires window-configuration-change-hook → resize → SIGWINCH at startup. Claude Code's TUI sometimes mishandles a SIGWINCH-during-startup and never re-renders the input box.
  • Concrete numbers from the bug report: body 1307 px / 27 px frame char = 48; / 29 px default-line = 45.069. PTY spawned at 48, immediately SIGWINCH'd to 45. Bug is intermittent because Claude Code's re-layout reaction is non-deterministic.

Approach

  • Switch every height-capture site to floor(window-screen-lines) — same metric term.el, vterm, eat, and the standard adjust-fn use. With init capturing the right value from the start, the SIGWINCH-during-startup goes away.
  • Touched sites: ghostel--init-buffer, ghostel-exec, ghostel--commit-cropped-size, plus 3 sites in ghostel-compile.el.
  • Adds (max 1 …) guard on init-buffer height (parity with ghostel-exec).
  • Removes ghostel--reconcile-display-size and its window-buffer-change-functions registration (added in b9c12ca). Now redundant: with init using the right metric, the standard machinery catches every transition the helper tried to catch (chrome reshuffles via init_iterator's body-pixel comparison in xdisp.c:3443-3474, buffer migration via set_window_buffer setting FRAME_WINDOW_CHANGE).
  • Fixes the "Size sync" block in ghostel-debug-info (added in 0b19011) which compared against window-body-height and cried wolf for any face-remapped buffer.
  • Net: +71 / −205, mostly removing the dead --reconcile-display-size machinery.

Test plan

  • make -j4 all — 184 elisp + 97 native + 39 evil all green
  • aaronjensen verifies the bug is gone in his Doom + nano-light setup with Claude Code /tui fullscreen
  • M-x ghostel-debug-info Size sync block still reads "in sync" in non-face-remapped setups (verified locally)
  • Manual sanity in a face-remapped setup: confirm no SIGWINCH at startup (PTY rows match libghostty rows from the very first frame)

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes issue #192 where Claude Code’s TUI input can render collapsed when ghostel runs in face-remapped popup windows by aligning ghostel’s initial/captured terminal row calculations with Emacs’s standard window-adjust-process-window-size-* machinery (using floor(window-screen-lines)), eliminating a startup SIGWINCH size correction.

Changes:

  • Switch terminal height capture to floor(window-screen-lines) across ghostel startup/exec/compile sizing paths.
  • Remove now-redundant ghostel--reconcile-display-size and its window-buffer-change-functions registration.
  • Update ghostel-debug-info “Size sync” diagnostics and adjust tests accordingly.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
test/ghostel-test.el Updates resize-related tests for window-screen-lines and removes tests for deleted reconcile logic.
lisp/ghostel.el Uses floor(window-screen-lines) for sizing; removes ghostel--reconcile-display-size hook/function.
lisp/ghostel-debug.el Fixes “Size sync” diagnostics to compare against floor(window-screen-lines) and adds face-height context.
lisp/ghostel-compile.el Aligns compile-terminal height capture with floor(window-screen-lines) to avoid face-remap row mismatches.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lisp/ghostel.el
Comment thread test/ghostel-test.el Outdated
Comment thread test/ghostel-test.el Outdated
Comment thread lisp/ghostel.el
@dakra dakra force-pushed the size-init-with-screen-lines branch from d817181 to 0e4e113 Compare April 27, 2026 22:24
ghostel captured terminal height via `(window-body-height)' — which
divides the window's pixel height by frame char height.  But the
standard `window-adjust-process-window-size-smallest' (and term.el,
vterm, eat all do likewise) divides by `default-line-height' via
`(window-screen-lines)', which respects `face-remapping-alist' and
`:height' on the default face.

When a theme remaps the buffer's default face — `nano-light' /
`nano-dark' bump it ~7% higher than frame default — the two
metrics disagree.  Concrete report (#192): body 1307 px / 27 px
frame char = 48 (window-body-height); 1307 px / 29 px default-line
= 45.069 (window-screen-lines).  Init captures 48, libghostty +
PTY spawn at 48 rows; first redisplay fires
`window-configuration-change-hook' (because body-pixel differs
from the freshly-zeroed `old_body_pixel'), the standard adjust-fn
runs, returns 45, and we issue an immediate startup SIGWINCH down
to 45.  Claude Code's /tui fullscreen sometimes mishandles the
SIGWINCH-during-startup case and ends up with a collapsed input box.

Switch every height-capture site to `floor(window-screen-lines)':
- `ghostel--init-buffer' and `ghostel-exec' (the spawn paths).
- `ghostel--commit-cropped-size' (minibuffer focus return).
- `ghostel-compile.el' init/reconcile (3 sites) — same bug class.

Add the `(max 1 …)' guard on the init-buffer height that
`ghostel-exec' already had, since `floor' of a sub-1 value is a
real (if unlikely) source of a 0-row terminal.

Remove `ghostel--reconcile-display-size' and its
`window-buffer-change-functions' registration (added in b9c12ca).
Now redundant: with init capturing the right metric, the standard
machinery (`window-configuration-change-hook' →
`window--adjust-process-windows' → `--window-adjust-process-window-size')
catches every transition the helper tried to catch — chrome
reshuffles via `init_iterator''s body-pixel comparison
(xdisp.c:3443-3474), buffer migration via `set_window_buffer'
setting `FRAME_WINDOW_CHANGE'.

Fix the "Size sync" block in `ghostel-debug-info' (added in
0b19011): compare `term-rows' against `(floor (window-screen-lines))'
instead of `window-body-height', and surface the
frame-vs-default line-height delta directly so a face-remap shows
up in the report.

Update affected tests to mock `window-screen-lines'.
@dakra dakra force-pushed the size-init-with-screen-lines branch from 0e4e113 to ce966eb Compare April 27, 2026 22:26
@dakra dakra merged commit ce966eb into main Apr 28, 2026
20 checks passed
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.

Starting Claude with CLAUDE_CODE_NO_FLICKER=1 results in rendering defect

2 participants