summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-21 20:19:34 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-21 20:19:34 +0000
commitd207c182fd764ee3df9ef18380bdb2e91fd4ae12 (patch)
tree79d4783261e96fb2cd0535aca49a683c46fee000 /chrome/browser
parent419766797da235ca0017e51ec22a9d55c437cae1 (diff)
downloadchromium_src-d207c182fd764ee3df9ef18380bdb2e91fd4ae12.zip
chromium_src-d207c182fd764ee3df9ef18380bdb2e91fd4ae12.tar.gz
chromium_src-d207c182fd764ee3df9ef18380bdb2e91fd4ae12.tar.bz2
Make GTK file dialog box modal for parent window, instead of for the entire
application. This works by adding the top-level GtkWindow objects, such as BrowserWindowGtk and BookmarkManagerGtk, to their own unique window groups. Without this change, all top-level windows are added to a default application-wide window group. This ensures that all grabs created with gtk_grab_add(...) only affect the window group of the grabbed widget, as opposed to the entire application. Note that gtk_window_set_modal(...) is implemented with gtk_grab_add(...) and therefore is only modal to a specific window group. In order for this to work correctly, changes were also made to the info bubble and render widget popup (<select> tag) code. Since these widgets also call gtk_grab_add(...), they must be added to the top level window group to work correctly. Test 1: - Open two new chrome window: A and B - Open "Save file as..." dialog in window A - Verify that window A does not respond to keyboard or mouse events. - Verify that window B does responde to keyboard and mouse events. - Open "Save file as..." dialog in window B - Verify that window B does not respond to keyboard or mouse events. - Cancel dialog on window A. - Verify that window A starts responding to keyboard and mouse events. - Cancel dialog on window B. - Verify that window B starts responding to keyboard and mouse events. Test 2: - Verify that <select> tag allows for correct selection of items. Test 3: - Click bookmark star and verify that info bubble works correctly. BUG=8727 TEST=none patch by Mohit Muthanna Cheppudira <mohit.muthanna [at] gmail> original review url: <http://codereview.chromium.org/155852> Review URL: http://codereview.chromium.org/159147 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21207 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/gtk/bookmark_manager_gtk.cc5
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc5
-rw-r--r--chrome/browser/gtk/dialogs_gtk.cc13
-rw-r--r--chrome/browser/gtk/info_bubble_gtk.cc7
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc7
5 files changed, 30 insertions, 7 deletions
diff --git a/chrome/browser/gtk/bookmark_manager_gtk.cc b/chrome/browser/gtk/bookmark_manager_gtk.cc
index 76e9fb7..f5219dd 100644
--- a/chrome/browser/gtk/bookmark_manager_gtk.cc
+++ b/chrome/browser/gtk/bookmark_manager_gtk.cc
@@ -323,6 +323,11 @@ void BookmarkManagerGtk::InitWidgets() {
gtk_window_set_title(GTK_WINDOW(window_),
l10n_util::GetStringUTF8(IDS_BOOKMARK_MANAGER_TITLE).c_str());
+ // Add this window to its own unique window group to allow for
+ // window-to-parent modality.
+ gtk_window_group_add_window(gtk_window_group_new(), GTK_WINDOW(window_));
+ g_object_unref(gtk_window_get_group(GTK_WINDOW(window_)));
+
// Set the default size of the bookmark manager.
int width, height;
gtk_util::GetWidgetSizeFromResources(window_,
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index bff26ed..2d4d1a9 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -392,6 +392,11 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
gtk_widget_add_events(GTK_WIDGET(window_), GDK_BUTTON_PRESS_MASK |
GDK_POINTER_MOTION_MASK);
+ // Add this window to its own unique window group to allow for
+ // window-to-parent modality.
+ gtk_window_group_add_window(gtk_window_group_new(), window_);
+ g_object_unref(gtk_window_get_group(window_));
+
gtk_util::SetWindowIcon(window_);
SetBackgroundColor();
SetGeometryHints();
diff --git a/chrome/browser/gtk/dialogs_gtk.cc b/chrome/browser/gtk/dialogs_gtk.cc
index 62de9ce6..1283d4d 100644
--- a/chrome/browser/gtk/dialogs_gtk.cc
+++ b/chrome/browser/gtk/dialogs_gtk.cc
@@ -26,12 +26,7 @@ static const int kPreviewWidth = 256;
static const int kPreviewHeight = 512;
// Implementation of SelectFileDialog that shows a Gtk common dialog for
-// choosing a file or folder.
-// This acts as a modal dialog. Ideally we want to only act modally for the
-// parent window and allow other toplevel chrome windows to still function while
-// the dialog is showing, but we need the GtkWindowGroup or something similar to
-// get that, and that API is only available in more recent versions of GTK.
-// TODO(port): fix modality: crbug.com/8727
+// choosing a file or folder. This acts as a modal dialog.
class SelectFileDialogImpl : public SelectFileDialog {
public:
explicit SelectFileDialogImpl(Listener* listener);
@@ -208,7 +203,13 @@ void SelectFileDialogImpl::SelectFile(
gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog), preview_);
params_map_[dialog] = params;
+
+ // Set window-to-parent modality by adding the dialog to the same window
+ // group as the parent.
+ gtk_window_group_add_window(gtk_window_get_group(owning_window),
+ GTK_WINDOW(dialog));
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+
gtk_widget_show_all(dialog);
}
diff --git a/chrome/browser/gtk/info_bubble_gtk.cc b/chrome/browser/gtk/info_bubble_gtk.cc
index cee6ad3..892d08e 100644
--- a/chrome/browser/gtk/info_bubble_gtk.cc
+++ b/chrome/browser/gtk/info_bubble_gtk.cc
@@ -209,6 +209,13 @@ void InfoBubbleGtk::Init(GtkWindow* transient_toplevel,
// of the info bubble. We don't use an X grab since that would steal
// keystrokes from your window manager, prevent you from interacting with
// other applications, etc.
+ //
+ // Before adding the grab, we need to ensure that the bubble is added
+ // to the window group of the top level window. This ensures that the
+ // grab only affects the current browser window, and not all the open
+ // browser windows in the application.
+ gtk_window_group_add_window(gtk_window_get_group(transient_toplevel),
+ GTK_WINDOW(window_));
gtk_grab_add(window_);
registrar_.Add(this, NotificationType::ACTIVE_WINDOW_CHANGED,
diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
index d70c601..98ed533 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -873,8 +873,13 @@ void RenderWidgetHostViewGtk::InitAsPopup(
// and webkit will manage our destruction.
if (activatable()) {
// Grab all input for the app. If a click lands outside the bounds of the
- // popup, WebKit will notice and destroy us.
+ // popup, WebKit will notice and destroy us. Before doing this we need
+ // to ensure that the the popup is added to the browser's window group,
+ // to allow for the grabs to work correctly.
+ gtk_window_group_add_window(gtk_window_get_group(
+ GTK_WINDOW(gtk_widget_get_toplevel(parent_))), GTK_WINDOW(popup));
gtk_grab_add(view_.get());
+
// Now grab all of X's input.
gdk_pointer_grab(
parent_->window,