mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Use Chrome file dialogs on all platforms and runtimes (fixes issue #3314)
All file dialogs irrespective of source, platform and runtime will now be routed through CefFileDialogManager and trigger CefDialogHandler callbacks (see issue #3293). Adds Chrome runtime support for CefBrowserHost::RunFileDialog and CefDialogHandler callbacks. Adds Alloy runtime support for internal GTK file and print dialogs on Linux subject to the following limitations: 1. Internal GTK implementation: - Cannot be used with multi-threaded-message-loop because Chromium's internal GTK implementation is not thread-safe (does not use GDK threads). - Dialogs will not be modal to application windows when used with off-screen rendering due to lack of access to the client's top-level GtkWindow. 2. Cefclient CefDialogHandler implementation: - Cannot be used with Views because it requires a top-level GtkWindow. Due to the above limitations no dialog implementation is currently provided for Views + multi-threaded-message-loop on Linux. In cases where both implementations are supported the cefclient version is now behind an optional `--use-client-dialogs` command-line flag. Expressly forbids multiple simultaneous file dialogs with the internal platform implementation which uses modal dialogs. CefDialogHandler will still be notified and can optionally handle each request without a modal dialog (see issue #3154). Removes some RunFileDialog parameters that are not supported by the Chrome file dialog implementation (selected_accept_filter parameter, cef_file_dialog_mode_t overwrite/read-only flags).
This commit is contained in:
@ -136,6 +136,7 @@ GtkWindow* GetWindow(CefRefPtr<CefBrowser> browser) {
|
||||
RootWindow::GetForBrowser(browser->GetIdentifier());
|
||||
if (root_window) {
|
||||
GtkWidget* window = root_window->GetWindowHandle();
|
||||
DCHECK(window);
|
||||
if (!window)
|
||||
LOG(ERROR) << "No GtkWindow for browser";
|
||||
return GTK_WINDOW(window);
|
||||
@ -153,7 +154,6 @@ bool ClientDialogHandlerGtk::OnFileDialog(
|
||||
const CefString& title,
|
||||
const CefString& default_file_path,
|
||||
const std::vector<CefString>& accept_filters,
|
||||
int selected_accept_filter,
|
||||
CefRefPtr<CefFileDialogCallback> callback) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
@ -163,7 +163,6 @@ bool ClientDialogHandlerGtk::OnFileDialog(
|
||||
params.title = title;
|
||||
params.default_file_path = default_file_path;
|
||||
params.accept_filters = accept_filters;
|
||||
params.selected_accept_filter = selected_accept_filter;
|
||||
params.callback = callback;
|
||||
|
||||
GetWindowAndContinue(
|
||||
@ -221,8 +220,9 @@ void ClientDialogHandlerGtk::OnResetDialogState(CefRefPtr<CefBrowser> browser) {
|
||||
js_dialog_callback_ = nullptr;
|
||||
}
|
||||
|
||||
void ClientDialogHandlerGtk::OnFileDialogContinue(OnFileDialogParams params,
|
||||
GtkWindow* window) {
|
||||
void ClientDialogHandlerGtk::OnFileDialogContinue(
|
||||
const OnFileDialogParams& params,
|
||||
GtkWindow* window) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
ScopedGdkThreadsEnter scoped_gdk_threads;
|
||||
@ -232,17 +232,14 @@ void ClientDialogHandlerGtk::OnFileDialogContinue(OnFileDialogParams params,
|
||||
GtkFileChooserAction action;
|
||||
const gchar* accept_button;
|
||||
|
||||
// Remove any modifier flags.
|
||||
FileDialogMode mode_type =
|
||||
static_cast<FileDialogMode>(params.mode & FILE_DIALOG_TYPE_MASK);
|
||||
|
||||
if (mode_type == FILE_DIALOG_OPEN || mode_type == FILE_DIALOG_OPEN_MULTIPLE) {
|
||||
if (params.mode == FILE_DIALOG_OPEN ||
|
||||
params.mode == FILE_DIALOG_OPEN_MULTIPLE) {
|
||||
action = GTK_FILE_CHOOSER_ACTION_OPEN;
|
||||
accept_button = "_Open";
|
||||
} else if (mode_type == FILE_DIALOG_OPEN_FOLDER) {
|
||||
} else if (params.mode == FILE_DIALOG_OPEN_FOLDER) {
|
||||
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
|
||||
accept_button = "_Open";
|
||||
} else if (mode_type == FILE_DIALOG_SAVE) {
|
||||
} else if (params.mode == FILE_DIALOG_SAVE) {
|
||||
action = GTK_FILE_CHOOSER_ACTION_SAVE;
|
||||
accept_button = "_Save";
|
||||
} else {
|
||||
@ -255,7 +252,7 @@ void ClientDialogHandlerGtk::OnFileDialogContinue(OnFileDialogParams params,
|
||||
if (!params.title.empty()) {
|
||||
title_str = params.title;
|
||||
} else {
|
||||
switch (mode_type) {
|
||||
switch (params.mode) {
|
||||
case FILE_DIALOG_OPEN:
|
||||
title_str = "Open File";
|
||||
break;
|
||||
@ -277,19 +274,10 @@ void ClientDialogHandlerGtk::OnFileDialogContinue(OnFileDialogParams params,
|
||||
title_str.c_str(), GTK_WINDOW(window), action, "_Cancel",
|
||||
GTK_RESPONSE_CANCEL, accept_button, GTK_RESPONSE_ACCEPT, nullptr);
|
||||
|
||||
if (mode_type == FILE_DIALOG_OPEN_MULTIPLE)
|
||||
if (params.mode == FILE_DIALOG_OPEN_MULTIPLE)
|
||||
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
|
||||
|
||||
if (mode_type == FILE_DIALOG_SAVE) {
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(
|
||||
GTK_FILE_CHOOSER(dialog),
|
||||
!!(params.mode & FILE_DIALOG_OVERWRITEPROMPT_FLAG));
|
||||
}
|
||||
|
||||
gtk_file_chooser_set_show_hidden(
|
||||
GTK_FILE_CHOOSER(dialog), !(params.mode & FILE_DIALOG_HIDEREADONLY_FLAG));
|
||||
|
||||
if (!params.default_file_path.empty() && mode_type == FILE_DIALOG_SAVE) {
|
||||
if (!params.default_file_path.empty() && params.mode == FILE_DIALOG_SAVE) {
|
||||
const std::string& file_path = params.default_file_path;
|
||||
bool exists = false;
|
||||
|
||||
@ -310,20 +298,17 @@ void ClientDialogHandlerGtk::OnFileDialogContinue(OnFileDialogParams params,
|
||||
|
||||
std::vector<GtkFileFilter*> filters;
|
||||
AddFilters(GTK_FILE_CHOOSER(dialog), params.accept_filters, true, &filters);
|
||||
if (params.selected_accept_filter < static_cast<int>(filters.size())) {
|
||||
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog),
|
||||
filters[params.selected_accept_filter]);
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
|
||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
if (mode_type == FILE_DIALOG_OPEN || mode_type == FILE_DIALOG_OPEN_FOLDER ||
|
||||
mode_type == FILE_DIALOG_SAVE) {
|
||||
if (params.mode == FILE_DIALOG_OPEN ||
|
||||
params.mode == FILE_DIALOG_OPEN_FOLDER ||
|
||||
params.mode == FILE_DIALOG_SAVE) {
|
||||
char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
files.push_back(std::string(filename));
|
||||
success = true;
|
||||
} else if (mode_type == FILE_DIALOG_OPEN_MULTIPLE) {
|
||||
} else if (params.mode == FILE_DIALOG_OPEN_MULTIPLE) {
|
||||
GSList* filenames =
|
||||
gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
|
||||
if (filenames) {
|
||||
@ -339,29 +324,15 @@ void ClientDialogHandlerGtk::OnFileDialogContinue(OnFileDialogParams params,
|
||||
}
|
||||
}
|
||||
|
||||
int filter_index = params.selected_accept_filter;
|
||||
if (success) {
|
||||
GtkFileFilter* selected_filter =
|
||||
gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
|
||||
if (selected_filter != nullptr) {
|
||||
for (size_t x = 0; x < filters.size(); ++x) {
|
||||
if (filters[x] == selected_filter) {
|
||||
filter_index = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
|
||||
if (success)
|
||||
params.callback->Continue(filter_index, files);
|
||||
params.callback->Continue(files);
|
||||
else
|
||||
params.callback->Cancel();
|
||||
}
|
||||
|
||||
void ClientDialogHandlerGtk::OnJSDialogContinue(OnJSDialogParams params,
|
||||
void ClientDialogHandlerGtk::OnJSDialogContinue(const OnJSDialogParams& params,
|
||||
GtkWindow* window) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
|
Reference in New Issue
Block a user