Adds the PyQt6 Windows client (Homepage, Scan & results, About & updates, Settings), ClamAV scanning and quarantine, browser-download watch with an exclusive scan gate, Bolt loopback/PKCE sign-in with DPAPI key storage, Gitea release feed with checksum verification, opt-in diagnostics, and Windows/portable build tooling. Co-Authored-By: Claude Code <noreply@anthropic.com>
27 lines
884 B
Python
27 lines
884 B
Python
"""Bounded QThread shutdown for window close."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from PyQt6.QtCore import QThread
|
|
|
|
|
|
def stop_thread(worker: QThread | None, wait_ms: int = 4000) -> None:
|
|
"""Let a worker finish, then terminate it as a last resort.
|
|
|
|
QThread must never be destroyed while still running; Qt aborts the
|
|
process. Network and PowerShell calls can outlive a window close, so
|
|
request interruption, wait, and only then terminate. This runs during
|
|
application shutdown, never on a normal user action.
|
|
"""
|
|
if worker is None:
|
|
return
|
|
try:
|
|
if worker.isRunning():
|
|
worker.requestInterruption()
|
|
if not worker.wait(max(250, int(wait_ms))):
|
|
worker.terminate()
|
|
worker.wait(1000)
|
|
except RuntimeError:
|
|
# The C++ object was already deleted by deleteLater().
|
|
pass
|