diff --git a/client/app.go b/client/app.go index fc54109..7618815 100644 --- a/client/app.go +++ b/client/app.go @@ -34,6 +34,8 @@ import ( ) var blockedReportLast sync.Map // processName -> time.Time +var lastKillDialogTime time.Time +var killDialogMu sync.Mutex var API_BASE = getEnv("API_BASE", "https://sv.rikkeiraia.org") @@ -212,11 +214,29 @@ func (a *App) startup(ctx context.Context) { go a.reportBlockedApp(procName, title) } blocker.Instance.OnKill = func(procName string, title string) { - _, _ = runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ - Type: runtime.WarningDialog, - Title: "Ứng dụng bị đóng", - Message: fmt.Sprintf("Hệ thống đã tự động đóng ứng dụng '%s' (%s) do không nằm trong danh sách các ứng dụng được phép sử dụng trong giờ học.", procName, title), - }) + killDialogMu.Lock() + if time.Since(lastKillDialogTime) < 5*time.Second { + killDialogMu.Unlock() + return + } + lastKillDialogTime = time.Now() + killDialogMu.Unlock() + + go func() { + defer func() { + if r := recover(); r != nil { + log.Printf("[APP] Recovered from MessageDialog panic: %v", r) + } + }() + if a.ctx == nil { + return + } + _, _ = runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{ + Type: runtime.WarningDialog, + Title: "Ứng dụng bị đóng", + Message: fmt.Sprintf("Hệ thống đã tự động đóng ứng dụng '%s' (%s) do không nằm trong danh sách các ứng dụng được phép sử dụng trong giờ học.", procName, title), + }) + }() } // Giám sát môi trường Windows: đa màn hình, desktop ảo, đổi user