Repository navigation
fix(terminal): clique sem seleção chega ao programa do pane (GLPI #272) - #24
Conversation
…swha#272) Com o mouse tracking ligado, todo clique esquerdo ganhava Shift forçado e virava seleção, então nenhum clique chegava ao pty. O ✕ que fecha o painel de diff do Claude Code não respondia. O herdr repassa o clique (testado com herdr terminal attach): um clique que não selecionou nada é reenviado ao xterm sem o modificador, e um arrasto continua selecionando e copiando. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gianlukamoraes
left a comment
There was a problem hiding this comment.
🟢 APROVADO — clique simples volta a chegar ao programa do pane (GLPI devswha#272)
🧑 Resumo (para humanos)
- 🟢 Corrige o chamado: um clique que não seleciona nada agora chega ao programa do terminal, então o ✕ do painel de diff do Claude Code volta a funcionar. Arrastar continua selecionando e copiando como antes.
- 🟡 Clique com a mão tremendo — se o ponteiro passar para a célula vizinha entre apertar e soltar, vira seleção de 1–2 letras e o clique não chega ao programa. É raro e o usuário tenta de novo. (não bloqueia)
- 🟡 Gate automático sem configuração para este repo — o monitor não tem a matriz de testes do herdr-web-ui, então rodei os testes à mão (abaixo). (não bloqueia; falta rodar
/pr-monitor:setupno repo)
O que fazer: nada obrigatório. Os critérios de merge estão atendidos; este monitor está em modo revisor e não faz merge.
🤖 Detalhe técnico (file:line, fix, cenário) — para o Claude Code / quem for corrigir
[N-1] Limiar de "clique" é a mesma célula — src/components/PaneTerminal.tsx:761
- Cenário: mousedown na col 10 e mouseup na col 11 (trackpad/jitter).
d.anchor !== d.cursor, e o mousedown com Shift forçado fez o xterm criar uma seleção de 2 células →hasSelection()true → copia "ab" e não envia o clique. - Fix (opcional): tratar como clique se o deslocamento em pixels for < ~4 px (guardar
clientX/YnoDrag) e chamarterm.clearSelection()antes de reenviar. Só vale a pena se aparecer reclamação.
[N-2] Gate — pr-gate.sh 24 → rc=2 GATE SETUP FAILED: sem matriz para dataagile/herdr-web-ui. Isso não é verdict. Rodei à mão num worktree no head 95e75c9:
bun run typecheck→ okbun run build→ okbun run test:unit→ 2194 pass, 6 skip, 0 fail (2200 testes)scripts/ui-regression.ts(Chrome real) não foi rodado aqui. Vale o resultado do autor no corpo do PR (89 PASS, o caso novo falha sem o fix).
Verificado limpo:
- Sem recursão nem drag fantasma: o mousedown reenviado tem
isTrusted=falseeonMouseDown(capture no host) retorna antes de forçar Shift ou criardrag. O mouseup reenviado chega aonMouseUpcomdrag === null(zerado antes do dispatch) e retorna. - O xterm reporta o evento sintético: com tracking ligado,
SelectionService.handleMouseDownretorna cedo (!_enabled && !shouldForceSelection) e o handler de mouse do xterm codifica press/release no modo pedido (SGR). O teste de UI cobre isso: um press e um release na mesma célula, e um arrasto sem report. - O clique depois de uma seleção não estende a seleção:
_handleIncrementalClicksó roda com_enabled, que é false em modo mouse. Com Shift forçado, o clique cai em_handleSingleClick, a seleção some e o clique é reenviado ao pane. - Modo observar / prompt de senha / held: o report sai por
term.onData, que já descarta input nesses estados (PaneTerminal.tsx:1044). O replay não fura o modo observar. - Touch e margem: mousedown vindo de toque e clique fora de
term.element(margem do grid seguido) não criamdrag, então não há replay. O comportamento anterior continua igual. - Duplo clique: o 1º clique chega ao pane. O 2º (
detail=2, com Shift forçado) seleciona a palavra e copia, como o PR descreve. - CHANGELOG em
### Fixedcom link do PR. Nenhum arquivo fora do escopo.
Checks de UI: não há campo de texto editável alterado (o check de digitação não se aplica). Não há regra de validação nova. A evidência é o teste em Chrome real em scripts/ui-regression.ts, que falha sem o fix, mais a reprodução manual via herdr terminal attach descrita no corpo.
Revisão do #24 (head 95e75c9)Veredito: precisa de ajustes. O caminho principal funciona: um clique sem seleção chega ao pane como SGR, e o arrasto continua só selecionando. Mas o clique reenviado abre o link duas vezes. A correção é de uma linha. Achados confirmados1. Clique num link abre o link duas vezes ( 2. O clique reenviado pode cair fora deste terminal ( Sugestão para o teste: o caso novo não cobre links. Vale imprimir uma URL no pane, trocar O que verifiquei e como
🤖 Generated with Claude Code |
…z (GLPI devswha#272) O clique reenviado ia ao elemento sob o ponteiro. O tratador de links da tela também escuta ali e abria o link de novo, e um soltar além da borda podia cair no pane vizinho. Agora vai a term.element. O ui-regression ganha um clique em link que deve abrir uma vez só (falha sem o fix: abre duas). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gianlukamoraes
left a comment
There was a problem hiding this comment.
🟢 APROVADO — os dois achados da revisão anterior foram corrigidos (GLPI devswha#272, head fda4a50)
🧑 Resumo (para humanos)
- 🟢 Link abre uma vez só: o clique reenviado agora vai à raiz do terminal, onde o detector de links não escuta. Clicar numa URL num pane com mouse ligado (Claude Code, por exemplo) abre uma aba, não duas.
- 🟢 O clique não escapa para o pane vizinho: soltar o mouse logo além da borda conta como clique na última coluna deste terminal, nunca no do lado.
- 🟢 Teste novo para o link, como sugerido: imprime uma URL no pane, clica e confere que abriu exatamente uma vez.
- 🟡 O teste de tela (navegador real) não rodou nesta máquina: falta uma biblioteca do sistema (
libatk) para abrir o Chromium. Typecheck e testes unitários passaram. (não bloqueia)
O que fazer: nada obrigatório. Os critérios estão atendidos; este monitor está em modo revisor e não faz merge.
🤖 Detalhe técnico (file:line, fix, cenário) — para o Claude Code / quem for corrigir
Delta revisado: 95e75c9..fda4a50 (1 commit): src/components/PaneTerminal.tsx:762-768 e o caso novo em scripts/ui-regression.ts:432-469.
Verificado no código:
- Link uma vez: o par sintético é disparado em
term.element. OLinkifierescuta mousedown/mouseup no filho.xterm-screen, e um evento disparado no pai não desce até o filho. ObindMousedo xterm escuta emterm.element, então o report SGR continua saindo. - Vizinho: com o alvo fixo em
term.element, o par só pode chegar a este xterm. A coluna é limitada à área do canvas emMouseService.getMouseReportCoords(node_modules/@xterm/xterm/src/browser/services/MouseService.ts:37-38), então um release fora da borda reporta a última coluna deste pane. - Sem recursão: o host (
onMouseDown, fase de captura) é ancestral determ.element. Ele vê o mousedown sintético, que temisTrusted=false, e retorna antes de forçar Shift. O mouseup sintético sobe até oonMouseUpcomdrag === nulle retorna. Nada mudou aqui em relação ao head anterior. rootnulo: antes determ.openoterm.elementé undefined, mas aí não hádrag. O guard&& rootcobre o caso.
Gate: pr-gate.sh 24 → rc=2 GATE SETUP FAILED: sem matriz para dataagile/herdr-web-ui. Isso não é verdict. Rodei à mão num worktree no head fda4a50:
bun run typecheck→ okbun run test:unit→ 2194 pass, 6 skip, 0 fail (2200 testes)bun run check run bun scripts/ui-regression.ts→ não rodou:/opt/google/chrome/chromenão existe aqui, e comCHROME_PATHapontando para o Chromium do Playwright o processo sai comlibatk-1.0.so.0: cannot open shared object file. Não confirmei oPASS a link in the terminal opens oncenem que ele falha sem o fix. Vale rodar no ambiente do autor antes do merge.
Nota (não bloqueia): o [N-1] da revisão de 27/10 (um tremor que passa para a célula vizinha vira seleção e não clique) continua como estava. Só vale mexer se aparecer reclamação.
Checks de UI: nenhum campo de texto editável alterado e nenhuma regra de validação nova. A evidência é o teste em navegador real em scripts/ui-regression.ts.
Revisão do #24 (head fda4a50)Veredito: ok para merge. O último commit resolve os dois achados da revisão anterior. Sobrou um ponto pequeno, que não bloqueia. A revisão anterior foi resolvida?
Achado (não bloqueia)1. O clique reenviado perde os modificadores (
Sugestão: copiar os modificadores do mouseup real, que não é alterado (o const init = { bubbles: true, cancelable: true, button: 0, clientX: event.clientX, clientY: event.clientY,
ctrlKey: event.ctrlKey, altKey: event.altKey, shiftKey: event.shiftKey, metaKey: event.metaKey };Com Shift (ou Option no Mac) de verdade, o O que verifiquei e como
🤖 Generated with Claude Code |
Chamado GLPI devswha#272 (Cláudio Carrijo, DevDA 0.9.3 / UI f8bb39e): "Não consigo fechar a tela do lado direito."
Faz parte dos glpi-pequenos, pedido do Gianluka em 26/10/2026.
O que é a tela: o painel de diff do próprio Claude Code ("No changes this session"). No modo fullscreen ele abre sozinho com 144 colunas ou mais e fecha pelo ✕ no canto ou por
/diff.Causa: com o mouse tracking ligado,
PaneTerminal.tsxforçava Shift em todo mousedown esquerdo para o arrasto selecionar. Com isso nenhum clique chegava ao pty, e o ✕ (como qualquer controle de mouse de um programa no pane) não respondia. O comentário dizia queherdr terminal attachignora clique esquerdo, mas não ignora: numherdr terminal attachno tmux, um clique SGR no ✕ fechou o painel.Mudança
onMouseUp: um clique que não selecionou nada (mesma célula, sem rolagem) é reenviado ao xterm como mousedown/mouseup sem o modificador. O xterm codifica o clique no modo que o pane pediu (SGR no herdr).onMouseDownignora evento não confiável, então o clique reenviado não ganha Shift.Testes
bun run typecheckebun run build: okbun run test:unit: 2200 testes, 0 falhasbun run check run bun scripts/ui-regression.ts(Chrome real, herdr isolado): 89 PASS, incluindo o caso novo "a terminal click reaches the pane and a drag sends no click". Sem o fix, o caso novo falha comTimed out: click as a mouse report.Paliativo até o deploy: digitar
/diffno prompt do Claude Code fecha o painel, e ele não volta a abrir sozinho.🤖 Generated with Claude Code