MODULO 4.7

📺 Fullscreen Mode

O alternate screen buffer (DEC mode 1049) que permite UI rica interativa, mouse tracking e scroll virtualizado -- as mesmas sequencias usadas por vim, less e htop.

7
Topicos
~65
Minutos
Deep
Nivel
Source
Tipo
1

📟 DEC Private Mode Sequences

const DEC = {
  CURSOR_VISIBLE:      25,
  ALT_SCREEN:         47,     // older; NAO salva/restaura cursor
  ALT_SCREEN_CLEAR:   1049,   // modern: save cursor + switch + clear
  MOUSE_NORMAL:       1000,   // button press/release + wheel
  MOUSE_BUTTON:       1002,   // adds drag (button-motion)
  MOUSE_ANY:          1003,   // adds all-motion (hover)
  MOUSE_SGR:          1006,   // SGR format
  FOCUS_EVENTS:       1004,
  BRACKETED_PASTE:    2004,
  SYNCHRONIZED_UPDATE:2026,
}

💡 Por que 1049 e nao 47?

DEC mode 1049 salva posicao do cursor antes de trocar e restaura na saida. O antigo mode 47 troca buffers sem preservar cursor. Claude Code usa 1049 exclusivamente para preservar a posicao do cursor do shell.

2

🖱️ Mouse Tracking & Teardown

Os 4 modos mouse sao habilitados em ordem crescente e desabilitados em ordem reversa (outer para inner):

Enable:  1000 -> 1002 -> 1003 -> 1006
Disable: 1006 -> 1003 -> 1002 -> 1000

Desabilitar em ordem reversa garante teardown limpo. Se o processo crashar entre dois decreset, nao deixa modo parcial ativo.

Env var Desabilita Ainda funciona
NO_FLICKER=0Alt-screen + mouse trackingTerminal scrollback normal
DISABLE_MOUSE=1Mouse capture (wheel+click)Alt-screen + keyboard nav
DISABLE_MOUSE_CLICKS=1Click e dragAlt-screen + wheel scroll
3

🔍 Logica de Deteccao Fullscreen

flowchart TD
    A["isFullscreenActive()"] --> B{"getIsInteractive()"}
    B -->|"false (headless/SDK)"| Z["return false"]
    B -->|"true"| C["isFullscreenEnvEnabled()"]
    C --> D{"NO_FLICKER\nexplicitly falsy?"}
    D -->|"yes (=0)"| Z
    D -->|"no"| E{"NO_FLICKER\nexplicitly truthy?"}
    E -->|"yes (=1)"| Y["return true"]
    E -->|"no"| F{"isTmuxControlMode()?"}
    F -->|"yes (iTerm2 -CC)"| Z
    F -->|"no"| G{"USER_TYPE === 'ant'?"}
    G -->|"yes"| Y
    G -->|"no"| Z
                    
4

🔌 tmux -CC Probe Sincrono

probeTmuxControlModeSync() chama spawnSync('tmux', ['display-message', '-p', '#{client_control_mode}']) -- subprocess sincrono bloqueando o event loop por ~5ms.

⚠️ Por que sincrono?

Um probe async competiu com o React render e perdeu: usuarios de SSH + tmux -CC terminavam com alt-screen ativo e mouse wheel morto. O custo de 5ms uma vez no startup evita um bug de UX irrecuperavel. So dispara quando $TMUX esta setado E $TERM_PROGRAM esta ausente.

5

⚛️ AlternateScreen React Component

Limite React que escreve sequencias DEC no terminal. Constrainte critico: escapes devem chegar ao terminal antes do primeiro frame renderizado.

useInsertionEffect vs useLayoutEffect

useInsertionEffect dispara durante a mutation phase, antes de resetAfterCommit do Ink. Com useLayoutEffect, o primeiro onRender dispararia ANTES deste efeito -- pintando um frame na tela principal que seria preservado como view quebrada ao sair do alt-screen.

Height Constraint

Alt-screen nao tem scrollback. AlternateScreen pina sua altura em size.rows de TerminalSizeContext, forcando todo overflow a ser tratado pelo flexbox do Ink.

6

🏗️ FullscreenLayout: 5 Slots

scrollableMessage list -- vive em ScrollBox com stickyScroll
bottomStrip inferior pinado: prompt, spinner, permissions
overlayRenderizado dentro do ScrollBox apos mensagens
bottomFloatAbsolute bottom-right do scroll area
modalDialogo slash-command, absolute bottom-anchored

💡 OffscreenFreeze

Explora bail-out por identidade de objeto do React para produzir zero diff output para conteudo que scrollou para o scrollback do terminal. Usa 'use no memo' para opt-out do React Compiler, porque memoizacao automatica derrotaria o mecanismo de freeze.

7

🔄 Ciclo de Vida Completo

sequenceDiagram
    participant Startup
    participant fullscreen.ts
    participant AlternateScreen
    participant Ink
    participant Terminal
    Startup->>fullscreen.ts: isFullscreenActive()?
    fullscreen.ts-->>Startup: true
    Startup->>AlternateScreen: mount (useInsertionEffect)
    AlternateScreen->>Terminal: ENTER_ALT_SCREEN + clear + ENABLE_MOUSE
    AlternateScreen->>Ink: setAltScreenActive(true, mouseTracking)
    Note over Ink: renderer clamps cursor to viewport
    loop Every render frame
        Ink->>Terminal: diff output within alt-screen bounds
    end
    Startup->>AlternateScreen: unmount (cleanup)
    AlternateScreen->>Ink: setAltScreenActive(false)
    AlternateScreen->>Terminal: DISABLE_MOUSE + EXIT_ALT_SCREEN
    Note over Terminal: main screen + cursor restored
                    

📋 Resumo do Modulo

Alt-screen e DEC mode 1049, nao o antigo 47 -- 1049 salva e restaura posicao do cursor
useInsertionEffect garante que ENTER_ALT_SCREEN chega ao terminal antes do primeiro frame do Ink
Probe tmux -CC e sincrono por design -- probe async causava bug irrecuperavel para usuarios SSH+tmux
Fullscreen default ON para usuarios internos (USER_TYPE=ant), OFF para externos (opt-in via NO_FLICKER=1)
OffscreenFreeze elimina full resets per-tick para conteudo no scrollback do terminal
Mouse tracking tem dois kill-switches ortogonais: DISABLE_MOUSE (mata captura) e NO_FLICKER=0 (mata tudo)
Modulo Anterior Proximo Modulo