From 6605adaed5168771df379fdd5fa87b5fc0e6142a Mon Sep 17 00:00:00 2001 From: ngfchl Date: Sat, 20 Jun 2026 14:53:59 +0800 Subject: [PATCH] fix: nvidia-smi field index mapping, TUI vertical layout to prevent scroll jump --- cmd/client/main.go | 78 +++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 50 deletions(-) diff --git a/cmd/client/main.go b/cmd/client/main.go index 85011bc..6f06cf7 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -549,10 +549,7 @@ func (m model) viewMonitor() string { if tw < 60 { tw = 60 } - th := m.h - if th < 20 { - th = 20 - } + innerW := tw - 4 // ── 顶栏 ── wsDot := "○" @@ -572,47 +569,28 @@ func (m model) viewMonitor() string { ) sep := stDim.Render(strings.Repeat("─", tw)) - // ── 列宽计算 ── - gap := 2 - var leftW, rightW int - if tw >= 100 { - leftW = (tw - gap) / 2 - rightW = tw - gap - leftW - } else { - leftW = tw - rightW = tw - gap = 0 - } - innerL := leftW - 4 - innerR := rightW - 4 - - // ── 左列: CPU + History ── - cpuBox := m.viewCPUBox(innerL) - histBox := m.viewHistBox(innerL) - leftCol := lipgloss.JoinVertical(lipgloss.Left, cpuBox, "", histBox) - - // ── 右列: Memory + GPU ── - memBox := m.viewMemBox(innerR) - gpuBox := m.viewGPUBox(innerR) - rightCol := lipgloss.JoinVertical(lipgloss.Left, memBox, "", gpuBox) - - // ── 合并列 ── - var mainContent string - if gap > 0 { - mainContent = lipgloss.JoinHorizontal(lipgloss.Top, - leftCol, strings.Repeat(" ", gap), rightCol, - ) - } else { - mainContent = lipgloss.JoinVertical(lipgloss.Left, leftCol, "", rightCol) - } - - // ── 底栏 ── - footer := stDim.Render(" q 退出 · r 重新配置 · 连接: " + m.cfg.Server) + // ── 内容:全部垂直排列 ── + cpuBox := m.viewCPUBox(innerW) + memBox := m.viewMemBox(innerW) + histBox := m.viewHistBox(innerW) + gpuBox := m.viewGPUBox(innerW) full := lipgloss.JoinVertical(lipgloss.Left, - header, sep, "", mainContent, "", sep, footer, + header, sep, "", + cpuBox, "", + memBox, "", + histBox, "", + gpuBox, "", + sep, + stDim.Render(" q 退出 · r 重新配置 · 连接: "+m.cfg.Server), ) - return lipgloss.Place(tw, th, lipgloss.Left, lipgloss.Top, full) + + // 截断到终端高度,防止滚动 + lines := strings.Split(full, "\n") + if len(lines) > m.h { + lines = lines[:m.h] + } + return strings.Join(lines, "\n") } // ── CPU 盒子 ── @@ -1212,7 +1190,7 @@ func tryNvidiaSMI() []GPUInfo { var gpus []GPUInfo for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") { parts := strings.Split(line, ",") - if len(parts) < 11 { + if len(parts) < 17 { continue } for i := range parts { @@ -1220,10 +1198,10 @@ func tryNvidiaSMI() []GPUInfo { parts[i] = strings.Trim(parts[i], "[]") } - fan := parseFloatSafe(parts[10]) - power := parseFloatSafe(parts[9]) - powerLimit := parseFloatSafe(parts[10]) - + // 0:index 1:name 2:vram_total 3:vram_used 4:vram_free + // 5:temp 6:load 7:core_clk 8:mem_clk 9:power 10:power_limit + // 11:fan 12:pstate 13:persistence 14:compute_mode + // 15:driver 16:cuda gpus = append(gpus, GPUInfo{ Name: parts[1], VRAMTotalMB: parseFloat(parts[2]), @@ -1232,9 +1210,9 @@ func tryNvidiaSMI() []GPUInfo { LoadPercent: parseFloat(parts[6]), CoreClock: parseFloat(parts[7]), MemClock: parseFloat(parts[8]), - Power: power, - PowerLimit: powerLimit, - FanSpeed: fan, + Power: parseFloatSafe(parts[9]), + PowerLimit: parseFloatSafe(parts[10]), + FanSpeed: parseFloatSafe(parts[11]), PState: cleanStr(parts[12]), Persistence: cleanStr(parts[13]), ComputeMode: cleanStr(parts[14]),