diff --git a/source/bridges-ui/CarlaBridgeToolkitGtk.cpp b/source/bridges-ui/CarlaBridgeToolkitGtk.cpp index 233f36e58..6c41f790b 100644 --- a/source/bridges-ui/CarlaBridgeToolkitGtk.cpp +++ b/source/bridges-ui/CarlaBridgeToolkitGtk.cpp @@ -20,6 +20,10 @@ #include +#ifdef CARLA_OS_LINUX +# include +#endif + CARLA_BRIDGE_START_NAMESPACE // ------------------------------------------------------------------------- @@ -47,13 +51,13 @@ public: ~CarlaBridgeToolkitGtk() override { - CARLA_ASSERT(fWindow == nullptr); + CARLA_SAFE_ASSERT(fWindow == nullptr); carla_debug("CarlaBridgeToolkitGtk::~CarlaBridgeToolkitGtk()"); } void init() override { - CARLA_ASSERT(fWindow == nullptr); + CARLA_SAFE_ASSERT_RETURN(fWindow == nullptr,); carla_debug("CarlaBridgeToolkitGtk::init()"); gtk_init(&gargc, &gargv); @@ -65,8 +69,8 @@ public: void exec(const bool showUI) override { - CARLA_ASSERT(kClient != nullptr); - CARLA_ASSERT(fWindow != nullptr); + CARLA_SAFE_ASSERT_RETURN(kClient != nullptr,); + CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,); carla_debug("CarlaBridgeToolkitGtk::exec(%s)", bool2str(showUI)); GtkWidget* const widget((GtkWidget*)kClient->getWidget()); @@ -76,6 +80,33 @@ public: gtk_window_set_resizable(GTK_WINDOW(fWindow), kClient->isResizable()); gtk_window_set_title(GTK_WINDOW(fWindow), kWindowTitle); + if (const char* const winIdStr = std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID")) + { + if (const long long winId = std::strtoll(winIdStr, nullptr, 16)) + { +#ifdef CARLA_OS_LINUX + if (GdkWindow* const gdkWindow = GDK_WINDOW(fWindow)) + { + if (GdkDisplay* const gdkDisplay = gdk_window_get_display(gdkWindow)) + { + ::Display* const display(gdk_x11_display_get_xdisplay(gdkDisplay)); +# ifdef BRIDGE_GTK3 + ::XID const xid(gdk_x11_window_get_xid(gdkWindow)); +# else + ::XID xid = 0; + if (GdkDrawable* const gdkDrawable = GDK_DRAWABLE(fWindow)) + xid = gdk_x11_drawable_get_xid(gdkDrawable); +# endif + if (display != nullptr && xid != 0) + XSetTransientForHint(display, xid, static_cast<::Window>(winId)); + } + } +#else + (void)winId; +#endif + } + } + if (showUI || fNeedsShow) { show(); @@ -101,8 +132,7 @@ public: gtk_widget_destroy(fWindow); fWindow = nullptr; - if (gtk_main_level() != 0) - gtk_main_quit(); + gtk_main_quit_if_needed(); } } @@ -128,11 +158,10 @@ public: void resize(int width, int height) override { - CARLA_ASSERT(fWindow != nullptr); + CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,); carla_debug("CarlaBridgeToolkitGtk::resize(%i, %i)", width, height); - if (fWindow != nullptr) - gtk_window_resize(GTK_WINDOW(fWindow), width, height); + gtk_window_resize(GTK_WINDOW(fWindow), width, height); } // --------------------------------------------------------------------- @@ -162,30 +191,38 @@ protected: } kClient->uiIdle(); - return kClient->oscIdle(); + + if (! kClient->oscIdle()) + { + gtk_main_quit_if_needed(); + return false; + } + + return true; } // --------------------------------------------------------------------- private: - static void gtk_ui_destroy(GtkWidget*, gpointer data) + static void gtk_main_quit_if_needed() { - CARLA_ASSERT(data != nullptr); + if (gtk_main_level() != 0) + gtk_main_quit(); + } - if (CarlaBridgeToolkitGtk* const _this_ = (CarlaBridgeToolkitGtk*)data) - _this_->handleDestroy(); + static void gtk_ui_destroy(GtkWidget*, gpointer data) + { + CARLA_SAFE_ASSERT_RETURN(data != nullptr,); - gtk_main_quit(); + ((CarlaBridgeToolkitGtk*)data)->handleDestroy(); + gtk_main_quit_if_needed(); } static gboolean gtk_ui_timeout(gpointer data) { - CARLA_ASSERT(data != nullptr); - - if (CarlaBridgeToolkitGtk* const _this_ = (CarlaBridgeToolkitGtk*)data) - return _this_->handleTimeout(); + CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); - return false; + return ((CarlaBridgeToolkitGtk*)data)->handleTimeout(); } CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgeToolkitGtk) diff --git a/source/bridges-ui/CarlaBridgeToolkitPlugin.cpp b/source/bridges-ui/CarlaBridgeToolkitPlugin.cpp index da16d3313..bc0ccc499 100644 --- a/source/bridges-ui/CarlaBridgeToolkitPlugin.cpp +++ b/source/bridges-ui/CarlaBridgeToolkitPlugin.cpp @@ -72,6 +72,12 @@ public: CARLA_SAFE_ASSERT_RETURN(fUI != nullptr,); carla_debug("CarlaBridgeToolkitPlugin::exec(%s)", bool2str(showUI)); + if (const char* const winIdStr = std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID")) + { + if (const long long winId = std::strtoll(winIdStr, nullptr, 16)) + fUI->setTransientWinId(static_cast(winId)); + } + if (showUI) fUI->show(); diff --git a/source/bridges-ui/CarlaBridgeToolkitQt.cpp b/source/bridges-ui/CarlaBridgeToolkitQt.cpp index ea53057d3..e6a3fbcd4 100644 --- a/source/bridges-ui/CarlaBridgeToolkitQt.cpp +++ b/source/bridges-ui/CarlaBridgeToolkitQt.cpp @@ -22,7 +22,7 @@ #include #include -#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) # include # include #else @@ -30,6 +30,11 @@ # include #endif +#if defined(CARLA_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# include +# include +#endif + CARLA_BRIDGE_START_NAMESPACE // ------------------------------------------------------------------------- @@ -61,17 +66,17 @@ public: ~CarlaBridgeToolkitQt() override { - CARLA_ASSERT(fApp == nullptr); - CARLA_ASSERT(fWindow == nullptr); - CARLA_ASSERT(fMsgTimer == 0); + CARLA_SAFE_ASSERT(fApp == nullptr); + CARLA_SAFE_ASSERT(fWindow == nullptr); + CARLA_SAFE_ASSERT(fMsgTimer == 0); carla_debug("CarlaBridgeToolkitQt::~CarlaBridgeToolkitQt()"); } void init() override { - CARLA_ASSERT(fApp == nullptr); - CARLA_ASSERT(fWindow == nullptr); - CARLA_ASSERT(fMsgTimer == 0); + CARLA_SAFE_ASSERT_RETURN(fApp == nullptr,); + CARLA_SAFE_ASSERT_RETURN(fWindow == nullptr,); + CARLA_SAFE_ASSERT_RETURN(fMsgTimer == 0,); carla_debug("CarlaBridgeToolkitQt::init()"); fApp = new QApplication(qargc, qargv); @@ -83,9 +88,9 @@ public: void exec(const bool showUI) override { - CARLA_ASSERT(kClient != nullptr); - CARLA_ASSERT(fApp != nullptr); - CARLA_ASSERT(fWindow != nullptr); + CARLA_SAFE_ASSERT_RETURN(kClient != nullptr,); + CARLA_SAFE_ASSERT_RETURN(fApp != nullptr,); + CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,); carla_debug("CarlaBridgeToolkitQt::exec(%s)", bool2str(showUI)); QWidget* const widget((QWidget*)kClient->getWidget()); @@ -99,7 +104,7 @@ public: if (! kClient->isResizable()) { fWindow->setFixedSize(fWindow->width(), fWindow->height()); -#ifdef Q_OS_WIN +#ifdef CARLA_OS_WIN fWindow->setWindowFlags(fWindow->windowFlags() | Qt::MSWindowsFixedSizeDialogHint); #endif } @@ -107,6 +112,18 @@ public: fWindow->setWindowIcon(QIcon::fromTheme("carla", QIcon(":/scalable/carla.svg"))); fWindow->setWindowTitle(kWindowTitle.buffer()); + if (const char* const winIdStr = std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID")) + { + if (const long long winId = std::strtoll(winIdStr, nullptr, 16)) + { +#if defined(CARLA_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + XSetTransientForHint(QX11Info::display(), static_cast<::Window>(fWindow->winId()), static_cast<::Window>(winId)); +#else + (void)winId; +#endif + } + } + if (showUI || fNeedsShow) { show(); @@ -124,9 +141,9 @@ public: void quit() override { - CARLA_ASSERT(kClient != nullptr); - CARLA_ASSERT(fApp != nullptr); - CARLA_ASSERT(fWindow != nullptr); + CARLA_SAFE_ASSERT_RETURN(kClient != nullptr,); + CARLA_SAFE_ASSERT_RETURN(fApp != nullptr,); + CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,); carla_debug("CarlaBridgeToolkitQt::quit()"); if (fMsgTimer != 0) @@ -175,16 +192,11 @@ public: void resize(const int width, const int height) override { - CARLA_ASSERT_INT(width > 0, width); - CARLA_ASSERT_INT(height > 0, height); + CARLA_SAFE_ASSERT_RETURN(width > 0,); + CARLA_SAFE_ASSERT_RETURN(height > 0,); carla_debug("CarlaBridgeToolkitQt::resize(%i, %i)", width, height); - if (width <= 0) - return; - if (height <= 0) - return; - - emit setSizeSafeSignal(width, height); + emit setSizeSafeSignal(static_cast(width), static_cast(height)); } protected: @@ -205,6 +217,7 @@ protected: { killTimer(fMsgTimer); fMsgTimer = 0; + fApp->quit(); } } @@ -221,13 +234,10 @@ signals: void setSizeSafeSignal(int, int); private slots: - void setSizeSafeSlot(int width, int height) + void setSizeSafeSlot(uint width, uint height) { - CARLA_ASSERT(kClient != nullptr && ! kClient->isResizable()); - CARLA_ASSERT(fWindow != nullptr); - - if (kClient == nullptr || fWindow == nullptr) - return; + CARLA_SAFE_ASSERT_RETURN(kClient != nullptr,); + CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,); if (kClient->isResizable()) fWindow->resize(width, height); @@ -263,7 +273,7 @@ CARLA_BRIDGE_END_NAMESPACE int qInitResources(); int qCleanupResources(); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) # include "resources.qt5.cpp" #else # include "resources.qt4.cpp" diff --git a/source/bridges-ui/Makefile b/source/bridges-ui/Makefile index 5cab8255b..a16124f74 100644 --- a/source/bridges-ui/Makefile +++ b/source/bridges-ui/Makefile @@ -61,6 +61,12 @@ LINK_LV2_WINDOWS_FLAGS = $(LINK_FLAGS) -static -mwindows BUILD_VST2_X11_FLAGS = $(BUILD_VST2_FLAGS) -DBRIDGE_X11 -DBRIDGE_VST2_X11 $(X11_FLAGS) LINK_VST2_X11_FLAGS = $(LINK_FLAGS) $(X11_LIBS) -ldl +ifeq ($(LINUX),true) +LINK_LV2_GTK2_FLAGS += -lX11 +LINK_LV2_GTK3_FLAGS += -lX11 +LINK_LV2_QT4_FLAGS += -lX11 +endif + # ---------------------------------------------------------------------------------------------------------------------------- ifeq ($(MACOS_OR_WIN32),true)