From 31a8877fc070ce9776e0bb6bda3ee3e9da269f2e Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Mon, 16 Jun 2025 16:49:00 +0200 Subject: [PATCH] qt: intercept closeEvent for Macos On MacOS, the Quit shortcut (Command+Q/Ctrl+Q) is intercepted directly by AppKit which emits an event on the NSApplicationDelegate bound to NSApp.delegate. The event is caught by Qt Cocoa integration which sends a closeEvent to the QApplication, and stops the Qt eventloop if the closeEvent pass through. This is problematic since we don't want to kill the eventloop right away, and it provides a different behaviour when closing than other ways (SIGINT/closing the window) where we redirect to libvlc_Quit() and handle the termination of interfaces from their Deactivation callback directly. Instead this commit install a handler to catch Qt's closeEvent, on every platforms, so as to redirect it to libvlc_Quit(); Co-authored-by: Pierre Lamot --- modules/gui/qt/qt.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/modules/gui/qt/qt.cpp b/modules/gui/qt/qt.cpp index 0ccfd0aefe..de47229096 100644 --- a/modules/gui/qt/qt.cpp +++ b/modules/gui/qt/qt.cpp @@ -917,6 +917,34 @@ static void *Thread( void *obj ) assert(ret); } + /* Ctrl+Q, or more specifically Command+Q on MacOS is going + * through the NSApplication/NSApplicationDelegate selector + * applicationShouldTerminate:, which is catched by Qt and + * trigger termination of the app.exec() runloop. + * We don't want to quit right now and instead trigger + * libvlc_Quit() to unload the interface from Close and avoid + * racing the window by removing the eventloop before it's + * destroyed. */ + class QuitSpy : public QObject + { + public: + QuitSpy(QObject *parent) : QObject(parent) + { + qGuiApp->installEventFilter(this); + } + bool eventFilter(QObject *o, QEvent *e) override + { + (void)o; + if (e->type() == QEvent::Quit) + { + THEDP->quit(); + return true; + } + return false; + } + }; + QuitSpy quitSpy(&app); + registerMetaTypes(); //app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);