diff --git a/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp b/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp index 97f5e0202..ffb651993 100644 --- a/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.cpp @@ -33,6 +33,8 @@ constexpr auto kPropertiesInterface = "org.freedesktop.DBus.Properties"_cs; const char *filterRegExp = "^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; +std::optional FileChooserPortalVersion; + auto QStringListToStd(const QStringList &list) { std::vector result; ranges::transform( @@ -69,53 +71,55 @@ auto MakeFilterList(const QString &filter) { return result; } -std::optional FileChooserPortalVersion() { - try { - const auto connection = [] { - try { - return Gio::DBus::Connection::get_sync( - Gio::DBus::BusType::BUS_TYPE_SESSION); - } catch (...) { - return Glib::RefPtr(); - } - }(); - - if (!connection) { - return std::nullopt; +void ComputeFileChooserPortalVersion() { + const auto connection = [] { + try { + return Gio::DBus::Connection::get_sync( + Gio::DBus::BusType::BUS_TYPE_SESSION); + } catch (...) { + return Glib::RefPtr(); } + }(); - auto reply = connection->call_sync( - std::string(kXDGDesktopPortalObjectPath), - std::string(kPropertiesInterface), - "Get", - base::Platform::MakeGlibVariant(std::tuple{ - Glib::ustring( - std::string(kXDGDesktopPortalFileChooserInterface)), - Glib::ustring("version"), - }), - std::string(kXDGDesktopPortalService)); - - return base::Platform::GlibVariantCast( - base::Platform::GlibVariantCast( - reply.get_child(0))); - } catch (const Glib::Error &e) { - static const auto NotSupportedErrors = { - "org.freedesktop.DBus.Error.ServiceUnknown", - }; - - const auto errorName = Gio::DBus::ErrorUtils::get_remote_error(e); - if (ranges::contains(NotSupportedErrors, errorName)) { - return std::nullopt; - } - - LOG(("XDP File Dialog Error: %1").arg( - QString::fromStdString(e.what()))); - } catch (const std::exception &e) { - LOG(("XDP File Dialog Error: %1").arg( - QString::fromStdString(e.what()))); + if (!connection) { + return; } - return std::nullopt; + connection->call( + std::string(kXDGDesktopPortalObjectPath), + std::string(kPropertiesInterface), + "Get", + base::Platform::MakeGlibVariant(std::tuple{ + Glib::ustring( + std::string(kXDGDesktopPortalFileChooserInterface)), + Glib::ustring("version"), + }), + [=](const Glib::RefPtr &result) { + try { + auto reply = connection->call_finish(result); + + FileChooserPortalVersion = + base::Platform::GlibVariantCast( + base::Platform::GlibVariantCast( + reply.get_child(0))); + } catch (const Glib::Error &e) { + static const auto NotSupportedErrors = { + "org.freedesktop.DBus.Error.ServiceUnknown", + }; + + const auto errorName = + Gio::DBus::ErrorUtils::get_remote_error(e); + + if (!ranges::contains(NotSupportedErrors, errorName)) { + LOG(("XDP File Dialog Error: %1").arg( + QString::fromStdString(e.what()))); + } + } catch (const std::exception &e) { + LOG(("XDP File Dialog Error: %1").arg( + QString::fromStdString(e.what()))); + } + }, + std::string(kXDGDesktopPortalService)); } // This is a patched copy of file dialog from qxdgdesktopportal theme plugin. @@ -682,10 +686,13 @@ rpl::producer<> XDPFileDialog::rejected() { } // namespace +void Start() { + ComputeFileChooserPortalVersion(); +} + bool Use(Type type) { - static const auto Version = FileChooserPortalVersion(); - return Version.has_value() - && (type != Type::ReadFolder || *Version >= 3); + return FileChooserPortalVersion.has_value() + && (type != Type::ReadFolder || *FileChooserPortalVersion >= 3); } std::optional Get( diff --git a/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.h b/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.h index 3c1cdc95a..f1ca9603a 100644 --- a/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.h +++ b/Telegram/SourceFiles/platform/linux/linux_xdp_file_dialog.h @@ -15,6 +15,7 @@ namespace XDP { using Type = ::FileDialog::internal::Type; +void Start(); bool Use(Type type = Type::ReadFile); std::optional Get( QPointer parent, diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp index 339f61c5d..32b0a150d 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp @@ -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_xdp_utilities.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_gsd_media_keys.h" #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION @@ -964,6 +965,7 @@ void start() { #ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION NSWInstance = std::make_unique(); + FileDialog::XDP::Start(); #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION }