diff --git a/applet/contents/config/main.xml b/applet/contents/config/main.xml --- a/applet/contents/config/main.xml +++ b/applet/contents/config/main.xml @@ -23,6 +23,10 @@ true + + + true + true diff --git a/applet/contents/ui/ConfigGeneral.qml b/applet/contents/ui/ConfigGeneral.qml --- a/applet/contents/ui/ConfigGeneral.qml +++ b/applet/contents/ui/ConfigGeneral.qml @@ -30,6 +30,7 @@ property alias cfg_volumeStep: volumeStep.value property alias cfg_volumeFeedback: volumeFeedback.checked property alias cfg_volumeOsd: volumeOsd.checked + property alias cfg_microphoneIndicator: microphoneIndicator.checked property alias cfg_micOsd: micOsd.checked property alias cfg_muteOsd: muteOsd.checked property alias cfg_outputChangeOsd: outputChangeOsd.checked @@ -38,6 +39,10 @@ id: feedback } + MicrophoneIndicator { + id: micIndicator + } + QQC2.SpinBox { id: volumeStep @@ -95,4 +100,18 @@ id: outputChangeOsd text: i18n("Default output device") } + + + Item { + Kirigami.FormData.isSection: true + } + + + QQC2.CheckBox { + id: microphoneIndicator + + Kirigami.FormData.label: i18n("Show an indicator when an application is using the:") + checked: micIndicator.enabled + text: i18n("Microphone") + } } diff --git a/applet/contents/ui/main.qml b/applet/contents/ui/main.qml --- a/applet/contents/ui/main.qml +++ b/applet/contents/ui/main.qml @@ -36,6 +36,7 @@ property bool volumeFeedback: Plasmoid.configuration.volumeFeedback property bool globalMute: Plasmoid.configuration.globalMute + property bool microphoneIndicator : Plasmoid.configuration.microphoneIndicator property int raiseMaxVolumeValue: 150 property int maxVolumeValue: Math.round(raiseMaxVolumeValue * PulseAudio.NormalVolume / 100.0) property int currentMaxVolumeValue: plasmoid.configuration.raiseMaximumVolume ? maxVolumeValue : PulseAudio.NormalVolume @@ -389,6 +390,11 @@ id: feedback } + MicrophoneIndicator { + id: micIndicator + enabled: main.microphoneIndicator + } + PlasmaCore.Svg { id: lineSvg imagePath: "widgets/line" @@ -668,8 +674,4 @@ } } } - - Component.onCompleted: { - MicrophoneIndicator.init(); - } } diff --git a/src/qml/microphoneindicator.h b/src/qml/microphoneindicator.h --- a/src/qml/microphoneindicator.h +++ b/src/qml/microphoneindicator.h @@ -44,15 +44,21 @@ Q_OBJECT public: - explicit MicrophoneIndicator(QObject *parent = nullptr); + static MicrophoneIndicator *instance(); ~MicrophoneIndicator() override; - Q_INVOKABLE void init(); - Q_SIGNALS: void enabledChanged(); private: + friend class MicrophoneIndicatorInterface; + + explicit MicrophoneIndicator(QObject *parent = nullptr); + static MicrophoneIndicator *m_pThis; + + bool m_enabled = true; + void setStatus(bool status); + void scheduleUpdate(); void update(); @@ -81,6 +87,27 @@ int m_wheelDelta = 0; - QTimer *m_updateTimer; + QTimer *m_updateTimer = nullptr; + +}; +class MicrophoneIndicatorInterface : public QObject +{ + Q_OBJECT + + Q_PROPERTY(bool enabled READ isEnabled WRITE setStatus NOTIFY statusChanged) + +public: + explicit MicrophoneIndicatorInterface(QObject *parent = nullptr); + + bool isEnabled() const; + void setStatus(bool status); + + ~MicrophoneIndicatorInterface() override; + +Q_SIGNALS: + void statusChanged(); + +private: + MicrophoneIndicator *m_pInstance = nullptr; }; diff --git a/src/qml/microphoneindicator.cpp b/src/qml/microphoneindicator.cpp --- a/src/qml/microphoneindicator.cpp +++ b/src/qml/microphoneindicator.cpp @@ -37,32 +37,44 @@ using namespace QPulseAudio; -MicrophoneIndicator::MicrophoneIndicator(QObject *parent) - : QObject(parent) - , m_sourceModel(new SourceModel(this)) - , m_sourceOutputModel(new SourceOutputModel(this)) - , m_updateTimer(new QTimer(this)) +MicrophoneIndicator* MicrophoneIndicator::m_pThis = nullptr; + +MicrophoneIndicator::MicrophoneIndicator(QObject *parent) : QObject(parent) { +} - connect(m_sourceModel, &QAbstractItemModel::rowsInserted, this, &MicrophoneIndicator::scheduleUpdate); - connect(m_sourceModel, &QAbstractItemModel::rowsRemoved, this, &MicrophoneIndicator::scheduleUpdate); - connect(m_sourceModel, &QAbstractItemModel::dataChanged, this, &MicrophoneIndicator::scheduleUpdate); +MicrophoneIndicator::~MicrophoneIndicator() = default; - connect(m_sourceOutputModel, &QAbstractItemModel::rowsInserted, this, &MicrophoneIndicator::scheduleUpdate); - connect(m_sourceOutputModel, &QAbstractItemModel::rowsRemoved, this, &MicrophoneIndicator::scheduleUpdate); +MicrophoneIndicator *MicrophoneIndicator::instance() +{ + // Allow only a single instance + if (!m_pThis) { + m_pThis = new MicrophoneIndicator; + m_pThis->m_sourceModel = new SourceModel(m_pThis); + m_pThis->m_sourceOutputModel = new SourceOutputModel(m_pThis); + m_pThis->m_updateTimer = new QTimer(m_pThis); - m_updateTimer->setInterval(0); - m_updateTimer->setSingleShot(true); - connect(m_updateTimer, &QTimer::timeout, this, &MicrophoneIndicator::update); + connect(m_pThis->m_sourceModel, &QAbstractItemModel::rowsInserted, m_pThis, &MicrophoneIndicator::scheduleUpdate); + connect(m_pThis->m_sourceModel, &QAbstractItemModel::rowsRemoved, m_pThis, &MicrophoneIndicator::scheduleUpdate); + connect(m_pThis->m_sourceModel, &QAbstractItemModel::dataChanged, m_pThis, &MicrophoneIndicator::scheduleUpdate); - scheduleUpdate(); -} + connect(m_pThis->m_sourceOutputModel, &QAbstractItemModel::rowsInserted, m_pThis, &MicrophoneIndicator::scheduleUpdate); + connect(m_pThis->m_sourceOutputModel, &QAbstractItemModel::rowsRemoved, m_pThis, &MicrophoneIndicator::scheduleUpdate); -MicrophoneIndicator::~MicrophoneIndicator() = default; + connect(m_pThis, &MicrophoneIndicator::enabledChanged, m_pThis, &MicrophoneIndicator::scheduleUpdate); -void MicrophoneIndicator::init() + m_pThis->m_updateTimer->setInterval(0); + m_pThis->m_updateTimer->setSingleShot(true); + connect(m_pThis->m_updateTimer, &QTimer::timeout, m_pThis, &MicrophoneIndicator::update); + } + + return m_pThis; +} + +void MicrophoneIndicator::setStatus(bool status) { - // does nothing, just prompts QML engine to create an instance of the singleton + m_enabled = status; + Q_EMIT enabledChanged(); } void MicrophoneIndicator::scheduleUpdate() @@ -261,8 +273,8 @@ QStringList MicrophoneIndicator::appNames() const { - // If there are no microphones present, there's nothing to record - if (m_sourceModel->rowCount() == 0) { + // Return an empty list if disabled by the user or no microphone is connected + if (!m_enabled || m_sourceModel->rowCount() == 0) { return QStringList(); } @@ -293,3 +305,21 @@ return names; } + + +MicrophoneIndicatorInterface::MicrophoneIndicatorInterface(QObject *parent) : QObject(parent) +{ + m_pInstance = MicrophoneIndicator::instance(); +} + +bool MicrophoneIndicatorInterface::isEnabled() const +{ + return m_pInstance->m_enabled; +} + +void MicrophoneIndicatorInterface::setStatus(bool status) +{ + m_pInstance->setStatus(status); +} + +MicrophoneIndicatorInterface::~MicrophoneIndicatorInterface() = default; diff --git a/src/qml/plugin.cpp b/src/qml/plugin.cpp --- a/src/qml/plugin.cpp +++ b/src/qml/plugin.cpp @@ -63,13 +63,9 @@ qmlRegisterType(uri, 0, 1, "GlobalActionCollection"); qmlRegisterType(uri, 0, 1, "VolumeOSD"); qmlRegisterType(uri, 0, 1, "VolumeFeedback"); + qmlRegisterType(uri, 0, 1, "MicrophoneIndicator"); qmlRegisterSingletonType(uri, 0, 1, "PulseAudio", pulseaudio_singleton); - qmlRegisterSingletonType(uri, 0, 1, "MicrophoneIndicator", - [](QQmlEngine *engine, QJSEngine *jsEngine) -> QObject* { - Q_UNUSED(engine); - Q_UNUSED(jsEngine); - return new MicrophoneIndicator(); - }); + #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) qmlRegisterType(); qmlRegisterType();