Add Qt6 Support (#7339)

* Rebase against master

Co-authored-by: michaelgregorius <michael.gregorius.git@arcor.de>
Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com>

* Fix Qt6 DMG on Apple (#7240)

- Fix linking issues with Qt Framework files
- Fix qmake detection

* Fixes after rebase

* Fix embed.cpp compilation

Fix implicit conversion from int when using QString.arg(...)

* Fix Qt6 signature change for nativeEventFilter (#7254)

* Adds win32EventFilter a wrapper for nativeEventFilter on Windows
* win32EventFilter is currently used to intercept top-level Window events (currently, to avoid VSTs setting transparency of the parent application)

* fix broken signal slot connections (#7274)

QComboBox activated() replaced with textActivated() since Qt 5.14

* Enabled VSTs on Qt 6 (#7273)

* enabled VST support for Qt 6 builds
* Note : Embedding on QT6 will be buggy on linux as a result of using qt embedding, which unfortunately is a qt bug which hasn't been resolved.

* Changed bar lines to follow snap size (#7034)

* Added lines in between bars
* Changed bar lines to follow snap size
* Changed default zoom and quantization value
* Added constants for line widths
* Added QSS configuration for new grid line colors
* Tied line widths to QSS properties
* Changed default quantization to 1/4
* Removed clear() from destructor model
* Removed destructor in ComboBoxModel.h
* Changed member set/get functions to pass by value
* Updated signal connection with newer syntax

* Fix compilation

* Fix MSVC builds

* fix nullptr deref in AudioFileProcessor (qt6 branch) (#7532)

* ensured mouse event != nullptr before deref

* separation of concerns: AFP WaveView updateCursor

extract check to pointerCloseToStartEndOrLoop()

* marked some function parameters as const

* Remove Core5Compat usage

* Fix bad merge

* Fixes after rebase

* Simplify QTX_WRAP_CPP call

* Remove comments that are obvious to a developer

* Whitespace

* Try using Qt 6 for MSVC CI

I chose Qt 6.5 because it's the last Qt LTS release with declared
support for Visual Studio 2019. Once we upgrade to Visual Studio 2022,
we could upgrade Qt as well.

* Fix MSVC build

Also fixes two memory leaks in MidiWinMM

* Fix GuiApplication on MSVC

* Fix interpolateInRgb

* Try building with patched Calf

* Fix submodule

* Fix OpulenZ build

* Try to fix zyn

* Fix comment

* Ty to fix zyn (again)

* Ty to fix RemotePluginBase

* Revert "Ty to fix RemotePluginBase"

This reverts commit 92dac44ffb11e19d1d5a21d9155369f017bd59e9.

* Update plugins/ZynAddSubFx/CMakeLists.txt

Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>

* Fix vertical & horizontal scroll wheel in SongEditor

* AppImage: Fix finding of Qt6 libs

* Fix implicit QString --> QFileInfo conversion

* Point submodule to lmms

* Fix multiple deprecation warnings

* Fix for Clang compiler

* Build with latest Qt LTS version now that we use MSVC 2022

* Update jurplel/install-qt-action to v4.3.0

* Bump minimum Qt6 version for MSVC

* Fix incorrect Qt version checks

Some comparisons were using ">" rather than ">="

* `QSize()` != `QSize(0, 0)`

* Fix more deprecation warnings

* Fix style

* Simplify Spectrum Analyzer mouse events

The Qt bug that used to be present appears to have been fixed, so the
workaround can be removed

* Minor changes

* Fix deprecated QCheckBox signal

* Fix setContent helper functions

* Remove QMultiMap usage from ControlLayout

* Remove SIGNAL and SLOT macros

* Revert TrackView.cpp changes

* Remove Q_DISABLE_MOVE usage since it does not seem to be available in Qt6

---------

Co-authored-by: michaelgregorius <michael.gregorius.git@arcor.de>
Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com>
Co-authored-by: BoredGuy1 <66702733+BoredGuy1@users.noreply.github.com>
Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
Co-authored-by: Lisa Magdalena Riedler <git@riedler.wien>
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
This commit is contained in:
Tres Finocchiaro
2025-11-03 12:58:15 -05:00
committed by GitHub
parent fcb356df3d
commit 51529cefb1
76 changed files with 798 additions and 457 deletions

View File

@@ -55,8 +55,7 @@ protected:
//! Forward key events to the parent to prevent stuck notes when the dialog gets focus
void keyReleaseEvent(QKeyEvent *event) override
{
QKeyEvent ke(*event);
QApplication::sendEvent(parentWidget(), &ke);
QApplication::sendEvent(parentWidget(), event);
}
private:
//! Copy the current QColorDialog palette into an array

View File

@@ -35,17 +35,23 @@ class ColorHelper
public:
static QColor interpolateInRgb(const QColor& a, const QColor& b, float t)
{
qreal ar, ag, ab, aa;
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
using ColorType = float;
#else
using ColorType = qreal;
#endif
ColorType ar, ag, ab, aa;
a.getRgbF(&ar, &ag, &ab, &aa);
qreal br, bg, bb, ba;
ColorType br, bg, bb, ba;
b.getRgbF(&br, &bg, &bb, &ba);
const auto t2 = static_cast<qreal>(t);
const float interH = std::lerp(ar, br, t2);
const float interS = std::lerp(ag, bg, t2);
const float interV = std::lerp(ab, bb, t2);
const float interA = std::lerp(aa, ba, t2);
const auto t2 = static_cast<ColorType>(t);
const auto interH = std::lerp(ar, br, t2);
const auto interS = std::lerp(ag, bg, t2);
const auto interV = std::lerp(ab, bb, t2);
const auto interA = std::lerp(aa, ba, t2);
return QColor::fromRgbF(interH, interS, interV, interA);
}

View File

@@ -96,6 +96,8 @@ class ControlLayout : public QLayout
{
Q_OBJECT
using ControlLayoutMap = QMap<QString, QLayoutItem*>;
public:
explicit ControlLayout(QWidget *parent,
int margin = -1, int hSpacing = -1, int vSpacing = -1);
@@ -124,9 +126,9 @@ private slots:
private:
int doLayout(const QRect &rect, bool testOnly) const;
int smartSpacing(QStyle::PixelMetric pm) const;
QMap<QString, QLayoutItem *>::const_iterator pairAt(int index) const;
ControlLayoutMap::const_iterator pairAt(int index) const;
QMultiMap<QString, QLayoutItem *> m_itemMap;
ControlLayoutMap m_itemMap;
int m_hSpace;
int m_vSpace;
// relevant dimension is width, as later, heightForWidth() will be called

View File

@@ -29,8 +29,10 @@
#include <type_traits>
#include <QDomDocument>
#include <QFontMetrics>
#include <QKeySequence>
#include <QVariant>
#include <QWheelEvent>
namespace lmms
@@ -58,15 +60,74 @@ inline int horizontalAdvance(const QFontMetrics& metrics, const QString& text)
* @param wheelEvent
* @return the position of wheelEvent
*/
inline QPoint position(QWheelEvent *wheelEvent)
inline QPoint position(const QWheelEvent* wheelEvent)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
return wheelEvent->position().toPoint();
#else
return wheelEvent->pos();
#endif
}
/**
* @brief position is a backwards-compatible adapter for
* QDropEvent::position and pos functions.
* @param me
* @return the position of the drop event
*/
inline QPoint position(const QDropEvent* de)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return de->position().toPoint();
#else
return de->pos();
#endif
}
/**
* @brief position is a backwards-compatible adapter for
* QMouseEvent::position and pos functions.
* @param me
* @return the position of the mouse event
*/
inline QPoint position(const QMouseEvent* me)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return me->position().toPoint();
#else
return me->pos();
#endif
}
/**
* @brief positionF is a backwards-compatible adapter for
* QMouseEvent::position and localPos functions.
* @param me
* @return the position of the mouse event
*/
inline QPointF positionF(const QMouseEvent* me)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return me->position();
#else
return me->localPos();
#endif
}
/**
* @brief globalPosition is a backwards-compatible adapter for
* QMouseEvent::globalPosition and globalPos functions.
* @param me
* @return the global position of the mouse event
*/
inline QPoint globalPosition(const QMouseEvent* me)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return me->globalPosition().toPoint();
#else
return me->globalPos();
#endif
}
namespace detail
{
@@ -77,20 +138,69 @@ inline constexpr bool IsKeyOrModifier = std::is_same_v<T, Qt::Key>
} // namespace detail
/**
* @brief Combines Qt key and modifier arguments together,
* replacing `A | B` which was deprecated in C++20
* due to the enums being different types. (P1120R0)
* @param args Any number of Qt::Key, Qt::Modifier, or Qt::KeyboardModifier
* @return The combination of the given keys/modifiers as an int
* @return The combination of the given keys/modifiers as a QKeySequence
*/
template<typename... Args, std::enable_if_t<(detail::IsKeyOrModifier<Args> && ...), bool> = true>
constexpr int combine(Args... args)
template<typename... Args> requires (detail::IsKeyOrModifier<Args> && ...)
inline QKeySequence keySequence(Args... args)
{
return (0 | ... | static_cast<int>(args));
}
/**
* @brief typeId is a backwards-compatible adapter for
* QVariant::typeId and type functions.
* @param variant
* @return the type id of the variant
*/
inline QMetaType::Type typeId(const QVariant& variant)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return static_cast<QMetaType::Type>(variant.typeId());
#else
return static_cast<QMetaType::Type>(variant.type());
#endif
}
//! Backwards-compatible adapter for QDomDocument::setContent
inline bool setContent(QDomDocument& doc, const QByteArray& text,
QString* errorMsg = nullptr, int* errorLine = nullptr, int* errorColumn = nullptr)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
auto result = doc.setContent(text, QDomDocument::ParseOption::Default);
if (result) { return true; }
if (errorMsg) { *errorMsg = std::move(result.errorMessage); }
if (errorLine) { *errorLine = static_cast<int>(result.errorLine); }
if (errorColumn) { *errorColumn = static_cast<int>(result.errorColumn); }
return false;
#else
return doc.setContent(text, errorMsg, errorLine, errorColumn);
#endif
}
//! Backwards-compatible adapter for QDomDocument::setContent
inline bool setContent(QDomDocument& doc, QIODevice* dev, bool namespaceProcessing,
QString* errorMsg = nullptr, int* errorLine = nullptr, int* errorColumn = nullptr)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
const auto options = namespaceProcessing
? QDomDocument::ParseOption::UseNamespaceProcessing
: QDomDocument::ParseOption::Default;
auto result = doc.setContent(dev, options);
if (result) { return true; }
if (errorMsg) { *errorMsg = std::move(result.errorMessage); }
if (errorLine) { *errorLine = static_cast<int>(result.errorLine); }
if (errorColumn) { *errorColumn = static_cast<int>(result.errorColumn); }
return false;
#else
return doc.setContent(dev, namespaceProcessing, errorMsg, errorLine, errorColumn);
#endif
}
} // namespace lmms
#endif // LMMS_DEPRECATIONHELPER_H

View File

@@ -48,6 +48,11 @@ public:
*/
static void openDir(const QFileInfo item);
static void openDir(const QString& itemPath)
{
openDir(QFileInfo(itemPath));
}
/**
* @brief Checks whether the file manager supports selecting a specific file.
* @return True if selection is supported, otherwise false.
@@ -60,6 +65,11 @@ public:
*/
static void reveal(const QFileInfo item);
static void reveal(const QString& itemPath)
{
reveal(QFileInfo(itemPath));
}
private:
static bool s_canSelect;

View File

@@ -52,6 +52,11 @@ public:
//! Stop processing and destroys the object.
~FileSearchJob();
FileSearchJob(const FileSearchJob&) = delete;
FileSearchJob(FileSearchJob&&) = delete;
FileSearchJob& operator=(const FileSearchJob&) = delete;
FileSearchJob& operator=(FileSearchJob&&) = delete;
//! Commit to searching with the given @p task.
//! Cancels any previous search.
//! Callers can connect to the provided signals to interact with the search and its progress.
@@ -68,7 +73,6 @@ signals:
void finished();
private:
Q_DISABLE_MOVE(FileSearchJob)
void runSearch(Task task);
std::future<void> m_task;
std::atomic_flag m_stop = ATOMIC_FLAG_INIT;

View File

@@ -81,7 +81,11 @@ protected:
void paintEvent(QPaintEvent * me) override;
void wheelEvent(QWheelEvent * me) override;
void enterEvent(QEvent *event) override;
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
void enterEvent(QEnterEvent*) override;
#else
void enterEvent(QEvent*) override;
#endif
void leaveEvent(QEvent *event) override;
virtual float getValue(const QPoint & p);

View File

@@ -49,10 +49,14 @@ public:
MainApplication(int& argc, char** argv);
bool event(QEvent* event) override;
#ifdef LMMS_BUILD_WIN32
bool winEventFilter(MSG* msg, long* result);
bool nativeEventFilter(const QByteArray& eventType, void* message,
long* result);
#endif
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
using FilterResult = long;
#else
using FilterResult = qintptr;
#endif // QT6 check
bool win32EventFilter(MSG* msg, FilterResult* result);
bool nativeEventFilter(const QByteArray& eventType, void* message, FilterResult* result);
#endif // LMMS_BUILD_WIN32
inline QString& queuedFile()
{
return m_queuedFile;

View File

@@ -65,7 +65,11 @@ public:
void openInNewInstrumentTrack(QString value);
protected:
void enterEvent( QEvent * _e ) override;
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
void enterEvent(QEnterEvent* event) override;
#else
void enterEvent(QEvent* event) override;
#endif
void leaveEvent( QEvent * _e ) override;
void mousePressEvent( QMouseEvent * _me ) override;
void paintEvent( QPaintEvent * _pe ) override;

View File

@@ -48,7 +48,7 @@ public:
void setActiveTab(int idx);
int findTabAtPos(const QPoint* pos);
int findTabAtPos(const QPoint& pos);
inline int activeTab() const
{

View File

@@ -27,6 +27,7 @@
#define LMMS_BASE64_H
#include <QByteArray>
#include <QMetaType>
#include <QString>
#include <QVariant>
@@ -47,9 +48,10 @@ namespace lmms::base64
*_data = new T[*_size / sizeof(T)];
memcpy( *_data, data.constData(), *_size );
}
// for compatibility-code only
QVariant decode( const QString & _b64,
QVariant::Type _force_type = QVariant::Invalid );
QVariant decode(const QString& b64,
QMetaType::Type forceType = QMetaType::UnknownType);
} // namespace lmms::base64

View File

@@ -58,16 +58,12 @@ auto LMMS_EXPORT getText(std::string_view name) -> QString;
* @param pixmap The pixmap to get the size of.
* @return The device-independent size of the pixmap.
*/
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
[[deprecated("Use QPixmap::deviceIndependentSize() instead; See "
"https://doc.qt.io/qt-6/qpixmap.html#deviceIndependentSize")]]
#endif
inline auto logicalSize(const QPixmap &pixmap) noexcept
inline auto logicalSize(const QPixmap& pixmap) noexcept
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
return pixmap.deviceIndependentSize().toSize();
#else
return pixmap.isNull() ? QSize() : pixmap.size() / pixmap.devicePixelRatio();
return pixmap.isNull() ? QSize(0, 0) : pixmap.size() / pixmap.devicePixelRatio();
#endif
}