diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-24 18:04:41 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-24 18:04:41 +0000 |
commit | a450e540e1f001d5d37374ae8fcc099d6bbb7ace (patch) | |
tree | d9e87f4f819e96ac75cef01872237c7548389fdd /ui/views/widget | |
parent | a4d0c7d2fa06be57cb732751d743f2bbae4c0019 (diff) | |
download | chromium_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.cc | 30 | ||||
-rw-r--r-- | ui/views/widget/native_widget_gtk.h | 1 |
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); }; |