|
@@ -199,21 +199,68 @@ index 64a79ebe2e2d21d5a6b4a98042d1cdb7b6edad52..16f2ae01a8d33e6341ed52638e963c34
|
|
|
&SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse, this,
|
|
|
parent));
|
|
|
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.cc b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
|
|
|
-index 143f5fe1028e154192767599a1e68b45301a894d..d612e1614a313db0dcf7dc592fd6fa74c89e70e1 100644
|
|
|
+index 143f5fe1028e154192767599a1e68b45301a894d..132e670dc3ccd9a0f904a8869e516f4556fbf0af 100644
|
|
|
--- a/ui/shell_dialogs/select_file_dialog_linux_portal.cc
|
|
|
+++ b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
|
|
|
-@@ -40,7 +40,9 @@ namespace {
|
|
|
+@@ -11,6 +11,7 @@
|
|
|
+
|
|
|
+ #include <string_view>
|
|
|
+
|
|
|
++#include "base/command_line.h"
|
|
|
+ #include "base/functional/bind.h"
|
|
|
+ #include "base/logging.h"
|
|
|
+ #include "base/no_destructor.h"
|
|
|
+@@ -40,6 +41,8 @@ namespace {
|
|
|
constexpr char kXdgPortalService[] = "org.freedesktop.portal.Desktop";
|
|
|
constexpr char kXdgPortalObject[] = "/org/freedesktop/portal/desktop";
|
|
|
|
|
|
--constexpr int kXdgPortalRequiredVersion = 3;
|
|
|
+// Version 4 includes support for current_folder option to the OpenFile method via
|
|
|
+// https://github.com/flatpak/xdg-desktop-portal/commit/71165a5.
|
|
|
-+constexpr int kXdgPortalRequiredVersion = 4;
|
|
|
+ constexpr int kXdgPortalRequiredVersion = 3;
|
|
|
|
|
|
constexpr char kXdgPortalRequestInterfaceName[] =
|
|
|
- "org.freedesktop.portal.Request";
|
|
|
-@@ -214,6 +216,8 @@ void SelectFileDialogLinuxPortal::SelectFileImpl(
|
|
|
+@@ -66,6 +69,8 @@ constexpr int kFileChooserFilterKindGlob = 0;
|
|
|
+
|
|
|
+ constexpr char kFileUriPrefix[] = "file://";
|
|
|
+
|
|
|
++const char kXdgPortalRequiredVersionFlag[] = "xdg-portal-required-version";
|
|
|
++
|
|
|
+ struct FileChooserProperties : dbus::PropertySet {
|
|
|
+ dbus::Property<uint32_t> version;
|
|
|
+
|
|
|
+@@ -171,10 +176,18 @@ void SelectFileDialogLinuxPortal::StartAvailabilityTestInBackground() {
|
|
|
+ if (GetAvailabilityTestCompletionFlag()->IsSet())
|
|
|
+ return;
|
|
|
+
|
|
|
++ auto* cmd = base::CommandLine::ForCurrentProcess();
|
|
|
++ unsigned int xdg_portal_required_version;
|
|
|
++ if (!base::StringToUint(cmd->GetSwitchValueASCII(kXdgPortalRequiredVersionFlag),
|
|
|
++ &xdg_portal_required_version)) {
|
|
|
++ xdg_portal_required_version = kXdgPortalRequiredVersion;
|
|
|
++ }
|
|
|
++
|
|
|
+ dbus_thread_linux::GetTaskRunner()->PostTask(
|
|
|
+ FROM_HERE,
|
|
|
+ base::BindOnce(
|
|
|
+- &SelectFileDialogLinuxPortal::CheckPortalAvailabilityOnBusThread));
|
|
|
++ &SelectFileDialogLinuxPortal::CheckPortalAvailabilityOnBusThread,
|
|
|
++ xdg_portal_required_version));
|
|
|
+ }
|
|
|
+
|
|
|
+ // static
|
|
|
+@@ -185,6 +198,11 @@ bool SelectFileDialogLinuxPortal::IsPortalAvailable() {
|
|
|
+ return is_portal_available_;
|
|
|
+ }
|
|
|
+
|
|
|
++// static
|
|
|
++int SelectFileDialogLinuxPortal::GetPortalVersion() {
|
|
|
++ return available_portal_version_;
|
|
|
++}
|
|
|
++
|
|
|
+ // static
|
|
|
+ void SelectFileDialogLinuxPortal::DestroyPortalConnection() {
|
|
|
+ dbus_thread_linux::GetTaskRunner()->PostTask(
|
|
|
+@@ -214,6 +232,8 @@ void SelectFileDialogLinuxPortal::SelectFileImpl(
|
|
|
weak_factory_.GetWeakPtr()));
|
|
|
info_->type = type;
|
|
|
info_->main_task_runner = base::SequencedTaskRunner::GetCurrentDefault();
|
|
@@ -222,7 +269,50 @@ index 143f5fe1028e154192767599a1e68b45301a894d..d612e1614a313db0dcf7dc592fd6fa74
|
|
|
|
|
|
if (owning_window) {
|
|
|
if (auto* root = owning_window->GetRootWindow()) {
|
|
|
-@@ -471,7 +475,9 @@ void SelectFileDialogLinuxPortal::DialogInfo::AppendOptions(
|
|
|
+@@ -260,7 +280,8 @@ bool SelectFileDialogLinuxPortal::HasMultipleFileTypeChoicesImpl() {
|
|
|
+ }
|
|
|
+
|
|
|
+ // static
|
|
|
+-void SelectFileDialogLinuxPortal::CheckPortalAvailabilityOnBusThread() {
|
|
|
++void SelectFileDialogLinuxPortal::CheckPortalAvailabilityOnBusThread(
|
|
|
++ unsigned int xdg_portal_required_version) {
|
|
|
+ DCHECK(dbus_thread_linux::GetTaskRunner()->RunsTasksInCurrentSequence());
|
|
|
+ base::AtomicFlag* availability_test_complete =
|
|
|
+ GetAvailabilityTestCompletionFlag();
|
|
|
+@@ -274,6 +295,7 @@ void SelectFileDialogLinuxPortal::CheckPortalAvailabilityOnBusThread() {
|
|
|
+ base::BindOnce(
|
|
|
+ [](scoped_refptr<dbus::Bus> bus,
|
|
|
+ base::AtomicFlag* availability_test_complete,
|
|
|
++ unsigned int xdg_portal_required_version,
|
|
|
+ std::optional<bool> name_has_owner) {
|
|
|
+ if (name_has_owner.value_or(false)) {
|
|
|
+ // The portal service has an owner, proceed to check the version.
|
|
|
+@@ -285,15 +307,22 @@ void SelectFileDialogLinuxPortal::CheckPortalAvailabilityOnBusThread() {
|
|
|
+ if (!properties.GetAndBlock(&properties.version)) {
|
|
|
+ LOG(ERROR) << "Failed to read portal version property";
|
|
|
+ } else if (properties.version.value() >=
|
|
|
+- kXdgPortalRequiredVersion) {
|
|
|
++ xdg_portal_required_version) {
|
|
|
+ is_portal_available_ = true;
|
|
|
++ available_portal_version_ = properties.version.value();
|
|
|
++ } else {
|
|
|
++ VLOG(1) << "File chooser portal available version: "
|
|
|
++ << properties.version.value();
|
|
|
++ available_portal_version_ = properties.version.value();
|
|
|
+ }
|
|
|
+ }
|
|
|
++ VLOG(1) << "File chooser portal expected version: "
|
|
|
++ << xdg_portal_required_version;
|
|
|
+ VLOG(1) << "File chooser portal available: "
|
|
|
+ << (is_portal_available_ ? "yes" : "no");
|
|
|
+ availability_test_complete->Set();
|
|
|
+ },
|
|
|
+- bus, availability_test_complete));
|
|
|
++ bus, availability_test_complete, xdg_portal_required_version));
|
|
|
+ }
|
|
|
+
|
|
|
+ // static
|
|
|
+@@ -471,7 +500,9 @@ void SelectFileDialogLinuxPortal::DialogInfo::AppendOptions(
|
|
|
response_handle_token);
|
|
|
|
|
|
if (type == SelectFileDialog::Type::SELECT_UPLOAD_FOLDER) {
|
|
@@ -233,7 +323,7 @@ index 143f5fe1028e154192767599a1e68b45301a894d..d612e1614a313db0dcf7dc592fd6fa74
|
|
|
l10n_util::GetStringUTF8(
|
|
|
IDS_SELECT_UPLOAD_FOLDER_DIALOG_UPLOAD_BUTTON));
|
|
|
}
|
|
|
-@@ -480,6 +486,8 @@ void SelectFileDialogLinuxPortal::DialogInfo::AppendOptions(
|
|
|
+@@ -480,6 +511,8 @@ void SelectFileDialogLinuxPortal::DialogInfo::AppendOptions(
|
|
|
type == SelectFileDialog::Type::SELECT_UPLOAD_FOLDER ||
|
|
|
type == SelectFileDialog::Type::SELECT_EXISTING_FOLDER) {
|
|
|
AppendBoolOption(&options_writer, kFileChooserOptionDirectory, true);
|
|
@@ -242,11 +332,29 @@ index 143f5fe1028e154192767599a1e68b45301a894d..d612e1614a313db0dcf7dc592fd6fa74
|
|
|
} else if (type == SelectFileDialog::Type::SELECT_OPEN_MULTI_FILE) {
|
|
|
AppendBoolOption(&options_writer, kFileChooserOptionMultiple, true);
|
|
|
}
|
|
|
+@@ -820,6 +853,7 @@ SelectFileDialogLinuxPortal::DialogInfo::DialogInfo(
|
|
|
+ SelectFileDialogLinuxPortal::DialogInfo::~DialogInfo() = default;
|
|
|
+
|
|
|
+ bool SelectFileDialogLinuxPortal::is_portal_available_ = false;
|
|
|
++unsigned int SelectFileDialogLinuxPortal::available_portal_version_ = 0;
|
|
|
+ int SelectFileDialogLinuxPortal::handle_token_counter_ = 0;
|
|
|
+
|
|
|
+ } // namespace ui
|
|
|
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.h b/ui/shell_dialogs/select_file_dialog_linux_portal.h
|
|
|
-index d57a52b3ccbd3bd6d390615351ea2ad1e475b157..433f34ac6779611623241cd977dd1214e97fece7 100644
|
|
|
+index d57a52b3ccbd3bd6d390615351ea2ad1e475b157..6a2800add2428ffd91286748f886d6c42510ba31 100644
|
|
|
--- a/ui/shell_dialogs/select_file_dialog_linux_portal.h
|
|
|
+++ b/ui/shell_dialogs/select_file_dialog_linux_portal.h
|
|
|
-@@ -120,6 +120,8 @@ class SelectFileDialogLinuxPortal : public SelectFileDialogLinux {
|
|
|
+@@ -47,6 +47,9 @@ class SelectFileDialogLinuxPortal : public SelectFileDialogLinux {
|
|
|
+ // availability test has not yet completed.
|
|
|
+ static bool IsPortalAvailable();
|
|
|
+
|
|
|
++ // Get version of portal if available.
|
|
|
++ static int GetPortalVersion();
|
|
|
++
|
|
|
+ // Destroys the connection to the bus.
|
|
|
+ static void DestroyPortalConnection();
|
|
|
+
|
|
|
+@@ -120,6 +123,8 @@ class SelectFileDialogLinuxPortal : public SelectFileDialogLinux {
|
|
|
Type type;
|
|
|
// The task runner the SelectFileImpl method was called on.
|
|
|
scoped_refptr<base::SequencedTaskRunner> main_task_runner;
|
|
@@ -255,3 +363,23 @@ index d57a52b3ccbd3bd6d390615351ea2ad1e475b157..433f34ac6779611623241cd977dd1214
|
|
|
|
|
|
private:
|
|
|
friend class base::RefCountedThreadSafe<DialogInfo>;
|
|
|
+@@ -176,7 +181,8 @@ class SelectFileDialogLinuxPortal : public SelectFileDialogLinux {
|
|
|
+ };
|
|
|
+
|
|
|
+ // D-Bus configuration and initialization.
|
|
|
+- static void CheckPortalAvailabilityOnBusThread();
|
|
|
++ static void CheckPortalAvailabilityOnBusThread(
|
|
|
++ unsigned int xdg_portal_required_version);
|
|
|
+
|
|
|
+ // Returns a flag, written by the D-Bus thread and read by the UI thread,
|
|
|
+ // indicating whether or not the availability test has completed.
|
|
|
+@@ -208,6 +214,9 @@ class SelectFileDialogLinuxPortal : public SelectFileDialogLinux {
|
|
|
+ // Written by the D-Bus thread and read by the UI thread.
|
|
|
+ static bool is_portal_available_;
|
|
|
+
|
|
|
++ // Written by the D-Bus thread and read by the UI thread.
|
|
|
++ static unsigned int available_portal_version_;
|
|
|
++
|
|
|
+ // Used by the D-Bus thread to generate unique handle tokens.
|
|
|
+ static int handle_token_counter_;
|
|
|
+
|