fix(windows/conpty): pass HPCON value, not &hPC (v0.7.8)
All checks were successful
PR Check / check (pull_request) Successful in 1m3s

User reported regression introduced in v0.7.6: PowerShell / cmd open
in a separate external console window instead of attaching to the
xterm.js tab (v0.7.5 worked).

Root cause: the ConPTY wiring used
  attrList.Update(PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
                  unsafe.Pointer(&hPC),    // ← wrong
                  unsafe.Sizeof(hPC))

The PSEUDOCONSOLE attribute is a Win32 API quirk: lpValue must be
the HPCON *value* (cast to PVOID), not a pointer to the local
variable holding the handle. With &hPC the kernel reads garbage,
silently drops the attribute, and CreateProcessW spawns the child
with a fresh console — hence the external window.

Fix is one line:
  unsafe.Pointer(uintptr(hPC))

Confirmed against Microsoft's EchoCon sample and Go libraries that
work in production (UserExistsError/conpty, aymanbagabas/go-pty).

- internal/version/version.go: 0.7.7 → 0.7.8
- CHANGELOG.md: v0.7.8 entry with the diagnostic write-up
This commit is contained in:
Muyue
2026-04-27 14:39:26 +02:00
parent af5fbf9324
commit a3487392c0
3 changed files with 30 additions and 2 deletions

View File

@@ -4,6 +4,28 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## v0.7.8
### Fix régression v0.7.6 : terminaux ouverts en fenêtre externe
Symptôme rapporté : depuis v0.7.6, cliquer sur PowerShell / cmd dans l'onglet Terminal ouvre une **fenêtre console séparée** au lieu de s'afficher dans le tab xterm.js (régression — v0.7.5 fonctionnait).
**Cause** : le binding ConPTY introduit en v0.7.6 passait `&hPC` (pointeur vers la variable Go locale) à `UpdateProcThreadAttribute(PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, …)`. Or cet attribut est un quirk de l'API Win32 : `lpValue` doit être la **valeur du handle** (cast en `PVOID`), **pas** un pointeur vers la variable. Avec `&hPC`, le kernel lisait des octets aléatoires, l'attribut PSEUDOCONSOLE était silencieusement ignoré, et `CreateProcessW` créait une nouvelle console pour l'enfant — d'où la fenêtre externe.
**Fix** (1 ligne) :
```go
// Avant
unsafe.Pointer(&hPC)
// Après
unsafe.Pointer(uintptr(hPC)) // le HPCON value comme PVOID
```
Référence : Microsoft EchoCon sample + bibliothèques Go ConPTY existantes (`UserExistsError/conpty`, `aymanbagabas/go-pty`) utilisent toutes la valeur du handle directement.
Conséquence : terminaux PowerShell / cmd / WSL s'ouvrent à nouveau **dans** le tab xterm.js avec TTY complet (ANSI, prompt couleur, vim, etc.).
## v0.7.7 ## v0.7.7
### Fix : install Windows échoue silencieusement quand une version précédente tourne ### Fix : install Windows échoue silencieusement quand une version précédente tourne

View File

@@ -80,9 +80,15 @@ func startConptySession(cmd *exec.Cmd) (termSession, error) {
windows.CloseHandle(outRead) windows.CloseHandle(outRead)
return nil, fmt.Errorf("NewProcThreadAttributeList: %w", err) return nil, fmt.Errorf("NewProcThreadAttributeList: %w", err)
} }
// PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE is a quirk of the Win32 API: lpValue
// is the HPCON *value* (cast to PVOID), not a pointer to the handle. If
// we pass &hPC the kernel reads garbage, the PC attribute is silently
// ignored, and cmd/pwsh get their own external console window — which is
// exactly the regression v0.7.6 introduced. The cbSize stays the size of
// the handle (8 bytes on amd64). Reference: Microsoft EchoCon sample.
if err := attrList.Update( if err := attrList.Update(
procThreadAttributePseudoconsole, procThreadAttributePseudoconsole,
unsafe.Pointer(&hPC), unsafe.Pointer(uintptr(hPC)),
unsafe.Sizeof(hPC), unsafe.Sizeof(hPC),
); err != nil { ); err != nil {
attrList.Delete() attrList.Delete()

View File

@@ -7,7 +7,7 @@ import (
const ( const (
Name = "muyue" Name = "muyue"
Version = "0.7.7" Version = "0.7.8"
Author = "La Légion de Muyue" Author = "La Légion de Muyue"
) )