@@ -466,6 +466,7 @@ CarlaPluginProtectedData::CarlaPluginProtectedData(CarlaEngine* const eng, const | |||||
ctrlChannel(0), | ctrlChannel(0), | ||||
extraHints(0x0), | extraHints(0x0), | ||||
patchbayClientId(0), | patchbayClientId(0), | ||||
transientTryCounter(0), | |||||
latency(0), | latency(0), | ||||
latencyBuffers(nullptr), | latencyBuffers(nullptr), | ||||
name(nullptr), | name(nullptr), | ||||
@@ -477,6 +478,7 @@ CarlaPluginProtectedData::CarlaPluginProtectedData(CarlaEngine* const eng, const | |||||
CarlaPluginProtectedData::~CarlaPluginProtectedData() | CarlaPluginProtectedData::~CarlaPluginProtectedData() | ||||
{ | { | ||||
CARLA_SAFE_ASSERT(! needsReset); | CARLA_SAFE_ASSERT(! needsReset); | ||||
CARLA_SAFE_ASSERT(transientTryCounter == 0); | |||||
if (name != nullptr) | if (name != nullptr) | ||||
{ | { | ||||
@@ -243,6 +243,7 @@ struct CarlaPluginProtectedData { | |||||
int8_t ctrlChannel; | int8_t ctrlChannel; | ||||
uint extraHints; | uint extraHints; | ||||
int patchbayClientId; | int patchbayClientId; | ||||
uint transientTryCounter; | |||||
// latency | // latency | ||||
uint32_t latency; | uint32_t latency; | ||||
@@ -176,7 +176,6 @@ private: | |||||
bool CarlaPluginUi::tryTransientWinIdMatch(const ulong pid, const char* const uiTitle, const uintptr_t winId) | bool CarlaPluginUi::tryTransientWinIdMatch(const ulong pid, const char* const uiTitle, const uintptr_t winId) | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(pid != 0, true); | |||||
CARLA_SAFE_ASSERT_RETURN(uiTitle != nullptr && uiTitle[0] != '\0', true); | CARLA_SAFE_ASSERT_RETURN(uiTitle != nullptr && uiTitle[0] != '\0', true); | ||||
CARLA_SAFE_ASSERT_RETURN(winId != 0, true); | CARLA_SAFE_ASSERT_RETURN(winId != 0, true); | ||||
@@ -227,25 +226,30 @@ bool CarlaPluginUi::tryTransientWinIdMatch(const ulong pid, const char* const ui | |||||
// ------------------------------------------------ | // ------------------------------------------------ | ||||
// try using pid | // try using pid | ||||
unsigned long pidSize; | |||||
unsigned char* pidData = nullptr; | |||||
status = XGetWindowProperty(sd.display, window, _nwp, 0L, (~0L), False, XA_CARDINAL, &actualType, &actualFormat, &pidSize, &bytesAfter, &pidData); | |||||
if (pidData != nullptr) | |||||
if (pid != 0) | |||||
{ | { | ||||
const ScopedFreeData sfd2(pidData); | |||||
unsigned long pidSize; | |||||
unsigned char* pidData = nullptr; | |||||
CARLA_SAFE_ASSERT_CONTINUE(status == Success); | |||||
CARLA_SAFE_ASSERT_CONTINUE(pidSize != 0); | |||||
status = XGetWindowProperty(sd.display, window, _nwp, 0L, (~0L), False, XA_CARDINAL, &actualType, &actualFormat, &pidSize, &bytesAfter, &pidData); | |||||
if (*(ulong*)pidData == pid) | |||||
if (pidData != nullptr) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(lastGoodWindow == window || lastGoodWindow == 0, true); | |||||
lastGoodWindow = window; | |||||
carla_stdout("Match found using pid"); | |||||
const ScopedFreeData sfd2(pidData); | |||||
CARLA_SAFE_ASSERT_CONTINUE(status == Success); | |||||
CARLA_SAFE_ASSERT_CONTINUE(pidSize != 0); | |||||
if (*(ulong*)pidData == pid) | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(lastGoodWindow == window || lastGoodWindow == 0, true); | |||||
lastGoodWindow = window; | |||||
carla_stdout("Match found using pid"); | |||||
break; | |||||
} | |||||
} | } | ||||
} | } | ||||
// ------------------------------------------------ | // ------------------------------------------------ | ||||
// try using name | // try using name | ||||
@@ -261,7 +265,7 @@ bool CarlaPluginUi::tryTransientWinIdMatch(const ulong pid, const char* const ui | |||||
CARLA_SAFE_ASSERT_CONTINUE(status == Success); | CARLA_SAFE_ASSERT_CONTINUE(status == Success); | ||||
CARLA_SAFE_ASSERT_CONTINUE(nameSize != 0); | CARLA_SAFE_ASSERT_CONTINUE(nameSize != 0); | ||||
if (std::strcmp((const char*)nameData, uiTitle) == 0) | |||||
if (std::strstr((const char*)nameData, uiTitle) != nullptr) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(lastGoodWindow == window || lastGoodWindow == 0, true); | CARLA_SAFE_ASSERT_RETURN(lastGoodWindow == window || lastGoodWindow == 0, true); | ||||
lastGoodWindow = window; | lastGoodWindow = window; | ||||
@@ -47,8 +47,7 @@ public: | |||||
fUiFilename(nullptr), | fUiFilename(nullptr), | ||||
fAudioInBuffers(nullptr), | fAudioInBuffers(nullptr), | ||||
fAudioOutBuffers(nullptr), | fAudioOutBuffers(nullptr), | ||||
fParamBuffers(nullptr), | |||||
fTransientTryCounter(0) | |||||
fParamBuffers(nullptr) | |||||
{ | { | ||||
carla_debug("DssiPlugin::DssiPlugin(%p, %i)", engine, id); | carla_debug("DssiPlugin::DssiPlugin(%p, %i)", engine, id); | ||||
@@ -381,7 +380,7 @@ public: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
fTransientTryCounter = 0; | |||||
pData->transientTryCounter = 0; | |||||
if (pData->osc.data.target != nullptr) | if (pData->osc.data.target != nullptr) | ||||
{ | { | ||||
@@ -398,18 +397,18 @@ public: | |||||
{ | { | ||||
CarlaPlugin::idle(); | CarlaPlugin::idle(); | ||||
if (fTransientTryCounter == 0) | |||||
if (pData->transientTryCounter == 0) | |||||
return; | return; | ||||
if (++fTransientTryCounter % 10 != 0) | |||||
if (++pData->transientTryCounter % 10 != 0) | |||||
return; | return; | ||||
if (fTransientTryCounter >= 200) | |||||
if (pData->transientTryCounter >= 200) | |||||
return; | return; | ||||
carla_stdout("Trying to get window..."); | carla_stdout("Trying to get window..."); | ||||
QString uiTitle(QString("%1 (GUI)").arg(pData->name)); | QString uiTitle(QString("%1 (GUI)").arg(pData->name)); | ||||
if (CarlaPluginUi::tryTransientWinIdMatch(pData->osc.thread.getPid(), uiTitle.toUtf8().constData(), carla_standalone_get_transient_win_id())) | if (CarlaPluginUi::tryTransientWinIdMatch(pData->osc.thread.getPid(), uiTitle.toUtf8().constData(), carla_standalone_get_transient_win_id())) | ||||
fTransientTryCounter = 0; | |||||
pData->transientTryCounter = 0; | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -1729,7 +1728,7 @@ public: | |||||
CarlaPlugin::updateOscData(source, url); | CarlaPlugin::updateOscData(source, url); | ||||
if (carla_standalone_get_transient_win_id() != 0) | if (carla_standalone_get_transient_win_id() != 0) | ||||
fTransientTryCounter = 1; | |||||
pData->transientTryCounter = 1; | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -2005,9 +2004,6 @@ private: | |||||
float* fParamBuffers; | float* fParamBuffers; | ||||
snd_seq_event_t fMidiEvents[kPluginMaxMidiEvents]; | snd_seq_event_t fMidiEvents[kPluginMaxMidiEvents]; | ||||
// used to try and set transient hint for external windows | |||||
uint fTransientTryCounter; | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
static LinkedList<const char*> sMultiSynthList; | static LinkedList<const char*> sMultiSynthList; | ||||
@@ -29,6 +29,8 @@ | |||||
#include "../engine/CarlaEngineOsc.hpp" | #include "../engine/CarlaEngineOsc.hpp" | ||||
#include "CarlaHost.h" | |||||
extern "C" { | extern "C" { | ||||
#include "rtmempool/rtmempool-lv2.h" | #include "rtmempool/rtmempool-lv2.h" | ||||
} | } | ||||
@@ -1073,6 +1075,9 @@ public: | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(fUi.type != UI::TYPE_NULL,); | CARLA_SAFE_ASSERT_RETURN(fUi.type != UI::TYPE_NULL,); | ||||
if (! yesNo) | |||||
pData->transientTryCounter = 0; | |||||
if (fUi.type == UI::TYPE_OSC) | if (fUi.type == UI::TYPE_OSC) | ||||
{ | { | ||||
if (yesNo) | if (yesNo) | ||||
@@ -1113,54 +1118,57 @@ public: | |||||
{ | { | ||||
if (fUi.handle == nullptr) | if (fUi.handle == nullptr) | ||||
{ | { | ||||
const char* msg = nullptr; | |||||
switch (fUi.rdfDescriptor->Type) | |||||
if (fUi.type == UI::TYPE_EMBED) | |||||
{ | { | ||||
case LV2_UI_GTK2: | |||||
case LV2_UI_GTK3: | |||||
case LV2_UI_QT4: | |||||
case LV2_UI_QT5: | |||||
case LV2_UI_EXTERNAL: | |||||
case LV2_UI_OLD_EXTERNAL: | |||||
msg = "Invalid UI type"; | |||||
break; | |||||
const char* msg = nullptr; | |||||
case LV2_UI_COCOA: | |||||
switch (fUi.rdfDescriptor->Type) | |||||
{ | |||||
case LV2_UI_GTK2: | |||||
case LV2_UI_GTK3: | |||||
case LV2_UI_QT4: | |||||
case LV2_UI_QT5: | |||||
case LV2_UI_EXTERNAL: | |||||
case LV2_UI_OLD_EXTERNAL: | |||||
msg = "Invalid UI type"; | |||||
break; | |||||
case LV2_UI_COCOA: | |||||
#ifdef CARLA_OS_MAC | #ifdef CARLA_OS_MAC | ||||
fUi.window = CarlaPluginUi::newCocoa(this); | |||||
fUi.window = CarlaPluginUi::newCocoa(this); | |||||
#else | #else | ||||
msg = "UI is for MacOS only"; | |||||
msg = "UI is for MacOS only"; | |||||
#endif | #endif | ||||
break; | |||||
break; | |||||
case LV2_UI_WINDOWS: | |||||
case LV2_UI_WINDOWS: | |||||
#ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
fUi.window = CarlaPluginUi::newWindows(this); | |||||
fUi.window = CarlaPluginUi::newWindows(this); | |||||
#else | #else | ||||
msg = "UI is for Windows only"; | |||||
msg = "UI is for Windows only"; | |||||
#endif | #endif | ||||
break; | |||||
break; | |||||
case LV2_UI_X11: | |||||
case LV2_UI_X11: | |||||
#ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
fUi.window = CarlaPluginUi::newX11(this); | |||||
fUi.window = CarlaPluginUi::newX11(this); | |||||
#else | #else | ||||
msg = "UI is only for systems with X11"; | |||||
msg = "UI is only for systems with X11"; | |||||
#endif | #endif | ||||
break; | |||||
break; | |||||
default: | |||||
msg = "Unknown UI type"; | |||||
break; | |||||
} | |||||
default: | |||||
msg = "Unknown UI type"; | |||||
break; | |||||
} | |||||
if (fUi.window == nullptr) | |||||
return pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, msg); | |||||
if (fUi.window == nullptr) | |||||
return pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, msg); | |||||
fUi.window->setTitle(fUi.title); | |||||
fUi.window->setTitle(fUi.title); | |||||
fFeatures[kFeatureIdUiParent]->data = fUi.window->getPtr(); | |||||
fFeatures[kFeatureIdUiParent]->data = fUi.window->getPtr(); | |||||
} | |||||
fUi.widget = nullptr; | fUi.widget = nullptr; | ||||
fUi.handle = fUi.descriptor->instantiate(fUi.descriptor, fRdfDescriptor->URI, fUi.rdfDescriptor->Bundle, | fUi.handle = fUi.descriptor->instantiate(fUi.descriptor, fRdfDescriptor->URI, fUi.rdfDescriptor->Bundle, | ||||
@@ -1190,7 +1198,12 @@ public: | |||||
fUi.window->show(); | fUi.window->show(); | ||||
} | } | ||||
else | else | ||||
{ | |||||
LV2_EXTERNAL_UI_SHOW((LV2_External_UI_Widget*)fUi.widget); | LV2_EXTERNAL_UI_SHOW((LV2_External_UI_Widget*)fUi.widget); | ||||
if (carla_standalone_get_transient_win_id() != 0) | |||||
pData->transientTryCounter = 1; | |||||
} | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -1255,9 +1268,28 @@ public: | |||||
if (fUi.handle != nullptr && fUi.descriptor != nullptr) | if (fUi.handle != nullptr && fUi.descriptor != nullptr) | ||||
{ | { | ||||
if (fUi.type == UI::TYPE_EMBED && fUi.window != nullptr) | if (fUi.type == UI::TYPE_EMBED && fUi.window != nullptr) | ||||
{ | |||||
fUi.window->idle(); | fUi.window->idle(); | ||||
else if (fUi.type == UI::TYPE_EXTERNAL && fUi.widget != nullptr) | |||||
LV2_EXTERNAL_UI_RUN((LV2_External_UI_Widget*)fUi.widget); | |||||
} | |||||
else if ((fUi.type == UI::TYPE_EXTERNAL && fUi.widget != nullptr) || | |||||
(fUi.type == UI::TYPE_OSC && pData->osc.data.target != nullptr)) | |||||
{ | |||||
if (fUi.type == UI::TYPE_EXTERNAL && fUi.widget != nullptr) | |||||
LV2_EXTERNAL_UI_RUN((LV2_External_UI_Widget*)fUi.widget); | |||||
if (pData->transientTryCounter == 0) | |||||
return; | |||||
if (++pData->transientTryCounter % 10 != 0) | |||||
return; | |||||
if (pData->transientTryCounter >= 200) | |||||
return; | |||||
carla_stdout("Trying to get window..."); | |||||
QString uiTitle(QString("%1 (GUI)").arg(pData->name)); | |||||
if (CarlaPluginUi::tryTransientWinIdMatch((fUi.type == UI::TYPE_OSC) ? pData->osc.thread.getPid() : 0, uiTitle.toUtf8().constData(), carla_standalone_get_transient_win_id())) | |||||
pData->transientTryCounter = 0; | |||||
} | |||||
if (fExt.uiidle != nullptr && fExt.uiidle->idle(fUi.handle) != 0) | if (fExt.uiidle != nullptr && fExt.uiidle->idle(fUi.handle) != 0) | ||||
{ | { | ||||
@@ -3473,6 +3505,9 @@ public: | |||||
for (size_t i=CARLA_URI_MAP_ID_COUNT, count=fCustomURIDs.count(); i < count; ++i) | for (size_t i=CARLA_URI_MAP_ID_COUNT, count=fCustomURIDs.count(); i < count; ++i) | ||||
osc_send_lv2_urid_map(pData->osc.data, static_cast<uint32_t>(i), fCustomURIDs.getAt(i)); | osc_send_lv2_urid_map(pData->osc.data, static_cast<uint32_t>(i), fCustomURIDs.getAt(i)); | ||||
if (carla_standalone_get_transient_win_id() != 0) | |||||
pData->transientTryCounter = 1; | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -75,10 +75,10 @@ BridgePlugin.cpp.o: BridgePlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE | |||||
LadspaPlugin.cpp.o: LadspaPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_LADSPA_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) | LadspaPlugin.cpp.o: LadspaPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_LADSPA_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) | ||||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | ||||
DssiPlugin.cpp.o: DssiPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_DSSI_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_PLUGIN_UI_HPP) | |||||
DssiPlugin.cpp.o: DssiPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_DSSI_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_PLUGIN_UI_HPP) $(CARLA_HOST_H) | |||||
$(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ | $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ | ||||
Lv2Plugin.cpp.o: Lv2Plugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_LV2_UTILS_HPP) $(CARLA_PLUGIN_UI_HPP) $(LV2_ATOM_QUEUE_HPP) $(CARLA_ENGINE_OSC_HPP) | |||||
Lv2Plugin.cpp.o: Lv2Plugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_LV2_UTILS_HPP) $(CARLA_PLUGIN_UI_HPP) $(LV2_ATOM_QUEUE_HPP) $(CARLA_ENGINE_OSC_HPP) $(CARLA_HOST_H) | |||||
$(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ | $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ | ||||
VstPlugin.cpp.o: VstPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_VST_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) | VstPlugin.cpp.o: VstPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_VST_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) | ||||