1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file.
4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_win.h"
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/tab_contents/web_drop_target_win.h"
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/tab_contents/tab_contents_drag_win.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_delegate.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/tab_contents/tab_contents.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/tab_contents/tab_contents_view.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace {
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tabs must be created as child widgets, otherwise they will be given
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// a FocusManager which will conflict with the FocusManager of the
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// window they eventually end up attached to.
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// A tab will not have a parent HWND whenever it is not active in its
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// host window - for example at creation time and when it's in the
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// background, so we provide a default widget to host them.
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// It may be tempting to use GetDesktopWindow() instead, but this is
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// problematic as the shell sends messages to children of the desktop
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// window that interact poorly with us.
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// See: http://crbug.com/16476
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenHWND GetHiddenTabHostWindow() {
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static views::Widget* widget = NULL;
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!widget) {
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    views::Widget::CreateParams params(views::Widget::CreateParams::TYPE_POPUP);
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    widget = views::Widget::CreateWidget(params);
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    widget->Init(NULL, gfx::Rect());
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // If a background window requests focus, the hidden tab host will
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // be activated to focus the tab.  Use WS_DISABLED to prevent
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // this.
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EnableWindow(widget->GetNativeView(), FALSE);
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return widget->GetNativeView();
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// NativeTabContentsViewWin, public:
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenNativeTabContentsViewWin::NativeTabContentsViewWin(
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    internal::NativeTabContentsViewDelegate* delegate)
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : delegate_(delegate),
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      focus_manager_(NULL) {
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenNativeTabContentsViewWin::~NativeTabContentsViewWin() {
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CloseNow();
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTabContents* NativeTabContentsViewWin::GetTabContents() const {
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return delegate_->GetTabContents();
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::EndDragging() {
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate_->OnNativeTabContentsViewDraggingEnded();
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  drag_handler_ = NULL;
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// NativeTabContentsViewWin, NativeTabContentsView implementation:
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::InitNativeTabContentsView() {
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  views::Widget::CreateParams params(views::Widget::CreateParams::TYPE_CONTROL);
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  params.delete_on_destroy = false;
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SetCreateParams(params);
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WidgetWin::Init(GetHiddenTabHostWindow(), gfx::Rect());
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Remove the root view drop target so we can register our own.
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RevokeDragDrop(GetNativeView());
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  drop_target_ = new WebDropTarget(GetNativeView(),
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   delegate_->GetTabContents());
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::Unparent() {
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Remember who our FocusManager is, we won't be able to access it once
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // unparented.
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  focus_manager_ = views::WidgetWin::GetFocusManager();
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Note that we do not DCHECK on focus_manager_ as it may be NULL when used
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // with an external tab container.
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NativeWidget::ReparentNativeView(GetNativeView(), GetHiddenTabHostWindow());
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenRenderWidgetHostView* NativeTabContentsViewWin::CreateRenderWidgetHostView(
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    RenderWidgetHost* render_widget_host) {
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderWidgetHostViewWin* view =
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new RenderWidgetHostViewWin(render_widget_host);
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  view->CreateWnd(GetNativeView());
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  view->ShowWindow(SW_SHOW);
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return view;
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsengfx::NativeWindow NativeTabContentsViewWin::GetTopLevelNativeWindow() const {
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return ::GetAncestor(GetNativeView(), GA_ROOT);
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::SetPageTitle(const std::wstring& title) {
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // It's possible to get this after the hwnd has been destroyed.
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (GetNativeView())
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ::SetWindowText(GetNativeView(), title.c_str());
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::StartDragging(const WebDropData& drop_data,
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                             WebKit::WebDragOperationsMask ops,
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                             const SkBitmap& image,
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                             const gfx::Point& image_offset) {
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  drag_handler_ = new TabContentsDragWin(this);
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  drag_handler_->StartDragging(drop_data, ops, image, image_offset);
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::CancelDrag() {
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  drag_handler_->CancelDrag();
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool NativeTabContentsViewWin::IsDoingDrag() const {
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return drag_handler_.get() != NULL;
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::SetDragCursor(
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    WebKit::WebDragOperation operation) {
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  drop_target_->set_drag_cursor(operation);
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenviews::NativeWidget* NativeTabContentsViewWin::AsNativeWidget() {
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return this;
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// NativeTabContentsViewWin, views::WidgetWin overrides:
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::OnDestroy() {
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (drop_target_.get()) {
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    RevokeDragDrop(GetNativeView());
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    drop_target_ = NULL;
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WidgetWin::OnDestroy();
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::OnHScroll(int scroll_type,
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         short position,
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         HWND scrollbar) {
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScrollCommon(WM_HSCROLL, scroll_type, position, scrollbar);
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenLRESULT NativeTabContentsViewWin::OnMouseRange(UINT msg,
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               WPARAM w_param,
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               LPARAM l_param) {
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (delegate_->IsShowingSadTab())
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return WidgetWin::OnMouseRange(msg, w_param, l_param);
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  switch (msg) {
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case WM_LBUTTONDOWN:
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case WM_MBUTTONDOWN:
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case WM_RBUTTONDOWN: {
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      delegate_->OnNativeTabContentsViewMouseDown();
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case WM_MOUSEMOVE:
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      delegate_->OnNativeTabContentsViewMouseMove();
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    default:
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return 0;
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// A message is reflected here from view().
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Return non-zero to indicate that it is handled here.
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Return 0 to allow view() to further process it.
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenLRESULT NativeTabContentsViewWin::OnReflectedMessage(UINT msg,
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                     WPARAM w_param,
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                     LPARAM l_param) {
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MSG* message = reinterpret_cast<MSG*>(l_param);
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  switch (message->message) {
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case WM_MOUSEWHEEL:
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // This message is reflected from the view() to this window.
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (GET_KEYSTATE_WPARAM(message->wParam) & MK_CONTROL) {
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        delegate_->OnNativeTabContentsViewWheelZoom(
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            GET_WHEEL_DELTA_WPARAM(message->wParam));
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return 1;
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case WM_HSCROLL:
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case WM_VSCROLL:
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (ScrollZoom(LOWORD(message->wParam)))
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return 1;
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    default:
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return 0;
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::OnVScroll(int scroll_type,
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         short position,
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         HWND scrollbar) {
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ScrollCommon(WM_VSCROLL, scroll_type, position, scrollbar);
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::OnWindowPosChanged(WINDOWPOS* window_pos) {
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (window_pos->flags & SWP_HIDEWINDOW) {
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delegate_->OnNativeTabContentsViewHidden();
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The TabContents was shown by a means other than the user selecting a
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Tab, e.g. the window was minimized then restored.
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (window_pos->flags & SWP_SHOWWINDOW)
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      delegate_->OnNativeTabContentsViewShown();
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Unless we were specifically told not to size, cause the renderer to be
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // sized to the new bounds, which forces a repaint. Not required for the
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // simple minimize-restore case described above, for example, since the
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // size hasn't changed.
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!(window_pos->flags & SWP_NOSIZE)) {
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      delegate_->OnNativeTabContentsViewSized(
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          gfx::Size(window_pos->cx, window_pos->cy));
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WidgetWin::OnWindowPosChanged(window_pos);
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::OnSize(UINT param, const CSize& size) {
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // NOTE: Because TabContentsViewViews handles OnWindowPosChanged without
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // calling DefWindowProc, OnSize is NOT called on window resize. This handler
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // is called only once when the window is created.
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Don't call base class OnSize to avoid useless layout for 0x0 size.
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We will get OnWindowPosChanged later and layout root view in WasSized.
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Hack for ThinkPad touch-pad driver.
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Set fake scrollbars so that we can get scroll messages,
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SCROLLINFO si = {0};
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  si.cbSize = sizeof(si);
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  si.fMask = SIF_ALL;
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  si.nMin = 1;
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  si.nMax = 100;
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  si.nPage = 10;
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  si.nPos = 50;
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ::SetScrollInfo(GetNativeView(), SB_HORZ, &si, FALSE);
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ::SetScrollInfo(GetNativeView(), SB_VERT, &si, FALSE);
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenLRESULT NativeTabContentsViewWin::OnNCCalcSize(BOOL w_param, LPARAM l_param) {
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Hack for ThinkPad mouse wheel driver. We have set the fake scroll bars
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // to receive scroll messages from ThinkPad touch-pad driver. Suppress
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // painting of scrollbars by returning 0 size for them.
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return 0;
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::OnNCPaint(HRGN rgn) {
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Suppress default WM_NCPAINT handling. We don't need to do anything
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // here since the view will draw everything correctly.
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenviews::FocusManager* NativeTabContentsViewWin::GetFocusManager() {
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  views::FocusManager* focus_manager = WidgetWin::GetFocusManager();
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (focus_manager) {
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // If focus_manager_ is non NULL, it means we have been reparented, in which
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // case its value may not be valid anymore.
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    focus_manager_ = NULL;
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return focus_manager;
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(jcampan): we should DCHECK on focus_manager_, as it should not be
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // NULL.  We are not doing it as it breaks some unit-tests.  We should
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // probably have an empty TabContentView implementation for the unit-tests,
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // that would prevent that code being executed in the unit-test case.
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // DCHECK(focus_manager_);
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return focus_manager_;
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// NativeTabContentsViewWin, private:
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NativeTabContentsViewWin::ScrollCommon(UINT message, int scroll_type,
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            short position, HWND scrollbar) {
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // This window can receive scroll events as a result of the ThinkPad's
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // touch-pad scroll wheel emulation.
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!ScrollZoom(scroll_type)) {
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Reflect scroll message to the view() to give it a chance
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // to process scrolling.
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SendMessage(delegate_->GetTabContents()->view()->GetContentNativeView(),
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                message, MAKELONG(scroll_type, position),
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                reinterpret_cast<LPARAM>(scrollbar));
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool NativeTabContentsViewWin::ScrollZoom(int scroll_type) {
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If ctrl is held, zoom the UI.  There are three issues with this:
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // 1) Should the event be eaten or forwarded to content?  We eat the event,
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  //    which is like Firefox and unlike IE.
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // 2) Should wheel up zoom in or out?  We zoom in (increase font size), which
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  //    is like IE and Google maps, but unlike Firefox.
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // 3) Should the mouse have to be over the content area?  We zoom as long as
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  //    content has focus, although FF and IE require that the mouse is over
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  //    content.  This is because all events get forwarded when content has
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  //    focus.
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (GetAsyncKeyState(VK_CONTROL) & 0x8000) {
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int distance = 0;
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    switch (scroll_type) {
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case SB_LINEUP:
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        distance = WHEEL_DELTA;
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case SB_LINEDOWN:
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        distance = -WHEEL_DELTA;
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // TODO(joshia): Handle SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION,
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // and SB_THUMBTRACK for completeness
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      default:
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delegate_->OnNativeTabContentsViewWheelZoom(distance);
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return true;
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return false;
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// NativeTabContentsView, public:
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenNativeTabContentsView* NativeTabContentsView::CreateNativeTabContentsView(
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    internal::NativeTabContentsViewDelegate* delegate) {
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return new NativeTabContentsViewWin(delegate);
336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
337