summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-04 01:57:59 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-04 01:57:59 +0000
commit2f4dead0246a6043ad9539ed8a95ab2955aab442 (patch)
tree0f829467bd0ddd1645f73279bf587b7139185726 /chrome/browser/gtk
parent29de42c9c4ed71039af911a3331be51c2da9a098 (diff)
downloadchromium_src-2f4dead0246a6043ad9539ed8a95ab2955aab442.zip
chromium_src-2f4dead0246a6043ad9539ed8a95ab2955aab442.tar.gz
chromium_src-2f4dead0246a6043ad9539ed8a95ab2955aab442.tar.bz2
reland r57885 with a fix for the DCHECK failures observed by nsylvain.
Now we only delay shutdown of the constrained window in the escape case (see constrained_window_gtk.cc). Locally this fixes the DCHECKs in both manual testing and the login prompt ui tests. BUG=53242, 50799 TEST=ui_tests --gtest_filter=LoginPromptTest* Review URL: http://codereview.chromium.org/3351006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58570 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r--chrome/browser/gtk/constrained_window_gtk.cc50
-rw-r--r--chrome/browser/gtk/constrained_window_gtk.h13
-rw-r--r--chrome/browser/gtk/focus_store_gtk.cc27
-rw-r--r--chrome/browser/gtk/focus_store_gtk.h7
-rw-r--r--chrome/browser/gtk/gtk_util.cc7
-rw-r--r--chrome/browser/gtk/gtk_util.h4
6 files changed, 53 insertions, 55 deletions
diff --git a/chrome/browser/gtk/constrained_window_gtk.cc b/chrome/browser/gtk/constrained_window_gtk.cc
index 321aa16..b901083 100644
--- a/chrome/browser/gtk/constrained_window_gtk.cc
+++ b/chrome/browser/gtk/constrained_window_gtk.cc
@@ -16,7 +16,7 @@ ConstrainedWindowGtk::ConstrainedWindowGtk(
: owner_(owner),
delegate_(delegate),
visible_(false),
- accel_group_(gtk_accel_group_new()) {
+ factory_(this) {
DCHECK(owner);
DCHECK(delegate);
GtkWidget* dialog = delegate->GetWidgetRoot();
@@ -34,20 +34,14 @@ ConstrainedWindowGtk::ConstrainedWindowGtk(
gtk_container_add(GTK_CONTAINER(frame), alignment);
gtk_container_add(GTK_CONTAINER(ebox), frame);
border_.Own(ebox);
- ConnectAccelerators();
+
+ gtk_widget_add_events(widget(), GDK_KEY_PRESS_MASK);
+ g_signal_connect(widget(), "key-press-event", G_CALLBACK(OnKeyPressThunk),
+ this);
}
ConstrainedWindowGtk::~ConstrainedWindowGtk() {
border_.Destroy();
-
- gtk_accel_group_disconnect_key(accel_group_, GDK_Escape,
- static_cast<GdkModifierType>(0));
- if (ContainingView() && ContainingView()->GetTopLevelNativeWindow()) {
- gtk_window_remove_accel_group(
- GTK_WINDOW(ContainingView()->GetTopLevelNativeWindow()),
- accel_group_);
- }
- g_object_unref(accel_group_);
}
void ConstrainedWindowGtk::ShowConstrainedWindow() {
@@ -73,29 +67,18 @@ TabContentsViewGtk* ConstrainedWindowGtk::ContainingView() {
return static_cast<TabContentsViewGtk*>(owner_->view());
}
-void ConstrainedWindowGtk::ConnectAccelerators() {
- gtk_accel_group_connect(accel_group_,
- GDK_Escape, static_cast<GdkModifierType>(0),
- static_cast<GtkAccelFlags>(0),
- g_cclosure_new(G_CALLBACK(OnEscapeThunk),
- this, NULL));
- gtk_window_add_accel_group(
- GTK_WINDOW(ContainingView()->GetTopLevelNativeWindow()),
- accel_group_);
-}
-
-
-gboolean ConstrainedWindowGtk::OnEscape(GtkAccelGroup* group,
- GObject* acceleratable,
- guint keyval,
- GdkModifierType modifier) {
- // Handle this accelerator only if this is on the currently selected tab.
- Browser* browser = BrowserList::GetLastActive();
- if (!browser || browser->GetSelectedTabContents() != owner_)
- return FALSE;
+gboolean ConstrainedWindowGtk::OnKeyPress(GtkWidget* sender,
+ GdkEventKey* key) {
+ if (key->keyval == GDK_Escape) {
+ // Let the stack unwind so the event handler can release its ref
+ // on widget().
+ MessageLoop::current()->PostTask(FROM_HERE,
+ factory_.NewRunnableMethod(
+ &ConstrainedWindowGtk::CloseConstrainedWindow));
+ return TRUE;
+ }
- CloseConstrainedWindow();
- return TRUE;
+ return FALSE;
}
// static
@@ -104,4 +87,3 @@ ConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog(
ConstrainedWindowGtkDelegate* delegate) {
return new ConstrainedWindowGtk(parent, delegate);
}
-
diff --git a/chrome/browser/gtk/constrained_window_gtk.h b/chrome/browser/gtk/constrained_window_gtk.h
index 2312cb3..117fd33 100644
--- a/chrome/browser/gtk/constrained_window_gtk.h
+++ b/chrome/browser/gtk/constrained_window_gtk.h
@@ -10,12 +10,12 @@
#include "app/gtk_signal.h"
#include "base/basictypes.h"
+#include "base/task.h"
#include "chrome/browser/gtk/owned_widget_gtk.h"
#include "chrome/browser/tab_contents/constrained_window.h"
class TabContents;
class TabContentsViewGtk;
-typedef struct _GtkWidget GtkWidget;
class ConstrainedWindowGtkDelegate {
public:
@@ -56,12 +56,9 @@ class ConstrainedWindowGtk : public ConstrainedWindow {
ConstrainedWindowGtk(TabContents* owner,
ConstrainedWindowGtkDelegate* delegate);
- // Connects the ESC accelerator to the window.
- void ConnectAccelerators();
-
- // Handles an ESC accelerator being pressed.
- CHROMEG_CALLBACK_3(ConstrainedWindowGtk, gboolean, OnEscape, GtkAccelGroup*,
- GObject*, guint, GdkModifierType);
+ // Handler for Escape.
+ CHROMEGTK_CALLBACK_1(ConstrainedWindowGtk, gboolean, OnKeyPress,
+ GdkEventKey*);
// The TabContents that owns and constrains this ConstrainedWindow.
TabContents* owner_;
@@ -75,7 +72,7 @@ class ConstrainedWindowGtk : public ConstrainedWindow {
// Stores if |ShowConstrainedWindow()| has been called.
bool visible_;
- GtkAccelGroup* accel_group_;
+ ScopedRunnableMethodFactory<ConstrainedWindowGtk> factory_;
DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowGtk);
};
diff --git a/chrome/browser/gtk/focus_store_gtk.cc b/chrome/browser/gtk/focus_store_gtk.cc
index dc099fc..50ebfa7 100644
--- a/chrome/browser/gtk/focus_store_gtk.cc
+++ b/chrome/browser/gtk/focus_store_gtk.cc
@@ -19,19 +19,22 @@ FocusStoreGtk::~FocusStoreGtk() {
}
void FocusStoreGtk::Store(GtkWidget* widget) {
- DisconnectDestroyHandler();
- if (!widget) {
- widget_ = NULL;
- return;
+ GtkWidget* focus_widget = NULL;
+ if (widget) {
+ GtkWindow* window = platform_util::GetTopLevel(widget);
+ if (window)
+ focus_widget = window->focus_widget;
}
- GtkWindow* window = platform_util::GetTopLevel(widget);
- if (!window) {
- widget_ = NULL;
- return;
- }
+ SetWidget(focus_widget);
+}
- widget_ = window->focus_widget;
+void FocusStoreGtk::SetWidget(GtkWidget* widget) {
+ DisconnectDestroyHandler();
+
+ // We don't add a ref. The signal handler below effectively gives us a weak
+ // reference.
+ widget_ = widget;
if (widget_) {
// When invoked, |gtk_widget_destroyed| will set |widget_| to NULL.
destroy_handler_id_ = g_signal_connect(widget_, "destroy",
@@ -41,6 +44,8 @@ void FocusStoreGtk::Store(GtkWidget* widget) {
}
void FocusStoreGtk::DisconnectDestroyHandler() {
- if (widget_)
+ if (widget_) {
g_signal_handler_disconnect(widget_, destroy_handler_id_);
+ widget_ = NULL;
+ }
}
diff --git a/chrome/browser/gtk/focus_store_gtk.h b/chrome/browser/gtk/focus_store_gtk.h
index ce3b68b..2159f1e 100644
--- a/chrome/browser/gtk/focus_store_gtk.h
+++ b/chrome/browser/gtk/focus_store_gtk.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -19,9 +19,12 @@ class FocusStoreGtk {
GtkWidget* widget() const { return widget_; }
// Save the widget that is currently focused for |widget|'s toplevel (NOT
- // |widget|). Call with NULL to clear |widget_|.
+ // |widget|).
void Store(GtkWidget* widget);
+ // Save |widget| as the focus widget. Call with NULL to clear |widget_|.
+ void SetWidget(GtkWidget* widget);
+
private:
// Disconnect the previous destroy handler (if any).
void DisconnectDestroyHandler();
diff --git a/chrome/browser/gtk/gtk_util.cc b/chrome/browser/gtk/gtk_util.cc
index 5a5a815..541d2da 100644
--- a/chrome/browser/gtk/gtk_util.cc
+++ b/chrome/browser/gtk/gtk_util.cc
@@ -1059,4 +1059,11 @@ string16 GetStockPreferencesMenuLabel() {
return preferences;
}
+bool IsWidgetAncestryVisible(GtkWidget* widget) {
+ GtkWidget* parent = widget;
+ while (parent && GTK_WIDGET_VISIBLE(parent))
+ parent = parent->parent;
+ return !parent;
+}
+
} // namespace gtk_util
diff --git a/chrome/browser/gtk/gtk_util.h b/chrome/browser/gtk/gtk_util.h
index 20d3c6a..95200d4 100644
--- a/chrome/browser/gtk/gtk_util.h
+++ b/chrome/browser/gtk/gtk_util.h
@@ -315,6 +315,10 @@ gfx::Rect GetDialogBounds(GtkWidget* dialog);
// empty string if no stock item found.
string16 GetStockPreferencesMenuLabel();
+// Checks whether a widget is actually visible, i.e. whether it and all its
+// ancestors up to its toplevel are visible.
+bool IsWidgetAncestryVisible(GtkWidget* widget);
+
} // namespace gtk_util
#endif // CHROME_BROWSER_GTK_GTK_UTIL_H_