diff --git a/patches/chromium/feat_add_support_for_missing_dialog_features_to_shell_dialogs.patch b/patches/chromium/feat_add_support_for_missing_dialog_features_to_shell_dialogs.patch index 74fdefc9e484..f18011ef64cf 100644 --- a/patches/chromium/feat_add_support_for_missing_dialog_features_to_shell_dialogs.patch +++ b/patches/chromium/feat_add_support_for_missing_dialog_features_to_shell_dialogs.patch @@ -14,10 +14,25 @@ It also: This may be partially upstreamed to Chromium in the future. diff --git a/ui/gtk/select_file_dialog_linux_gtk.cc b/ui/gtk/select_file_dialog_linux_gtk.cc -index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a846f0d923 100644 +index b83f0177a2adb0a19be49684f865941e6708f626..a8c7032cfc122b97665c41da9e1191e747b95a33 100644 --- a/ui/gtk/select_file_dialog_linux_gtk.cc +++ b/ui/gtk/select_file_dialog_linux_gtk.cc -@@ -407,9 +407,11 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateFileOpenHelper( +@@ -259,8 +259,12 @@ void SelectFileDialogLinuxGtk::SelectFileImpl( + case SELECT_EXISTING_FOLDER: + dialog = CreateSelectFolderDialog(type, title_string, default_path, + owning_window); +- connect("response", +- &SelectFileDialogLinuxGtk::OnSelectSingleFolderDialogResponse); ++ if (allow_multiple_selection()) ++ connect("response", ++ &SelectFileDialogLinuxGtk::OnSelectMultiFolderDialogResponse); ++ else ++ connect("response", ++ &SelectFileDialogLinuxGtk::OnSelectSingleFolderDialogResponse); + break; + case SELECT_OPEN_FILE: + dialog = CreateFileOpenDialog(title_string, default_path, owning_window); +@@ -407,9 +411,11 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateFileOpenHelper( const std::string& title, const base::FilePath& default_path, gfx::NativeWindow parent) { @@ -30,7 +45,7 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8 SetGtkTransientForAura(dialog, parent); AddFilters(GTK_FILE_CHOOSER(dialog)); -@@ -425,6 +427,7 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateFileOpenHelper( +@@ -425,6 +431,7 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateFileOpenHelper( GtkFileChooserSetCurrentFolder(GTK_FILE_CHOOSER(dialog), *last_opened_path()); } @@ -38,7 +53,7 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8 return dialog; } -@@ -440,11 +443,15 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSelectFolderDialog( +@@ -440,11 +447,15 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSelectFolderDialog( ? l10n_util::GetStringUTF8(IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE) : l10n_util::GetStringUTF8(IDS_SELECT_FOLDER_DIALOG_TITLE); } @@ -59,7 +74,7 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8 GtkWidget* dialog = GtkFileChooserDialogNew( title_string.c_str(), nullptr, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, -@@ -466,7 +473,8 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSelectFolderDialog( +@@ -466,7 +477,8 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSelectFolderDialog( gtk_file_filter_add_mime_type(only_folders, "inode/directory"); gtk_file_filter_add_mime_type(only_folders, "text/directory"); gtk_file_chooser_add_filter(chooser, only_folders); @@ -69,7 +84,7 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8 return dialog; } -@@ -503,10 +511,11 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSaveAsDialog( +@@ -503,10 +515,11 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSaveAsDialog( std::string title_string = !title.empty() ? title : l10n_util::GetStringUTF8(IDS_SAVE_AS_DIALOG_TITLE); @@ -83,7 +98,7 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8 GTK_RESPONSE_ACCEPT); SetGtkTransientForAura(dialog, parent); -@@ -532,9 +541,10 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSaveAsDialog( +@@ -532,9 +545,10 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSaveAsDialog( gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE); // Overwrite confirmation is always enabled in GTK4. if (!GtkCheckVersion(4)) { @@ -96,6 +111,65 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8 return dialog; } +@@ -589,15 +603,29 @@ void SelectFileDialogLinuxGtk::OnSelectSingleFolderDialogResponse( + void SelectFileDialogLinuxGtk::OnSelectMultiFileDialogResponse( + GtkWidget* dialog, + int response_id) { ++ SelectMultiFileHelper(dialog, response_id, false); ++} ++ ++void SelectFileDialogLinuxGtk::OnSelectMultiFolderDialogResponse( ++ GtkWidget* dialog, ++ int response_id) { ++ SelectMultiFileHelper(dialog, response_id, true); ++} ++ ++void SelectFileDialogLinuxGtk::SelectMultiFileHelper(GtkWidget* dialog, ++ int response_id, ++ bool allow_folder) { + if (IsCancelResponse(response_id)) { + FileNotSelected(dialog); + return; + } + + auto filenames = GtkFileChooserGetFilenames(dialog); +- std::erase_if(filenames, [this](const base::FilePath& path) { +- return CallDirectoryExistsOnUIThread(path); ++ std::erase_if(filenames, [this, &allow_folder](const base::FilePath& path) { ++ bool directory_exists = CallDirectoryExistsOnUIThread(path); ++ return !allow_folder && directory_exists; + }); ++ + if (filenames.empty()) { + FileNotSelected(dialog); + return; +diff --git a/ui/gtk/select_file_dialog_linux_gtk.h b/ui/gtk/select_file_dialog_linux_gtk.h +index 213eaa5ec6d657a659726cb38103e8bd671fe907..f497447c598198bf690758b1d1c5c6fe4112627f 100644 +--- a/ui/gtk/select_file_dialog_linux_gtk.h ++++ b/ui/gtk/select_file_dialog_linux_gtk.h +@@ -108,6 +108,12 @@ class SelectFileDialogLinuxGtk : public ui::SelectFileDialogLinux, + gint response_id, + bool allow_folder); + ++ // Common function for OnSelectMultiFileDialogResponse and ++ // OnSelectMultiFolderDialogResponse. ++ void SelectMultiFileHelper(GtkWidget* dialog, ++ gint response_id, ++ bool allow_folder); ++ + // Common function for CreateFileOpenDialog and CreateMultiFileOpenDialog. + GtkWidget* CreateFileOpenHelper(const std::string& title, + const base::FilePath& default_path, +@@ -122,6 +128,9 @@ class SelectFileDialogLinuxGtk : public ui::SelectFileDialogLinux, + // Callback for when the user responds to a Open Multiple Files dialog. + void OnSelectMultiFileDialogResponse(GtkWidget* dialog, int response_id); + ++ // Callback for when the user responds to a Select Multiple Folders dialog. ++ void OnSelectMultiFolderDialogResponse(GtkWidget* dialog, int response_id); ++ + // Callback for when the file chooser gets destroyed. + void OnFileChooserDestroy(GtkWidget* dialog); + diff --git a/ui/shell_dialogs/select_file_dialog.h b/ui/shell_dialogs/select_file_dialog.h index eb3d997598631b220c3566748f23a5cdac3e4692..b4b2f7294ce6e9349a4a8a05f614e93359eca25a 100644 --- a/ui/shell_dialogs/select_file_dialog.h @@ -186,18 +260,90 @@ index 61683d0eddb04c494ca5e650e7d556b44968ec49..5492456a9138b250e97a5479838bb443 } // namespace ui diff --git a/ui/shell_dialogs/select_file_dialog_linux_kde.cc b/ui/shell_dialogs/select_file_dialog_linux_kde.cc -index 64a79ebe2e2d21d5a6b4a98042d1cdb7b6edad52..16f2ae01a8d33e6341ed52638e963c340455ebf8 100644 +index 64a79ebe2e2d21d5a6b4a98042d1cdb7b6edad52..748c2506781a237641b25b426876be14c8b7ba82 100644 --- a/ui/shell_dialogs/select_file_dialog_linux_kde.cc +++ b/ui/shell_dialogs/select_file_dialog_linux_kde.cc -@@ -468,7 +468,7 @@ void SelectFileDialogLinuxKde::CreateSelectFolderDialog( +@@ -154,9 +154,20 @@ class SelectFileDialogLinuxKde : public SelectFileDialogLinux { + void OnSelectMultiFileDialogResponse( + gfx::AcceleratedWidget parent, + std::unique_ptr results); ++ ++ // Common function for OnSelectSingleFolderDialogResponse and ++ // OnSelectMultiFileDialogResponse. ++ void SelectMultiFileDialogHelper( ++ bool allow_folder, ++ gfx::AcceleratedWidget parent, ++ std::unique_ptr results); ++ + void OnSelectSingleFolderDialogResponse( + gfx::AcceleratedWidget parent, + std::unique_ptr results); ++ void OnSelectMultiFolderDialogResponse( ++ gfx::AcceleratedWidget parent, ++ std::unique_ptr results); + + // Should be either DESKTOP_ENVIRONMENT_KDE3, KDE4, KDE5, or KDE6. + base::nix::DesktopEnvironment desktop_; +@@ -461,6 +472,7 @@ void SelectFileDialogLinuxKde::CreateSelectFolderDialog( + int title_message_id = (type == SELECT_UPLOAD_FOLDER) + ? IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE + : IDS_SELECT_FOLDER_DIALOG_TITLE; ++ bool multiple_selection = allow_multiple_selection(); + pipe_task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce( +@@ -468,10 +480,12 @@ void SelectFileDialogLinuxKde::CreateSelectFolderDialog( KDialogParams( "--getexistingdirectory", GetTitle(title, title_message_id), default_path.empty() ? *last_opened_path() : default_path, parent, - false, false)), -+ false, allow_multiple_selection())), ++ false, multiple_selection)), base::BindOnce( - &SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse, this, - parent)); +- &SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse, this, +- parent)); ++ multiple_selection ++ ? &SelectFileDialogLinuxKde::OnSelectMultiFolderDialogResponse ++ : &SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse, ++ this, parent)); + } + + void SelectFileDialogLinuxKde::CreateFileOpenDialog( +@@ -561,7 +575,8 @@ void SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse( + SelectSingleFileHelper(true, std::move(results)); + } + +-void SelectFileDialogLinuxKde::OnSelectMultiFileDialogResponse( ++void SelectFileDialogLinuxKde::SelectMultiFileDialogHelper( ++ bool allow_folder, + gfx::AcceleratedWidget parent, + std::unique_ptr results) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +@@ -579,7 +594,7 @@ void SelectFileDialogLinuxKde::OnSelectMultiFileDialogResponse( + base::SplitStringPiece(results->output, "\n", base::KEEP_WHITESPACE, + base::SPLIT_WANT_NONEMPTY)) { + base::FilePath path(line); +- if (CallDirectoryExistsOnUIThread(path)) ++ if (!allow_folder && CallDirectoryExistsOnUIThread(path)) + continue; + filenames_fp.push_back(path); + } +@@ -591,4 +606,16 @@ void SelectFileDialogLinuxKde::OnSelectMultiFileDialogResponse( + MultiFilesSelected(filenames_fp); + } + ++void SelectFileDialogLinuxKde::OnSelectMultiFolderDialogResponse( ++ gfx::AcceleratedWidget parent, ++ std::unique_ptr results) { ++ SelectMultiFileDialogHelper(true, parent, std::move(results)); ++} ++ ++void SelectFileDialogLinuxKde::OnSelectMultiFileDialogResponse( ++ gfx::AcceleratedWidget parent, ++ std::unique_ptr results) { ++ SelectMultiFileDialogHelper(false, parent, std::move(results)); ++} ++ + } // namespace ui diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.cc b/ui/shell_dialogs/select_file_dialog_linux_portal.cc index 9780c80ffff7bdb715a9adcb656e5d33be974db6..cf6edf5c68a8e2f8ffda119b58c6283bc43199c0 100644 --- a/ui/shell_dialogs/select_file_dialog_linux_portal.cc