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

Add Qt6 Support #7339

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
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
52 changes: 37 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ option(WANT_DEBUG_TSAN "Enable ThreadSanitizer" OFF)
option(WANT_DEBUG_MSAN "Enable MemorySanitizer" OFF)
option(WANT_DEBUG_UBSAN "Enable UndefinedBehaviorSanitizer" OFF)
OPTION(BUNDLE_QT_TRANSLATIONS "Install Qt translation files for LMMS" OFF)
option(WANT_QT6 "Build with experimental Qt6 support" OFF)


IF(LMMS_BUILD_APPLE)
Expand Down Expand Up @@ -170,30 +171,50 @@ check_library_exists(rt shm_open "" LMMS_HAVE_LIBRT)

LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}")

FIND_PACKAGE(Qt5 5.9.0 COMPONENTS Core Gui Widgets Xml REQUIRED)
FIND_PACKAGE(Qt5 COMPONENTS LinguistTools QUIET)
IF(WANT_QT6)
SET(QT_VERSION_MAJOR 6)
SET(LMMS_QT_MIN_VERSION 6.0.0)
SET(STATUS_QT6 "ENABLED")
ELSE()
SET(QT_VERSION_MAJOR 5)
SET(LMMS_QT_MIN_VERSION 5.9.0)
SET(STATUS_QT6 "NOT ENABLED")
ENDIF()

FIND_PACKAGE(Qt${QT_VERSION_MAJOR} ${LMMS_QT_MIN_VERSION} COMPONENTS Core Gui Widgets Xml REQUIRED)
FIND_PACKAGE(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools QUIET)

include_directories(SYSTEM
${Qt5Core_INCLUDE_DIRS}
${Qt5Gui_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS}
${Qt5Xml_INCLUDE_DIRS}
${Qt${QT_VERSION_MAJOR}Core_INCLUDE_DIRS}
${Qt${QT_VERSION_MAJOR}Gui_INCLUDE_DIRS}
${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS}
${Qt${QT_VERSION_MAJOR}Xml_INCLUDE_DIRS}
)

SET(QT_LIBRARIES
Qt5::Core
Qt5::Gui
Qt5::Widgets
Qt5::Xml
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Xml
)

IF(LMMS_BUILD_LINUX AND WANT_VST)
IF(WANT_QT6)
# Core5Compat is needed so that we get QTextCodec which is used by
# the Hydrogen importer plugin.
# TODO : fix hydrogen importer plugin with qt6
# See: https://doc.qt.io/qt-6/qtcore5-index.html
FIND_PACKAGE(Qt6 COMPONENTS Core5Compat REQUIRED)
INCLUDE_DIRECTORIES(${Qt6Core5Compat_INCLUDE_DIRS})
SET(QT_LIBRARIES ${QT_LIBRARIES} Qt6::Core5Compat)
ENDIF()

IF(LMMS_BUILD_LINUX AND WANT_VST AND NOT WANT_QT6)
FIND_PACKAGE(Qt5 COMPONENTS X11Extras REQUIRED)
LIST(APPEND QT_LIBRARIES Qt5::X11Extras)
ENDIF()

# Resolve Qt5::qmake to full path for use in packaging scripts
GET_TARGET_PROPERTY(QT_QMAKE_EXECUTABLE "${Qt5Core_QMAKE_EXECUTABLE}" IMPORTED_LOCATION)
# Resolve qmake to full path for use in packaging scripts
GET_TARGET_PROPERTY(QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)

# Find the location of Qt translation files
execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
Expand All @@ -206,8 +227,8 @@ IF(EXISTS "${QT_TRANSLATIONS_DIR}")
ADD_DEFINITIONS("-DQT_TRANSLATIONS_DIR=\"${QT_TRANSLATIONS_DIR}\"")
ENDIF()

FIND_PACKAGE(Qt5Test)
SET(QT_QTTEST_LIBRARY Qt5::Test)
FIND_PACKAGE(Qt${QT_VERSION_MAJOR}Test)
SET(QT_QTTEST_LIBRARY Qt${QT_VERSION_MAJOR}::Test)

# check for libsndfile
FIND_PACKAGE(SndFile REQUIRED)
Expand Down Expand Up @@ -831,6 +852,7 @@ MESSAGE(
"* Debug using ThreadSanitizer : ${STATUS_DEBUG_TSAN}\n"
"* Debug using MemorySanitizer : ${STATUS_DEBUG_MSAN}\n"
"* Debug using UBSanitizer : ${STATUS_DEBUG_UBSAN}\n"
"* Experimental Qt6 support : ${STATUS_QT6}\n"
)

MESSAGE(
Expand Down
3 changes: 3 additions & 0 deletions cmake/apple/install_apple.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ echo -e "$MSG_COLOR\n\nCreating App Bundle \"$APP\"...$COLOR_RESET"
qtpath="$(dirname "@QT_QMAKE_EXECUTABLE@")"
export PATH="$PATH:$qtpath"

# Qt6: Fix @rpath bug https://github.com/orgs/Homebrew/discussions/2823
ln -sf "$qtpath/../lib" "@CMAKE_BINARY_DIR@/lib"

# Remove any old .app bundles
rm -Rf "$APP"

Expand Down
2 changes: 1 addition & 1 deletion cmake/install/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SET(PLUGIN_FILES "")
IF(LMMS_BUILD_WIN32)
INSTALL(FILES $<TARGET_FILE:Qt5::QWindowsIntegrationPlugin> DESTINATION platforms)
INSTALL(FILES $<TARGET_FILE:Qt${QT_VERSION_MAJOR}::QWindowsIntegrationPlugin> DESTINATION platforms)
ENDIF()

IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES)
Expand Down
10 changes: 8 additions & 2 deletions cmake/modules/BuildPlugin.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME)
ADD_GEN_QRC(RCC_OUT "${PLUGIN_NAME}.qrc" PREFIX artwork/${PLUGIN_NAME} ${PLUGIN_EMBEDDED_RESOURCES})
ENDIF(ER_LEN)

QT5_WRAP_CPP(plugin_MOC_out ${PLUGIN_MOCFILES})
IF(WANT_QT6)
QT6_WRAP_CPP(plugin_MOC_out ${PLUGIN_MOCFILES})
QT6_WRAP_UI(plugin_UIC_out ${PLUGIN_UICFILES})
ELSE()
QT5_WRAP_CPP(plugin_MOC_out ${PLUGIN_MOCFILES})
QT5_WRAP_UI(plugin_UIC_out ${PLUGIN_UICFILES})
ENDIF()

FOREACH(f ${PLUGIN_SOURCES})
ADD_FILE_DEPENDENCIES(${f} ${RCC_OUT})
Expand All @@ -51,7 +57,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME)

ADD_LIBRARY(${PLUGIN_NAME} ${PLUGIN_LINK} ${PLUGIN_SOURCES} ${plugin_MOC_out} ${RCC_OUT})

target_link_libraries("${PLUGIN_NAME}" lmms Qt5::Widgets Qt5::Xml)
target_link_libraries("${PLUGIN_NAME}" lmms Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Xml)

INSTALL(TARGETS ${PLUGIN_NAME}
LIBRARY DESTINATION "${PLUGIN_DIR}"
Expand Down
2 changes: 1 addition & 1 deletion cmake/modules/GenQrc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function(add_gen_qrc RCC_OUT QRC_NAME)
# generators. See issue #6177.
add_custom_command(
OUTPUT "${CPP_FILE}"
COMMAND Qt5::rcc
COMMAND Qt${QT_VERSION_MAJOR}::rcc
--name "${RESOURCE_NAME}"
--output "${CPP_FILE}"
"${QRC_FILE}"
Expand Down
4 changes: 2 additions & 2 deletions data/locale/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
SET(QT_LUPDATE_EXECUTABLE "${Qt5_LUPDATE_EXECUTABLE}")
SET(QT_LRELEASE_EXECUTABLE "${Qt5_LRELEASE_EXECUTABLE}")
SET(QT_LUPDATE_EXECUTABLE "${Qt${QT_VERSION_MAJOR}_LUPDATE_EXECUTABLE}")
SET(QT_LRELEASE_EXECUTABLE "${Qt${QT_VERSION_MAJOR}_LRELEASE_EXECUTABLE}")

IF(QT_LUPDATE_EXECUTABLE STREQUAL "")
EXECUTE_PROCESS(COMMAND "lupdate" "-help" RESULT_VARIABLE LUPDATE_FALLBACK OUTPUT_QUIET)
Expand Down
3 changes: 1 addition & 2 deletions include/ColorChooser.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ class ColorChooser : public QColorDialog
//! 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
Expand Down
18 changes: 12 additions & 6 deletions include/ColorHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,22 @@ 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 float interH = lerp(ar, br, t);
const float interS = lerp(ag, bg, t);
const float interV = lerp(ab, bb, t);
const float interA = lerp(aa, ba, t);
const colorType interH = lerp(ar, br, t);
const colorType interS = lerp(ag, bg, t);
const colorType interV = lerp(ab, bb, t);
const colorType interA = lerp(aa, ba, t);

return QColor::fromRgbF(interH, interS, interV, interA);
}
Expand Down
12 changes: 10 additions & 2 deletions include/ControlLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ class ControlLayout : public QLayout
{
Q_OBJECT

#if (QT_VERSION > QT_VERSION_CHECK(6, 0, 0))
using ControlLayoutMap = QMultiMap<QString, QLayoutItem *>;
using ControlLayoutMapIterator = QMultiMapIterator<QString, QLayoutItem *>;
#else
using ControlLayoutMap = QMap<QString, QLayoutItem*>;
using ControlLayoutMapIterator = QMapIterator<QString, QLayoutItem*>;
#endif

public:
explicit ControlLayout(QWidget *parent,
int margin = -1, int hSpacing = -1, int vSpacing = -1);
Expand Down Expand Up @@ -126,9 +134,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
Expand Down
30 changes: 30 additions & 0 deletions include/DeprecationHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,36 @@ inline QPoint position(QWheelEvent *wheelEvent)
#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(QMouseEvent* me)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return me->position().toPoint();
#else
return me->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(QDropEvent* de)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return de->position().toPoint();
#else
return de->pos();
#endif
}

} // namespace lmms

#endif // LMMS_DEPRECATIONHELPER_H
5 changes: 5 additions & 0 deletions include/FloatModelEditorBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ class LMMS_EXPORT FloatModelEditorBase : public QWidget, public FloatModelView
void paintEvent(QPaintEvent * me) override;
void wheelEvent(QWheelEvent * me) override;

// Todo : cleanup once we drop QT5 support
#if (QT_VERSION > QT_VERSION_CHECK(6, 0, 0))
void enterEvent(QEnterEvent *event) override;
#else
void enterEvent(QEvent *event) override;
#endif
void leaveEvent(QEvent *event) override;

virtual float getValue(const QPoint & p);
Expand Down
12 changes: 8 additions & 4 deletions include/MainApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,14 @@ class MainApplication : public QApplication
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;
Expand Down
7 changes: 6 additions & 1 deletion include/PluginBrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ class PluginDescWidget : public QWidget
void openInNewInstrumentTrack(QString value);

protected:
void enterEvent( QEvent * _e ) override;
// Todo : cleanup once QT 5 support is dropped
#if (QT_VERSION > QT_VERSION_CHECK(6, 0, 0))
void enterEvent( QEnterEvent * _e) override;
#else
void enterEvent(QEvent* _e) override;
#endif
void leaveEvent( QEvent * _e ) override;
void mousePressEvent( QMouseEvent * _me ) override;
void paintEvent( QPaintEvent * _pe ) override;
Expand Down
25 changes: 16 additions & 9 deletions plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "AudioFileProcessorWaveView.h"

#include "ConfigManager.h"
#include "DeprecationHelper.h"
#include "gui_templates.h"
#include "SampleWaveform.h"

Expand Down Expand Up @@ -113,10 +114,12 @@ void AudioFileProcessorWaveView::leaveEvent(QEvent * e)

void AudioFileProcessorWaveView::mousePressEvent(QMouseEvent * me)
{
const auto pos = position(me);

m_isDragging = true;
m_draggingLastPoint = me->pos();

const int x = me->x();
const int x = pos.x();

const int start_dist = qAbs(m_startFrameX - x);
const int end_dist = qAbs(m_endFrameX - x);
Expand Down Expand Up @@ -154,7 +157,9 @@ void AudioFileProcessorWaveView::mouseMoveEvent(QMouseEvent * me)
return;
}

const int step = me->x() - m_draggingLastPoint.x();
const auto pos = position(me);

const int step = pos.x() - m_draggingLastPoint.x();
switch(m_draggingType)
{
case DraggingType::SampleStart:
Expand All @@ -170,12 +175,12 @@ void AudioFileProcessorWaveView::mouseMoveEvent(QMouseEvent * me)
slide(step);
break;
case DraggingType::ZoomWave:
zoom(me->y() < m_draggingLastPoint.y());
zoom(pos.y() < m_draggingLastPoint.y());
break;
case DraggingType::Wave:
default:
if (qAbs(me->y() - m_draggingLastPoint.y())
< 2 * qAbs(me->x() - m_draggingLastPoint.x()))
if (qAbs(pos.y() - m_draggingLastPoint.y())
< 2 * qAbs(pos.x() - m_draggingLastPoint.x()))
{
m_draggingType = DraggingType::SlideWave;
}
Expand All @@ -185,7 +190,7 @@ void AudioFileProcessorWaveView::mouseMoveEvent(QMouseEvent * me)
}
}

m_draggingLastPoint = me->pos();
m_draggingLastPoint = pos;
update();
}

Expand Down Expand Up @@ -475,11 +480,13 @@ void AudioFileProcessorWaveView::reverse()

void AudioFileProcessorWaveView::updateCursor(QMouseEvent * me)
{
const auto pos = position(me);

bool const waveIsDragged = m_isDragging && (m_draggingType == DraggingType::Wave);
bool const pointerCloseToStartEndOrLoop = (me != nullptr) &&
(isCloseTo(me->x(), m_startFrameX) ||
isCloseTo(me->x(), m_endFrameX) ||
isCloseTo(me->x(), m_loopFrameX));
(isCloseTo(pos.x(), m_startFrameX) ||
isCloseTo(pos.x(), m_endFrameX) ||
isCloseTo(pos.x(), m_loopFrameX));

if (!m_isDragging && pointerCloseToStartEndOrLoop)
setCursor(Qt::SizeHorCursor);
Expand Down
Loading
Loading