16using namespace std::chrono_literals;
20Server::Server(Context *context)
22 , d(new ServerPrivate(this))
26 connect(&context->d->m_sinks, &MapBaseQObject::added,
this, &Server::updateDefaultDevices);
27 connect(&context->d->m_sinks, &MapBaseQObject::removed,
this, &Server::updateDefaultDevices);
28 connect(&context->d->m_sources, &MapBaseQObject::added,
this, &Server::updateDefaultDevices);
29 connect(&context->d->m_sources, &MapBaseQObject::removed,
this, &Server::updateDefaultDevices);
34 d->m_wirePlumberFindTimer.setInterval(250ms);
35 d->m_wirePlumberFindTimer.setSingleShot(
true);
39 connect(&context->d->m_clients, &MapBaseQObject::added, &d->m_wirePlumberFindTimer, qOverload<>(&
QTimer::start));
40 connect(&context->d->m_clients, &MapBaseQObject::removed, &d->m_wirePlumberFindTimer, qOverload<>(&
QTimer::start));
47ServerPrivate::ServerPrivate(Server *q)
49 , m_defaultSink(nullptr)
50 , m_defaultSource(nullptr)
54ServerPrivate::~ServerPrivate()
58Sink *Server::defaultSink()
const
60 return d->m_defaultSink;
63void Server::setDefaultSink(Sink *sink)
66 Context::instance()->setDefaultSink(sink->name());
69Source *Server::defaultSource()
const
71 return d->m_defaultSource;
74void Server::setDefaultSource(Source *source)
77 Context::instance()->setDefaultSource(source->name());
82 if (d->m_defaultSink) {
83 d->m_defaultSink =
nullptr;
84 Q_EMIT defaultSinkChanged(d->m_defaultSink);
87 if (d->m_defaultSource) {
88 d->m_defaultSource =
nullptr;
89 Q_EMIT defaultSourceChanged(d->m_defaultSource);
93void Server::disconnectSignals()
95 disconnect(
this, &Server::defaultSinkChanged,
nullptr,
nullptr);
96 disconnect(
this, &Server::defaultSourceChanged,
nullptr,
nullptr);
97 disconnect(
this, &Server::isPipeWireChanged,
nullptr,
nullptr);
98 disconnect(
this, &Server::updated,
nullptr,
nullptr);
99 disconnect(
this, &Server::hasWirePlumberChanged,
nullptr,
nullptr);
102void ServerPrivate::update(
const pa_server_info *info)
109 if (isPw != m_isPipeWire) {
111 Q_EMIT q->isPipeWireChanged();
114 q->updateDefaultDevices();
120template<
typename Type,
typename Vector>
127 for (Type *t : vector) {
129 if (out->name() == name) {
133 qCWarning(PULSEAUDIOQT) <<
"No object for name" <<
name;
137void Server::updateDefaultDevices()
139 Sink *sink = findByName<Sink>(Context::instance()->d->m_sinks.data(), d->m_defaultSinkName);
140 Source *source = findByName<Source>(Context::instance()->d->m_sources.data(), d->m_defaultSourceName);
142 if (d->m_defaultSink != sink) {
143 qCDebug(PULSEAUDIOQT) <<
"Default sink changed" << sink;
144 d->m_defaultSink = sink;
145 Q_EMIT defaultSinkChanged(d->m_defaultSink);
148 if (d->m_defaultSource != source) {
149 qCDebug(PULSEAUDIOQT) <<
"Default source changed" << source;
150 d->m_defaultSource = source;
151 Q_EMIT defaultSourceChanged(d->m_defaultSource);
155bool Server::isPipeWire()
const
157 return d->m_isPipeWire;
160void ServerPrivate::findWirePlumber()
166 const auto clients = Context::instance()->clients();
167 for (
const auto &client : clients) {
168 if (client->properties().value(QStringLiteral(
"wireplumber.daemon")) ==
QLatin1String(
"true")) {
169 m_hasWirePlumber =
true;
170 Q_EMIT q->hasWirePlumberChanged();
176 m_hasWirePlumber =
false;
177 Q_EMIT q->hasWirePlumberChanged();
180bool Server::hasWirePlumber()
const
182 return d->m_hasWirePlumber;
QString name(GameStandardAction id)
StandardShortcut findByName(const QString &name)
The primary namespace of PulseAudioQt.
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromUtf8(QByteArrayView str)
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)