Stabilisation quick fixes: orderly close, visible version and update band, chat pop-ups on, Windows shaders and hwdec, render logs
ci / core (push) Successful in 27s
ci / server (push) Successful in 1m4s
ci / updater-windows (push) Successful in 5m50s

- Close: hide the window, dispose every player, thumbnail job and the
  sound engine, leave, then close normally; Linux runner _exit (the
  NVIDIA EGL exit handler crashed 10/10 closes, 0/41 now); Windows tears
  down inside the message loop, then TerminateProcess; watchdogs.
- Version under the Settings tab; an update band instead of a dot,
  never over a video; checks at start and every 4 hours.
- Chat pop-ups default to All again.
- Shader read-back compared as a list (old mpv joins with ','), so
  Windows stops turning shaders off; Windows hwdec auto-copy.
- Render diagnostics (`mpv: render` lines); RAM-only demuxer cache pin
  silences the file-cache warning; a volume readout test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
foxyzandClaude Opus 5.5 committed 2026-10-15 18:01:44 +03:00
1 parent e537f9d5f8
commit ea607c1a52
29 files changed
+873 -168

No files matched your search

+7 -24
View File
@@ -10,6 +10,7 @@ import 'package:window_manager/window_manager.dart';
import 'app.dart';
import 'src/playback/yt_dlp_app.dart';
import 'src/platform/app_log.dart';
import 'src/platform/app_shutdown.dart';
import 'src/platform/desktop_entry.dart';
import 'src/platform/window_memory.dart';
import 'src/screens/home/ui.dart';
@@ -48,7 +49,8 @@ Future<void> main(List<String> args) async {
await windowManager.ensureInitialized();
await windowManager.setPreventClose(true);
final memory = WindowMemory(Hive.isBoxOpen(settingsBoxName) ? Hive.box(settingsBoxName) : null);
windowManager.addListener(_CloseGuard(memory));
shutdownWindowMemory = memory;
windowManager.addListener(_CloseGuard());
final windowOptions = WindowOptions(
size: memory.size,
minimumSize: const Size(160, 90),
@@ -77,29 +79,10 @@ Future<void> main(List<String> args) async {
Future.delayed(const Duration(seconds: 2), SessionState.instance.sfx.warmUp);
}
/// Close button / Alt+F4: leave gracefully first (others see "left", a
/// hosted server shuts down), bounded so a hung socket can't keep the
/// window open.
/// Close button / Alt+F4: the orderly close ([shutDownApp]), so others
/// see "left", a hosted server shuts down and no player outlives the
/// engine.
class _CloseGuard with WindowListener {
final WindowMemory memory;
bool _closing = false;
_CloseGuard(this.memory);
@override
Future<void> onWindowClose() async {
if (_closing) return;
_closing = true;
await memory.save();
try {
await SessionState.instance.sfx.dispose().timeout(const Duration(milliseconds: 500));
} catch (e) {
debugPrint('sound shutdown on close failed: $e');
}
try {
await SessionState.instance.leave().timeout(const Duration(seconds: 2));
} catch (e) {
debugPrint('leave on close failed: $e');
}
await windowManager.destroy();
}
void onWindowClose() => unawaited(shutDownApp());
}