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

+12 -2
View File
@@ -1,6 +1,16 @@
#include <stdio.h>
#include <unistd.h>
#include "my_application.h"
int main(int argc, char** argv) {
g_autoptr(MyApplication) app = my_application_new();
return g_application_run(G_APPLICATION(app), argc, argv);
MyApplication* app = my_application_new();
int status = g_application_run(G_APPLICATION(app), argc, argv);
// The window is gone and the engine with it (the app disposed its mpv
// players and left before closing the window). Skip exit(): its handlers
// include NVIDIA's EGL teardown (libEGL_nvidia), which segfaults inside
// exit() for Flutter apps. Nothing is left to flush but stdio.
fflush(stdout);
fflush(stderr);
_exit(status);
}
@@ -1,5 +1,8 @@
#include "my_application.h"
#include <stdio.h>
#include <unistd.h>
#include <flutter_linux/flutter_linux.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
@@ -38,6 +41,28 @@ static void window_method_cb(FlMethodChannel* channel, FlMethodCall* call,
fl_method_call_respond(call, response, nullptr);
}
// Ends the process 15 s after the first close request whatever is still
// running: the app's close (lib/src/platform/app_shutdown.dart) is bounded
// to a few seconds, but a native teardown can block for good, and the
// process must never stay behind a hidden window.
static gpointer exit_watchdog(gpointer data) {
g_usleep(15 * G_USEC_PER_SEC);
fflush(stdout);
fflush(stderr);
_exit(0);
return nullptr;
}
static gboolean window_delete_cb(GtkWidget* widget, GdkEvent* event,
gpointer user_data) {
static gboolean armed = FALSE;
if (!armed) {
armed = TRUE;
g_thread_unref(g_thread_new("exit-watchdog", exit_watchdog, nullptr));
}
return FALSE; // window_manager decides whether the window closes
}
static gboolean window_focus_in_cb(GtkWidget* widget, GdkEvent* event,
gpointer user_data) {
gtk_window_set_urgency_hint(GTK_WINDOW(widget), FALSE);
@@ -111,6 +136,10 @@ static void my_application_activate(GApplication* application) {
self);
gtk_widget_realize(GTK_WIDGET(view));
// Before the plugins: window_manager's delete-event handler stops the
// emission while the app holds the close.
g_signal_connect(window, "delete-event", G_CALLBACK(window_delete_cb),
nullptr);
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();