Avoid 30s freeze when opening file dialog in broken envirionments

This commit is contained in:
Ilya Fedin 2021-04-30 08:17:37 +04:00 committed by John Preston
parent 896eee9841
commit b72260f420
3 changed files with 56 additions and 46 deletions

View file

@ -33,6 +33,8 @@ constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs;
const char *filterRegExp = const char *filterRegExp =
"^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; "^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
std::optional<uint> FileChooserPortalVersion;
auto QStringListToStd(const QStringList &list) { auto QStringListToStd(const QStringList &list) {
std::vector<Glib::ustring> result; std::vector<Glib::ustring> result;
ranges::transform( ranges::transform(
@ -69,8 +71,7 @@ auto MakeFilterList(const QString &filter) {
return result; return result;
} }
std::optional<uint> FileChooserPortalVersion() { void ComputeFileChooserPortalVersion() {
try {
const auto connection = [] { const auto connection = [] {
try { try {
return Gio::DBus::Connection::get_sync( return Gio::DBus::Connection::get_sync(
@ -81,10 +82,10 @@ std::optional<uint> FileChooserPortalVersion() {
}(); }();
if (!connection) { if (!connection) {
return std::nullopt; return;
} }
auto reply = connection->call_sync( connection->call(
std::string(kXDGDesktopPortalObjectPath), std::string(kXDGDesktopPortalObjectPath),
std::string(kPropertiesInterface), std::string(kPropertiesInterface),
"Get", "Get",
@ -93,9 +94,12 @@ std::optional<uint> FileChooserPortalVersion() {
std::string(kXDGDesktopPortalFileChooserInterface)), std::string(kXDGDesktopPortalFileChooserInterface)),
Glib::ustring("version"), Glib::ustring("version"),
}), }),
std::string(kXDGDesktopPortalService)); [=](const Glib::RefPtr<Gio::AsyncResult> &result) {
try {
auto reply = connection->call_finish(result);
return base::Platform::GlibVariantCast<uint>( FileChooserPortalVersion =
base::Platform::GlibVariantCast<uint>(
base::Platform::GlibVariantCast<Glib::VariantBase>( base::Platform::GlibVariantCast<Glib::VariantBase>(
reply.get_child(0))); reply.get_child(0)));
} catch (const Glib::Error &e) { } catch (const Glib::Error &e) {
@ -103,19 +107,19 @@ std::optional<uint> FileChooserPortalVersion() {
"org.freedesktop.DBus.Error.ServiceUnknown", "org.freedesktop.DBus.Error.ServiceUnknown",
}; };
const auto errorName = Gio::DBus::ErrorUtils::get_remote_error(e); const auto errorName =
if (ranges::contains(NotSupportedErrors, errorName)) { Gio::DBus::ErrorUtils::get_remote_error(e);
return std::nullopt;
}
if (!ranges::contains(NotSupportedErrors, errorName)) {
LOG(("XDP File Dialog Error: %1").arg( LOG(("XDP File Dialog Error: %1").arg(
QString::fromStdString(e.what()))); QString::fromStdString(e.what())));
}
} catch (const std::exception &e) { } catch (const std::exception &e) {
LOG(("XDP File Dialog Error: %1").arg( LOG(("XDP File Dialog Error: %1").arg(
QString::fromStdString(e.what()))); QString::fromStdString(e.what())));
} }
},
return std::nullopt; std::string(kXDGDesktopPortalService));
} }
// This is a patched copy of file dialog from qxdgdesktopportal theme plugin. // This is a patched copy of file dialog from qxdgdesktopportal theme plugin.
@ -682,10 +686,13 @@ rpl::producer<> XDPFileDialog::rejected() {
} // namespace } // namespace
void Start() {
ComputeFileChooserPortalVersion();
}
bool Use(Type type) { bool Use(Type type) {
static const auto Version = FileChooserPortalVersion(); return FileChooserPortalVersion.has_value()
return Version.has_value() && (type != Type::ReadFolder || *FileChooserPortalVersion >= 3);
&& (type != Type::ReadFolder || *Version >= 3);
} }
std::optional<bool> Get( std::optional<bool> Get(

View file

@ -15,6 +15,7 @@ namespace XDP {
using Type = ::FileDialog::internal::Type; using Type = ::FileDialog::internal::Type;
void Start();
bool Use(Type type = Type::ReadFile); bool Use(Type type = Type::ReadFile);
std::optional<bool> Get( std::optional<bool> Get(
QPointer<QWidget> parent, QPointer<QWidget> parent,

View file

@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/platform/linux/base_linux_dbus_utilities.h" #include "base/platform/linux/base_linux_dbus_utilities.h"
#include "base/platform/linux/base_linux_xdp_utilities.h" #include "base/platform/linux/base_linux_xdp_utilities.h"
#include "platform/linux/linux_notification_service_watcher.h" #include "platform/linux/linux_notification_service_watcher.h"
#include "platform/linux/linux_xdp_file_dialog.h"
#include "platform/linux/linux_mpris_support.h" #include "platform/linux/linux_mpris_support.h"
#include "platform/linux/linux_gsd_media_keys.h" #include "platform/linux/linux_gsd_media_keys.h"
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
@ -964,6 +965,7 @@ void start() {
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION #ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
NSWInstance = std::make_unique<internal::NotificationServiceWatcher>(); NSWInstance = std::make_unique<internal::NotificationServiceWatcher>();
FileDialog::XDP::Start();
#endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
} }