System Volume Plugin for macOS
This commit is contained in:
parent
12f1a0a75b
commit
074c42c72b
4 changed files with 490 additions and 3 deletions
|
@ -7,9 +7,7 @@ add_subdirectory(battery)
|
|||
add_subdirectory(sendnotifications)
|
||||
add_subdirectory(mpriscontrol)
|
||||
add_subdirectory(photo)
|
||||
if(NOT APPLE)
|
||||
add_subdirectory(systemvolume)
|
||||
endif()
|
||||
add_subdirectory(systemvolume)
|
||||
|
||||
if(NOT SAILFISHOS)
|
||||
add_subdirectory(clipboard)
|
||||
|
|
|
@ -2,6 +2,10 @@ if(WIN32)
|
|||
set(kdeconnect_systemvolume_SRCS
|
||||
systemvolumeplugin-win.cpp
|
||||
)
|
||||
elseif(APPLE)
|
||||
set(kdeconnect_systemvolume_SRCS
|
||||
systemvolumeplugin-macos.cpp
|
||||
)
|
||||
else()
|
||||
set(kdeconnect_systemvolume_SRCS
|
||||
systemvolumeplugin-pulse.cpp
|
||||
|
@ -16,6 +20,12 @@ if(WIN32)
|
|||
Qt5::Core
|
||||
ole32
|
||||
)
|
||||
elseif(APPLE)
|
||||
target_link_libraries(kdeconnect_systemvolume
|
||||
kdeconnectcore
|
||||
Qt5::Core
|
||||
"-framework CoreAudio"
|
||||
)
|
||||
else()
|
||||
target_link_libraries(kdeconnect_systemvolume
|
||||
kdeconnectcore
|
||||
|
|
427
plugins/systemvolume/systemvolumeplugin-macos.cpp
Normal file
427
plugins/systemvolume/systemvolumeplugin-macos.cpp
Normal file
|
@ -0,0 +1,427 @@
|
|||
/**
|
||||
* Copyright 2019 Weixuan XIAO <veyx.shaw@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "systemvolumeplugin-macos.h"
|
||||
|
||||
#include <KPluginFactory>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QLoggingCategory>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_systemvolume.json", registerPlugin< SystemvolumePlugin >(); )
|
||||
|
||||
Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_SYSTEMVOLUME, "kdeconnect.plugin.systemvolume")
|
||||
|
||||
class MacOSCoreAudioDevice
|
||||
{
|
||||
private:
|
||||
AudioDeviceID deviceId;
|
||||
QString description;
|
||||
bool isStereo;
|
||||
|
||||
friend class SystemvolumePlugin;
|
||||
public:
|
||||
MacOSCoreAudioDevice(AudioDeviceID);
|
||||
~MacOSCoreAudioDevice();
|
||||
|
||||
void setVolume(float volume);
|
||||
float volume();
|
||||
void setMuted(bool muted);
|
||||
bool isMuted();
|
||||
|
||||
void updateType();
|
||||
};
|
||||
|
||||
static const AudioObjectPropertyAddress kAudioHardwarePropertyAddress = {
|
||||
kAudioHardwarePropertyDevices,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster};
|
||||
|
||||
static const AudioObjectPropertyAddress kAudioStreamPropertyAddress = {
|
||||
kAudioDevicePropertyStreams,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMaster};
|
||||
|
||||
static const AudioObjectPropertyAddress kAudioMasterVolumePropertyAddress = {
|
||||
kAudioDevicePropertyVolumeScalar,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMaster};
|
||||
|
||||
static const AudioObjectPropertyAddress kAudioLeftVolumePropertyAddress = {
|
||||
kAudioDevicePropertyVolumeScalar,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
1};
|
||||
|
||||
static const AudioObjectPropertyAddress kAudioRightVolumePropertyAddress = {
|
||||
kAudioDevicePropertyVolumeScalar,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
2};
|
||||
|
||||
static const AudioObjectPropertyAddress kAudioMasterMutedPropertyAddress = {
|
||||
kAudioDevicePropertyMute,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMaster};
|
||||
|
||||
static const AudioObjectPropertyAddress kAudioMasterDataSourcePropertyAddress = {
|
||||
kAudioDevicePropertyDataSource,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMaster};
|
||||
|
||||
OSStatus onVolumeChanged(AudioObjectID object, UInt32 num_addresses, const AudioObjectPropertyAddress addresses[], void *context)
|
||||
{
|
||||
SystemvolumePlugin *plugin = (SystemvolumePlugin*)context;
|
||||
plugin->updateDeviceVolume(object);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
OSStatus onMutedChanged(AudioObjectID object, UInt32 num_addresses, const AudioObjectPropertyAddress addresses[], void *context)
|
||||
{
|
||||
SystemvolumePlugin *plugin = (SystemvolumePlugin*)context;
|
||||
plugin->updateDeviceMuted(object);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
OSStatus onOutputSourceChanged(AudioObjectID object, UInt32 num_addresses, const AudioObjectPropertyAddress addresses[], void *context)
|
||||
{
|
||||
SystemvolumePlugin *plugin = (SystemvolumePlugin*)context;
|
||||
plugin->sendSinkList();
|
||||
return noErr;
|
||||
}
|
||||
|
||||
UInt32 getDeviceSourceId(AudioObjectID deviceId) {
|
||||
UInt32 dataSourceId;
|
||||
UInt32 size = sizeof(dataSourceId);
|
||||
OSStatus result = AudioObjectGetPropertyData(deviceId, &kAudioMasterDataSourcePropertyAddress, 0, NULL, &size, &dataSourceId);
|
||||
if (result != noErr)
|
||||
return kAudioDeviceUnknown;
|
||||
|
||||
return dataSourceId;
|
||||
}
|
||||
|
||||
QString translateDeviceSource(AudioObjectID deviceId) {
|
||||
UInt32 sourceId = getDeviceSourceId(deviceId);
|
||||
|
||||
if (sourceId == kAudioDeviceUnknown) {
|
||||
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Unknown data source id of device" << deviceId;
|
||||
return QStringLiteral("");
|
||||
}
|
||||
|
||||
CFStringRef sourceName = nullptr;
|
||||
AudioValueTranslation translation;
|
||||
translation.mInputData = &sourceId;
|
||||
translation.mInputDataSize = sizeof(sourceId);
|
||||
translation.mOutputData = &sourceName;
|
||||
translation.mOutputDataSize = sizeof(sourceName);
|
||||
|
||||
UInt32 translationSize = sizeof(AudioValueTranslation);
|
||||
AudioObjectPropertyAddress propertyAddress = {
|
||||
kAudioDevicePropertyDataSourceNameForIDCFString,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMaster};
|
||||
|
||||
OSStatus result = AudioObjectGetPropertyData(deviceId, &propertyAddress, 0, NULL, &translationSize, &translation);
|
||||
if (result != noErr) {
|
||||
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Cannot get description of device" << deviceId;
|
||||
return QStringLiteral("");
|
||||
}
|
||||
|
||||
QString ret = QString::fromCFString(sourceName);
|
||||
CFRelease(sourceName);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<AudioObjectID> GetAllOutputAudioDeviceIDs() {
|
||||
std::vector<AudioObjectID> outputDeviceIds;
|
||||
|
||||
UInt32 size = 0;
|
||||
OSStatus result;
|
||||
|
||||
result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &kAudioHardwarePropertyAddress, 0, NULL, &size);
|
||||
|
||||
if (result != noErr) {
|
||||
qCDebug(KDECONNECT_PLUGIN_SYSTEMVOLUME)
|
||||
<< "Failed to read size of property " << kAudioHardwarePropertyDevices
|
||||
<< " for device/object " << kAudioObjectSystemObject;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return {};
|
||||
|
||||
size_t device_count = size / sizeof(AudioObjectID);
|
||||
std::vector<AudioObjectID> deviceIds(device_count);
|
||||
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &kAudioHardwarePropertyAddress, 0, NULL, &size, deviceIds.data());
|
||||
if (result != noErr) {
|
||||
qCDebug(KDECONNECT_PLUGIN_SYSTEMVOLUME)
|
||||
<< "Failed to read object IDs from property " << kAudioHardwarePropertyDevices
|
||||
<< " for device/object " << kAudioObjectSystemObject;
|
||||
return {};
|
||||
}
|
||||
|
||||
for (AudioDeviceID deviceId : deviceIds) {
|
||||
UInt32 streamCount = 0;
|
||||
result = AudioObjectGetPropertyDataSize(deviceId, &kAudioStreamPropertyAddress, 0, NULL, &streamCount);
|
||||
|
||||
if (result == noErr && streamCount > 0) {
|
||||
outputDeviceIds.push_back(deviceId);
|
||||
qCDebug(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Device" << deviceId << "added";
|
||||
} else {
|
||||
qCDebug(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Device" << deviceId << "dropped";
|
||||
}
|
||||
}
|
||||
|
||||
return outputDeviceIds;
|
||||
}
|
||||
|
||||
SystemvolumePlugin::SystemvolumePlugin(QObject* parent, const QVariantList& args)
|
||||
: KdeConnectPlugin(parent, args)
|
||||
, sinksMap()
|
||||
{}
|
||||
|
||||
bool SystemvolumePlugin::receivePacket(const NetworkPacket& np)
|
||||
{
|
||||
if (np.has(QStringLiteral("requestSinks"))) {
|
||||
sendSinkList();
|
||||
} else {
|
||||
QString name = np.get<QString>(QStringLiteral("name"));
|
||||
|
||||
if (sinksMap.contains(name)) {
|
||||
if (np.has(QStringLiteral("volume"))) {
|
||||
sinksMap[name]->setVolume(np.get<int>(QStringLiteral("volume")) / 100.0);
|
||||
}
|
||||
if (np.has(QStringLiteral("muted"))) {
|
||||
sinksMap[name]->setMuted(np.get<bool>(QStringLiteral("muted")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SystemvolumePlugin::sendSinkList()
|
||||
{
|
||||
QJsonDocument document;
|
||||
QJsonArray array;
|
||||
|
||||
if (!sinksMap.empty()) {
|
||||
for (MacOSCoreAudioDevice *sink : sinksMap) {
|
||||
delete sink;
|
||||
}
|
||||
sinksMap.clear();
|
||||
}
|
||||
|
||||
std::vector<AudioObjectID> deviceIds = GetAllOutputAudioDeviceIDs();
|
||||
|
||||
for (AudioDeviceID deviceId : deviceIds) {
|
||||
MacOSCoreAudioDevice *audioDevice = new MacOSCoreAudioDevice(deviceId);
|
||||
|
||||
audioDevice->description = translateDeviceSource(deviceId);
|
||||
|
||||
sinksMap.insert(QStringLiteral("default-") + QString::number(deviceId), audioDevice);
|
||||
|
||||
// Add volume change listener
|
||||
AudioObjectAddPropertyListener(deviceId, &kAudioMasterVolumePropertyAddress, &onVolumeChanged, (void *)this);
|
||||
|
||||
AudioObjectAddPropertyListener(deviceId, &kAudioLeftVolumePropertyAddress, &onVolumeChanged, (void *)this);
|
||||
AudioObjectAddPropertyListener(deviceId, &kAudioRightVolumePropertyAddress, &onVolumeChanged, (void *)this);
|
||||
|
||||
// Add muted change listener
|
||||
AudioObjectAddPropertyListener(deviceId, &kAudioMasterMutedPropertyAddress, &onMutedChanged, (void *)this);
|
||||
|
||||
// Add data source change listerner
|
||||
AudioObjectAddPropertyListener(deviceId, &kAudioMasterDataSourcePropertyAddress, &onOutputSourceChanged, (void *)this);
|
||||
|
||||
QJsonObject sinkObject {
|
||||
{QStringLiteral("name"), QStringLiteral("default-") + QString::number(deviceId)},
|
||||
{QStringLiteral("muted"), audioDevice->isMuted()},
|
||||
{QStringLiteral("description"), audioDevice->description},
|
||||
{QStringLiteral("volume"), audioDevice->volume() * 100},
|
||||
{QStringLiteral("maxVolume"), 100}
|
||||
};
|
||||
|
||||
array.append(sinkObject);
|
||||
}
|
||||
|
||||
document.setArray(array);
|
||||
|
||||
NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME);
|
||||
np.set<QJsonDocument>(QStringLiteral("sinkList"), document);
|
||||
sendPacket(np);
|
||||
}
|
||||
|
||||
void SystemvolumePlugin::connected()
|
||||
{
|
||||
sendSinkList();
|
||||
}
|
||||
|
||||
void SystemvolumePlugin::updateDeviceMuted(AudioDeviceID deviceId)
|
||||
{
|
||||
for (MacOSCoreAudioDevice *sink : sinksMap) {
|
||||
if (sink->deviceId == deviceId) {
|
||||
NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME);
|
||||
np.set<bool>(QStringLiteral("muted"), (bool)(sink->isMuted()));
|
||||
np.set<int>(QStringLiteral("volume"), (int)(sink->volume() * 100));
|
||||
np.set<QString>(QStringLiteral("name"), QStringLiteral("default-") + QString::number(deviceId));
|
||||
sendPacket(np);
|
||||
return;
|
||||
}
|
||||
}
|
||||
qCDebug(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Device" << deviceId << "not found while update mute state";
|
||||
}
|
||||
|
||||
void SystemvolumePlugin::updateDeviceVolume(AudioDeviceID deviceId)
|
||||
{
|
||||
for (MacOSCoreAudioDevice *sink : sinksMap) {
|
||||
if (sink->deviceId == deviceId) {
|
||||
NetworkPacket np(PACKET_TYPE_SYSTEMVOLUME);
|
||||
np.set<int>(QStringLiteral("volume"), (int)(sink->volume() * 100));
|
||||
np.set<QString>(QStringLiteral("name"), QStringLiteral("default-") + QString::number(deviceId));
|
||||
sendPacket(np);
|
||||
return;
|
||||
}
|
||||
}
|
||||
qCDebug(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Device" << deviceId << "not found while update volume";
|
||||
}
|
||||
|
||||
MacOSCoreAudioDevice::MacOSCoreAudioDevice(AudioDeviceID _deviceId)
|
||||
: deviceId(_deviceId)
|
||||
{
|
||||
updateType();
|
||||
}
|
||||
|
||||
MacOSCoreAudioDevice::~MacOSCoreAudioDevice()
|
||||
{
|
||||
// Volume listener
|
||||
AudioObjectRemovePropertyListener(deviceId, &kAudioMasterVolumePropertyAddress,
|
||||
&onVolumeChanged, (void *)this);
|
||||
AudioObjectRemovePropertyListener(deviceId, &kAudioLeftVolumePropertyAddress,
|
||||
&onVolumeChanged, (void *)this);
|
||||
AudioObjectRemovePropertyListener(deviceId, &kAudioRightVolumePropertyAddress,
|
||||
&onVolumeChanged, (void *)this);
|
||||
|
||||
// Muted listener
|
||||
AudioObjectRemovePropertyListener(deviceId, &kAudioMasterMutedPropertyAddress,
|
||||
&onMutedChanged, (void *)this);
|
||||
|
||||
// Data source listener
|
||||
AudioObjectRemovePropertyListener(deviceId, &kAudioMasterDataSourcePropertyAddress,
|
||||
&onOutputSourceChanged, (void *)this);
|
||||
}
|
||||
|
||||
void MacOSCoreAudioDevice::setVolume(float volume)
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
if (deviceId == kAudioObjectUnknown) {
|
||||
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Unable to set volume of Unknown Device";
|
||||
return;
|
||||
}
|
||||
|
||||
if (isStereo) {
|
||||
result = AudioObjectSetPropertyData(deviceId, &kAudioLeftVolumePropertyAddress, 0, NULL, sizeof(volume), &volume);
|
||||
result = AudioObjectSetPropertyData(deviceId, &kAudioRightVolumePropertyAddress, 0, NULL, sizeof(volume), &volume);
|
||||
} else {
|
||||
result = AudioObjectSetPropertyData(deviceId, &kAudioMasterVolumePropertyAddress, 0, NULL, sizeof(volume), &volume);
|
||||
}
|
||||
|
||||
if (result != noErr) {
|
||||
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Unable to set volume of Device" << deviceId << "to" << volume;
|
||||
}
|
||||
}
|
||||
|
||||
void MacOSCoreAudioDevice::setMuted(bool muted)
|
||||
{
|
||||
if (deviceId == kAudioObjectUnknown) {
|
||||
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Unable to mute an Unknown Device";
|
||||
return;
|
||||
}
|
||||
|
||||
UInt32 mutedValue = muted ? 1 : 0;
|
||||
|
||||
OSStatus result = AudioObjectSetPropertyData(deviceId, &kAudioMasterMutedPropertyAddress, 0, NULL, sizeof(mutedValue), &mutedValue);
|
||||
|
||||
if (result != noErr) {
|
||||
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Unable to set muted state of Device" << deviceId << "to" << muted;
|
||||
}
|
||||
}
|
||||
|
||||
float MacOSCoreAudioDevice::volume()
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
if (deviceId == kAudioObjectUnknown) {
|
||||
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Unable to get volume of Unknown Device";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float volume = 0.0;
|
||||
UInt32 volumeDataSize = sizeof(volume);
|
||||
|
||||
if (isStereo) {
|
||||
// Try to get steoreo device volume
|
||||
result = AudioObjectGetPropertyData(deviceId, &kAudioLeftVolumePropertyAddress, 0, NULL, &volumeDataSize, &volume);
|
||||
} else {
|
||||
// Try to get master volume
|
||||
result = AudioObjectGetPropertyData(deviceId, &kAudioMasterVolumePropertyAddress, 0, NULL, &volumeDataSize, &volume);
|
||||
}
|
||||
|
||||
if (result != noErr) {
|
||||
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Unable to get volume of Device" << deviceId;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return volume;
|
||||
}
|
||||
|
||||
bool MacOSCoreAudioDevice::isMuted()
|
||||
{
|
||||
if (deviceId == kAudioObjectUnknown) {
|
||||
qWarning(KDECONNECT_PLUGIN_SYSTEMVOLUME) << "Unable to get muted state of an Unknown Device";
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt32 muted = 0;
|
||||
UInt32 muteddataSize = sizeof(muted);
|
||||
|
||||
AudioObjectGetPropertyData(deviceId, &kAudioMasterMutedPropertyAddress, 0, NULL, &muteddataSize, &muted);
|
||||
|
||||
return muted == 1;
|
||||
}
|
||||
|
||||
void MacOSCoreAudioDevice::updateType()
|
||||
{
|
||||
// Try to get volume from left channel to check if it's a stereo device
|
||||
float volume = 0.0;
|
||||
UInt32 volumeDataSize = sizeof(volume);
|
||||
OSStatus result = AudioObjectGetPropertyData(deviceId, &kAudioLeftVolumePropertyAddress, 0, NULL, &volumeDataSize, &volume);
|
||||
if (result == noErr) {
|
||||
isStereo = true;
|
||||
} else {
|
||||
isStereo = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include "systemvolumeplugin-macos.moc"
|
||||
|
52
plugins/systemvolume/systemvolumeplugin-macos.h
Normal file
52
plugins/systemvolume/systemvolumeplugin-macos.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* Copyright 2019 Weixuan XIAO <veyx.shaw@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEMVOLUMEPLUGINMACOS_H
|
||||
#define SYSTEMVOLUMEPLUGINMACOS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
#include <core/kdeconnectplugin.h>
|
||||
|
||||
#import <CoreAudio/CoreAudio.h>
|
||||
|
||||
#define PACKET_TYPE_SYSTEMVOLUME QStringLiteral("kdeconnect.systemvolume")
|
||||
#define PACKET_TYPE_SYSTEMVOLUME_REQUEST QStringLiteral("kdeconnect.systemvolume.request")
|
||||
|
||||
class MacOSCoreAudioDevice;
|
||||
|
||||
class Q_DECL_EXPORT SystemvolumePlugin : public KdeConnectPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SystemvolumePlugin(QObject *parent, const QVariantList &args);
|
||||
bool receivePacket(const NetworkPacket& np) override;
|
||||
void connected() override;
|
||||
void sendSinkList();
|
||||
|
||||
void updateDeviceVolume(AudioDeviceID deviceId);
|
||||
void updateDeviceMuted(AudioDeviceID deviceId);
|
||||
private:
|
||||
QMap<QString, MacOSCoreAudioDevice*> sinksMap;
|
||||
};
|
||||
|
||||
#endif // SYSTEMVOLUMEPLUGINMACOS_H
|
Loading…
Reference in a new issue