diff options
Diffstat (limited to 'views/widget')
-rw-r--r-- | views/widget/widget_gtk.cc | 17 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 8 |
2 files changed, 21 insertions, 4 deletions
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 20b0287..6e78a71 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -136,6 +136,7 @@ WidgetGtk::WidgetGtk(Type type) type_(type), widget_(NULL), window_contents_(NULL), + focus_manager_(NULL), is_mouse_down_(false), has_capture_(false), last_mouse_event_was_move_(false), @@ -162,7 +163,7 @@ WidgetGtk::WidgetGtk(Type type) } if (type_ != TYPE_CHILD) - focus_manager_.reset(new FocusManager(this)); + focus_manager_ = new FocusManager(this); } WidgetGtk::~WidgetGtk() { @@ -170,6 +171,16 @@ WidgetGtk::~WidgetGtk() { if (type_ != TYPE_CHILD) ActiveWindowWatcherX::RemoveObserver(this); MessageLoopForUI::current()->RemoveObserver(this); + + // Defer focus manager's destruction. This is for the case when the + // focus manager is referenced by a child WidgetGtk (e.g. TabbedPane in a + // dialog). When gtk_widget_destroy is called on the parent, the destroy + // signal reaches parent first and then the child. Thus causing the parent + // WidgetGtk's dtor executed before the child's. If child's view hierarchy + // references this focus manager, it crashes. This will defer focus manager's + // destruction after child WidgetGtk's dtor. + if (focus_manager_) + MessageLoop::current()->DeleteSoon(FROM_HERE, focus_manager_); } GtkWindow* WidgetGtk::GetTransientParent() const { @@ -680,8 +691,8 @@ ThemeProvider* WidgetGtk::GetDefaultThemeProvider() const { } FocusManager* WidgetGtk::GetFocusManager() { - if (focus_manager_.get()) - return focus_manager_.get(); + if (focus_manager_) + return focus_manager_; Widget* root = GetRootWidget(); if (root && root != this) { diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index d10237d..b86820a 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -282,6 +282,12 @@ class WidgetGtk // Are we a subclass of WindowGtk? bool is_window_; + // For test code to provide a customized focus manager. + void set_focus_manager(FocusManager* focus_manager) { + delete focus_manager_; + focus_manager_ = focus_manager; + } + private: class DropObserver; friend class DropObserver; @@ -341,7 +347,7 @@ class WidgetGtk // children. NULL for non top-level widgets. // WARNING: RootView's destructor calls into the FocusManager. As such, this // must be destroyed AFTER root_view_. - scoped_ptr<FocusManager> focus_manager_; + FocusManager* focus_manager_; // The root of the View hierarchy attached to this window. scoped_ptr<RootView> root_view_; |