Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes to get Qt5 working on Windows. #872

Merged
merged 2 commits into from
Apr 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 30 additions & 7 deletions Gui/FileTypeMainWindow_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,27 +87,50 @@ DocumentWindow::~DocumentWindow()
// —— public slots ——————————————————————————
// —— protected slots —————————————————————————
// —— events ————————————————————————————
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
bool
DocumentWindow::winEvent(MSG *message,
long *result)
DocumentWindow::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid double curly braces, which may confuse indenteds. I would prefer having two separate function definitions (will make the change)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would you think about something like this instead

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
bool
DocumentWindow::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
    auto t = handleWindowEvent(static_cast<MSG*>(message), result);
    return t.first ? t.second : QMainWindow::nativeEvent(eventType, message, result);
}
#else
bool
DocumentWindow::winEvent(MSG* msg,  long *result)
{
    auto t = handleWindowEvent(msg, result);
    return t.first ? t.second : QMainWindow::winEvent(msg, result);
}
#endif

std::pair<bool, bool>
DocumentWindow::handleWindowEvent(MSG *msg, long *result)
{
    switch (msg->message) {
    case WM_DDE_INITIATE:
        return std::make_pair(true, ddeInitiate(msg, result));
        break;
    case WM_DDE_EXECUTE:
        return std::make_pair(true, ddeExecute(msg, result));
        break;
    case WM_DDE_TERMINATE:
        return std::make_pair(true, ddeTerminate(msg, result));
        break;
    }
    return std::make_pair(false, false);
}

My thinking here is that it keeps the main logic that is common in a single place and keeps the Qt version differences minimal and in their appropriate #if sections. I don't have a strong feeling here, just trying to address your concern and avoid duplicate code. It's too bad I can't use std::optional. It would be a little cleaner looking.

switch (message->message) {
MSG* msg = static_cast<MSG*>(message);
switch (msg->message) {
case WM_DDE_INITIATE:

return ddeInitiate(message, result);
return ddeInitiate(msg, result);
break;
case WM_DDE_EXECUTE:

return ddeExecute(message, result);
return ddeExecute(msg, result);
break;
case WM_DDE_TERMINATE:

return ddeTerminate(message, result);
return ddeTerminate(msg, result);
break;
}

return QMainWindow::winEvent(message, result);
return QMainWindow::nativeEvent(eventType, message, result);
}
#else
bool
DocumentWindow::winEvent(MSG* msg, long *result)
{
switch (msg->message) {
case WM_DDE_INITIATE:

return ddeInitiate(msg, result);
break;
case WM_DDE_EXECUTE:

return ddeExecute(msg, result);
break;
case WM_DDE_TERMINATE:

return ddeTerminate(msg, result);
break;
}

return QMainWindow::winEvent(msg, result);
}
#endif

void
DocumentWindow::ddeOpenFile(const QString&)
Expand Down
6 changes: 5 additions & 1 deletion Gui/FileTypeMainWindow_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,11 @@ class DocumentWindow
/**
* reimpl as DDE events come as windows events and are not translated by Qt.
*/
virtual bool winEvent(MSG *message, long *result);
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
virtual bool nativeEvent(const QByteArray& eventType, void* message, long* result);
#else
virtual bool winEvent(MSG *msg, long *result);
#endif

// —— helpers for the file registration ——————————————————
/**
Expand Down
3 changes: 3 additions & 0 deletions Gui/Pyside_Gui_Python.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
#include <pyside_global.h>
#endif

#include <QSize>
#include <QObject>

#include <QtGui/qpytextobject.h>

//Global
Expand Down
2 changes: 2 additions & 0 deletions Gui/PythonPanels.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

CLANG_DIAG_OFF(deprecated)
CLANG_DIAG_OFF(uninitialized)
// Include order matters here to keep shiboken happy.
#include <QWidget>
#include <QDialog>
CLANG_DIAG_ON(deprecated)
CLANG_DIAG_ON(uninitialized)
Expand Down
7 changes: 4 additions & 3 deletions Gui/TaskBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ TaskBar::TaskBar(QWidget *parent)
, _state(NoProgress)
{
#ifdef Q_OS_WIN
_wid = parent->window()->winId();
// QT4 typedefs WId as an HWND, but QT5 typdefs it as a quintptr, so a cast is needed.
_hwnd = reinterpret_cast<HWND>(parent->window()->winId());
CoInitialize(NULL);
HRESULT hres = CoCreateInstance(CLSID_TaskbarList,
NULL,
Expand Down Expand Up @@ -112,7 +113,7 @@ TaskBar::setProgressValue(double value)
if (!_wtask) {
return;
}
if (_wtask->SetProgressValue(_wid, currentVal, totalVal) == S_OK) {
if (_wtask->SetProgressValue(_hwnd, currentVal, totalVal) == S_OK) {
_val = value;
}
#elif defined(Q_OS_DARWIN)
Expand Down Expand Up @@ -153,7 +154,7 @@ TaskBar::setProgressState(TaskBar::ProgressState state)
flag = TBPF_NORMAL;
break;
}
if (_wtask->SetProgressState(_wid, flag) == S_OK) {
if (_wtask->SetProgressState(_hwnd, flag) == S_OK) {
_state = state;
}
#elif defined(Q_OS_DARWIN)
Expand Down
2 changes: 1 addition & 1 deletion Gui/TaskBar.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public Q_SLOTS:

#ifdef Q_OS_WIN
ITaskbarList3 *_wtask;
WId _wid;
HWND _hwnd;
#elif defined(Q_OS_DARWIN)
TaskBarMac *_mtask;
#endif
Expand Down
13 changes: 8 additions & 5 deletions global.pri
Original file line number Diff line number Diff line change
Expand Up @@ -419,11 +419,14 @@ win32-g++ {
expat: PKGCONFIG += expat
cairo: PKGCONFIG += cairo fontconfig
equals(QT_MAJOR_VERSION, 5) {
shiboken: INCLUDEPATH += $$PYTHON_SITE_PACKAGES/PySide2/include/shiboken2
pyside: INCLUDEPATH += $$PYTHON_SITE_PACKAGES/PySide2/include/PySide2
pyside: INCLUDEPATH += $$PYTHON_SITE_PACKAGES/PySide2/include/PySide2/QtCore
pyside: INCLUDEPATH += $$PYTHON_SITE_PACKAGES/PySide2/include/PySide2/QtGui
pyside: INCLUDEPATH += $$PYTHON_SITE_PACKAGES/PySide2/include/PySide2/QtWidgets
shiboken: INCLUDEPATH += $$system(pkg-config --variable=includedir shiboken2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that makes pkg-config a build requirement. Will that still be possible if we switch to - say - vcpkg?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There already is a dependency on pkg-config. I'm basically doing the same thing that the Qt4 block is doing below.

I'm not really familiar with vcpkg but I suspect it would be trivial to get similar info from whatever it uses to describe where the package include directory is. FWIW, as a side project, I've been trying to get various Natron components to build with the Conan package manager (https://conan.io/). I have prototypes of openfx-misc and openfx-io building on Windows, Linux, & Mac all from the same source. Part of why I was trying to get Qt5 working is because I didn't want to port Qt4 to conan and I knew you folks were trying to migrate to Qt5 anyways. For conan, at least, it does support pkg-config and will allow you to actually build it from source if needed. Conan will automatically generate the .pc files for all your dependencies if needed. This is usually only required for automake/make builds though because it uses more direct means with cmake.

PYSIDE_INCLUDEDIR = $$system(pkg-config --variable=includedir pyside2)
pyside: INCLUDEPATH += $$PYSIDE_INCLUDEDIR
pyside: INCLUDEPATH += $$PYSIDE_INCLUDEDIR/QtCore
pyside: INCLUDEPATH += $$PYSIDE_INCLUDEDIR/QtGui
pyside: INCLUDEPATH += $$PYSIDE_INCLUDEDIR/QtWidgets
shiboken: PKGCONFIG += shiboken2
pyside: PKGCONFIG += pyside2
}
equals(QT_MAJOR_VERSION, 4) {
shiboken: PKGCONFIG += shiboken-py$$PYV
Expand Down
35 changes: 25 additions & 10 deletions tools/jenkins/build-Windows-installer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ popd () {
}

# Generate dll versions with dlls on the system
env BITS="$BITS" PYVER="$PYVER" PYV="${PYV}" NATRON_LICENSE="$NATRON_LICENSE" ./genDllVersions.sh
env BITS="$BITS" PYVER="$PYVER" PYV="${PYV}" QT_VERSION_MAJOR="${QT_VERSION_MAJOR}" NATRON_LICENSE="$NATRON_LICENSE" ./genDllVersions.sh

source dllVersions.sh

Expand Down Expand Up @@ -365,19 +365,21 @@ for location in "${COPY_LOCATIONS[@]}"; do
#cp -a "$SDK_HOME/etc/fonts"/* "$location/Resources/etc/fonts"
cp -a "${TMP_BINARIES_PATH}/Resources/etc/fonts"/* "$location/Resources/etc/fonts/"
cp -a "$SDK_HOME/share/poppler" "$location/Resources/"
cp -a "$SDK_HOME/share/qt4/plugins"/* "$location/bin/"
rm -f "$location/bin"/*/*d4.dll || true
cp -a "$SDK_HOME/share/qt${QT_VERSION_MAJOR}/plugins"/* "$location/bin/"

for depend in "${NATRON_DLL[@]}"; do
cp "$depend" "$location/bin/"
done

#Copy Qt dlls (required for all PySide modules to work correctly)
cp "$SDK_HOME/bin"/Qt*4.dll "$location/bin/"

if [ "${QT_VERSION_MAJOR}" = 4 ]; then
cp "$SDK_HOME/bin"/Qt*4.dll "$location/bin/"
# Ignore debug dlls of Qt
rm "$location/bin"/*d4.dll || true
else
cp "$SDK_HOME/bin"/Qt${QT_VERSION_MAJOR}*.dll "$location/bin/"
fi

# Ignore debug dlls of Qt
rm "$location/bin"/*d4.dll || true
rm "$location/bin/sqldrivers"/{*mysql*,*psql*} || true

if [ "$COMPILE_TYPE" != "debug" ]; then
Expand All @@ -394,7 +396,15 @@ done
mkdir -p "${TMP_PORTABLE_DIR}/Plugins"
cp -a "$SDK_HOME/lib/python${PYVER}" "${TMP_PORTABLE_DIR}/lib/"

mv "${TMP_PORTABLE_DIR}/lib/python${PYVER}/site-packages/PySide" "${TMP_PORTABLE_DIR}/Plugins/"

if [[ ${QT_VERSION_MAJOR} -ge 5 ]]; then
PYSIDE_PLUGIN_PATH="${TMP_PORTABLE_DIR}/Plugins/PySide2"
mv "${TMP_PORTABLE_DIR}/lib/python${PYVER}/site-packages/PySide2" "${TMP_PORTABLE_DIR}/lib/python${PYVER}/site-packages/shiboken2" "${TMP_PORTABLE_DIR}/Plugins"
else
PYSIDE_PLUGIN_PATH="${TMP_PORTABLE_DIR}/Plugins/PySide"
mv "${TMP_PORTABLE_DIR}/lib/python${PYVER}/site-packages/PySide" "${TMP_PORTABLE_DIR}/Plugins"
fi

rm -rf "${TMP_PORTABLE_DIR}/lib/python${PYVER}"/{test,config,config-"${PYVER}"m}

( cd "${TMP_PORTABLE_DIR}/lib/python${PYVER}/site-packages";
Expand All @@ -414,13 +424,17 @@ find "${PYDIR}" -type f -name '*.pyo' -exec rm {} \;
)

if [ "$COMPILE_TYPE" != "debug" ]; then
for dir in "${TMP_PORTABLE_DIR}/Plugins/PySide" "${TMP_PORTABLE_DIR}/lib/python${PYVER:-}"; do
for dir in "${PYSIDE_PLUGIN_PATH}" "${TMP_PORTABLE_DIR}/lib/python${PYVER:-}"; do
echo "*** stripping binaries in $dir"
find "$dir" -type f \( -iname '*.exe' -o -iname '*.dll' -o -iname '*.pyd' -o -iname '*.ofx' \) -exec strip -s {} \;
echo "*** stripping binaries in $dir... done!"
done
fi

if [[ ${QT_VERSION_MAJOR} -ge 5 ]]; then
USE_QT5=1
fi

# python zip
if [ "${USE_QT5:-}" != 1 ]; then
rm -rf "$PYDIR"/site-packages/shiboken2* "$PYDIR"/site-packages/PySide2 || true
Expand Down Expand Up @@ -466,7 +480,8 @@ fi
cp -r "$PYDIR" "$DLLS_PACKAGE_PATH/data/lib/"
cp "${TMP_PORTABLE_DIR}"/lib/python*.zip "${DLLS_PACKAGE_PATH}/data/lib/"
mkdir -p "${DLLS_PACKAGE_PATH}/data/Plugins"
cp -a "${TMP_PORTABLE_DIR}/Plugins/PySide" "${DLLS_PACKAGE_PATH}/data/Plugins/"

cp -a "${PYSIDE_PLUGIN_PATH}" "${DLLS_PACKAGE_PATH}/data/Plugins/"

# Configure the package date using the most recent DLL modification date
CLIBS_VERSION="00000000000000"
Expand Down
8 changes: 5 additions & 3 deletions tools/jenkins/build-natron.sh
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,12 @@ if [ "$QT_VERSION_MAJOR" = 5 ]; then
esac

rm Engine/Qt${QT_VERSION_MAJOR}/NatronEngine/* Gui/Qt${QT_VERSION_MAJOR}/NatronGui/* || true
# ${PYTHON_HOME}/lib/python${PYVER}/site-packages/PySide2/include
shiboken2-${PYVER} --avoid-protected-hack --enable-pyside-extensions --include-paths=.:Engine:Global:libs/OpenFX/include:${SDK_HOME}/include:${QTDIR}/include:${PYTHON_HOME}/include/python${PYVER}:${PYTHON_HOME}/lib/python${PYVER}/site-packages/PySide2/include --typesystem-paths=${PYTHON_HOME}/lib/python${PYVER}/site-packages/PySide2/typesystems --output-directory=Engine/Qt${QT_VERSION_MAJOR} Engine/Pyside2_Engine_Python.h Engine/typesystem_engine.xml
UNIX_PYTHON_HOME=`cygpath -u "${PYTHON_HOME}"`
SHIBOKEN_INCLUDE_PATHS=".:./Engine:./Global:libs/OpenFX/include:${UNIX_PYTHON_HOME}/include/python${PYVER}:${UNIX_PYTHON_HOME}/include/PySide2"
SHIBOKEN_TYPESYSTEM_PATHS="${UNIX_PYTHON_HOME}/share/PySide2/typesystems"
shiboken2 --avoid-protected-hack --enable-pyside-extensions --include-paths=${SHIBOKEN_INCLUDE_PATHS} --typesystem-paths=${SHIBOKEN_TYPESYSTEM_PATHS} --output-directory=Engine/Qt${QT_VERSION_MAJOR} Engine/Pyside2_Engine_Python.h Engine/typesystem_engine.xml

shiboken2-${PYVER} --avoid-protected-hack --enable-pyside-extensions --include-paths=.:Engine:Global:libs/OpenFX/include:${SDK_HOME}/include:${QTDIR}/include:${QTDIR}/include/QtWidgets:${PYTHON_HOME}/include/python${PYVER}:${PYTHON_HOME}/lib/python${PYVER}/site-packages/PySide2/include --typesystem-paths=${PYTHON_HOME}/lib/python${PYVER}/site-packages/PySide2/typesystems:Engine:Shiboken --output-directory=Gui/Qt${QT_VERSION_MAJOR} Gui/Pyside2_Gui_Python.h Gui/typesystem_natronGui.xml
shiboken2 --avoid-protected-hack --enable-pyside-extensions --include-paths=${SHIBOKEN_INCLUDE_PATHS}:${QTDIR}/include/QtWidgets:${QTDIR}/include/QtCore --typesystem-paths=${SHIBOKEN_TYPESYSTEM_PATHS}:./Engine:./Shiboken --output-directory=Gui/Qt${QT_VERSION_MAJOR} Gui/Pyside2_Gui_Python.h Gui/typesystem_natronGui.xml

tools/utils/runPostShiboken2.sh Engine/Qt${QT_VERSION_MAJOR}/NatronEngine natronengine
tools/utils/runPostShiboken2.sh Gui/Qt${QT_VERSION_MAJOR}/NatronGui natrongui
Expand Down
78 changes: 56 additions & 22 deletions tools/jenkins/genDllVersions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,26 +89,62 @@ function catDll() {
INIT_VAR=1
DLL_VAR_PREFIX="NATRON"
BIN_PATH="$SDK_HOME_BIN"
# all Qt libraries are necessary for PySide
catDll Qt3Support4
catDll QtCLucene4
catDll QtCore4
catDll QtDBus4
catDll QtDeclarative4
catDll QtDesigner4
catDll QtDesignerComponents4
catDll QtGui4
catDll QtHelp4
catDll QtMultimedia4
catDll QtNetwork4
catDll QtOpenGL4
catDll QtScript4
catDll QtScriptTools4
catDll QtSql4
catDll QtSvg4
catDll QtTest4
catDll QtXml4
catDll QtXmlPatterns4
if [ "$QT_VERSION_MAJOR" = "4" ]; then
# all Qt libraries are necessary for PySide
catDll Qt3Support4
catDll QtCLucene4
catDll QtCore4
catDll QtDBus4
catDll QtDeclarative4
catDll QtDesigner4
catDll QtDesignerComponents4
catDll QtGui4
catDll QtHelp4
catDll QtMultimedia4
catDll QtNetwork4
catDll QtOpenGL4
catDll QtScript4
catDll QtScriptTools4
catDll QtSql4
catDll QtSvg4
catDll QtTest4
catDll QtXml4
catDll QtXmlPatterns4

catDll phonon4
catDll libmng-
catDll libpcre-
elif [ "$QT_VERSION_MAJOR" = "5" ]; then
catDll Qt5Concurrent
catDll Qt5Core
catDll Qt5DBus
catDll Qt5Gui
catDll Qt5Network
catDll Qt5OpenGL
catDll Qt5PrintSupport
catDll Qt5Qml
catDll Qt5QmlModels
catDll Qt5QmlWorkerScript
catDll Qt5Quick
catDll Qt5QuickParticles
catDll Qt5QuickShapes
catDll Qt5QuickTest
catDll Qt5QuickWidgets
catDll Qt5Sql
catDll Qt5Test
catDll Qt5Widgets
catDll Qt5Xml
catDll Qt5XmlPatterns

catDll libdouble-conversion
catDll libicuin
catDll libpcre2-16-
catDll libmd4c
else
echo "Unsupported QT_MAJOR_VERSION" ${QT_VERSION_MAJOR}
exit 1
fi


catDll fbclient
catDll libass-
Expand Down Expand Up @@ -157,7 +193,6 @@ catDll libjpeg-
catDll liblcms2-
catDll liblzma-
catDll libmfx
catDll libmng-
catDll libmodplug-
catDll libmp3lame-
catDll libnettle-
Expand Down Expand Up @@ -200,7 +235,6 @@ catDll libwebpdemux-
catDll libwebpmux-
catDll libwinpthread-
catDll libxml2-
catDll phonon4
#catDll SDL2
#catDll SSLEAY32
catDll zlib1
Expand Down