| @@ -148,19 +148,53 @@ public: | |||
| #ifdef CARLA_OS_LINUX | |||
| const ScopedEngineEnvironmentLocker _seel(kEngine); | |||
| // get current LD_PRELOAD, will restore it later | |||
| const char* const oldPreload(std::getenv("LD_PRELOAD")); | |||
| # ifdef HAVE_X11 | |||
| // if the frontend uses winId parent, set LD_PRELOAD to auto-map the DSSI UI | |||
| const uintptr_t winId = kEngine->getOptions().frontendWinId; | |||
| if (winId != 0) | |||
| { | |||
| char strBuf[STR_MAX+1]; | |||
| strBuf[STR_MAX] = '\0'; | |||
| std::snprintf(strBuf, STR_MAX, P_UINTPTR, kEngine->getOptions().frontendWinId); | |||
| ::setenv("CARLA_ENGINE_OPTION_FRONTEND_WIN_ID", strBuf, 1); | |||
| CarlaString interposerPath(CarlaString(kEngine->getOptions().binaryDir) + | |||
| CARLA_OS_SEP_STR "libcarla_interposer-x11.so"); | |||
| ::setenv("LD_PRELOAD", interposerPath.buffer(), 1); | |||
| } | |||
| else | |||
| # else | |||
| // if no X11 or winId set, simply unset LD_PRELOAD | |||
| // (it might be set to libcarla_interposer-safe) | |||
| if (oldPreload != nullptr) | |||
| ::unsetenv("LD_PRELOAD"); | |||
| #endif | |||
| # endif | |||
| #endif // CARLA_OS_LINUX | |||
| // start the DSSI UI application | |||
| carla_stdout("starting DSSI UI..."); | |||
| started = fProcess->start(arguments); | |||
| #ifdef CARLA_OS_LINUX | |||
| // restore initial state | |||
| if (oldPreload != nullptr) | |||
| { | |||
| ::setenv("LD_PRELOAD", oldPreload, 1); | |||
| #endif | |||
| } | |||
| # ifdef HAVE_X11 | |||
| if (winId != 0) | |||
| { | |||
| ::unsetenv("CARLA_ENGINE_OPTION_FRONTEND_WIN_ID"); | |||
| if (oldPreload == nullptr) | |||
| ::unsetenv("LD_PRELOAD"); | |||
| } | |||
| # endif | |||
| #endif // CARLA_OS_LINUX | |||
| } | |||
| if (! started) | |||
| @@ -22,6 +22,7 @@ endif | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| BUILD_CXX_FLAGS += -I$(CWD)/includes -I$(CWD)/utils | |||
| LINK_FLAGS += -ldl | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| @@ -17,11 +17,72 @@ | |||
| #include "CarlaUtils.hpp" | |||
| #include <dlfcn.h> | |||
| #include <X11/Xlib.h> | |||
| // ----------------------------------------------------------------------- | |||
| // Function typedefs | |||
| typedef int (*XMapWindowFunc)(Display*, Window); | |||
| typedef int (*XUnmapWindowFunc)(Display*, Window); | |||
| // ----------------------------------------------------------------------- | |||
| // Global counter so we only map the first (hopefully main) window | |||
| static int sMapWindowCounter = 0; | |||
| // ----------------------------------------------------------------------- | |||
| // Calling the real functions | |||
| static int real_XMapWindow(Display* display, Window w) | |||
| { | |||
| static XMapWindowFunc func = (XMapWindowFunc)::dlsym(RTLD_NEXT, "XMapWindow"); | |||
| CARLA_SAFE_ASSERT_RETURN(func != nullptr, 0); | |||
| return func(display, w); | |||
| } | |||
| static int real_XUnmapWindow(Display* display, Window w) | |||
| { | |||
| static XUnmapWindowFunc func = (XUnmapWindowFunc)::dlsym(RTLD_NEXT, "XUnmapWindow"); | |||
| CARLA_SAFE_ASSERT_RETURN(func != nullptr, 0); | |||
| return func(display, w); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| // Our custom functions | |||
| CARLA_EXPORT | |||
| int XMapWindow(Display* /*display*/, Window /*w*/) | |||
| int XMapWindow(Display* display, Window w) | |||
| { | |||
| carla_stdout("------------------------------- XMapWindow called"); | |||
| return 0; | |||
| if (++sMapWindowCounter != 1) | |||
| return real_XMapWindow(display, w); | |||
| if (const char* const winIdStr = std::getenv("CARLA_ENGINE_OPTION_FRONTEND_WIN_ID")) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(winIdStr[0] != '\0', real_XMapWindow(display, w)); | |||
| const long long winId(std::strtoll(winIdStr, nullptr, 16)); | |||
| CARLA_SAFE_ASSERT_RETURN(winId >= 0, real_XMapWindow(display, w)); | |||
| carla_stdout("Transient hint correctly applied before mapping window"); | |||
| XSetTransientForHint(display, w, static_cast<Window>(winId)); | |||
| } | |||
| return real_XMapWindow(display, w); | |||
| } | |||
| CARLA_EXPORT | |||
| int XUnmapWindow(Display* display, Window w) | |||
| { | |||
| carla_stdout("------------------------------- XUnmapWindow called"); | |||
| --sMapWindowCounter; | |||
| return real_XUnmapWindow(display, w); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -716,7 +716,7 @@ bool CarlaPluginUI::tryTransientWinIdMatch(const uintptr_t pid, const char* cons | |||
| XSetTransientForHint(sd.display, lastGoodWindow, hostWinId); | |||
| if (centerUI) | |||
| if (centerUI && false /* moving the window after being shown isn't pretty... */) | |||
| { | |||
| int hostX, hostY, pluginX, pluginY; | |||
| uint hostWidth, hostHeight, pluginWidth, pluginHeight, border, depth; | |||