feat(v2): T-309 no startup foreground grab, auto-close popup, rename buttons
- Comment out Gio's startup SetForegroundWindow/SetFocus in the vendored os_windows.go (marked SILVER-POSE PATCH; reverts on re-vendor) so the window no longer steals foreground on launch. Gio has no option for this. - The fall confirm popup auto-closes 5s after opening (op.InvalidateCmd schedules the redraw even with no live frames); '我已知晓' still closes early. - Rename save buttons to 保存摄像头参数 / 保存常用检测参数. Cross-compiles for Windows. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -639,3 +639,12 @@
|
||||
- 验证:UI 用 `GOOS=windows CGO_ENABLED=0` 交叉编译;store(sqlite,cgo) 本地 `CGO_ENABLED=1` gcc 编译;窗口/弹窗/DB 目视需 Windows。
|
||||
- 决策:SQLite 用 cgo mattn(用户选,vendor 更小;V2 本就 cgo)。DB 只存内网 host/端口/通道,不存密码;DB 放 artifacts/ 下随 gitignore。先做 ①(取消置顶/抢前台)。
|
||||
- 下一步:定位并取消窗口置顶(Gio ViewEvent 拿 HWND + SetWindowPos NOTOPMOST/NOACTIVATE),交叉编译验证。
|
||||
|
||||
## 【2026-07-23】T-309 A:取消抢前台 + 弹窗自动关 + 按钮改名
|
||||
|
||||
- 状态:DOING
|
||||
- 变更:①**vendored patch**——注释掉 `v2/vendor/gioui.org/app/os_windows.go` 启动时的 `SetForegroundWindow`/`SetFocus`(带 `SILVER-POSE PATCH (T-309)` 标记),取消"启动抢前台"。**注意:Gio 无 API 可关此行为;重跑 `go mod vendor` 会还原此补丁,需按标记重打。** 窗口默认非置顶(TopMost=false),故不需另改置顶。②④ 保存按钮改名为"保存摄像头参数"/"保存常用检测参数"。⑤ 摔倒确认弹窗记录打开时间,`layout` 中超 5 秒自动清除,并用 `op.InvalidateCmd{At:}` 调度到期重绘(停流也能自动关);"我已知晓"仍可提前关。
|
||||
- 验证:`GOOS=windows CGO_ENABLED=0 go build -mod=vendor ./internal/ui/... ./cmd/ui-spike/...` 退出码 0(含 patched os_windows.go);gofmt 干净。窗口不抢前台/弹窗自动关的实际行为需 Windows 目视。
|
||||
- 阻塞:③测试连接、⑥SQLite 未做。
|
||||
- 决策:抢前台只能靠 patch vendored Gio(无 API);已加显著标记并在此记录,便于 re-vendor 后重打。
|
||||
- 下一步:③测试连接摄像头按钮+弹窗;⑥SQLite(mattn) 记录(config 保留 host/端口/通道 + internal/store + 接线)。
|
||||
|
||||
@@ -115,6 +115,7 @@ type Window struct {
|
||||
latestImage *image.RGBA
|
||||
imageGen uint64
|
||||
pending *alert.Record
|
||||
pendingAt time.Time
|
||||
seenAlerts map[string]struct{}
|
||||
incoming []galleryIncoming
|
||||
seenEvents map[string]struct{}
|
||||
@@ -335,6 +336,7 @@ func (window *Window) PresentAlert(record alert.Record) {
|
||||
window.seenAlerts[record.Event.EventID] = struct{}{}
|
||||
queued := record
|
||||
window.pending = &queued
|
||||
window.pendingAt = time.Now()
|
||||
window.mu.Unlock()
|
||||
playAlertSound()
|
||||
window.appWindow.Invalidate()
|
||||
@@ -360,6 +362,7 @@ func (window *Window) layout(gtx layout.Context) layout.Dimensions {
|
||||
frame := window.latestImage
|
||||
gen := window.imageGen
|
||||
pending := window.pending
|
||||
pendingAt := window.pendingAt
|
||||
incoming := window.incoming
|
||||
running := window.running
|
||||
window.incoming = nil
|
||||
@@ -410,6 +413,17 @@ func (window *Window) layout(gtx layout.Context) layout.Dimensions {
|
||||
window.mu.Unlock()
|
||||
pending = nil
|
||||
}
|
||||
// The confirm popup auto-closes 5 seconds after it opens.
|
||||
if pending != nil {
|
||||
if time.Since(pendingAt) >= 5*time.Second {
|
||||
window.mu.Lock()
|
||||
window.pending = nil
|
||||
window.mu.Unlock()
|
||||
pending = nil
|
||||
} else {
|
||||
gtx.Execute(op.InvalidateCmd{At: pendingAt.Add(5 * time.Second)})
|
||||
}
|
||||
}
|
||||
|
||||
content := func(gtx layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
@@ -701,7 +715,7 @@ func (window *Window) layoutSettings(gtx layout.Context, model ViewModel) layout
|
||||
window.editorRow("传输 (tcp/udp)", &window.editTransport),
|
||||
window.editorRow("连接超时 (秒)", &window.editTimeout),
|
||||
window.checkRow("低延迟", &window.lowLatency),
|
||||
window.buttonRow(&window.saveCamera, "保存摄像头"),
|
||||
window.buttonRow(&window.saveCamera, "保存摄像头参数"),
|
||||
)
|
||||
paramsCard := verticalRows(
|
||||
window.heading("常用检测参数(下次启动生效)"),
|
||||
@@ -711,7 +725,7 @@ func (window *Window) layoutSettings(gtx layout.Context, model ViewModel) layout
|
||||
window.editorRow("模型置信度", &window.editModelConf),
|
||||
window.checkRow("要求先快速下移", &window.requireRapid),
|
||||
window.checkRow("要求膝踝清晰", &window.requireLower),
|
||||
window.buttonRow(&window.saveParams, "保存参数"),
|
||||
window.buttonRow(&window.saveParams, "保存常用检测参数"),
|
||||
window.labelRow(window.settingsStatus),
|
||||
)
|
||||
depsCard := verticalRows(
|
||||
|
||||
+4
-2
@@ -112,8 +112,10 @@ func newWindow(win *callbacks, options []Option) {
|
||||
defer winMap.Delete(w.hwnd)
|
||||
w.Configure(options)
|
||||
w.ProcessEvent(Win32ViewEvent{HWND: uintptr(w.hwnd)})
|
||||
windows.SetForegroundWindow(w.hwnd)
|
||||
windows.SetFocus(w.hwnd)
|
||||
// SILVER-POSE PATCH (T-309): do not steal foreground/focus on startup.
|
||||
// Re-applying `go mod vendor` reverts this; see progress.md.
|
||||
// windows.SetForegroundWindow(w.hwnd)
|
||||
// windows.SetFocus(w.hwnd)
|
||||
// Since the window class for the cursor is null,
|
||||
// set it here to show the cursor.
|
||||
w.SetCursor(pointer.CursorDefault)
|
||||
|
||||
Reference in New Issue
Block a user