| @@ -20,6 +20,10 @@ | |||
| #include <gtk/gtk.h> | |||
| #ifdef CARLA_OS_LINUX | |||
| # include <gdk/gdkx.h> | |||
| #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) | |||
| @@ -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<uintptr_t>(winId)); | |||
| } | |||
| if (showUI) | |||
| fUI->show(); | |||
| @@ -22,7 +22,7 @@ | |||
| #include <QtCore/QThread> | |||
| #include <QtCore/QTimerEvent> | |||
| #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) | |||
| #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) | |||
| # include <QtWidgets/QApplication> | |||
| # include <QtWidgets/QMainWindow> | |||
| #else | |||
| @@ -30,6 +30,11 @@ | |||
| # include <QtGui/QMainWindow> | |||
| #endif | |||
| #if defined(CARLA_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(5, 0, 0) | |||
| # include <QtGui/QX11Info> | |||
| # include <X11/Xlib.h> | |||
| #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<uint>(width), static_cast<uint>(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" | |||
| @@ -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) | |||