@@ -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); | |||
@@ -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); | |||
@@ -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<XSizeHints>(sizeHints); | |||
sizeHints.flags = PSize|PMinSize|PMaxSize; | |||
sizeHints.width = static_cast<int>(width); | |||
sizeHints.height = static_cast<int>(height); | |||
sizeHints.min_width = static_cast<int>(width); | |||
sizeHints.min_height = static_cast<int>(height); | |||
sizeHints.max_width = static_cast<int>(width); | |||
sizeHints.max_height = static_cast<int>(height); | |||
XSetNormalHints(fDisplay, fWindow, &sizeHints); | |||
if (! fIsResizable) | |||
{ | |||
XSizeHints sizeHints; | |||
carla_zeroStruct<XSizeHints>(sizeHints); | |||
sizeHints.flags = PSize|PMinSize|PMaxSize; | |||
sizeHints.width = static_cast<int>(width); | |||
sizeHints.height = static_cast<int>(height); | |||
sizeHints.min_width = static_cast<int>(width); | |||
sizeHints.min_height = static_cast<int>(height); | |||
sizeHints.max_width = static_cast<int>(width); | |||
sizeHints.max_height = static_cast<int>(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 | |||
@@ -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) | |||
}; | |||