summaryrefslogtreecommitdiffstats
path: root/ui/views/widget
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-24 18:04:41 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-24 18:04:41 +0000
commita450e540e1f001d5d37374ae8fcc099d6bbb7ace (patch)
treed9e87f4f819e96ac75cef01872237c7548389fdd /ui/views/widget
parenta4d0c7d2fa06be57cb732751d743f2bbae4c0019 (diff)
downloadchromium_src-a450e540e1f001d5d37374ae8fcc099d6bbb7ace.zip
chromium_src-a450e540e1f001d5d37374ae8fcc099d6bbb7ace.tar.gz
chromium_src-a450e540e1f001d5d37374ae8fcc099d6bbb7ace.tar.bz2
Disconnect signal connectors before destroying gtk widget.
Disconnect signal connectors before deleting NativeWidgetGtk whose ownership is WIDGET_OWNS_NATIVE_WIDGET. This is hypothetical fix for 24352 BUG=chromium-os:24352 TEST=none Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=116518 Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=116630 Review URL: https://chromiumcodereview.appspot.com/9109004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118858 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views/widget')
-rw-r--r--ui/views/widget/native_widget_gtk.cc30
-rw-r--r--ui/views/widget/native_widget_gtk.h1
2 files changed, 23 insertions, 8 deletions
diff --git a/ui/views/widget/native_widget_gtk.cc b/ui/views/widget/native_widget_gtk.cc
index 7aac5b4..e4a3d67 100644
--- a/ui/views/widget/native_widget_gtk.cc
+++ b/ui/views/widget/native_widget_gtk.cc
@@ -361,7 +361,8 @@ NativeWidgetGtk::NativeWidgetGtk(internal::NativeWidgetDelegate* delegate)
has_keyboard_grab_(false),
grab_notify_signal_id_(0),
is_menu_(false),
- signal_registrar_(new ui::GtkSignalRegistrar) {
+ signal_registrar_(new ui::GtkSignalRegistrar),
+ destroy_signal_registrar_(new ui::GtkSignalRegistrar) {
static bool installed_message_loop_observer = false;
if (!installed_message_loop_observer) {
installed_message_loop_observer = true;
@@ -372,19 +373,24 @@ NativeWidgetGtk::NativeWidgetGtk(internal::NativeWidgetDelegate* delegate)
}
NativeWidgetGtk::~NativeWidgetGtk() {
- // We need to delete the input method before calling DestroyRootView(),
- // because it'll set focus_manager_ to NULL.
if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) {
DCHECK(widget_ == NULL);
delete delegate_;
} else {
- // Disconnect from GObjectDestructorFILO because we're
- // deleting the NativeWidgetGtk.
bool has_widget = !!widget_;
- if (has_widget)
+ if (has_widget) {
+ // Disconnect all signal handlers registered with this object,
+ // except one for "destroy", before deleting the NativeWidgetGtk.
ui::GObjectDestructorFILO::GetInstance()->Disconnect(
G_OBJECT(widget_), &OnDestroyedThunk, this);
+ signal_registrar_.reset();
+ }
CloseNow();
+ // If gtk_widget_destroy didn't fire destroy signal for whatever reason,
+ // fail in debug build and call OnDestroy() for release build.
+ DCHECK(!widget_);
+ if (widget_)
+ OnDestroy(widget_);
// Call OnNativeWidgetDestroyed because we're not calling
// OnDestroyedThunk
if (has_widget)
@@ -711,8 +717,12 @@ void NativeWidgetGtk::InitNativeWidget(const Widget::InitParams& params) {
G_CALLBACK(&OnFocusInThunk), this);
signal_registrar_->Connect(widget_, "focus_out_event",
G_CALLBACK(&OnFocusOutThunk), this);
- signal_registrar_->Connect(widget_, "destroy",
- G_CALLBACK(&OnDestroyThunk), this);
+
+ // Use the dedicated registrar for destory so that other handlers
+ // can be unregistered first.
+ destroy_signal_registrar_->Connect(widget_, "destroy",
+ G_CALLBACK(&OnDestroyThunk), this);
+
signal_registrar_->Connect(widget_, "show",
G_CALLBACK(&OnShowThunk), this);
signal_registrar_->Connect(widget_, "map",
@@ -1687,6 +1697,7 @@ void NativeWidgetGtk::OnGrabNotify(GtkWidget* widget, gboolean was_grabbed) {
void NativeWidgetGtk::OnDestroy(GtkWidget* object) {
signal_registrar_.reset();
+ destroy_signal_registrar_.reset();
if (grab_notify_signal_id_) {
g_signal_handler_disconnect(window_contents_, grab_notify_signal_id_);
grab_notify_signal_id_ = 0;
@@ -1694,6 +1705,9 @@ void NativeWidgetGtk::OnDestroy(GtkWidget* object) {
delegate_->OnNativeWidgetDestroying();
if (!child_)
ActiveWindowWatcherX::RemoveObserver(this);
+ if (widget_)
+ SetNativeWindowProperty(kNativeWidgetKey, NULL);
+
// Note that this handler is hooked to GtkObject::destroy.
// NULL out pointers here since we might still be in an observer list
// until deletion happens.
diff --git a/ui/views/widget/native_widget_gtk.h b/ui/views/widget/native_widget_gtk.h
index 79a9da7..a631c0f 100644
--- a/ui/views/widget/native_widget_gtk.h
+++ b/ui/views/widget/native_widget_gtk.h
@@ -465,6 +465,7 @@ class VIEWS_EXPORT NativeWidgetGtk : public internal::NativeWidgetPrivate,
bool is_menu_;
scoped_ptr<ui::GtkSignalRegistrar> signal_registrar_;
+ scoped_ptr<ui::GtkSignalRegistrar> destroy_signal_registrar_;
DISALLOW_COPY_AND_ASSIGN(NativeWidgetGtk);
};