Index: chrome/browser/ui/libgtk2ui/select_file_dialog_impl_gtk2.cc |
diff --git a/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_gtk2.cc b/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_gtk2.cc |
index 91daa5cdc9b6de2c516d45bc11f4735484a120ee..0c958de90a6a2241f5e375b5938eadebdca1b120 100644 |
--- a/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_gtk2.cc |
+++ b/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_gtk2.cc |
@@ -2,6 +2,7 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include <gdk/gdkx.h> |
#include <gtk/gtk.h> |
#include <map> |
#include <set> |
@@ -25,6 +26,7 @@ |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/shell_dialogs/select_file_dialog.h" |
#include "ui/strings/grit/ui_strings.h" |
+#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" |
#include "ui/views/widget/desktop_aura/x11_desktop_handler.h" |
namespace { |
@@ -69,6 +71,8 @@ class SelectFileDialogImplGTK : public SelectFileDialogImpl, |
const base::FilePath::StringType& default_extension, |
gfx::NativeWindow owning_window, |
void* params) override; |
+ // Close the file dialog. |
+ void CloseImpl() override; |
private: |
bool HasMultipleFileTypeChoicesImpl() override; |
@@ -273,9 +277,11 @@ void SelectFileDialogImplGTK::SelectFileImpl( |
params_map_[dialog] = params; |
- // TODO(erg): Figure out how to fake GTK window-to-parent modality without |
- // having the parent be a real GtkWindow. |
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); |
+ // Disable input events handling in the host window to make this dialog modal. |
+ views::DesktopWindowTreeHostX11* host = |
+ views::DesktopWindowTreeHostX11::GetHostForXID( |
+ owning_window->GetHost()->GetAcceleratedWidget()); |
+ host->DisableEventListening(GDK_WINDOW_XID(gtk_widget_get_window(dialog))); |
gtk_widget_show_all(dialog); |
@@ -285,6 +291,25 @@ void SelectFileDialogImplGTK::SelectFileImpl( |
gtk_window_present_with_time(GTK_WINDOW(dialog), time); |
} |
+// Close the file-picker by sending an ESC key event to it. |
+void SelectFileDialogImplGTK::CloseImpl() { |
+ // Get the focused window. |
+ XID focused_window; |
+ int revert; |
+ XGetInputFocus(gfx::GetXDisplay(), &focused_window, &revert); |
+ |
+ // Send an ESC key event to the focused_window. |
+ XKeyEvent event; |
+ memset(&event, 0, sizeof(event)); |
+ event.display = gfx::GetXDisplay(); |
+ event.window = focused_window; |
+ event.keycode = XKeysymToKeycode(gfx::GetXDisplay(), XK_Escape); |
+ event.type = KeyPress; |
+ |
+ XSendEvent(gfx::GetXDisplay(), focused_window, True, KeyPressMask, |
+ reinterpret_cast<XEvent*>(&event)); |
+} |
+ |
void SelectFileDialogImplGTK::AddFilters(GtkFileChooser* chooser) { |
for (size_t i = 0; i < file_types_.extensions.size(); ++i) { |
GtkFileFilter* filter = NULL; |
@@ -527,6 +552,12 @@ void SelectFileDialogImplGTK::FileDialogDestroyed(GtkWidget* dialog) { |
aura::Window* parent = GetAuraTransientParent(dialog); |
if (!parent) |
return; |
+ |
+ views::DesktopWindowTreeHostX11* host = |
+ views::DesktopWindowTreeHostX11::GetHostForXID( |
+ parent->GetHost()->GetAcceleratedWidget()); |
+ host->EnableEventListening(); |
+ |
std::set<aura::Window*>::iterator iter = parents_.find(parent); |
if (iter != parents_.end()) { |
(*iter)->RemoveObserver(this); |