summaryrefslogtreecommitdiffstats
path: root/views/focus/focus_manager_unittest.cc
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-20 20:02:51 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-20 20:02:51 +0000
commita3b8d979e2c8afa6f72998ad2dfdd95b3f9e577e (patch)
treefc345b44baa599a91ddc709ccd49036f80664d45 /views/focus/focus_manager_unittest.cc
parentaefc7d0cbd7934115a15f1b5b4eb69664f30799a (diff)
downloadchromium_src-a3b8d979e2c8afa6f72998ad2dfdd95b3f9e577e.zip
chromium_src-a3b8d979e2c8afa6f72998ad2dfdd95b3f9e577e.tar.gz
chromium_src-a3b8d979e2c8afa6f72998ad2dfdd95b3f9e577e.tar.bz2
Defer WidgetGtk's focus manager destruction
This is for the case when a WidgetGtk is hosted in another WidgtGtk and holds a reference to its focus manager. When hosting widget is destroied, it gets the "destroy" signal before the contained widget and thus schedules its destruction before the contained widget. And currently, we are not clearing the focus manager reference in another root view and when contained widget destructs, we crash. By changing focus manager's release into another message, the focus manager remains valid during contained widget destruction. BUG=none TEST=In ChromeOS, bring up options dialog and then click on buttons such as language settings, networ config etc. Then dismiss the options dialog and Chrome should not crash. Review URL: http://codereview.chromium.org/1661003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45071 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/focus/focus_manager_unittest.cc')
-rw-r--r--views/focus/focus_manager_unittest.cc102
1 files changed, 102 insertions, 0 deletions
diff --git a/views/focus/focus_manager_unittest.cc b/views/focus/focus_manager_unittest.cc
index cd89d5c..80cbd5f4 100644
--- a/views/focus/focus_manager_unittest.cc
+++ b/views/focus/focus_manager_unittest.cc
@@ -31,6 +31,7 @@
#include "views/controls/tabbed_pane/tabbed_pane.h"
#include "views/focus/accelerator_handler.h"
#include "views/widget/root_view.h"
+#include "views/window/non_client_view.h"
#include "views/window/window.h"
#include "views/window/window_delegate.h"
@@ -1401,4 +1402,105 @@ TEST_F(FocusManagerTest, CreationForNativeRoot) {
}
#endif
+#if defined(OS_CHROMEOS)
+class FocusManagerDtorTest : public FocusManagerTest {
+ protected:
+ typedef std::vector<std::string> DtorTrackVector;
+
+ class FocusManagerDtorTracked : public FocusManager {
+ public:
+ FocusManagerDtorTracked(Widget* widget, DtorTrackVector* dtor_tracker)
+ : FocusManager(widget),
+ dtor_tracker_(dtor_tracker) {
+ }
+
+ virtual ~FocusManagerDtorTracked() {
+ dtor_tracker_->push_back("FocusManagerDtorTracked");
+ }
+
+ DtorTrackVector* dtor_tracker_;
+ };
+
+ class NativeButtonDtorTracked : public NativeButton {
+ public:
+ NativeButtonDtorTracked(const std::wstring& text,
+ DtorTrackVector* dtor_tracker)
+ : NativeButton(NULL, text),
+ dtor_tracker_(dtor_tracker) {
+ };
+ virtual ~NativeButtonDtorTracked() {
+ dtor_tracker_->push_back("NativeButtonDtorTracked");
+ }
+
+ DtorTrackVector* dtor_tracker_;
+ };
+
+ class WindowGtkDtorTracked : public WindowGtk {
+ public:
+ WindowGtkDtorTracked(WindowDelegate* window_delegate,
+ DtorTrackVector* dtor_tracker)
+ : WindowGtk(window_delegate),
+ dtor_tracker_(dtor_tracker) {
+ tracked_focus_manager_ = new FocusManagerDtorTracked(this,
+ dtor_tracker_);
+ // Replace focus_manager_ with FocusManagerDtorTracked
+ set_focus_manager(tracked_focus_manager_);
+
+ GetNonClientView()->SetFrameView(CreateFrameViewForWindow());
+ Init(NULL, gfx::Rect(0, 0, 100, 100));
+ }
+
+ virtual ~WindowGtkDtorTracked() {
+ dtor_tracker_->push_back("WindowGtkDtorTracked");
+ }
+
+ FocusManagerDtorTracked* tracked_focus_manager_;
+ DtorTrackVector* dtor_tracker_;
+ };
+
+ public:
+ virtual void SetUp() {
+ // Create WindowGtkDtorTracked that uses FocusManagerDtorTracked.
+ window_ = new WindowGtkDtorTracked(this, &dtor_tracker_);
+ ASSERT_TRUE(GetFocusManager() ==
+ static_cast<WindowGtkDtorTracked*>(window_)->tracked_focus_manager_);
+
+ window_->Show();
+ }
+
+ virtual void TearDown() {
+ if (window_) {
+ window_->Close();
+ message_loop()->RunAllPending();
+ }
+ }
+
+ DtorTrackVector dtor_tracker_;
+};
+
+TEST_F(FocusManagerDtorTest, FocusManagerDestructedLast) {
+ // Setup views hierarchy.
+ TabbedPane* tabbed_pane = new TabbedPane();
+ content_view_->AddChildView(tabbed_pane);
+
+ NativeButtonDtorTracked* button = new NativeButtonDtorTracked(L"button",
+ &dtor_tracker_);
+ tabbed_pane->AddTab(L"Awesome tab", button);
+
+ // Close the window.
+ window_->Close();
+ message_loop()->RunAllPending();
+
+ // Test window, button and focus manager should all be destructed.
+ ASSERT_EQ(3, static_cast<int>(dtor_tracker_.size()));
+
+ // Focus manager should be the last one to destruct.
+ ASSERT_STREQ("FocusManagerDtorTracked", dtor_tracker_[2].c_str());
+
+ // Clear window_ so that we don't try to close it again.
+ window_ = NULL;
+}
+
+#endif // defined(OS_CHROMEOS)
+
} // namespace views