Merge pull request #3991 from PhysSong/fix/qt5-vst

Some fixes/enhancements for #3786
This commit is contained in:
Lukas W
2017-11-24 14:40:24 +01:00
committed by GitHub
9 changed files with 110 additions and 45 deletions

View File

@@ -12,6 +12,7 @@ matrix:
- env: TARGET_OS=win64
- os: osx
osx_image: xcode8.2
- env: QT5=
- env: QT5=True
- env: QT5=True TARGET_OS=win32
- env: QT5=True TARGET_OS=win64

View File

@@ -210,6 +210,7 @@ public:
return m_recentlyOpenedProjects;
}
static QStringList availabeVstEmbedMethods();
QString vstEmbedMethod() const;
// returns true if the working dir (e.g. ~/lmms) exists on disk

View File

@@ -128,10 +128,21 @@ void VstEffect::openPlugin( const QString & _plugin )
PLUGIN_NAME::getIconPixmap( "logo", 24, 24 ), 0 );
QMutexLocker ml( &m_pluginMutex ); Q_UNUSED( ml );
#if QT_VERSION > 0x050000
m_plugin.reset(new VstPlugin( _plugin ));
#else
{
QSharedPointer<VstPlugin> newPlugin(new VstPlugin( _plugin ));
std::swap(m_plugin, newPlugin);
}
#endif
if( m_plugin->failed() )
{
#if QT_VERSION > 0x050000
m_plugin.reset(nullptr);
#else
m_plugin.clear();
#endif
delete tf;
collectErrorForUI( VstPlugin::tr( "The VST plugin %1 could not be loaded." ).arg( _plugin ) );
return;

View File

@@ -29,7 +29,7 @@ SET(REMOTE_VST_PLUGIN_FILEPATH "RemoteVstPlugin" CACHE STRING "Relative file pat
ADD_DEFINITIONS(-DREMOTE_VST_PLUGIN_FILEPATH="${REMOTE_VST_PLUGIN_FILEPATH}")
BUILD_PLUGIN(vstbase vst_base.cpp VstPlugin.cpp VstPlugin.h communication.h MOCFILES VstPlugin.h)
IF(LMMS_BUILD_LINUX)
IF(LMMS_BUILD_LINUX AND WANT_QT5)
TARGET_LINK_LIBRARIES(vstbase qx11embedcontainer)
ENDIF()

View File

@@ -109,6 +109,7 @@ static VstHostLanguages hlang = LanguageEnglish;
static bool EMBED = false;
static bool EMBED_X11 = false;
static bool EMBED_WIN32 = false;
class RemoteVstPlugin;
@@ -567,17 +568,6 @@ bool RemoteVstPlugin::processMessage( const message & _m )
init( _m.getString() );
break;
// TODO: Drop Windows hack for Qt 4
#ifdef LMMS_BUILD_WIN32
case IdVstPluginWindowInformation:
{
HWND top = FindWindowEx( NULL, NULL, NULL,
_m.getString().c_str() );
m_window = FindWindowEx( top, NULL, NULL, NULL );
break;
}
#endif
case IdVstSetTempo:
setBPM( _m.getInt() );
break;
@@ -1977,13 +1967,6 @@ DWORD WINAPI RemoteVstPlugin::guiEventLoop()
while( GetMessage( &msg, NULL, 0, 0 ) > 0 )
{
TranslateMessage( &msg );
if( msg.message == WM_SYSCOMMAND && msg.wParam == SC_CLOSE )
{
__plugin->destroyEditor();
continue;
}
DispatchMessage( &msg );
}
@@ -2030,6 +2013,12 @@ LRESULT CALLBACK RemoteVstPlugin::messageWndProc( HWND hwnd, UINT uMsg,
break;
}
}
else if( uMsg == WM_SYSCOMMAND && wParam == SC_CLOSE )
{
__plugin->destroyEditor();
return 0;
}
return DefWindowProc( hwnd, uMsg, wParam, lParam );
}
@@ -2084,21 +2073,27 @@ int main( int _argc, char * * _argv )
if ( embedMethod == "none" )
{
cerr << "Starting detached." << endl;
EMBED = EMBED_X11 = false;
EMBED = EMBED_X11 = EMBED_WIN32 = false;
}
else if ( embedMethod == "win32" )
{
cerr << "Starting using Win32-native embedding." << endl;
EMBED = EMBED_WIN32 = true; EMBED_X11= false;
}
else if ( embedMethod == "qt" )
{
cerr << "Starting using Qt-native embedding." << endl;
EMBED = true; EMBED_X11 = false;
EMBED = true; EMBED_X11 = EMBED_WIN32 = false;
}
else if ( embedMethod == "xembed" )
{
cerr << "Starting using X11Embed protocol." << endl;
EMBED = true; EMBED_X11 = true;
EMBED = EMBED_X11 = true; EMBED_WIN32 = false;
}
else
{
cerr << "Unknown embed method " << embedMethod << ". Starting detached instead." << endl;
EMBED = EMBED_X11 = EMBED_WIN32 = false;
}
}

View File

@@ -51,6 +51,7 @@
#ifdef LMMS_BUILD_WIN32
# include <windows.h>
# include <QLayout>
#endif
#include "ConfigManager.h"
@@ -659,6 +660,7 @@ void VstPlugin::createUI( QWidget * parent, bool isEffect )
m_pluginSubWindow = new vstSubWin( gui->mainWindow()->workspace() );
auto sw = m_pluginSubWindow.data();
#if QT_VERSION >= 0x050100
if (m_embedMethod == "qt" )
{
QWindow* vw = QWindow::fromWinId(m_pluginWindowID);
@@ -667,17 +669,49 @@ void VstPlugin::createUI( QWidget * parent, bool isEffect )
// TODO: Synchronize show
// Tell remote that it is embedded
// Wait for remote reply
}
} else
#endif
#ifdef LMMS_BUILD_WIN32
if (m_embedMethod == "win32" )
{
QWidget * helper = new QWidget;
QHBoxLayout * l = new QHBoxLayout( helper );
QWidget * target = new QWidget( helper );
l->setSpacing( 0 );
l->setMargin( 0 );
l->addWidget( target );
// we've to call that for making sure, Qt created the windows
helper->winId();
HWND targetHandle = (HWND)target->winId();
HWND pluginHandle = (HWND)(intptr_t)m_pluginWindowID;
DWORD style = GetWindowLong(pluginHandle, GWL_STYLE);
style = style & ~(WS_POPUP);
style = style | WS_CHILD;
SetWindowLong(pluginHandle, GWL_STYLE, style);
SetParent(pluginHandle, targetHandle);
DWORD threadId = GetWindowThreadProcessId(pluginHandle, NULL);
DWORD currentThreadId = GetCurrentThreadId();
AttachThreadInput(currentThreadId, threadId, true);
container = helper;
RemotePlugin::showUI();
} else
#endif
#ifdef LMMS_BUILD_LINUX
else if (m_embedMethod == "xembed" )
if (m_embedMethod == "xembed" )
{
QX11EmbedContainer * embedContainer = new QX11EmbedContainer( sw );
connect(embedContainer, SIGNAL(clientIsEmbedded()), this, SLOT(handleClientEmbed()));
embedContainer->embedClient( m_pluginWindowID );
container = embedContainer;
}
} else
#endif
else
{
qCritical() << "Unknown embed method" << m_embedMethod;
delete m_pluginSubWindow;

View File

@@ -57,8 +57,6 @@ enum VstRemoteMessageIDs
{
// vstPlugin -> remoteVstPlugin
IdVstLoadPlugin = IdUserBase,
// TODO: Drop IdVstPluginWindowInformation, Windows hack for Qt 4
IdVstPluginWindowInformation,
IdVstClosePlugin,
IdVstSetTempo,
IdVstSetLanguage,

View File

@@ -35,10 +35,6 @@
#include "lmmsversion.h"
#ifdef LMMS_BUILD_LINUX
#include <QtX11Extras/QX11Info>
#endif
static inline QString ensureTrailingSlash( const QString & s )
{
if( ! s.isEmpty() && !s.endsWith('/') && !s.endsWith('\\') )
@@ -190,16 +186,37 @@ QString ConfigManager::defaultVersion() const
return LMMS_VERSION;
}
QString ConfigManager::vstEmbedMethod() const
QStringList ConfigManager::availabeVstEmbedMethods()
{
QString defaultMethod = "qt";
QStringList methods;
methods.append("none");
#if QT_VERSION >= 0x050100
methods.append("qt");
#endif
#ifdef LMMS_BUILD_WIN32
methods.append("win32");
#endif
#ifdef LMMS_BUILD_LINUX
if (QX11Info::isPlatformX11()) {
defaultMethod = "xembed";
#if QT_VERSION >= 0x050000
if (static_cast<QGuiApplication*>(QApplication::instance())->
platformName() == "xcb")
#else
if (qgetenv("QT_QPA_PLATFORM").isNull()
|| qgetenv("QT_QPA_PLATFORM") == "xcb")
#endif
{
methods.append("xembed");
}
#endif
return methods;
}
return value( "ui", "vstembedmethod", defaultMethod );
QString ConfigManager::vstEmbedMethod() const
{
QStringList methods = availabeVstEmbedMethods();
QString defaultMethod = *(methods.end() - 1);
QString currentMethod = value( "ui", "vstembedmethod", defaultMethod );
return methods.contains(currentMethod) ? currentMethod : defaultMethod;
}
bool ConfigManager::hasWorkingDir() const

View File

@@ -67,10 +67,6 @@
#include "MidiApple.h"
#include "MidiDummy.h"
#ifdef LMMS_BUILD_LINUX
#include <QtX11Extras/QX11Info>
#endif
inline void labelWidget( QWidget * _w, const QString & _txt )
{
QLabel * title = new QLabel( _txt, _w );
@@ -342,13 +338,21 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
embed_tw->setFixedHeight( 48 );
m_vstEmbedComboBox = new QComboBox( embed_tw );
m_vstEmbedComboBox->move( XDelta, YDelta );
QStringList embedMethods = ConfigManager::availabeVstEmbedMethods();
m_vstEmbedComboBox->addItem( tr( "No embedding" ), "none" );
m_vstEmbedComboBox->addItem( tr( "Embed using Qt API" ), "qt" );
#ifdef LMMS_BUILD_LINUX
if ( QX11Info::isPlatformX11() ) {
if( embedMethods.contains("qt") )
{
m_vstEmbedComboBox->addItem( tr( "Embed using Qt API" ), "qt" );
}
if( embedMethods.contains("win32") )
{
m_vstEmbedComboBox->addItem( tr( "Embed using native Win32 API" ), "win32" );
}
if( embedMethods.contains("xembed") )
{
m_vstEmbedComboBox->addItem( tr( "Embed using XEmbed protocol" ), "xembed" );
}
#endif
m_vstEmbedComboBox->setCurrentIndex( m_vstEmbedComboBox->findData( m_vstEmbedMethod ) );
TabWidget * lang_tw = new TabWidget( tr( "LANGUAGE" ), general );
@@ -1077,7 +1081,11 @@ void SetupDialog::accept()
QString::number( m_disableAutoQuit ) );
ConfigManager::inst()->setValue( "app", "language", m_lang );
ConfigManager::inst()->setValue( "ui", "vstembedmethod",
#if QT_VERSION >= 0x050000
m_vstEmbedComboBox->currentData().toString() );
#else
m_vstEmbedComboBox->itemData(m_vstEmbedComboBox->currentIndex()).toString() );
#endif
ConfigManager::inst()->setWorkingDir(QDir::fromNativeSeparators(m_workingDir));