mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 20:48:52 +03:00
Cleanup Qt D-Bus connections and watchers
This commit is contained in:
parent
7f98cd0133
commit
c3081ece40
4 changed files with 173 additions and 115 deletions
|
@ -1061,7 +1061,7 @@ CallManager::previewWindow(unsigned int index) const
|
|||
return;
|
||||
}
|
||||
GstElement *pipewiresrc = gst_element_factory_make("pipewiresrc", nullptr);
|
||||
g_object_set(pipewiresrc, "fd", (gint)stream->fd, nullptr);
|
||||
g_object_set(pipewiresrc, "fd", (gint)stream->fd.fileDescriptor(), nullptr);
|
||||
std::string path = std::to_string(stream->nodeId);
|
||||
g_object_set(pipewiresrc, "path", path.c_str(), nullptr);
|
||||
g_object_set(pipewiresrc, "do-timestamp", (gboolean)1, nullptr);
|
||||
|
|
|
@ -34,6 +34,48 @@ handle_path(QString handle_token)
|
|||
QStringLiteral("/") + handle_token;
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenCastPortal::makeConnection(QString service,
|
||||
QString path,
|
||||
QString interface,
|
||||
QString name,
|
||||
const char *slot)
|
||||
{
|
||||
if (QDBusConnection::sessionBus().connect(service, path, interface, name, this, slot)) {
|
||||
last_connection = {
|
||||
std::move(service), std::move(path), std::move(interface), std::move(name), slot};
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenCastPortal::disconnectClose()
|
||||
{
|
||||
QDBusConnection::sessionBus().disconnect(QStringLiteral("org.freedesktop.portal.Desktop"),
|
||||
sessionHandle.path(),
|
||||
QStringLiteral("org.freedesktop.portal.Session"),
|
||||
QStringLiteral("Closed"),
|
||||
this,
|
||||
SLOT(closedHandler(QVariantMap)));
|
||||
}
|
||||
|
||||
void
|
||||
ScreenCastPortal::removeConnection()
|
||||
{
|
||||
if (!last_connection.has_value())
|
||||
return;
|
||||
|
||||
const auto &connection = *last_connection;
|
||||
QDBusConnection::sessionBus().disconnect(connection[0],
|
||||
connection[1],
|
||||
connection[2],
|
||||
connection[3],
|
||||
this,
|
||||
connection[4].toLocal8Bit().data());
|
||||
last_connection = std::nullopt;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenCastPortal::init()
|
||||
{
|
||||
|
@ -79,13 +121,19 @@ ScreenCastPortal::close(bool reinit)
|
|||
break;
|
||||
case State::Starting:
|
||||
if (!reinit) {
|
||||
// Remaining handler will abort.
|
||||
disconnectClose();
|
||||
removeConnection();
|
||||
state = State::Closed;
|
||||
}
|
||||
break;
|
||||
case State::Started: {
|
||||
state = State::Closing;
|
||||
disconnectClose();
|
||||
// Close file descriptor if it was opened
|
||||
stream = Stream{};
|
||||
|
||||
emit readyChanged();
|
||||
|
||||
auto msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.portal.Desktop"),
|
||||
sessionHandle.path(),
|
||||
QStringLiteral("org.freedesktop.portal.Session"),
|
||||
|
@ -97,7 +145,9 @@ ScreenCastPortal::close(bool reinit)
|
|||
&QDBusPendingCallWatcher::finished,
|
||||
this,
|
||||
[this, reinit](QDBusPendingCallWatcher *self) {
|
||||
self->deleteLater();
|
||||
QDBusPendingReply reply = *self;
|
||||
|
||||
if (!reply.isValid()) {
|
||||
nhlog::ui()->warn("org.freedesktop.portal.ScreenCast (Close): {}",
|
||||
reply.error().message().toStdString());
|
||||
|
@ -116,8 +166,11 @@ ScreenCastPortal::close(bool reinit)
|
|||
void
|
||||
ScreenCastPortal::closedHandler(uint response, const QVariantMap &)
|
||||
{
|
||||
removeConnection();
|
||||
disconnectClose();
|
||||
|
||||
if (response != 0) {
|
||||
nhlog::ui()->error("org.freedekstop.portal.ScreenCast (Closed): {}", response);
|
||||
nhlog::ui()->error("org.freedesktop.portal.ScreenCast (Closed): {}", response);
|
||||
}
|
||||
|
||||
nhlog::ui()->debug("org.freedesktop.portal.ScreenCast: Connection closed");
|
||||
|
@ -130,12 +183,16 @@ ScreenCastPortal::createSession()
|
|||
{
|
||||
// Connect before sending the request to avoid missing the reply
|
||||
QString handle_token = make_token();
|
||||
QDBusConnection::sessionBus().connect(QStringLiteral("org.freedesktop.portal.Desktop"),
|
||||
if (!makeConnection(QStringLiteral("org.freedesktop.portal.Desktop"),
|
||||
handle_path(handle_token),
|
||||
QStringLiteral("org.freedesktop.portal.Request"),
|
||||
QStringLiteral("Response"),
|
||||
this,
|
||||
SLOT(createSessionHandler(uint, QVariantMap)));
|
||||
SLOT(createSessionHandler(uint, QVariantMap)))) {
|
||||
nhlog::ui()->error(
|
||||
"Connection to signal Response for org.freedesktop.portal.Request failed");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
auto msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.portal.Desktop"),
|
||||
QStringLiteral("/org/freedesktop/portal/desktop"),
|
||||
|
@ -145,11 +202,11 @@ ScreenCastPortal::createSession()
|
|||
{QStringLiteral("session_handle_token"), make_token()}};
|
||||
|
||||
QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(msg);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
|
||||
connect(
|
||||
watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
|
||||
QDBusPendingReply<QDBusObjectPath> reply = *self;
|
||||
self->deleteLater();
|
||||
QDBusPendingReply<QDBusObjectPath> reply = *self;
|
||||
|
||||
if (!reply.isValid()) {
|
||||
nhlog::ui()->error("org.freedesktop.portal.ScreenCast (CreateSession): {}",
|
||||
|
@ -162,13 +219,14 @@ ScreenCastPortal::createSession()
|
|||
void
|
||||
ScreenCastPortal::createSessionHandler(uint response, const QVariantMap &results)
|
||||
{
|
||||
switch (state) {
|
||||
case State::Closed:
|
||||
removeConnection();
|
||||
|
||||
if (state != State::Starting) {
|
||||
nhlog::ui()->warn("ScreenCastPortal not starting");
|
||||
break;
|
||||
case State::Starting: {
|
||||
return;
|
||||
}
|
||||
if (response != 0) {
|
||||
nhlog::ui()->error("org.freedekstop.portal.ScreenCast (CreateSession Response): {}",
|
||||
nhlog::ui()->error("org.freedesktop.portal.ScreenCast (CreateSession Response): {}",
|
||||
response);
|
||||
close();
|
||||
return;
|
||||
|
@ -179,14 +237,14 @@ ScreenCastPortal::createSessionHandler(uint response, const QVariantMap &results
|
|||
nhlog::ui()->debug("org.freedesktop.portal.ScreenCast: sessionHandle = {}",
|
||||
sessionHandle.path().toStdString());
|
||||
|
||||
QDBusConnection::sessionBus().connect(QStringLiteral("org.freedesktop.portal.Desktop"),
|
||||
sessionHandle.path(),
|
||||
QStringLiteral("org.freedesktop.portal.Session"),
|
||||
QStringLiteral("Closed"),
|
||||
this,
|
||||
SLOT(closedHandler(QVariantMap)));
|
||||
|
||||
getAvailableSourceTypes();
|
||||
} break;
|
||||
case State::Started:
|
||||
nhlog::ui()->warn("ScreenCastPortal already started");
|
||||
break;
|
||||
case State::Closing:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -200,11 +258,11 @@ ScreenCastPortal::getAvailableSourceTypes()
|
|||
<< QStringLiteral("AvailableSourceTypes");
|
||||
|
||||
QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(msg);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
|
||||
connect(
|
||||
watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
|
||||
QDBusPendingReply<QDBusVariant> reply = *self;
|
||||
self->deleteLater();
|
||||
QDBusPendingReply<QDBusVariant> reply = *self;
|
||||
|
||||
if (!reply.isValid()) {
|
||||
nhlog::ui()->error("org.freedesktop.DBus.Properties (Get AvailableSourceTypes): {}",
|
||||
|
@ -213,11 +271,10 @@ ScreenCastPortal::getAvailableSourceTypes()
|
|||
return;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case State::Closed:
|
||||
if (state != State::Starting) {
|
||||
nhlog::ui()->warn("ScreenCastPortal not starting");
|
||||
break;
|
||||
case State::Starting: {
|
||||
return;
|
||||
}
|
||||
const auto &value = reply.value().variant();
|
||||
if (value.canConvert<uint>()) {
|
||||
availableSourceTypes = value.value<uint>();
|
||||
|
@ -229,13 +286,6 @@ ScreenCastPortal::getAvailableSourceTypes()
|
|||
}
|
||||
|
||||
getAvailableCursorModes();
|
||||
} break;
|
||||
case State::Started:
|
||||
nhlog::ui()->warn("ScreenCastPortal already started");
|
||||
break;
|
||||
case State::Closing:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -250,11 +300,11 @@ ScreenCastPortal::getAvailableCursorModes()
|
|||
<< QStringLiteral("AvailableCursorModes");
|
||||
|
||||
QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(msg);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
|
||||
connect(
|
||||
watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
|
||||
QDBusPendingReply<QDBusVariant> reply = *self;
|
||||
self->deleteLater();
|
||||
QDBusPendingReply<QDBusVariant> reply = *self;
|
||||
|
||||
if (!reply.isValid()) {
|
||||
nhlog::ui()->error("org.freedesktop.DBus.Properties (Get AvailableCursorModes): {}",
|
||||
|
@ -263,11 +313,10 @@ ScreenCastPortal::getAvailableCursorModes()
|
|||
return;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case State::Closed:
|
||||
if (state != State::Starting) {
|
||||
nhlog::ui()->warn("ScreenCastPortal not starting");
|
||||
break;
|
||||
case State::Starting: {
|
||||
return;
|
||||
}
|
||||
const auto &value = reply.value().variant();
|
||||
if (value.canConvert<uint>()) {
|
||||
availableCursorModes = value.value<uint>();
|
||||
|
@ -279,13 +328,6 @@ ScreenCastPortal::getAvailableCursorModes()
|
|||
}
|
||||
|
||||
selectSources();
|
||||
} break;
|
||||
case State::Started:
|
||||
nhlog::ui()->warn("ScreenCastPortal already started");
|
||||
break;
|
||||
case State::Closing:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -294,12 +336,16 @@ ScreenCastPortal::selectSources()
|
|||
{
|
||||
// Connect before sending the request to avoid missing the reply
|
||||
auto handle_token = make_token();
|
||||
QDBusConnection::sessionBus().connect(QString(),
|
||||
if (!makeConnection(QString(),
|
||||
handle_path(handle_token),
|
||||
QStringLiteral("org.freedesktop.portal.Request"),
|
||||
QStringLiteral("Response"),
|
||||
this,
|
||||
SLOT(selectSourcesHandler(uint, QVariantMap)));
|
||||
SLOT(selectSourcesHandler(uint, QVariantMap)))) {
|
||||
nhlog::ui()->error(
|
||||
"Connection to signal Response for org.freedesktop.portal.Request failed");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
auto msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.portal.Desktop"),
|
||||
QStringLiteral("/org/freedesktop/portal/desktop"),
|
||||
|
@ -321,7 +367,9 @@ ScreenCastPortal::selectSources()
|
|||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
|
||||
connect(
|
||||
watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
|
||||
self->deleteLater();
|
||||
QDBusPendingReply<QDBusObjectPath> reply = *self;
|
||||
|
||||
if (!reply.isValid()) {
|
||||
nhlog::ui()->error("org.freedesktop.portal.ScreenCast (SelectSources): {}",
|
||||
reply.error().message().toStdString());
|
||||
|
@ -333,25 +381,19 @@ ScreenCastPortal::selectSources()
|
|||
void
|
||||
ScreenCastPortal::selectSourcesHandler(uint response, const QVariantMap &)
|
||||
{
|
||||
switch (state) {
|
||||
case State::Closed:
|
||||
removeConnection();
|
||||
|
||||
if (state != State::Starting) {
|
||||
nhlog::ui()->warn("ScreenCastPortal not starting");
|
||||
break;
|
||||
case State::Starting: {
|
||||
return;
|
||||
}
|
||||
if (response != 0) {
|
||||
nhlog::ui()->error("org.freedekstop.portal.ScreenCast (SelectSources Response): {}",
|
||||
nhlog::ui()->error("org.freedesktop.portal.ScreenCast (SelectSources Response): {}",
|
||||
response);
|
||||
close();
|
||||
return;
|
||||
}
|
||||
start();
|
||||
} break;
|
||||
case State::Started:
|
||||
nhlog::ui()->warn("ScreenCastPortal already started");
|
||||
break;
|
||||
case State::Closing:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -359,12 +401,15 @@ ScreenCastPortal::start()
|
|||
{
|
||||
// Connect before sending the request to avoid missing the reply
|
||||
auto handle_token = make_token();
|
||||
QDBusConnection::sessionBus().connect(QString(),
|
||||
if (!makeConnection(QString(),
|
||||
handle_path(handle_token),
|
||||
QStringLiteral("org.freedesktop.portal.Request"),
|
||||
QStringLiteral("Response"),
|
||||
this,
|
||||
SLOT(startHandler(uint, QVariantMap)));
|
||||
SLOT(startHandler(uint, QVariantMap)))) {
|
||||
nhlog::ui()->error("Connection to org.freedesktop.portal.Request Response failed");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
auto msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.portal.Desktop"),
|
||||
QStringLiteral("/org/freedesktop/portal/desktop"),
|
||||
|
@ -377,11 +422,12 @@ ScreenCastPortal::start()
|
|||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
|
||||
connect(
|
||||
watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
|
||||
self->deleteLater();
|
||||
QDBusPendingReply<QDBusObjectPath> reply = *self;
|
||||
|
||||
if (!reply.isValid()) {
|
||||
nhlog::ui()->error("org.freedesktop.portal.ScreenCast (Start): {}",
|
||||
reply.error().message().toStdString());
|
||||
} else {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -416,6 +462,8 @@ operator>>(const QDBusArgument &argument, PipeWireStream &stream)
|
|||
void
|
||||
ScreenCastPortal::startHandler(uint response, const QVariantMap &results)
|
||||
{
|
||||
removeConnection();
|
||||
|
||||
if (response != 0) {
|
||||
nhlog::ui()->error("org.freedesktop.portal.ScreenCast (Start Response): {}", response);
|
||||
close();
|
||||
|
@ -448,15 +496,17 @@ ScreenCastPortal::openPipeWireRemote()
|
|||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
|
||||
connect(
|
||||
watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
|
||||
self->deleteLater();
|
||||
QDBusPendingReply<QDBusUnixFileDescriptor> reply = *self;
|
||||
|
||||
if (!reply.isValid()) {
|
||||
nhlog::ui()->error("org.freedesktop.portal.ScreenCast (OpenPipeWireRemote): {}",
|
||||
reply.error().message().toStdString());
|
||||
close();
|
||||
} else {
|
||||
stream.fd = reply.value().fileDescriptor();
|
||||
nhlog::ui()->debug("org.freedesktop.portal.ScreenCast: fd = {}", stream.fd);
|
||||
|
||||
stream.fd = std::move(reply.value());
|
||||
nhlog::ui()->error("org.freedesktop.portal.ScreenCast: fd = {}",
|
||||
stream.fd.fileDescriptor());
|
||||
state = State::Started;
|
||||
emit readyChanged();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class ScreenCastPortal final : public QObject
|
|||
public:
|
||||
struct Stream
|
||||
{
|
||||
int fd;
|
||||
QDBusUnixFileDescriptor fd;
|
||||
quint32 nodeId;
|
||||
};
|
||||
|
||||
|
@ -51,6 +51,13 @@ private:
|
|||
void selectSources();
|
||||
void start();
|
||||
void openPipeWireRemote();
|
||||
bool makeConnection(QString service,
|
||||
QString path,
|
||||
QString interface,
|
||||
QString name,
|
||||
const char *slot);
|
||||
void removeConnection();
|
||||
void disconnectClose();
|
||||
QDBusObjectPath sessionHandle;
|
||||
uint availableSourceTypes;
|
||||
uint availableCursorModes;
|
||||
|
@ -65,6 +72,7 @@ private:
|
|||
Closing,
|
||||
};
|
||||
State state = State::Closed;
|
||||
std::optional<std::array<QString, 5>> last_connection;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1030,7 +1030,7 @@ WebRTCSession::addVideoPipeline(int vp8PayloadType)
|
|||
pipe_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
g_object_set(pipewiresrc, "fd", (gint)stream->fd, nullptr);
|
||||
g_object_set(pipewiresrc, "fd", (gint)stream->fd.fileDescriptor(), nullptr);
|
||||
std::string path = std::to_string(stream->nodeId);
|
||||
g_object_set(pipewiresrc, "path", path.c_str(), nullptr);
|
||||
g_object_set(pipewiresrc, "do-timestamp", (gboolean)1, nullptr);
|
||||
|
|
Loading…
Reference in a new issue