@@ -1207,7 +1207,7 @@ public: | |||||
case LV2_UI_X11: | case LV2_UI_X11: | ||||
# ifdef HAVE_X11 | # ifdef HAVE_X11 | ||||
fUI.window = CarlaPluginUI::newX11(this, frontendWinId); | |||||
fUI.window = CarlaPluginUI::newX11(this, frontendWinId, isUiResizable()); | |||||
# else | # else | ||||
msg = "UI is only for systems with X11"; | msg = "UI is only for systems with X11"; | ||||
# endif | # endif | ||||
@@ -4283,6 +4283,16 @@ public: | |||||
pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); | 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 | 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.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.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); | fExt.uiprograms = (const LV2_Programs_UI_Interface*)fUI.descriptor->extension_data(LV2_PROGRAMS__UIInterface); | ||||
// check if invalid | // check if invalid | ||||
@@ -5199,6 +5210,9 @@ public: | |||||
if (fExt.uishow != nullptr && (fExt.uishow->show == nullptr || fExt.uishow->hide == nullptr)) | if (fExt.uishow != nullptr && (fExt.uishow->show == nullptr || fExt.uishow->hide == nullptr)) | ||||
fExt.uishow = 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) | if (fExt.uiprograms != nullptr && fExt.uiprograms->select_program == nullptr) | ||||
fExt.uiprograms = nullptr; | fExt.uiprograms = nullptr; | ||||
} | } | ||||
@@ -5279,6 +5293,7 @@ private: | |||||
const LV2_Programs_Interface* programs; | const LV2_Programs_Interface* programs; | ||||
const LV2UI_Idle_Interface* uiidle; | const LV2UI_Idle_Interface* uiidle; | ||||
const LV2UI_Show_Interface* uishow; | const LV2UI_Show_Interface* uishow; | ||||
const LV2UI_Resize* uiresize; | |||||
const LV2_Programs_UI_Interface* uiprograms; | const LV2_Programs_UI_Interface* uiprograms; | ||||
Extensions() | Extensions() | ||||
@@ -5288,6 +5303,7 @@ private: | |||||
programs(nullptr), | programs(nullptr), | ||||
uiidle(nullptr), | uiidle(nullptr), | ||||
uishow(nullptr), | uishow(nullptr), | ||||
uiresize(nullptr), | |||||
uiprograms(nullptr) {} | uiprograms(nullptr) {} | ||||
CARLA_DECLARE_NON_COPY_STRUCT(Extensions); | CARLA_DECLARE_NON_COPY_STRUCT(Extensions); | ||||
@@ -442,7 +442,7 @@ public: | |||||
#if defined(CARLA_OS_LINUX) | #if defined(CARLA_OS_LINUX) | ||||
# ifdef HAVE_X11 | # ifdef HAVE_X11 | ||||
fUI.window = CarlaPluginUI::newX11(this, frontendWinId); | |||||
fUI.window = CarlaPluginUI::newX11(this, frontendWinId, false); | |||||
# else | # else | ||||
msg = "UI is only for systems with X11"; | msg = "UI is only for systems with X11"; | ||||
# endif | # endif | ||||
@@ -1778,6 +1778,18 @@ protected: | |||||
pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); | 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 | 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); | CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0); | ||||
@@ -44,8 +44,8 @@ static int temporaryErrorHandler(Display*, XErrorEvent*) | |||||
class X11PluginUI : public CarlaPluginUI | class X11PluginUI : public CarlaPluginUI | ||||
{ | { | ||||
public: | 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), | fDisplay(nullptr), | ||||
fWindow(0), | fWindow(0), | ||||
fIsVisible(false), | fIsVisible(false), | ||||
@@ -63,6 +63,9 @@ public: | |||||
attr.border_pixel = 0; | attr.border_pixel = 0; | ||||
attr.event_mask = KeyPressMask|KeyReleaseMask; | attr.event_mask = KeyPressMask|KeyReleaseMask; | ||||
if (fIsResizable) | |||||
attr.event_mask |= StructureNotifyMask; | |||||
fWindow = XCreateWindow(fDisplay, RootWindow(fDisplay, screen), | fWindow = XCreateWindow(fDisplay, RootWindow(fDisplay, screen), | ||||
0, 0, 300, 300, 0, | 0, 0, 300, 300, 0, | ||||
DefaultDepth(fDisplay, screen), | DefaultDepth(fDisplay, screen), | ||||
@@ -176,6 +179,13 @@ public: | |||||
switch (event.type) | 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: | case ClientMessage: | ||||
type = XGetAtomName(fDisplay, event.xclient.message_type); | type = XGetAtomName(fDisplay, event.xclient.message_type); | ||||
CARLA_SAFE_ASSERT_CONTINUE(type != nullptr); | CARLA_SAFE_ASSERT_CONTINUE(type != nullptr); | ||||
@@ -224,17 +234,21 @@ public: | |||||
XResizeWindow(fDisplay, fWindow, width, height); | 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) | if (forceUpdate) | ||||
XFlush(fDisplay); | XFlush(fDisplay); | ||||
@@ -494,7 +508,7 @@ bool CarlaPluginUI::tryTransientWinIdMatch(const uintptr_t pid, const char* cons | |||||
#ifdef CARLA_OS_MAC | #ifdef CARLA_OS_MAC | ||||
CarlaPluginUI* CarlaPluginUI::newCocoa(CloseCallback*, uintptr_t) | CarlaPluginUI* CarlaPluginUI::newCocoa(CloseCallback*, uintptr_t) | ||||
{ | { | ||||
//return new CocoaPluginUi(cb, parentId); | |||||
//return new CocoaPluginUi(cb, parentId, false); | |||||
return nullptr; | return nullptr; | ||||
} | } | ||||
#endif | #endif | ||||
@@ -502,15 +516,15 @@ CarlaPluginUI* CarlaPluginUI::newCocoa(CloseCallback*, uintptr_t) | |||||
#ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
CarlaPluginUI* CarlaPluginUI::newWindows(CloseCallback*, uintptr_t) | CarlaPluginUI* CarlaPluginUI::newWindows(CloseCallback*, uintptr_t) | ||||
{ | { | ||||
//return new WindowsPluginUi(cb, parentId); | |||||
//return new WindowsPluginUi(cb, parentId, false); | |||||
return nullptr; | return nullptr; | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef HAVE_X11 | #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 | #endif | ||||
@@ -29,6 +29,7 @@ public: | |||||
public: | public: | ||||
virtual ~CloseCallback() {} | virtual ~CloseCallback() {} | ||||
virtual void handlePluginUIClosed() = 0; | virtual void handlePluginUIClosed() = 0; | ||||
virtual void handlePluginUIResized(const uint width, const uint height) = 0; | |||||
}; | }; | ||||
virtual ~CarlaPluginUI() {} | virtual ~CarlaPluginUI() {} | ||||
@@ -53,13 +54,18 @@ public: | |||||
static CarlaPluginUI* newWindows(CloseCallback*, uintptr_t); | static CarlaPluginUI* newWindows(CloseCallback*, uintptr_t); | ||||
#endif | #endif | ||||
#ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
static CarlaPluginUI* newX11(CloseCallback*, uintptr_t); | |||||
static CarlaPluginUI* newX11(CloseCallback*, uintptr_t, bool); | |||||
#endif | #endif | ||||
protected: | protected: | ||||
bool fIsIdling; | bool fIsIdling; | ||||
bool fIsResizable; | |||||
CloseCallback* fCallback; | 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) | CARLA_DECLARE_NON_COPY_CLASS(CarlaPluginUI) | ||||
}; | }; | ||||