diff --git a/source/backend/plugin/CarlaPluginJack.cpp b/source/backend/plugin/CarlaPluginJack.cpp index f5465bed9..b6f7c0310 100644 --- a/source/backend/plugin/CarlaPluginJack.cpp +++ b/source/backend/plugin/CarlaPluginJack.cpp @@ -1182,11 +1182,7 @@ public: break; case kPluginBridgeNonRtServerUiClosed: - carla_stdout("got kPluginBridgeNonRtServerUiClosed, bridge closed cleanly?"); pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); - //fBridgeThread.signalThreadShouldExit(); - //handleProcessStopped(); - //fBridgeThread.stopThread(5000); break; case kPluginBridgeNonRtServerError: { diff --git a/source/interposer/interposer-jack-x11.cpp b/source/interposer/interposer-jack-x11.cpp index e9932b985..c28b1ed92 100644 --- a/source/interposer/interposer-jack-x11.cpp +++ b/source/interposer/interposer-jack-x11.cpp @@ -58,6 +58,7 @@ struct ScopedLibOpen { // Function typedefs typedef int (*XWindowFunc)(Display*, Window); +typedef int (*XNextEventFunc)(Display*, XEvent*); typedef int (*CarlaInterposedCallback)(int, void*); // -------------------------------------------------------------------------------------------------------------------- @@ -107,6 +108,14 @@ static int real_XUnmapWindow(Display* display, Window window) return func(display, window); } +static int real_XNextEvent(Display* display, XEvent* event) +{ + static const XNextEventFunc func = (XNextEventFunc)::dlsym(RTLD_NEXT, "XNextEvent"); + CARLA_SAFE_ASSERT_RETURN(func != nullptr, 0); + + return func(display, event); +} + // -------------------------------------------------------------------------------------------------------------------- // Custom carla window handling @@ -284,6 +293,39 @@ int XUnmapWindow(Display* display, Window window) return real_XUnmapWindow(display, window); } +CARLA_EXPORT +int XNextEvent(Display* display, XEvent* event) +{ + const int ret = real_XNextEvent(display, event); + + if (ret != 0) + return ret; + if (gCurrentlyMappedWindow == 0) + return ret; + if (event->type != ClientMessage) + return ret; + if (event->xclient.window != gCurrentlyMappedWindow) + return ret; + + char* const type = XGetAtomName(display, event->xclient.message_type); + CARLA_SAFE_ASSERT_RETURN(type != nullptr, 0); + + if (std::strcmp(type, "WM_PROTOCOLS") != 0) + return ret; + if (event->xclient.data.l[0] != XInternAtom(display, "WM_DELETE_WINDOW", False)) + return ret; + + gCurrentWindowVisible = false; + gCurrentWindowMapped = false; + + if (gInterposedCallback != nullptr) + gInterposedCallback(1, nullptr); + + event->type = 0; + carla_stdout("XNextEvent close event catched, hiding UI instead"); + return real_XUnmapWindow(display, gCurrentlyMappedWindow); +} + // -------------------------------------------------------------------------------------------------------------------- // Full control helper diff --git a/source/libjack/libjack.cpp b/source/libjack/libjack.cpp index 272b3fcf9..52bd64cbc 100644 --- a/source/libjack/libjack.cpp +++ b/source/libjack/libjack.cpp @@ -242,7 +242,7 @@ public: int handleInterposerCallback(const int cb_action, void* const ptr) { - carla_stdout("handleInterposerCallback(%o, %p)", cb_action, ptr); + carla_debug("handleInterposerCallback(%o, %p)", cb_action, ptr); switch (cb_action) { @@ -255,6 +255,9 @@ public: } return 0; + + // maybe unused + (void)ptr; } // -------------------------------------------------------------------