diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index c352e7e86..5a8974bf4 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -1207,7 +1207,7 @@ public: case LV2_UI_X11: # ifdef HAVE_X11 - fUI.window = CarlaPluginUI::newX11(this, frontendWinId); + fUI.window = CarlaPluginUI::newX11(this, frontendWinId, isUiResizable()); # else msg = "UI is only for systems with X11"; # endif @@ -4283,6 +4283,16 @@ public: pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); } + void handlePluginUIResized(const uint width, const uint height) override + { + CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::TYPE_EMBED,); + CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,); + carla_stdout("Lv2Plugin::handlePluginUIResized(%u, %u)", width, height); + + if (fUI.handle != nullptr && fExt.uiresize != nullptr) + fExt.uiresize->ui_resize(fUI.handle, width, height); + } + // ------------------------------------------------------------------- uint32_t handleUIPortMap(const char* const symbol) const noexcept @@ -5190,6 +5200,7 @@ public: fExt.uiidle = (const LV2UI_Idle_Interface*)fUI.descriptor->extension_data(LV2_UI__idleInterface); fExt.uishow = (const LV2UI_Show_Interface*)fUI.descriptor->extension_data(LV2_UI__showInterface); + fExt.uiresize = (const LV2UI_Resize*)fUI.descriptor->extension_data(LV2_UI__resize); fExt.uiprograms = (const LV2_Programs_UI_Interface*)fUI.descriptor->extension_data(LV2_PROGRAMS__UIInterface); // check if invalid @@ -5199,6 +5210,9 @@ public: if (fExt.uishow != nullptr && (fExt.uishow->show == nullptr || fExt.uishow->hide == nullptr)) fExt.uishow = nullptr; + if (fExt.uiresize != nullptr && fExt.uiresize->ui_resize == nullptr) + fExt.uiresize = nullptr; + if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program == nullptr) fExt.uiprograms = nullptr; } @@ -5279,6 +5293,7 @@ private: const LV2_Programs_Interface* programs; const LV2UI_Idle_Interface* uiidle; const LV2UI_Show_Interface* uishow; + const LV2UI_Resize* uiresize; const LV2_Programs_UI_Interface* uiprograms; Extensions() @@ -5288,6 +5303,7 @@ private: programs(nullptr), uiidle(nullptr), uishow(nullptr), + uiresize(nullptr), uiprograms(nullptr) {} CARLA_DECLARE_NON_COPY_STRUCT(Extensions); diff --git a/source/backend/plugin/VstPlugin.cpp b/source/backend/plugin/VstPlugin.cpp index 02ba526a9..05f6ba6fb 100644 --- a/source/backend/plugin/VstPlugin.cpp +++ b/source/backend/plugin/VstPlugin.cpp @@ -442,7 +442,7 @@ public: #if defined(CARLA_OS_LINUX) # ifdef HAVE_X11 - fUI.window = CarlaPluginUI::newX11(this, frontendWinId); + fUI.window = CarlaPluginUI::newX11(this, frontendWinId, false); # else msg = "UI is only for systems with X11"; # endif @@ -1778,6 +1778,18 @@ protected: pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); } + void handlePluginUIResized(const uint width, const uint height) override + { + CARLA_SAFE_ASSERT_RETURN(fUI.type == UI::UI_EMBED,); + CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,); + carla_debug("VstPlugin::handlePluginUIResized(%u, %u)", width, height); + + return; // unused + (void)width; (void)height; + } + + // ------------------------------------------------------------------- + intptr_t dispatcher(int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt) const noexcept { CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0); diff --git a/source/utils/CarlaPluginUI.cpp b/source/utils/CarlaPluginUI.cpp index fdffd3f7d..eb1d5fa82 100644 --- a/source/utils/CarlaPluginUI.cpp +++ b/source/utils/CarlaPluginUI.cpp @@ -44,8 +44,8 @@ static int temporaryErrorHandler(Display*, XErrorEvent*) class X11PluginUI : public CarlaPluginUI { public: - X11PluginUI(CloseCallback* const cb, const uintptr_t parentId) noexcept - : CarlaPluginUI(cb), + X11PluginUI(CloseCallback* const cb, const uintptr_t parentId, const bool isResizable) noexcept + : CarlaPluginUI(cb, isResizable), fDisplay(nullptr), fWindow(0), fIsVisible(false), @@ -63,6 +63,9 @@ public: attr.border_pixel = 0; attr.event_mask = KeyPressMask|KeyReleaseMask; + if (fIsResizable) + attr.event_mask |= StructureNotifyMask; + fWindow = XCreateWindow(fDisplay, RootWindow(fDisplay, screen), 0, 0, 300, 300, 0, DefaultDepth(fDisplay, screen), @@ -176,6 +179,13 @@ public: switch (event.type) { + case ConfigureNotify: + CARLA_SAFE_ASSERT_CONTINUE(fCallback != nullptr); + CARLA_SAFE_ASSERT_CONTINUE(event.xconfigure.width > 0); + CARLA_SAFE_ASSERT_CONTINUE(event.xconfigure.height > 0); + fCallback->handlePluginUIResized(event.xconfigure.width, event.xconfigure.height); + break; + case ClientMessage: type = XGetAtomName(fDisplay, event.xclient.message_type); CARLA_SAFE_ASSERT_CONTINUE(type != nullptr); @@ -224,17 +234,21 @@ public: XResizeWindow(fDisplay, fWindow, width, height); - XSizeHints sizeHints; - carla_zeroStruct(sizeHints); - - sizeHints.flags = PSize|PMinSize|PMaxSize; - sizeHints.width = static_cast(width); - sizeHints.height = static_cast(height); - sizeHints.min_width = static_cast(width); - sizeHints.min_height = static_cast(height); - sizeHints.max_width = static_cast(width); - sizeHints.max_height = static_cast(height); - XSetNormalHints(fDisplay, fWindow, &sizeHints); + if (! fIsResizable) + { + XSizeHints sizeHints; + carla_zeroStruct(sizeHints); + + sizeHints.flags = PSize|PMinSize|PMaxSize; + sizeHints.width = static_cast(width); + sizeHints.height = static_cast(height); + sizeHints.min_width = static_cast(width); + sizeHints.min_height = static_cast(height); + sizeHints.max_width = static_cast(width); + sizeHints.max_height = static_cast(height); + + XSetNormalHints(fDisplay, fWindow, &sizeHints); + } if (forceUpdate) XFlush(fDisplay); @@ -494,7 +508,7 @@ bool CarlaPluginUI::tryTransientWinIdMatch(const uintptr_t pid, const char* cons #ifdef CARLA_OS_MAC CarlaPluginUI* CarlaPluginUI::newCocoa(CloseCallback*, uintptr_t) { - //return new CocoaPluginUi(cb, parentId); + //return new CocoaPluginUi(cb, parentId, false); return nullptr; } #endif @@ -502,15 +516,15 @@ CarlaPluginUI* CarlaPluginUI::newCocoa(CloseCallback*, uintptr_t) #ifdef CARLA_OS_WIN CarlaPluginUI* CarlaPluginUI::newWindows(CloseCallback*, uintptr_t) { - //return new WindowsPluginUi(cb, parentId); + //return new WindowsPluginUi(cb, parentId, false); return nullptr; } #endif #ifdef HAVE_X11 -CarlaPluginUI* CarlaPluginUI::newX11(CloseCallback* cb, uintptr_t parentId) +CarlaPluginUI* CarlaPluginUI::newX11(CloseCallback* cb, uintptr_t parentId, bool isResizable) { - return new X11PluginUI(cb, parentId); + return new X11PluginUI(cb, parentId, isResizable); } #endif diff --git a/source/utils/CarlaPluginUI.hpp b/source/utils/CarlaPluginUI.hpp index 3676de2c7..3082ef0ad 100644 --- a/source/utils/CarlaPluginUI.hpp +++ b/source/utils/CarlaPluginUI.hpp @@ -29,6 +29,7 @@ public: public: virtual ~CloseCallback() {} virtual void handlePluginUIClosed() = 0; + virtual void handlePluginUIResized(const uint width, const uint height) = 0; }; virtual ~CarlaPluginUI() {} @@ -53,13 +54,18 @@ public: static CarlaPluginUI* newWindows(CloseCallback*, uintptr_t); #endif #ifdef HAVE_X11 - static CarlaPluginUI* newX11(CloseCallback*, uintptr_t); + static CarlaPluginUI* newX11(CloseCallback*, uintptr_t, bool); #endif protected: bool fIsIdling; + bool fIsResizable; CloseCallback* fCallback; - CarlaPluginUI(CloseCallback* const cb) noexcept : fIsIdling(false), fCallback(cb) {} + + CarlaPluginUI(CloseCallback* const cb, const bool isResizable) noexcept + : fIsIdling(false), + fIsResizable(isResizable), + fCallback(cb) {} CARLA_DECLARE_NON_COPY_CLASS(CarlaPluginUI) };