1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/scoped_testing_local_state.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/testing_browser_process.h"
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/view_event_test_base.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/controls/native/native_view_host.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/widget/widget.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class NativeWidgetWinTest : public ViewEventTestBase {
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NativeWidgetWinTest()
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : ViewEventTestBase(),
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        contents_view_(new views::View) {
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    local_state_.reset(new ScopedTestingLocalState(
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        TestingBrowserProcess::GetGlobal()));
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ViewEventTestBase::SetUp();
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual views::View* CreateContentsView() OVERRIDE {
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return contents_view_;
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual gfx::Size GetPreferredSize() OVERRIDE {
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return gfx::Size(500, 500);
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  views::View* contents_view_;
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<views::Widget> child_;
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ScopedTestingLocalState> local_state_;
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NativeWidgetWinTest);
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This test creates a child Widget that is attached by way of a NativeViewHost.
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The child HWND is focused (through NativeViewHost) the top level Widget is
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// minimized then restored and the test asserts focus is still on the child
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// widget and corresponding NativeViewHost.
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This scenario replicates what happens with a browser and a corresponding
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// RenderWidgetHostViewWin.
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This test really belongs in views, but as it exercises focus it needs to
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// be here.
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class NativeWidgetWinTest1 : public NativeWidgetWinTest {
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NativeWidgetWinTest1()
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : NativeWidgetWinTest(),
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        child_(NULL),
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        native_view_host_(NULL) {
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void DoTestOnMessageLoop() OVERRIDE {
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    AttachChildWidget();
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Focus the native widget.
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    native_view_host_->RequestFocus();
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(native_view_host_->HasFocus());
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(child_->GetNativeView(), ::GetFocus());
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Minimize then restore the window, focus should still be on the
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // NativeViewHost and its corresponding widget.
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window_->Minimize();
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DLOG(WARNING) << "Restoring widget=" << window_->GetNativeView();
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window_->Restore();
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(native_view_host_->HasFocus());
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(child_->GetNativeView(), ::GetFocus());
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Done();
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void AttachChildWidget() {
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    child_ = new views::Widget();
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    views::Widget::InitParams child_params(
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        views::Widget::InitParams::TYPE_CONTROL);
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    child_params.parent = window_->GetNativeView();
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    child_->Init(child_params);
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    native_view_host_ = new views::NativeViewHost;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    native_view_host_->set_focusable(true);
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    contents_view_->AddChildView(native_view_host_);
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    native_view_host_->SetBoundsRect(gfx::Rect(0, 0, 200, 200));
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    native_view_host_->Attach(child_->GetNativeView());
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Owned by the parent widget.
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  views::Widget* child_;
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Owned by the parent View.
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  views::NativeViewHost* native_view_host_;
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NativeWidgetWinTest1);
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)VIEW_TEST(NativeWidgetWinTest1, FocusRestoredToChildAfterMiniminize)
104