@@ -466,6 +466,7 @@ CarlaPluginProtectedData::CarlaPluginProtectedData(CarlaEngine* const eng, const | |||
ctrlChannel(0), | |||
extraHints(0x0), | |||
patchbayClientId(0), | |||
transientTryCounter(0), | |||
latency(0), | |||
latencyBuffers(nullptr), | |||
name(nullptr), | |||
@@ -477,6 +478,7 @@ CarlaPluginProtectedData::CarlaPluginProtectedData(CarlaEngine* const eng, const | |||
CarlaPluginProtectedData::~CarlaPluginProtectedData() | |||
{ | |||
CARLA_SAFE_ASSERT(! needsReset); | |||
CARLA_SAFE_ASSERT(transientTryCounter == 0); | |||
if (name != nullptr) | |||
{ | |||
@@ -243,6 +243,7 @@ struct CarlaPluginProtectedData { | |||
int8_t ctrlChannel; | |||
uint extraHints; | |||
int patchbayClientId; | |||
uint transientTryCounter; | |||
// latency | |||
uint32_t latency; | |||
@@ -176,7 +176,6 @@ private: | |||
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(winId != 0, true); | |||
@@ -227,25 +226,30 @@ bool CarlaPluginUi::tryTransientWinIdMatch(const ulong pid, const char* const ui | |||
// ------------------------------------------------ | |||
// 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 | |||
@@ -261,7 +265,7 @@ bool CarlaPluginUi::tryTransientWinIdMatch(const ulong pid, const char* const ui | |||
CARLA_SAFE_ASSERT_CONTINUE(status == Success); | |||
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); | |||
lastGoodWindow = window; | |||
@@ -47,8 +47,7 @@ public: | |||
fUiFilename(nullptr), | |||
fAudioInBuffers(nullptr), | |||
fAudioOutBuffers(nullptr), | |||
fParamBuffers(nullptr), | |||
fTransientTryCounter(0) | |||
fParamBuffers(nullptr) | |||
{ | |||
carla_debug("DssiPlugin::DssiPlugin(%p, %i)", engine, id); | |||
@@ -381,7 +380,7 @@ public: | |||
} | |||
else | |||
{ | |||
fTransientTryCounter = 0; | |||
pData->transientTryCounter = 0; | |||
if (pData->osc.data.target != nullptr) | |||
{ | |||
@@ -398,18 +397,18 @@ public: | |||
{ | |||
CarlaPlugin::idle(); | |||
if (fTransientTryCounter == 0) | |||
if (pData->transientTryCounter == 0) | |||
return; | |||
if (++fTransientTryCounter % 10 != 0) | |||
if (++pData->transientTryCounter % 10 != 0) | |||
return; | |||
if (fTransientTryCounter >= 200) | |||
if (pData->transientTryCounter >= 200) | |||
return; | |||
carla_stdout("Trying to get window..."); | |||
QString uiTitle(QString("%1 (GUI)").arg(pData->name)); | |||
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); | |||
if (carla_standalone_get_transient_win_id() != 0) | |||
fTransientTryCounter = 1; | |||
pData->transientTryCounter = 1; | |||
} | |||
// ------------------------------------------------------------------- | |||
@@ -2005,9 +2004,6 @@ private: | |||
float* fParamBuffers; | |||
snd_seq_event_t fMidiEvents[kPluginMaxMidiEvents]; | |||
// used to try and set transient hint for external windows | |||
uint fTransientTryCounter; | |||
// ------------------------------------------------------------------- | |||
static LinkedList<const char*> sMultiSynthList; | |||
@@ -29,6 +29,8 @@ | |||
#include "../engine/CarlaEngineOsc.hpp" | |||
#include "CarlaHost.h" | |||
extern "C" { | |||
#include "rtmempool/rtmempool-lv2.h" | |||
} | |||
@@ -1073,6 +1075,9 @@ public: | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fUi.type != UI::TYPE_NULL,); | |||
if (! yesNo) | |||
pData->transientTryCounter = 0; | |||
if (fUi.type == UI::TYPE_OSC) | |||
{ | |||
if (yesNo) | |||
@@ -1113,54 +1118,57 @@ public: | |||
{ | |||
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 | |||
fUi.window = CarlaPluginUi::newCocoa(this); | |||
fUi.window = CarlaPluginUi::newCocoa(this); | |||
#else | |||
msg = "UI is for MacOS only"; | |||
msg = "UI is for MacOS only"; | |||
#endif | |||
break; | |||
break; | |||
case LV2_UI_WINDOWS: | |||
case LV2_UI_WINDOWS: | |||
#ifdef CARLA_OS_WIN | |||
fUi.window = CarlaPluginUi::newWindows(this); | |||
fUi.window = CarlaPluginUi::newWindows(this); | |||
#else | |||
msg = "UI is for Windows only"; | |||
msg = "UI is for Windows only"; | |||
#endif | |||
break; | |||
break; | |||
case LV2_UI_X11: | |||
case LV2_UI_X11: | |||
#ifdef HAVE_X11 | |||
fUi.window = CarlaPluginUi::newX11(this); | |||
fUi.window = CarlaPluginUi::newX11(this); | |||
#else | |||
msg = "UI is only for systems with X11"; | |||
msg = "UI is only for systems with X11"; | |||
#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.handle = fUi.descriptor->instantiate(fUi.descriptor, fRdfDescriptor->URI, fUi.rdfDescriptor->Bundle, | |||
@@ -1190,7 +1198,12 @@ public: | |||
fUi.window->show(); | |||
} | |||
else | |||
{ | |||
LV2_EXTERNAL_UI_SHOW((LV2_External_UI_Widget*)fUi.widget); | |||
if (carla_standalone_get_transient_win_id() != 0) | |||
pData->transientTryCounter = 1; | |||
} | |||
} | |||
else | |||
{ | |||
@@ -1255,9 +1268,28 @@ public: | |||
if (fUi.handle != nullptr && fUi.descriptor != nullptr) | |||
{ | |||
if (fUi.type == UI::TYPE_EMBED && fUi.window != nullptr) | |||
{ | |||
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) | |||
{ | |||
@@ -3473,6 +3505,9 @@ public: | |||
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)); | |||
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) | |||
$(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 $@ | |||
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 $@ | |||
VstPlugin.cpp.o: VstPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_VST_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) | |||