| @@ -148,19 +148,53 @@ public: | |||||
| #ifdef CARLA_OS_LINUX | #ifdef CARLA_OS_LINUX | ||||
| const ScopedEngineEnvironmentLocker _seel(kEngine); | const ScopedEngineEnvironmentLocker _seel(kEngine); | ||||
| // get current LD_PRELOAD, will restore it later | |||||
| const char* const oldPreload(std::getenv("LD_PRELOAD")); | 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) | if (oldPreload != nullptr) | ||||
| ::unsetenv("LD_PRELOAD"); | ::unsetenv("LD_PRELOAD"); | ||||
| #endif | |||||
| # endif | |||||
| #endif // CARLA_OS_LINUX | |||||
| // start the DSSI UI application | |||||
| carla_stdout("starting DSSI UI..."); | carla_stdout("starting DSSI UI..."); | ||||
| started = fProcess->start(arguments); | started = fProcess->start(arguments); | ||||
| #ifdef CARLA_OS_LINUX | #ifdef CARLA_OS_LINUX | ||||
| // restore initial state | |||||
| if (oldPreload != nullptr) | if (oldPreload != nullptr) | ||||
| { | |||||
| ::setenv("LD_PRELOAD", oldPreload, 1); | ::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) | if (! started) | ||||
| @@ -22,6 +22,7 @@ endif | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
| BUILD_CXX_FLAGS += -I$(CWD)/includes -I$(CWD)/utils | BUILD_CXX_FLAGS += -I$(CWD)/includes -I$(CWD)/utils | ||||
| LINK_FLAGS += -ldl | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -17,11 +17,72 @@ | |||||
| #include "CarlaUtils.hpp" | #include "CarlaUtils.hpp" | ||||
| #include <dlfcn.h> | |||||
| #include <X11/Xlib.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 | CARLA_EXPORT | ||||
| int XMapWindow(Display* /*display*/, Window /*w*/) | |||||
| int XMapWindow(Display* display, Window w) | |||||
| { | { | ||||
| carla_stdout("------------------------------- XMapWindow called"); | 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); | XSetTransientForHint(sd.display, lastGoodWindow, hostWinId); | ||||
| if (centerUI) | |||||
| if (centerUI && false /* moving the window after being shown isn't pretty... */) | |||||
| { | { | ||||
| int hostX, hostY, pluginX, pluginY; | int hostX, hostY, pluginX, pluginY; | ||||
| uint hostWidth, hostHeight, pluginWidth, pluginHeight, border, depth; | uint hostWidth, hostHeight, pluginWidth, pluginHeight, border, depth; | ||||