From 6f590d44bb186178902a5fc3dc4a12cee8e88eaa Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 4 Apr 2024 15:55:10 +0200 Subject: [PATCH] Fix ABI breakage wrt QAudioSink/Source::stateChanged signals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Amends edaec2bf714c98d65f12c8ed9a2ffbd1603635a7, which removed the QAudioSink/Source::stateChanged(QAudio::State) symbols from the API, thus breaking binary compatibility to Qt 6.6. Since moc-generated code compares pointer-to-member- functions, we cannot bring that symbol back and still have such connections work. The only reasonable way to fix this is to reverse the namespace aliasing: QAudio is the real namespace, QtAudio becomes an alias. All symbols are then exported with the QAudio type in their signature, even if declared with QtAudio types as parameters, so we don't need any removed_api tricks to bring the old symbols back. We just need to trick qdoc into seeing the namespace as QtAudio, which is trivial and has no ABI implications. The previous caveat that string-based connections need to use QAudio doesn't change with this. [ChangeLog][Binary Compatibility Note] Qt 6.7.0 broke binary compatibility by renaming the QAudio namespace to QtAudio. Qt 6.7.1 restores compatibility with previous Qt 6 versions again by making QtAudio an alias for the QAudio namespace, but breaks BC with 6.7.0. Code previously built against 6.7.0 needs to be recompiled. Pick-to: 6.7 Fixes: QTBUG-123997 Change-Id: I456db61ff0bd1d97af7ce2d2a7968999d891a84d Reviewed-by: Axel Spoerl Reviewed-by: Jøger Hansegård --- src/multimedia/audio/qaudio.h | 8 +++- src/multimedia/audio/qaudiosink.cpp | 4 +- src/multimedia/audio/qaudiosink.h | 15 +++----- src/multimedia/audio/qaudiosource.cpp | 4 +- src/multimedia/audio/qaudiosource.h | 15 +++----- src/multimedia/audio/qtaudio.cpp | 4 ++ src/multimedia/compat/removed_api.cpp | 55 --------------------------- 7 files changed, 26 insertions(+), 79 deletions(-) diff --git a/src/multimedia/audio/qaudio.h b/src/multimedia/audio/qaudio.h index b569b3a15c..5ae994b9f0 100644 --- a/src/multimedia/audio/qaudio.h +++ b/src/multimedia/audio/qaudio.h @@ -19,7 +19,11 @@ QT_BEGIN_NAMESPACE // Class forward declaration required for QDoc bug class QString; +#if defined(Q_QDOC) namespace QtAudio +#else +namespace QAudio +#endif { enum Error { NoError, OpenError, IOError, UnderrunError, FatalError }; enum State { ActiveState, SuspendedState, StoppedState, IdleState }; @@ -34,8 +38,8 @@ namespace QtAudio Q_MULTIMEDIA_EXPORT float convertVolume(float volume, VolumeScale from, VolumeScale to); } -#if !defined(Q_QDOC) && !QT_MULTIMEDIA_REMOVED_SINCE(6, 7) -namespace QAudio = QtAudio; +#if !defined(Q_QDOC) +namespace QtAudio = QAudio; #endif #ifndef QT_NO_DEBUG_STREAM diff --git a/src/multimedia/audio/qaudiosink.cpp b/src/multimedia/audio/qaudiosink.cpp index aac96c342d..12263d32a2 100644 --- a/src/multimedia/audio/qaudiosink.cpp +++ b/src/multimedia/audio/qaudiosink.cpp @@ -279,7 +279,7 @@ qint64 QAudioSink::elapsedUSecs() const /*! Returns the error state. */ -QtAudio::Error QAudioSink::error(QT6_IMPL_NEW_OVERLOAD) const +QtAudio::Error QAudioSink::error() const { return d ? d->error() : QAudio::OpenError; } @@ -287,7 +287,7 @@ QtAudio::Error QAudioSink::error(QT6_IMPL_NEW_OVERLOAD) const /*! Returns the state of audio processing. */ -QtAudio::State QAudioSink::state(QT6_IMPL_NEW_OVERLOAD) const +QtAudio::State QAudioSink::state() const { return d ? d->state() : QAudio::StoppedState; } diff --git a/src/multimedia/audio/qaudiosink.h b/src/multimedia/audio/qaudiosink.h index 7a4eb732ae..e071e6fbc5 100644 --- a/src/multimedia/audio/qaudiosink.h +++ b/src/multimedia/audio/qaudiosink.h @@ -49,21 +49,18 @@ class Q_MULTIMEDIA_EXPORT QAudioSink : public QObject qint64 processedUSecs() const; qint64 elapsedUSecs() const; -#if QT_MULTIMEDIA_REMOVED_SINCE(6, 7) - QAudio::Error error() const; - QAudio::State state() const; -#endif - QtAudio::Error error(QT6_DECL_NEW_OVERLOAD) const; - QtAudio::State state(QT6_DECL_NEW_OVERLOAD) const; + QtAudio::Error error() const; + QtAudio::State state() const; void setVolume(qreal); qreal volume() const; Q_SIGNALS: -#ifdef Q_MOC_RUN - void stateChanged(QAudio::State state); -#else +#if defined(Q_QDOC) void stateChanged(QtAudio::State state); +#else + // use QAudio here to keep string-based connections working + void stateChanged(QAudio::State state); #endif private: diff --git a/src/multimedia/audio/qaudiosource.cpp b/src/multimedia/audio/qaudiosource.cpp index 5e59a47986..1ed5e82bcf 100644 --- a/src/multimedia/audio/qaudiosource.cpp +++ b/src/multimedia/audio/qaudiosource.cpp @@ -340,7 +340,7 @@ qint64 QAudioSource::elapsedUSecs() const Returns the error state. */ -QtAudio::Error QAudioSource::error(QT6_IMPL_NEW_OVERLOAD) const +QtAudio::Error QAudioSource::error() const { return d ? d->error() : QAudio::OpenError; } @@ -349,7 +349,7 @@ QtAudio::Error QAudioSource::error(QT6_IMPL_NEW_OVERLOAD) const Returns the state of audio processing. */ -QtAudio::State QAudioSource::state(QT6_IMPL_NEW_OVERLOAD) const +QtAudio::State QAudioSource::state() const { return d ? d->state() : QAudio::StoppedState; } diff --git a/src/multimedia/audio/qaudiosource.h b/src/multimedia/audio/qaudiosource.h index 71c5446eeb..f0ad0ceb5e 100644 --- a/src/multimedia/audio/qaudiosource.h +++ b/src/multimedia/audio/qaudiosource.h @@ -50,18 +50,15 @@ class Q_MULTIMEDIA_EXPORT QAudioSource : public QObject qint64 processedUSecs() const; qint64 elapsedUSecs() const; -#if QT_MULTIMEDIA_REMOVED_SINCE(6, 7) - QAudio::Error error() const; - QAudio::State state() const; -#endif - QtAudio::Error error(QT6_DECL_NEW_OVERLOAD) const; - QtAudio::State state(QT6_DECL_NEW_OVERLOAD) const; + QtAudio::Error error() const; + QtAudio::State state() const; Q_SIGNALS: -#ifdef Q_MOC_RUN - void stateChanged(QAudio::State state); -#else +#if defined(Q_QDOC) void stateChanged(QtAudio::State state); +#else + // use QAudio here to keep string-based connections working + void stateChanged(QAudio::State state); #endif private: diff --git a/src/multimedia/audio/qtaudio.cpp b/src/multimedia/audio/qtaudio.cpp index 999248bb6b..fb14e50934 100644 --- a/src/multimedia/audio/qtaudio.cpp +++ b/src/multimedia/audio/qtaudio.cpp @@ -62,7 +62,11 @@ QT_BEGIN_NAMESPACE \sa QtAudio::convertVolume() */ +#if defined(Q_QDOC) namespace QtAudio +#else +namespace QAudio +#endif { /*! diff --git a/src/multimedia/compat/removed_api.cpp b/src/multimedia/compat/removed_api.cpp index 15e92c4141..567024c8e4 100644 --- a/src/multimedia/compat/removed_api.cpp +++ b/src/multimedia/compat/removed_api.cpp @@ -9,61 +9,6 @@ QT_USE_NAMESPACE #if QT_MULTIMEDIA_REMOVED_SINCE(6, 7) -// implement removed functions from qaudio.h -#include -#include - -namespace QAudio -{ - enum VolumeScale {}; - enum Error {}; - enum State {}; - Q_MULTIMEDIA_EXPORT float convertVolume(float volume, QAudio::VolumeScale from, QAudio::VolumeScale to) - { - return QtAudio::convertVolume(volume, static_cast(from), - static_cast(to)); - } -} - -#ifndef QT_NO_DEBUG_STREAM -Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::Error error) -{ - return dbg << static_cast(error); -} -Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::State state) -{ - return dbg << static_cast(state); -} -Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::VolumeScale role) -{ - return dbg << static_cast(role); -} -#endif - -#include - -QAudio::Error QAudioSink::error() const -{ - return static_cast(error(QT6_CALL_NEW_OVERLOAD)); -} - -QAudio::State QAudioSink::state() const -{ - return static_cast(state(QT6_CALL_NEW_OVERLOAD)); -} - -#include - -QAudio::Error QAudioSource::error() const -{ - return static_cast(error(QT6_CALL_NEW_OVERLOAD)); -} - -QAudio::State QAudioSource::state() const -{ - return static_cast(state(QT6_CALL_NEW_OVERLOAD)); -} - // #include "qotherheader.h" // // implement removed functions from qotherheader.h // order sections alphabetically