mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Make PortalAutostart asynchronous
This commit is contained in:
parent
bf255c0e00
commit
e52e1672e8
1 changed files with 113 additions and 90 deletions
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "core/launcher.h"
|
#include "core/launcher.h"
|
||||||
|
#include "core/sandbox.h"
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
#include "core/update_checker.h"
|
#include "core/update_checker.h"
|
||||||
#include "webview/platform/linux/webview_linux_webkitgtk.h"
|
#include "webview/platform/linux/webview_linux_webkitgtk.h"
|
||||||
|
@ -52,115 +53,138 @@ using Platform::internal::WaylandIntegration;
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool PortalAutostart(bool start, bool silent) {
|
void PortalAutostart(bool enabled, Fn<void(bool)> done) {
|
||||||
if (cExeName().isEmpty()) {
|
if (cExeName().isEmpty()) {
|
||||||
return false;
|
if (done) {
|
||||||
|
done(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto error = false;
|
const auto connection = [&] {
|
||||||
|
try {
|
||||||
try {
|
return Gio::DBus::Connection::get_sync(
|
||||||
const auto connection = Gio::DBus::Connection::get_sync(
|
Gio::DBus::BusType::SESSION);
|
||||||
Gio::DBus::BusType::SESSION);
|
} catch (const std::exception &e) {
|
||||||
|
if (done) {
|
||||||
const auto handleToken = Glib::ustring("tdesktop")
|
LOG(("Portal Autostart Error: %1").arg(
|
||||||
+ std::to_string(base::RandomValue<uint>());
|
QString::fromStdString(e.what())));
|
||||||
|
}
|
||||||
std::vector<Glib::ustring> commandline;
|
return Glib::RefPtr<Gio::DBus::Connection>();
|
||||||
commandline.push_back(cExeName().toStdString());
|
|
||||||
if (Core::Launcher::Instance().customWorkingDir()) {
|
|
||||||
commandline.push_back("-workdir");
|
|
||||||
commandline.push_back(cWorkingDir().toStdString());
|
|
||||||
}
|
}
|
||||||
commandline.push_back("-autostart");
|
}();
|
||||||
|
|
||||||
std::map<Glib::ustring, Glib::VariantBase> options;
|
if (!connection) {
|
||||||
options["handle_token"] = Glib::create_variant(handleToken);
|
if (done) {
|
||||||
options["reason"] = Glib::create_variant(
|
done(false);
|
||||||
Glib::ustring(
|
}
|
||||||
tr::lng_settings_auto_start(tr::now).toStdString()));
|
return;
|
||||||
options["autostart"] = Glib::create_variant(start);
|
}
|
||||||
options["commandline"] = Glib::create_variant(commandline);
|
|
||||||
options["dbus-activatable"] = Glib::create_variant(false);
|
|
||||||
|
|
||||||
auto uniqueName = connection->get_unique_name();
|
const auto handleToken = Glib::ustring("tdesktop")
|
||||||
uniqueName.erase(0, 1);
|
+ std::to_string(base::RandomValue<uint>());
|
||||||
uniqueName.replace(uniqueName.find('.'), 1, 1, '_');
|
|
||||||
|
|
||||||
const auto requestPath = Glib::ustring(
|
std::vector<Glib::ustring> commandline;
|
||||||
"/org/freedesktop/portal/desktop/request/")
|
commandline.push_back(cExeName().toStdString());
|
||||||
+ uniqueName
|
if (Core::Launcher::Instance().customWorkingDir()) {
|
||||||
+ '/'
|
commandline.push_back("-workdir");
|
||||||
+ handleToken;
|
commandline.push_back(cWorkingDir().toStdString());
|
||||||
|
}
|
||||||
|
commandline.push_back("-autostart");
|
||||||
|
|
||||||
const auto loop = Glib::MainLoop::create();
|
std::map<Glib::ustring, Glib::VariantBase> options;
|
||||||
|
options["handle_token"] = Glib::create_variant(handleToken);
|
||||||
|
options["reason"] = Glib::create_variant(
|
||||||
|
Glib::ustring(
|
||||||
|
tr::lng_settings_auto_start(tr::now).toStdString()));
|
||||||
|
options["autostart"] = Glib::create_variant(enabled);
|
||||||
|
options["commandline"] = Glib::create_variant(commandline);
|
||||||
|
options["dbus-activatable"] = Glib::create_variant(false);
|
||||||
|
|
||||||
|
auto uniqueName = connection->get_unique_name();
|
||||||
|
uniqueName.erase(0, 1);
|
||||||
|
uniqueName.replace(uniqueName.find('.'), 1, 1, '_');
|
||||||
|
|
||||||
|
const auto requestPath = Glib::ustring(
|
||||||
|
"/org/freedesktop/portal/desktop/request/")
|
||||||
|
+ uniqueName
|
||||||
|
+ '/'
|
||||||
|
+ handleToken;
|
||||||
|
|
||||||
|
const auto window = std::make_shared<QWidget>();
|
||||||
|
window->setAttribute(Qt::WA_DontShowOnScreen);
|
||||||
|
window->setWindowModality(Qt::ApplicationModal);
|
||||||
|
window->show();
|
||||||
|
|
||||||
|
const auto signalId = std::make_shared<uint>();
|
||||||
|
*signalId = connection->signal_subscribe(
|
||||||
|
[=](
|
||||||
|
const Glib::RefPtr<Gio::DBus::Connection> &connection,
|
||||||
|
const Glib::ustring &sender_name,
|
||||||
|
const Glib::ustring &object_path,
|
||||||
|
const Glib::ustring &interface_name,
|
||||||
|
const Glib::ustring &signal_name,
|
||||||
|
const Glib::VariantContainerBase ¶meters) {
|
||||||
|
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||||
|
(void)window; // don't destroy until finish
|
||||||
|
|
||||||
const auto signalId = connection->signal_subscribe(
|
|
||||||
[&](
|
|
||||||
const Glib::RefPtr<Gio::DBus::Connection> &connection,
|
|
||||||
const Glib::ustring &sender_name,
|
|
||||||
const Glib::ustring &object_path,
|
|
||||||
const Glib::ustring &interface_name,
|
|
||||||
const Glib::ustring &signal_name,
|
|
||||||
const Glib::VariantContainerBase ¶meters) {
|
|
||||||
try {
|
try {
|
||||||
const auto response = parameters.get_child(
|
const auto response = parameters.get_child(
|
||||||
0
|
0
|
||||||
).get_dynamic<uint>();
|
).get_dynamic<uint>();
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
if (!silent) {
|
if (done) {
|
||||||
LOG(("Portal Autostart Error: Request denied"));
|
LOG(("Portal Autostart Error: Request denied"));
|
||||||
|
done(false);
|
||||||
}
|
}
|
||||||
error = true;
|
} else if (done) {
|
||||||
|
done(enabled);
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
if (!silent) {
|
if (done) {
|
||||||
LOG(("Portal Autostart Error: %1").arg(
|
LOG(("Portal Autostart Error: %1").arg(
|
||||||
QString::fromStdString(e.what())));
|
QString::fromStdString(e.what())));
|
||||||
|
done(false);
|
||||||
}
|
}
|
||||||
error = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loop->quit();
|
if (*signalId) {
|
||||||
},
|
connection->signal_unsubscribe(*signalId);
|
||||||
base::Platform::XDP::kService,
|
}
|
||||||
base::Platform::XDP::kRequestInterface,
|
});
|
||||||
"Response",
|
},
|
||||||
requestPath);
|
base::Platform::XDP::kService,
|
||||||
|
base::Platform::XDP::kRequestInterface,
|
||||||
|
"Response",
|
||||||
|
requestPath);
|
||||||
|
|
||||||
const auto signalGuard = gsl::finally([&] {
|
connection->call(
|
||||||
if (signalId != 0) {
|
base::Platform::XDP::kObjectPath,
|
||||||
connection->signal_unsubscribe(signalId);
|
"org.freedesktop.portal.Background",
|
||||||
}
|
"RequestBackground",
|
||||||
});
|
Glib::create_variant(std::tuple{
|
||||||
|
base::Platform::XDP::ParentWindowID(),
|
||||||
|
options,
|
||||||
|
}),
|
||||||
|
[=](const Glib::RefPtr<Gio::AsyncResult> &result) {
|
||||||
|
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
|
||||||
|
try {
|
||||||
|
connection->call_finish(result);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
if (done) {
|
||||||
|
LOG(("Portal Autostart Error: %1").arg(
|
||||||
|
QString::fromStdString(e.what())));
|
||||||
|
done(false);
|
||||||
|
}
|
||||||
|
|
||||||
connection->call_sync(
|
if (*signalId) {
|
||||||
base::Platform::XDP::kObjectPath,
|
connection->signal_unsubscribe(*signalId);
|
||||||
"org.freedesktop.portal.Background",
|
}
|
||||||
"RequestBackground",
|
}
|
||||||
Glib::create_variant(std::tuple{
|
});
|
||||||
base::Platform::XDP::ParentWindowID(),
|
},
|
||||||
options,
|
base::Platform::XDP::kService);
|
||||||
}),
|
|
||||||
base::Platform::XDP::kService);
|
|
||||||
|
|
||||||
if (signalId != 0) {
|
|
||||||
QWidget window;
|
|
||||||
window.setAttribute(Qt::WA_DontShowOnScreen);
|
|
||||||
window.setWindowModality(Qt::ApplicationModal);
|
|
||||||
window.show();
|
|
||||||
loop->run();
|
|
||||||
}
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
if (!silent) {
|
|
||||||
LOG(("Portal Autostart Error: %1").arg(
|
|
||||||
QString::fromStdString(e.what())));
|
|
||||||
}
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenerateDesktopFile(
|
bool GenerateDesktopFile(
|
||||||
|
@ -457,13 +481,12 @@ bool AutostartSupported() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutostartToggle(bool enabled, Fn<void(bool)> done) {
|
void AutostartToggle(bool enabled, Fn<void(bool)> done) {
|
||||||
|
if (KSandbox::isFlatpak()) {
|
||||||
|
PortalAutostart(enabled, done);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto success = [&] {
|
const auto success = [&] {
|
||||||
const auto silent = !done;
|
|
||||||
|
|
||||||
if (KSandbox::isFlatpak()) {
|
|
||||||
return PortalAutostart(enabled, silent);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto autostart = QStandardPaths::writableLocation(
|
const auto autostart = QStandardPaths::writableLocation(
|
||||||
QStandardPaths::GenericConfigLocation)
|
QStandardPaths::GenericConfigLocation)
|
||||||
+ u"/autostart/"_q;
|
+ u"/autostart/"_q;
|
||||||
|
@ -479,7 +502,7 @@ void AutostartToggle(bool enabled, Fn<void(bool)> done) {
|
||||||
autostart,
|
autostart,
|
||||||
{ u"-autostart"_q },
|
{ u"-autostart"_q },
|
||||||
true,
|
true,
|
||||||
silent);
|
!done);
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (done) {
|
if (done) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue