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));
48ServerPrivate::ServerPrivate(Server *q)
50 , m_defaultSink(nullptr)
51 , m_defaultSource(nullptr)
55ServerPrivate::~ServerPrivate()
59Sink *Server::defaultSink()
const
61 return d->m_defaultSink;
64void Server::setDefaultSink(Sink *sink)
67 Context::instance()->setDefaultSink(sink->name());
70Source *Server::defaultSource()
const
72 return d->m_defaultSource;
75void Server::setDefaultSource(Source *source)
78 Context::instance()->setDefaultSource(source->name());
83 if (d->m_defaultSink) {
84 d->m_defaultSink =
nullptr;
85 Q_EMIT defaultSinkChanged(d->m_defaultSink);
88 if (d->m_defaultSource) {
89 d->m_defaultSource =
nullptr;
90 Q_EMIT defaultSourceChanged(d->m_defaultSource);
94void Server::disconnectSignals()
96 disconnect(
this, &Server::defaultSinkChanged,
nullptr,
nullptr);
97 disconnect(
this, &Server::defaultSourceChanged,
nullptr,
nullptr);
98 disconnect(
this, &Server::isPipeWireChanged,
nullptr,
nullptr);
99 disconnect(
this, &Server::updated,
nullptr,
nullptr);
100 disconnect(
this, &Server::hasWirePlumberChanged,
nullptr,
nullptr);
103void ServerPrivate::update(
const pa_server_info *info)
110 if (isPw != m_isPipeWire) {
112 Q_EMIT q->isPipeWireChanged();
115 q->updateDefaultDevices();
121template<
typename Type,
typename Vector>
128 for (Type *t : vector) {
130 if (out->name() == name) {
134 qCWarning(PULSEAUDIOQT) <<
"No object for name" <<
name;
138void Server::updateDefaultDevices()
140 Sink *sink = findByName<Sink>(Context::instance()->d->m_sinks.data(), d->m_defaultSinkName);
141 Source *source = findByName<Source>(Context::instance()->d->m_sources.data(), d->m_defaultSourceName);
143 if (d->m_defaultSink != sink) {
144 qCDebug(PULSEAUDIOQT) <<
"Default sink changed" << sink;
145 d->m_defaultSink = sink;
146 Q_EMIT defaultSinkChanged(d->m_defaultSink);
149 if (d->m_defaultSource != source) {
150 qCDebug(PULSEAUDIOQT) <<
"Default source changed" << source;
151 d->m_defaultSource = source;
152 Q_EMIT defaultSourceChanged(d->m_defaultSource);
156bool Server::isPipeWire()
const
158 return d->m_isPipeWire;
161void ServerPrivate::findWirePlumber()
167 const auto clients = Context::instance()->clients();
168 for (
const auto &client : clients) {
169 if (client->properties().value(QStringLiteral(
"wireplumber.daemon")) ==
QLatin1String(
"true")) {
170 m_hasWirePlumber =
true;
171 Q_EMIT q->hasWirePlumberChanged();
177 m_hasWirePlumber =
false;
178 Q_EMIT q->hasWirePlumberChanged();
181bool Server::hasWirePlumber()
const
183 return d->m_hasWirePlumber;
QString name(StandardAction 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)