| @@ -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) | |||