1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <algorithm>
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/rtl.h"
11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/process_util.h"
133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/win/scoped_comptr.h"
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/win/scoped_gdi_object.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/win/wrapped_window_proc.h"
17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/accessibility/browser_accessibility_manager.h"
18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/accessibility/browser_accessibility_state.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/accessibility/browser_accessibility_win.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_trial.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/render_messages.h"
24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/plugin_process_host.h"
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/backing_store.h"
27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/backing_store_win.h"
28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_process_host.h"
29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_widget_host.h"
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/native_web_keyboard_event.h"
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/plugin_messages.h"
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/view_messages.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/webkit_resources.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "skia/ext/skia_utils_win.h"
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositionUnderline.h"
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/win/WebInputEventFactory.h"
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/ime/composition_text.h"
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util_win.h"
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/view_prop.h"
4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/win/hwnd_util.h"
4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas.h"
4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas_skia.h"
4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/gdi_util.h"
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/rect.h"
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/accessibility/native_view_accessibility_win.h"
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/focus/focus_manager.h"
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/focus/focus_util_win.h"
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Included for views::kReflectedMessage - TODO(beng): move this to win_util.h!
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/widget_win.h"
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "webkit/glue/webaccessibility.h"
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webcursor.h"
5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/plugins/npapi/plugin_constants_win.h"
5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/plugins/npapi/webplugin.h"
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeTicks;
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing ui::ViewProp;
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebInputEvent;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebInputEventFactory;
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebMouseEvent;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebTextDirection;
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing webkit::npapi::WebPluginGeometry;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69634420e363ef646c3b50a37b10d86a424b06ee49Ben Murdochconst wchar_t kRenderWidgetHostHWNDClass[] = L"Chrome_RenderWidgetHostHWND";
70634420e363ef646c3b50a37b10d86a424b06ee49Ben Murdoch
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tooltips will wrap after this width. Yes, wrap. Imagine that!
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTooltipMaxWidthPixels = 300;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Maximum number of characters we allow in a tooltip.
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kMaxTooltipLength = 1024;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// A custom MSAA object id used to determine if a screen reader is actively
80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// listening for MSAA events.
81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst int kIdCustom = 1;
82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// The delay before the compositor host window is destroyed. This gives the GPU
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// process a grace period to stop referencing it.
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kDestroyCompositorHostWindowDelay = 10000;
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
87201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char* const kRenderWidgetHostViewKey = "__RENDER_WIDGET_HOST_VIEW__";
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A callback function for EnumThreadWindows to enumerate and dismiss
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// any owned popop windows
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) {
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg);
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (::IsWindowVisible(window)) {
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const HWND owner = ::GetWindow(window, GW_OWNER);
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (toplevel_hwnd == owner) {
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ::PostMessage(window, WM_CANCELMODE, 0, 0);
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return TRUE;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass NotifyPluginProcessHostTask : public Task {
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotifyPluginProcessHostTask(HWND window, HWND parent)
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : window_(window), parent_(parent), tries_(kMaxTries) { }
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Run() {
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DWORD plugin_process_id;
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool found_starting_plugin_process = false;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetWindowThreadProcessId(window_, &plugin_process_id);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (BrowserChildProcessHost::Iterator iter(
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             ChildProcessInfo::PLUGIN_PROCESS);
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         !iter.Done(); ++iter) {
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!plugin->handle()) {
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        found_starting_plugin_process = true;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        continue;
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (base::GetProcId(plugin->handle()) == plugin_process_id) {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        plugin->AddWindow(parent_);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (found_starting_plugin_process) {
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // A plugin process has started but we don't have its handle yet.  Since
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // it's most likely the one for this plugin, try a few more times after a
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // delay.
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (tries_--) {
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        MessageLoop::current()->PostDelayedTask(FROM_HERE, this, kTryDelayMs);
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The plugin process might have died in the time to execute the task, don't
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // leak the HWND.
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PostMessage(parent_, WM_CLOSE, 0, 0);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HWND window_;  // Plugin HWND, created and destroyed in the plugin process.
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HWND parent_;  // Parent HWND, created and destroyed on the browser UI thread.
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int tries_;
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // How many times we try to find a PluginProcessHost whose process matches
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the HWND.
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const int kMaxTries = 5;
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // How long to wait between each try.
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const int kTryDelayMs = 200;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Windows callback for OnDestroy to detach the plugin windows.
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBOOL CALLBACK DetachPluginWindowsCallback(HWND window, LPARAM param) {
15721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (webkit::npapi::WebPluginDelegateImpl::IsPluginDelegateWindow(window) &&
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !IsHungAppWindow(window)) {
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ::ShowWindow(window, SW_HIDE);
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SetParent(window, NULL);
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return TRUE;
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Draw the contents of |backing_store_dc| onto |paint_rect| with a 70% grey
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// filter.
167201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid DrawDeemphasized(const SkColor& color,
168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                      const gfx::Rect& paint_rect,
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      HDC backing_store_dc,
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      HDC paint_dc) {
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::CanvasSkia canvas(paint_rect.width(), paint_rect.height(), true);
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HDC dc = canvas.beginPlatformPaint();
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BitBlt(dc,
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         0,
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         0,
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         paint_rect.width(),
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         paint_rect.height(),
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         backing_store_dc,
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         paint_rect.x(),
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         paint_rect.y(),
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         SRCCOPY);
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas.endPlatformPaint();
183201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  canvas.FillRectInt(color, 0, 0, paint_rect.width(), paint_rect.height());
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas.getTopPlatformDevice().drawToHDC(paint_dc, paint_rect.x(),
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          paint_rect.y(), NULL);
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// The plugin wrapper window which lives in the browser process has this proc
189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// as its window procedure. We only handle the WM_PARENTNOTIFY message sent by
190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// windowed plugins for mouse input. This is forwarded off to the wrappers
191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// parent which is typically the RVH window which turns on user gesture.
192dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenLRESULT CALLBACK PluginWrapperWindowProc(HWND window, unsigned int message,
193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                         WPARAM wparam, LPARAM lparam) {
194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (message == WM_PARENTNOTIFY) {
195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    switch (LOWORD(wparam)) {
196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      case WM_LBUTTONDOWN:
197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      case WM_RBUTTONDOWN:
198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      case WM_MBUTTONDOWN:
199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        ::SendMessage(GetParent(window), message, wparam, lparam);
200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        return 0;
201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      default:
202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        break;
203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return ::DefWindowProc(window, message, wparam, lparam);
206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// RenderWidgetHostView --------------------------------------------------------
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderWidgetHost* widget) {
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new RenderWidgetHostViewWin(widget);
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// RenderWidgetHostViewWin, public:
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget)
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : render_widget_host_(widget),
223201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      compositor_host_window_(NULL),
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      hide_compositor_window_at_next_paint_(false),
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      track_mouse_leave_(false),
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ime_notification_(false),
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      capture_enter_key_(false),
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_hidden_(false),
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      about_to_validate_and_paint_(false),
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      close_on_deactivate_(false),
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      being_destroyed_(false),
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tooltip_hwnd_(NULL),
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tooltip_showing_(false),
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      shutdown_factory_(this),
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent_hwnd_(NULL),
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_loading_(false),
237201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      overlay_color_(0),
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      text_input_type_(WebKit::WebTextInputTypeNone) {
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  render_widget_host_->set_view(this);
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationType::RENDERER_PROCESS_TERMINATED,
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderWidgetHostViewWin::~RenderWidgetHostViewWin() {
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetTooltip();
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::CreateWnd(HWND parent) {
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Create(parent);  // ATL function to create the window.
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// RenderWidgetHostViewWin, RenderWidgetHostView implementation:
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::InitAsPopup(
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  parent_hwnd_ = parent_host_view->GetNativeView();
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  close_on_deactivate_ = true;
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Create(parent_hwnd_, NULL, NULL, WS_POPUP, WS_EX_TOOLWINDOW);
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MoveWindow(pos.x(), pos.y(), pos.width(), pos.height(), TRUE);
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Popups are not activated.
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowWindow(IsActivatable() ? SW_SHOW : SW_SHOWNA);
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid RenderWidgetHostViewWin::InitAsFullscreen() {
2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  NOTIMPLEMENTED() << "Fullscreen not implemented on Win";
2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderWidgetHost* RenderWidgetHostViewWin::GetRenderWidgetHost() const {
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return render_widget_host_;
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::DidBecomeSelected() {
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!is_hidden_)
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_switch_paint_time_.is_null())
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tab_switch_paint_time_ = TimeTicks::Now();
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_hidden_ = false;
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EnsureTooltip();
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  render_widget_host_->WasRestored();
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::WasHidden() {
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_hidden_)
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we receive any more paint messages while we are hidden, we want to
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ignore them so we don't re-allocate the backing store.  We will paint
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // everything again when we become selected again.
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_hidden_ = true;
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetTooltip();
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we have a renderer, then inform it that we are being hidden so it can
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // reduce its resource utilization.
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  render_widget_host_->WasHidden();
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(darin): what about constrained windows?  it doesn't look like they
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // see a message when their parent is hidden.  maybe there is something more
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // generic we can do at the TabContents API level instead of relying on
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Windows messages.
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::SetSize(const gfx::Size& size) {
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SetBounds(gfx::Rect(GetViewBounds().origin(), size));
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid RenderWidgetHostViewWin::SetBounds(const gfx::Rect& rect) {
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_hidden_)
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // No SWP_NOREDRAW as autofill popups can move and the underneath window
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should redraw in that case.
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS |
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE;
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If the style is not popup, you have to convert the point to client
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // coordinate.
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  POINT point = { rect.x(), rect.y() };
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (GetStyle() & WS_CHILD)
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ScreenToClient(&point);
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SetWindowPos(NULL, point.x, point.y, rect.width(), rect.height(), swp_flags);
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  render_widget_host_->WasResized();
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EnsureTooltip();
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::NativeView RenderWidgetHostViewWin::GetNativeView() {
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return m_hWnd;
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::MovePluginWindows(
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<WebPluginGeometry>& plugin_window_moves) {
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (plugin_window_moves.empty())
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool oop_plugins =
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) &&
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    !CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessPlugins);
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HDWP defer_window_pos_info =
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ::BeginDeferWindowPos(static_cast<int>(plugin_window_moves.size()));
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!defer_window_pos_info) {
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < plugin_window_moves.size(); ++i) {
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unsigned long flags = 0;
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const WebPluginGeometry& move = plugin_window_moves[i];
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HWND window = move.window;
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // As the plugin parent window which lives on the browser UI thread is
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // destroyed asynchronously, it is possible that we have a stale window
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // sent in by the renderer for moving around.
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Note: get the parent before checking if the window is valid, to avoid a
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // race condition where the window is destroyed after the check but before
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the GetParent call.
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HWND parent = ::GetParent(window);
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!::IsWindow(window))
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (oop_plugins) {
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (parent == m_hWnd) {
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // The plugin window is a direct child of this window, add an
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // intermediate window that lives on this thread to speed up scrolling.
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // Note this only works with out of process plugins since we depend on
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // PluginProcessHost to destroy the intermediate HWNDs.
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        parent = ReparentWindow(window);
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ::ShowWindow(window, SW_SHOW);  // Window was created hidden.
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else if (::GetParent(parent) != m_hWnd) {
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // The renderer should only be trying to move windows that are children
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // of its render widget window. However, this may happen as a result of
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // a race condition, so we ignore it and not kill the plugin process.
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        continue;
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We move the intermediate parent window which doesn't result in cross-
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // process synchronous Windows messages.
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      window = parent;
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (move.visible)
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      flags |= SWP_SHOWWINDOW;
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      flags |= SWP_HIDEWINDOW;
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (move.rects_valid) {
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      HRGN hrgn = ::CreateRectRgn(move.clip_rect.x(),
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  move.clip_rect.y(),
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  move.clip_rect.right(),
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  move.clip_rect.bottom());
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::SubtractRectanglesFromRegion(hrgn, move.cutout_rects);
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Note: System will own the hrgn after we call SetWindowRgn,
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // so we don't need to call DeleteObject(hrgn)
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ::SetWindowRgn(window, hrgn, !move.clip_rect.IsEmpty());
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      flags |= SWP_NOMOVE;
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      flags |= SWP_NOSIZE;
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    defer_window_pos_info = ::DeferWindowPos(defer_window_pos_info,
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             window, NULL,
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             move.window_rect.x(),
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             move.window_rect.y(),
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             move.window_rect.width(),
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             move.window_rect.height(), flags);
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!defer_window_pos_info) {
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK(false) << "DeferWindowPos failed, so all plugin moves ignored.";
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ::EndDeferWindowPos(defer_window_pos_info);
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHWND RenderWidgetHostViewWin::ReparentWindow(HWND window) {
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static ATOM window_class = 0;
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!window_class) {
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WNDCLASSEX wcex;
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wcex.cbSize         = sizeof(WNDCLASSEX);
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wcex.style          = CS_DBLCLKS;
427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    wcex.lpfnWndProc    = base::win::WrappedWindowProc<PluginWrapperWindowProc>;
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wcex.cbClsExtra     = 0;
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wcex.cbWndExtra     = 0;
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wcex.hInstance      = GetModuleHandle(NULL);
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wcex.hIcon          = 0;
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wcex.hCursor        = 0;
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wcex.hbrBackground  = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wcex.lpszMenuName   = 0;
43521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    wcex.lpszClassName  = webkit::npapi::kWrapperNativeWindowClassName;
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wcex.hIconSm        = 0;
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    window_class = RegisterClassEx(&wcex);
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(window_class);
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HWND parent = CreateWindowEx(
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MAKEINTATOM(window_class), 0,
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      0, 0, 0, 0, ::GetParent(window), 0, GetModuleHandle(NULL), 0);
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ui::CheckWindowCreated(parent);
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ::SetParent(window, parent);
448731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
449731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::IO, FROM_HERE,
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new NotifyPluginProcessHostTask(window, parent));
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return parent;
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
454201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic BOOL CALLBACK AddChildWindowToVector(HWND hwnd, LPARAM lparam) {
455201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::vector<HWND>* vector = reinterpret_cast<std::vector<HWND>*>(lparam);
456201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  vector->push_back(hwnd);
457201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return TRUE;
458201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
459201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
460201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid RenderWidgetHostViewWin::CleanupCompositorWindow() {
461201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!compositor_host_window_)
462201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return;
463201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Hide the compositor and parent it to the desktop rather than destroying
465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // it immediately. The GPU process has a grace period to stop accessing the
466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // window. TODO(apatrick): the GPU process should acknowledge that it has
467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // finished with the window handle and the browser process should destroy it
468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // at that point.
469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ::ShowWindow(compositor_host_window_, SW_HIDE);
470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ::SetParent(compositor_host_window_, NULL);
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostDelayedTask(
473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread::UI,
474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      FROM_HERE,
475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewRunnableFunction(::DestroyWindow, compositor_host_window_),
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      kDestroyCompositorHostWindowDelay);
477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
478201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  compositor_host_window_ = NULL;
479201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
480201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool RenderWidgetHostViewWin::IsActivatable() const {
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Popups should not be activated.
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return popup_type_ == WebKit::WebPopupTypeNone;
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::Focus() {
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (IsWindow())
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SetFocus();
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::Blur() {
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::FocusManager* focus_manager =
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      views::FocusManager::GetFocusManagerForNativeView(m_hWnd);
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't have a FocusManager if we are hidden.
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (focus_manager)
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    focus_manager->ClearFocus();
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool RenderWidgetHostViewWin::HasFocus() {
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return ::GetFocus() == m_hWnd;
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::Show() {
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(parent_hwnd_);
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(parent_hwnd_ != GetDesktopWindow());
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetParent(parent_hwnd_);
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowWindow(SW_SHOW);
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Save away our HWND in the parent window as a property so that the
51072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // accessibility code can find it.
511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  accessibility_prop_.reset(new ViewProp(
512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetParent(),
513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      views::kViewsNativeHostPropForAccessibility,
514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      m_hWnd));
51572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DidBecomeSelected();
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::Hide() {
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (GetParent() == GetDesktopWindow()) {
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LOG(WARNING) << "Hide() called twice in a row: " << this << ":" <<
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        parent_hwnd_ << ":" << GetParent();
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  accessibility_prop_.reset();
52772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (::GetFocus() == m_hWnd)
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ::SetFocus(NULL);
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowWindow(SW_HIDE);
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cache the old parent, then orphan the window so we stop receiving messages
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  parent_hwnd_ = GetParent();
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetParent(NULL);
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WasHidden();
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool RenderWidgetHostViewWin::IsShowing() {
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return !!IsWindowVisible();
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect RenderWidgetHostViewWin::GetViewBounds() const {
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CRect window_rect;
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetWindowRect(&window_rect);
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return gfx::Rect(window_rect);
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::UpdateCursor(const WebCursor& cursor) {
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_cursor_ = cursor;
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateCursorIfOverSelf();
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::UpdateCursorIfOverSelf() {
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static HCURSOR kCursorArrow = LoadCursor(NULL, IDC_ARROW);
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static HCURSOR kCursorAppStarting = LoadCursor(NULL, IDC_APPSTARTING);
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static HINSTANCE module_handle =
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetModuleHandle(chrome::kBrowserResourcesDll);
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the mouse is over our HWND, then update the cursor state immediately.
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CPoint pt;
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetCursorPos(&pt);
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (WindowFromPoint(pt) == m_hWnd) {
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    BOOL result = ::ScreenToClient(m_hWnd, &pt);
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(result);
5664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // We cannot pass in NULL as the module handle as this would only work for
5674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // standard win32 cursors. We can also receive cursor types which are
5684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // defined as webkit resources. We need to specify the module handle of
5694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // chrome.dll while loading these cursors.
5704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    HCURSOR display_cursor = current_cursor_.GetCursor(module_handle);
5714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
5724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // If a page is in the loading state, we want to show the Arrow+Hourglass
5734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // cursor only when the current cursor is the ARROW cursor. In all other
5744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // cases we should continue to display the current cursor.
5754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (is_loading_ && display_cursor == kCursorArrow)
5764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      display_cursor = kCursorAppStarting;
5774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
5784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    SetCursor(display_cursor);
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::SetIsLoading(bool is_loading) {
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_loading_ = is_loading;
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateCursorIfOverSelf();
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::ImeUpdateTextInputState(
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WebKit::WebTextInputType type,
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const gfx::Rect& caret_rect) {
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (text_input_type_ != type) {
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    text_input_type_ = type;
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (type == WebKit::WebTextInputTypeText)
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ime_input_.EnableIME(m_hWnd);
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ime_input_.DisableIME(m_hWnd);
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Only update caret position if the input method is enabled.
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == WebKit::WebTextInputTypeText)
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ime_input_.UpdateCaretRect(m_hWnd, caret_rect);
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::ImeCancelComposition() {
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ime_input_.CancelIME(m_hWnd);
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lparam) {
60821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!webkit::npapi::WebPluginDelegateImpl::IsPluginDelegateWindow(hwnd))
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return TRUE;
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect* rect = reinterpret_cast<gfx::Rect*>(lparam);
61221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  static UINT msg = RegisterWindowMessage(webkit::npapi::kPaintMessageName);
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WPARAM wparam = rect->x() << 16 | rect->y();
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  lparam = rect->width() << 16 | rect->height();
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // SendMessage gets the message across much quicker than PostMessage, since it
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // doesn't get queued.  When the plugin thread calls PeekMessage or other
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Win32 APIs, sent messages are dispatched automatically.
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SendNotifyMessage(hwnd, msg, wparam, lparam);
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return TRUE;
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::Redraw() {
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RECT damage_bounds;
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetUpdateRect(&damage_bounds, FALSE);
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  base::win::ScopedGDIObject<HRGN> damage_region(CreateRectRgn(0, 0, 0, 0));
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetUpdateRgn(damage_region, FALSE);
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Paint the invalid region synchronously.  Our caller will not paint again
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // until we return, so by painting to the screen here, we ensure effective
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // rate-limiting of backing store updates.  This helps a lot on pages that
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // have animations or fairly expensive layout (e.g., google maps).
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We paint this window synchronously, however child windows (i.e. plugins)
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // are painted asynchronously.  By avoiding synchronous cross-process window
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // message dispatching we allow scrolling to be smooth, and also avoid the
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // browser process locking up if the plugin process is hung.
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RedrawWindow(NULL, damage_region, RDW_UPDATENOW | RDW_NOCHILDREN);
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Send the invalid rect in screen coordinates.
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect screen_rect = GetViewBounds();
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect invalid_screen_rect(damage_bounds);
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y());
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LPARAM lparam = reinterpret_cast<LPARAM>(&invalid_screen_rect);
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EnumChildWindows(m_hWnd, EnumChildProc, lparam);
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::DidUpdateBackingStore(
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy,
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<gfx::Rect>& copy_rects) {
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_hidden_)
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Schedule invalidations first so that the ScrollWindowEx call is closer to
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Redraw.  That minimizes chances of "flicker" resulting if the screen
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // refreshes before we have a chance to paint the exposed area.  Somewhat
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // surprisingly, this ordering matters.
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < copy_rects.size(); ++i)
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InvalidateRect(&copy_rects[i].ToRECT(), false);
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!scroll_rect.IsEmpty()) {
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RECT clip_rect = scroll_rect.ToRECT();
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ScrollWindowEx(scroll_dx, scroll_dy, NULL, &clip_rect, NULL, NULL,
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   SW_INVALIDATE);
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!about_to_validate_and_paint_)
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Redraw();
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid RenderWidgetHostViewWin::RenderViewGone(base::TerminationStatus status,
67721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                             int error_code) {
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(darin): keep this around, and draw sad-tab into it.
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateCursorIfOverSelf();
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  being_destroyed_ = true;
681201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CleanupCompositorWindow();
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DestroyWindow();
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
685201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid RenderWidgetHostViewWin::WillWmDestroy() {
686201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CleanupCompositorWindow();
687201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
688201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::WillDestroyRenderWidget(RenderWidgetHost* rwh) {
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (rwh == render_widget_host_)
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_ = NULL;
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::Destroy() {
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We've been told to destroy.
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // By clearing close_on_deactivate_, we prevent further deactivations
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (caused by windows messages resulting from the DestroyWindow) from
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // triggering further destructions.  The deletion of this is handled by
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // OnFinalMessage();
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  close_on_deactivate_ = false;
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  being_destroyed_ = true;
702201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CleanupCompositorWindow();
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DestroyWindow();
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::SetTooltipText(const std::wstring& tooltip_text) {
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Clamp the tooltip length to kMaxTooltipLength so that we don't
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // accidentally DOS the user with a mega tooltip (since Windows doesn't seem
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to do this itself).
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::wstring& new_tooltip_text =
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::TruncateString(tooltip_text, kMaxTooltipLength);
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (new_tooltip_text != tooltip_text_) {
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tooltip_text_ = new_tooltip_text;
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Need to check if the tooltip is already showing so that we don't
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // immediately show the tooltip with no delay when we move the mouse from
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // a region with no tooltip to a region with a tooltip.
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (::IsWindow(tooltip_hwnd_) && tooltip_showing_) {
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0);
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ::SendMessage(tooltip_hwnd_, TTM_POPUP, 0, 0);
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make sure the tooltip gets closed after TTN_POP gets sent. For some
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // reason this doesn't happen automatically, so moving the mouse around
726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // within the same link/image/etc doesn't cause the tooltip to re-appear.
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!tooltip_showing_) {
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (::IsWindow(tooltip_hwnd_))
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ::SendMessage(tooltip_hwnd_, TTM_POP, 0, 0);
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBackingStore* RenderWidgetHostViewWin::AllocBackingStore(
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const gfx::Size& size) {
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new BackingStoreWin(render_widget_host_, size);
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::SetBackground(const SkBitmap& background) {
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderWidgetHostView::SetBackground(background);
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Send(new ViewMsg_SetBackground(render_widget_host_->routing_id(),
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 background));
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool RenderWidgetHostViewWin::ContainsNativeView(
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::NativeView native_view) const {
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (m_hWnd == native_view)
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Traverse the set of parents of the given view to determine if native_view
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is a descendant of this window.
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HWND parent_window = ::GetParent(native_view);
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (parent_window) {
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (parent_window == m_hWnd)
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return true;
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    parent_window = ::GetParent(parent_window);
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
762201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid RenderWidgetHostViewWin::SetVisuallyDeemphasized(const SkColor* color,
763201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                                      bool animate) {
764201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // |animate| is not yet implemented, and currently isn't used.
765201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CHECK(!animate);
766201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
767201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SkColor overlay_color = color ? *color : 0;
768201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (overlay_color_ == overlay_color)
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
770201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  overlay_color_ = overlay_color;
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InvalidateRect(NULL, FALSE);
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// RenderWidgetHostViewWin, private:
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) {
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Call the WM_INPUTLANGCHANGE message handler to initialize the input locale
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // of a browser process.
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  OnInputLangChange(0, 0);
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Marks that window as supporting mouse-wheel messages rerouting so it is
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // scrolled when under the mouse pointer even if inactive.
784513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  props_.push_back(views::SetWindowSupportsRerouteMouseWheel(m_hWnd));
785201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  props_.push_back(new ViewProp(m_hWnd, kRenderWidgetHostViewKey,
786201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                static_cast<RenderWidgetHostView*>(this)));
787dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Save away our HWND in the parent window as a property so that the
788dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // accessibility code can find it.
789ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  accessibility_prop_.reset(new ViewProp(
790ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetParent(),
791ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      views::kViewsNativeHostPropForAccessibility,
792ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      m_hWnd));
793dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 0;
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnActivate(UINT action, BOOL minimized,
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         HWND window) {
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the container is a popup, clicking elsewhere on screen should close the
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // popup.
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (close_on_deactivate_ && action == WA_INACTIVE) {
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Send a windows message so that any derived classes
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // will get a change to override the default handling
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SendMessage(WM_CANCELMODE);
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnDestroy() {
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When a tab is closed all its child plugin windows are destroyed
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // automatically. This happens before plugins get any notification that its
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // instances are tearing down.
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Plugins like Quicktime assume that their windows will remain valid as long
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // as they have plugin instances active. Quicktime crashes in this case
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // because its windowing code cleans up an internal data structure that the
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // handler for NPP_DestroyStream relies on.
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The fix is to detach plugin windows from web contents when it is going
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // away. This will prevent the plugin windows from getting destroyed
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // automatically. The detached plugin windows will get cleaned up in proper
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // sequence as part of the usual cleanup when the plugin instance goes away.
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EnumChildWindows(m_hWnd, DetachPluginWindowsCallback, NULL);
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
824513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  props_.reset();
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
826201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CleanupCompositorWindow();
827201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetTooltip();
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TrackMouseLeave(false);
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnPaint(HDC unused_dc) {
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(render_widget_host_->process()->HasConnection());
834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
835731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // If the GPU process is rendering directly into the View,
836731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // call the compositor directly.
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderWidgetHost* render_widget_host = GetRenderWidgetHost();
838201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (render_widget_host->is_accelerated_compositing_active()) {
839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We initialize paint_dc here so that BeginPaint()/EndPaint()
840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // get called to validate the region.
841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CPaintDC paint_dc(m_hWnd);
842731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    render_widget_host_->ScheduleComposite();
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_to_validate_and_paint_ = true;
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BackingStoreWin* backing_store = static_cast<BackingStoreWin*>(
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      render_widget_host_->GetBackingStore(true));
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We initialize |paint_dc| (and thus call BeginPaint()) after calling
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // GetBackingStore(), so that if it updates the invalid rect we'll catch the
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // changes and repaint them.
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_to_validate_and_paint_ = false;
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Grab the region to paint before creation of paint_dc since it clears the
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // damage region.
85721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  base::win::ScopedGDIObject<HRGN> damage_region(CreateRectRgn(0, 0, 0, 0));
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetUpdateRgn(damage_region, FALSE);
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
860ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (hide_compositor_window_at_next_paint_) {
861ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ::ShowWindow(compositor_host_window_, SW_HIDE);
862ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    hide_compositor_window_at_next_paint_ = false;
863ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CPaintDC paint_dc(m_hWnd);
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint);
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (damaged_rect.IsEmpty())
869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (backing_store) {
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Rect bitmap_rect(gfx::Point(), backing_store->size());
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool manage_colors = BackingStoreWin::ColorManagementEnabled();
875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (manage_colors)
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SetICMMode(paint_dc.m_hDC, ICM_ON);
877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Blit only the damaged regions from the backing store.
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DWORD data_size = GetRegionData(damage_region, 0, NULL);
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_array<char> region_data_buf(new char[data_size]);
881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RGNDATA* region_data = reinterpret_cast<RGNDATA*>(region_data_buf.get());
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetRegionData(damage_region, data_size, region_data);
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RECT* region_rects = reinterpret_cast<RECT*>(region_data->Buffer);
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (DWORD i = 0; i < region_data->rdh.nCount; ++i) {
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::Rect paint_rect = bitmap_rect.Intersect(gfx::Rect(region_rects[i]));
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!paint_rect.IsEmpty()) {
888201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        if (SkColorGetA(overlay_color_) > 0) {
889201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          DrawDeemphasized(overlay_color_,
890201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                           paint_rect,
891201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                           backing_store->hdc(),
892201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                           paint_dc.m_hDC);
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        } else {
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          BitBlt(paint_dc.m_hDC,
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 paint_rect.x(),
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 paint_rect.y(),
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 paint_rect.width(),
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 paint_rect.height(),
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 backing_store->hdc(),
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 paint_rect.x(),
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 paint_rect.y(),
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 SRCCOPY);
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (manage_colors)
908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SetICMMode(paint_dc.m_hDC, ICM_OFF);
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Fill the remaining portion of the damaged_rect with the background
911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (damaged_rect.right() > bitmap_rect.right()) {
912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      RECT r;
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      r.left = std::max(bitmap_rect.right(), damaged_rect.x());
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      r.right = damaged_rect.right();
915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      r.top = damaged_rect.y();
916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      r.bottom = std::min(bitmap_rect.bottom(), damaged_rect.bottom());
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DrawBackground(r, &paint_dc);
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (damaged_rect.bottom() > bitmap_rect.bottom()) {
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      RECT r;
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      r.left = damaged_rect.x();
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      r.right = damaged_rect.right();
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      r.top = std::max(bitmap_rect.bottom(), damaged_rect.y());
924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      r.bottom = damaged_rect.bottom();
925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DrawBackground(r, &paint_dc);
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!whiteout_start_time_.is_null()) {
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TimeDelta whiteout_duration = TimeTicks::Now() - whiteout_start_time_;
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      UMA_HISTOGRAM_TIMES("MPArch.RWHH_WhiteoutDuration", whiteout_duration);
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Reset the start time to 0 so that we start recording again the next
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // time the backing store is NULL...
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      whiteout_start_time_ = TimeTicks();
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!tab_switch_paint_time_.is_null()) {
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TimeDelta tab_switch_paint_duration = TimeTicks::Now() -
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          tab_switch_paint_time_;
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration",
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          tab_switch_paint_duration);
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Reset tab_switch_paint_time_ to 0 so future tab selections are
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // recorded.
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_switch_paint_time_ = TimeTicks();
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DrawBackground(paint_dc.m_ps.rcPaint, &paint_dc);
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (whiteout_start_time_.is_null())
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      whiteout_start_time_ = TimeTicks::Now();
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::DrawBackground(const RECT& dirty_rect,
952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             CPaintDC* dc) {
953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!background_.empty()) {
954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::CanvasSkia canvas(dirty_rect.right - dirty_rect.left,
955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           dirty_rect.bottom - dirty_rect.top,
956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           true);  // opaque
957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    canvas.TranslateInt(-dirty_rect.left, -dirty_rect.top);
958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const RECT& dc_rect = dc->m_ps.rcPaint;
960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    canvas.TileImageInt(background_, 0, 0,
961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        dc_rect.right - dc_rect.left,
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        dc_rect.bottom - dc_rect.top);
963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    canvas.getTopPlatformDevice().drawToHDC(*dc, dirty_rect.left,
965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            dirty_rect.top, NULL);
966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HBRUSH white_brush = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    dc->FillRect(&dirty_rect, white_brush);
969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnNCPaint(HRGN update_region) {
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Do nothing.  This suppresses the resize corner that Windows would
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // otherwise draw for us.
975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
977c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnEraseBkgnd(HDC dc) {
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 1;
979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
981c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnSetCursor(HWND window, UINT hittest_code,
982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             UINT mouse_message_id) {
983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateCursorIfOverSelf();
984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 0;
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnSetFocus(HWND window) {
988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::FocusManager::GetWidgetFocusManager()->OnWidgetFocusEvent(window,
989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                                   m_hWnd);
990731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (browser_accessibility_manager_.get())
991731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    browser_accessibility_manager_->GotFocus();
992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (render_widget_host_)
993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->GotFocus();
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnKillFocus(HWND window) {
997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::FocusManager::GetWidgetFocusManager()->OnWidgetFocusEvent(m_hWnd,
998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                                   window);
999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (render_widget_host_)
1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->Blur();
1002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnCaptureChanged(HWND window) {
1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (render_widget_host_)
1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->LostCapture();
1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnCancelMode() {
1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (render_widget_host_)
1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->LostCapture();
1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (close_on_deactivate_ && shutdown_factory_.empty()) {
1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Dismiss popups and menus.  We do this asynchronously to avoid changing
1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // activation within this callstack, which may interfere with another window
1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // being activated.  We can synchronously hide the window, but we need to
1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // not change activation while doing so.
1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SetWindowPos(NULL, 0, 0, 0, 0,
1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE |
1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostTask(FROM_HERE,
1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        shutdown_factory_.NewRunnableMethod(
1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            &RenderWidgetHostViewWin::ShutdownHost));
1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnInputLangChange(DWORD character_set,
1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                HKL input_language_id) {
1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Send the given Locale ID to the ImeInput object and retrieves whether
1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // or not the current input context has IMEs.
1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the current input context has IMEs, a browser process has to send a
1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // request to a renderer process that it needs status messages about
1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the focused edit control from the renderer process.
1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // On the other hand, if the current input context does not have IMEs, the
1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // browser process also has to send a request to the renderer process that
1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // it does not need the status messages any longer.
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // To minimize the number of this notification request, we should check if
1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the browser process is actually retrieving the status messages (this
1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // state is stored in ime_notification_) and send a request only if the
1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // browser process has to update this status, its details are listed below:
1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // * If a browser process is not retrieving the status messages,
1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   (i.e. ime_notification_ == false),
1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   send this request only if the input context does have IMEs,
1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   (i.e. ime_status == true);
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   When it successfully sends the request, toggle its notification status,
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   (i.e.ime_notification_ = !ime_notification_ = true).
1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // * If a browser process is retrieving the status messages
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   (i.e. ime_notification_ == true),
1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   send this request only if the input context does not have IMEs,
1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   (i.e. ime_status == false).
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   When it successfully sends the request, toggle its notification status,
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   (i.e.ime_notification_ = !ime_notification_ = false).
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // To analyze the above actions, we can optimize them into the ones
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // listed below:
1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 1 Sending a request only if ime_status_ != ime_notification_, and;
1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 2 Copying ime_status to ime_notification_ if it sends the request
1057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   successfully (because Action 1 shows ime_status = !ime_notification_.)
1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ime_status = ime_input_.SetInputLanguage();
1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (ime_status != ime_notification_) {
1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (render_widget_host_) {
1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      render_widget_host_->SetInputMethodActive(ime_status);
1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ime_notification_ = ime_status;
1063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnThemeChanged() {
1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (render_widget_host_)
1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->SystemThemeChanged();
1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnNotify(int w_param, NMHDR* header) {
1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tooltip_hwnd_ == NULL)
1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return 0;
1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (header->code) {
1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case TTN_GETDISPINFO: {
1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NMTTDISPINFOW* tooltip_info = reinterpret_cast<NMTTDISPINFOW*>(header);
1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tooltip_info->szText[0] = L'\0';
1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tooltip_info->lpszText = const_cast<wchar_t*>(tooltip_text_.c_str());
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ::SendMessage(
1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        tooltip_hwnd_, TTM_SETMAXTIPWIDTH, 0, kTooltipMaxWidthPixels);
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SetMsgHandled(TRUE);
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          }
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case TTN_POP:
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tooltip_showing_ = false;
1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SetMsgHandled(TRUE);
1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case TTN_SHOW:
1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tooltip_showing_ = true;
1092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SetMsgHandled(TRUE);
1093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 0;
1096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1098c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnImeSetContext(
1099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
1100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!render_widget_host_)
1101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return 0;
1102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We need status messages about the focused input control from a
1104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // renderer process when:
1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   * the current input context has IMEs, and;
1106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //   * an application is activated.
1107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This seems to tell we should also check if the current input context has
1108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // IMEs before sending a request, however, this WM_IME_SETCONTEXT is
1109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // fortunately sent to an application only while the input context has IMEs.
1110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Therefore, we just start/stop status messages according to the activation
1111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // status of this application without checks.
1112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool activated = (wparam == TRUE);
1113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (render_widget_host_) {
1114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->SetInputMethodActive(activated);
1115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ime_notification_ = activated;
1116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (ime_notification_)
1119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ime_input_.CreateImeWindow(m_hWnd);
1120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ime_input_.CleanupComposition(m_hWnd);
1122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return ime_input_.SetImeWindowStyle(
1123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      m_hWnd, message, wparam, lparam, &handled);
1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnImeStartComposition(
1127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!render_widget_host_)
1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return 0;
1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset the composition status and create IME windows.
1132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ime_input_.CreateImeWindow(m_hWnd);
1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ime_input_.ResetComposition(m_hWnd);
1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We have to prevent WTL from calling ::DefWindowProc() because the function
1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // calls ::ImmSetCompositionWindow() and ::ImmSetCandidateWindow() to
1136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // over-write the position of IME windows.
1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handled = TRUE;
1138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 0;
1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnImeComposition(
1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
1143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!render_widget_host_)
1144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return 0;
1145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // At first, update the position of the IME window.
1147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ime_input_.UpdateImeWindow(m_hWnd);
1148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // ui::CompositionUnderline should be identical to
1150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // WebKit::WebCompositionUnderline, so that we can do reinterpret_cast safely.
1151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  COMPILE_ASSERT(sizeof(ui::CompositionUnderline) ==
1152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 sizeof(WebKit::WebCompositionUnderline),
1153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 ui_CompositionUnderline__WebKit_WebCompositionUnderline_diff);
1154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Retrieve the result string and its attributes of the ongoing composition
1156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and send it to a renderer process.
1157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ui::CompositionText composition;
1158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (ime_input_.GetResult(m_hWnd, lparam, &composition.text)) {
1159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    render_widget_host_->ImeConfirmComposition(composition.text);
1160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ime_input_.ResetComposition(m_hWnd);
1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Fall though and try reading the composition string.
1162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Japanese IMEs send a message containing both GCS_RESULTSTR and
1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // GCS_COMPSTR, which means an ongoing composition has been finished
1164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // by the start of another composition.
1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Retrieve the composition string and its attributes of the ongoing
1167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // composition and send it to a renderer process.
1168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (ime_input_.GetComposition(m_hWnd, lparam, &composition)) {
1169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // TODO(suzhe): due to a bug of webkit, we can't use selection range with
1170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // composition string. See: https://bugs.webkit.org/show_bug.cgi?id=37788
1171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    composition.selection = ui::Range(composition.selection.end());
1172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // TODO(suzhe): convert both renderer_host and renderer to use
1174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // ui::CompositionText.
1175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::vector<WebKit::WebCompositionUnderline>& underlines =
1176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        reinterpret_cast<const std::vector<WebKit::WebCompositionUnderline>&>(
1177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            composition.underlines);
1178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->ImeSetComposition(
1179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        composition.text, underlines,
1180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        composition.selection.start(), composition.selection.end());
1181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We have to prevent WTL from calling ::DefWindowProc() because we do not
1183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // want for the IMM (Input Method Manager) to send WM_IME_CHAR messages.
1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handled = TRUE;
1185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 0;
1186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1188c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnImeEndComposition(
1189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) {
1190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!render_widget_host_)
1191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return 0;
1192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (ime_input_.is_composing()) {
1194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // A composition has been ended while there is an ongoing composition,
1195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // i.e. the ongoing composition has been canceled.
1196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We need to reset the composition status both of the ImeInput object and
1197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // of the renderer process.
1198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->ImeCancelComposition();
1199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ime_input_.ResetComposition(m_hWnd);
1200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ime_input_.DestroyImeWindow(m_hWnd);
1202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let WTL call ::DefWindowProc() and release its resources.
1203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handled = FALSE;
1204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 0;
1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1207c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam,
1208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              LPARAM lparam, BOOL& handled) {
1209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handled = TRUE;
1210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (::IsWindow(tooltip_hwnd_)) {
1212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Forward mouse events through to the tooltip window
1213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MSG msg;
1214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    msg.hwnd = m_hWnd;
1215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    msg.message = message;
1216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    msg.wParam = wparam;
1217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    msg.lParam = lparam;
1218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SendMessage(tooltip_hwnd_, TTM_RELAYEVENT, NULL,
1219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                reinterpret_cast<LPARAM>(&msg));
1220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(jcampan): I am not sure if we should forward the message to the
1223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TabContents first in the case of popups.  If we do, we would need to
1224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // convert the click from the popup window coordinates to the TabContents'
1225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // window coordinates. For now we don't forward the message in that case to
1226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // address bug #907474.
1227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note: GetParent() on popup windows returns the top window and not the
1228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // parent the window was created with (the parent and the owner of the popup
1229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is the first non-child view of the view that was specified to the create
1230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // call).  So the TabContents window would have to be specified to the
1231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // RenderViewHostHWND as there is no way to retrieve it from the HWND.
1232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!close_on_deactivate_) {  // Don't forward if the container is a popup.
1233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (message) {
1234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case WM_LBUTTONDOWN:
1235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case WM_MBUTTONDOWN:
1236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case WM_RBUTTONDOWN:
1237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // Finish the ongoing composition whenever a mouse click happens.
1238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // It matches IE's behavior.
1239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ime_input_.CleanupComposition(m_hWnd);
1240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // Fall through.
1241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case WM_MOUSEMOVE:
1242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case WM_MOUSELEAVE: {
1243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // Give the TabContents first crack at the message. It may want to
1244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // prevent forwarding to the renderer if some higher level browser
1245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // functionality is invoked.
1246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        LPARAM parent_msg_lparam = lparam;
1247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (message != WM_MOUSELEAVE) {
1248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          // For the messages except WM_MOUSELEAVE, before forwarding them to
1249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          // parent window, we should adjust cursor position from client
1250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          // coordinates in current window to client coordinates in its parent
1251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          // window.
1252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          CPoint cursor_pos(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam));
1253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          ClientToScreen(&cursor_pos);
1254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          GetParent().ScreenToClient(&cursor_pos);
1255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          parent_msg_lparam = MAKELPARAM(cursor_pos.x, cursor_pos.y);
1256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
1257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (SendMessage(GetParent(), message, wparam, parent_msg_lparam) != 0)
1258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          return 1;
1259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
1260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ForwardMouseEventToRenderer(message, wparam, lparam);
1264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 0;
1265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1267c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnKeyEvent(UINT message, WPARAM wparam,
1268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            LPARAM lparam, BOOL& handled) {
1269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handled = TRUE;
1270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we are a pop-up, forward tab related messages to our parent HWND, so
1272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // that we are dismissed appropriately and so that the focus advance in our
1273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // parent.
1274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(jcampan): http://b/issue?id=1192881 Could be abstracted in the
1275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //                FocusManager.
1276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (close_on_deactivate_ &&
1277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      (((message == WM_KEYDOWN || message == WM_KEYUP) && (wparam == VK_TAB)) ||
1278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        (message == WM_CHAR && wparam == L'\t'))) {
1279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(parent_hwnd_);
1280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // First close the pop-up.
1281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SendMessage(WM_CANCELMODE);
1282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Then move the focus by forwarding the tab key to the parent.
1283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ::SendMessage(parent_hwnd_, message, wparam, lparam);
1284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!render_widget_host_)
1287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return 0;
1288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bug 1845: we need to update the text direction when a user releases
1290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // either a right-shift key or a right-control key after pressing both of
1291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // them. So, we just update the text direction while a user is pressing the
1292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // keys, and we notify the text direction when a user releases either of them.
1293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bug 9718: http://crbug.com/9718 To investigate IE and notepad, this
1294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // shortcut is enabled only on a PC having RTL keyboard layouts installed.
1295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We should emulate them.
1296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (ui::ImeInput::IsRTLKeyboardLayoutInstalled()) {
1297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (message == WM_KEYDOWN) {
1298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (wparam == VK_SHIFT) {
1299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        base::i18n::TextDirection dir;
1300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (ui::ImeInput::IsCtrlShiftPressed(&dir)) {
1301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          render_widget_host_->UpdateTextDirection(
1302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              dir == base::i18n::RIGHT_TO_LEFT ?
1303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              WebKit::WebTextDirectionRightToLeft :
1304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              WebKit::WebTextDirectionLeftToRight);
1305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
1306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else if (wparam != VK_CONTROL) {
1307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // Bug 9762: http://crbug.com/9762 A user pressed a key except shift
1308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // and control keys.
1309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // When a user presses a key while he/she holds control and shift keys,
1310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // we cancel sending an IPC message in NotifyTextDirection() below and
1311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // ignore succeeding UpdateTextDirection() calls while we call
1312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // NotifyTextDirection().
1313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // To cancel it, this call set a flag that prevents sending an IPC
1314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // message in NotifyTextDirection() only if we are going to send it.
1315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // It is harmless to call this function if we aren't going to send it.
1316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        render_widget_host_->CancelUpdateTextDirection();
1317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
1318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (message == WM_KEYUP &&
1319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               (wparam == VK_SHIFT || wparam == VK_CONTROL)) {
1320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We send an IPC message only if we need to update the text direction.
1321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      render_widget_host_->NotifyTextDirection();
1322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Special processing for enter key: When user hits enter in omnibox
1326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // we change focus to render host after the navigation, so repeat WM_KEYDOWNs
1327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and WM_KEYUP are going to render host, despite being initiated in other
1328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // window. This code filters out these messages.
1329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ignore_keyboard_event = false;
1330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (wparam == VK_RETURN) {
1331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN) {
1332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (KF_REPEAT & HIWORD(lparam)) {
1333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // this is a repeated key
1334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (!capture_enter_key_)
1335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          ignore_keyboard_event = true;
1336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
1337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        capture_enter_key_ = true;
1338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
1339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (message == WM_KEYUP || message == WM_SYSKEYUP) {
1340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!capture_enter_key_)
1341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ignore_keyboard_event = true;
1342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      capture_enter_key_ = false;
1343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
1344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Ignore all other keyboard events for the enter key if not captured.
1345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!capture_enter_key_)
1346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ignore_keyboard_event = true;
1347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (render_widget_host_ && !ignore_keyboard_event) {
1351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->ForwardKeyboardEvent(
1352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NativeWebKeyboardEvent(m_hWnd, message, wparam, lparam));
1353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 0;
1355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1357c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnWheelEvent(UINT message, WPARAM wparam,
1358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              LPARAM lparam, BOOL& handled) {
1359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Forward the mouse-wheel message to the window under the mouse if it belongs
1360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to us.
1361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (message == WM_MOUSEWHEEL &&
1362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      views::RerouteMouseWheel(m_hWnd, wparam, lparam)) {
1363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handled = TRUE;
1364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return 0;
1365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Workaround for Thinkpad mousewheel driver. We get mouse wheel/scroll
1368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // messages even if we are not in the foreground. So here we check if
1369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // we have any owned popup windows in the foreground and dismiss them.
1370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (m_hWnd != GetForegroundWindow()) {
1371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HWND toplevel_hwnd = ::GetAncestor(m_hWnd, GA_ROOT);
1372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EnumThreadWindows(
1373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        GetCurrentThreadId(),
1374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DismissOwnedPopups,
1375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        reinterpret_cast<LPARAM>(toplevel_hwnd));
1376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is a bit of a hack, but will work for now since we don't want to
1379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // pollute this object with TabContents-specific functionality...
1380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool handled_by_TabContents = false;
1381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (GetParent()) {
1382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Use a special reflected message to break recursion. If we send
1383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // WM_MOUSEWHEEL, the focus manager subclass of web contents will
1384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // route it back here.
1385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MSG new_message = {0};
1386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new_message.hwnd = m_hWnd;
1387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new_message.message = message;
1388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new_message.wParam = wparam;
1389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new_message.lParam = lparam;
1390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handled_by_TabContents =
1392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        !!::SendMessage(GetParent(), views::kReflectedMessage, 0,
1393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        reinterpret_cast<LPARAM>(&new_message));
1394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!handled_by_TabContents && render_widget_host_) {
1397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->ForwardWheelEvent(
1398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        WebInputEventFactory::mouseWheelEvent(m_hWnd, message, wparam,
1399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              lparam));
1400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handled = TRUE;
1402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return 0;
1403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14053345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickLRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT message,
14063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                 WPARAM wparam,
14073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                 LPARAM lparam,
1408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 BOOL& handled) {
1409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!IsActivatable())
1410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return MA_NOACTIVATE;
1411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HWND focus_window = GetFocus();
1413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!::IsWindow(focus_window) || !IsChild(focus_window)) {
1414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We handle WM_MOUSEACTIVATE to set focus to the underlying plugin
1415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // child window. This is to ensure that keyboard events are received
1416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // by the plugin. The correct way to fix this would be send over
1417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // an event to the renderer which would then eventually send over
1418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // a setFocus call to the plugin widget. This would ensure that
1419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the renderer (webkit) knows about the plugin widget receiving
1420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // focus.
1421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(iyengar) Do the right thing as per the above comment.
1422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    POINT cursor_pos = {0};
1423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ::GetCursorPos(&cursor_pos);
1424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ::ScreenToClient(m_hWnd, &cursor_pos);
1425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HWND child_window = ::RealChildWindowFromPoint(m_hWnd, cursor_pos);
14263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (::IsWindow(child_window) && child_window != m_hWnd) {
142772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (ui::GetClassName(child_window) ==
142821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              webkit::npapi::kWrapperNativeWindowClassName)
1429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        child_window = ::GetWindow(child_window, GW_CHILD);
1430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ::SetFocus(child_window);
1432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return MA_NOACTIVATE;
1433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handled = FALSE;
14363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  render_widget_host_->OnMouseActivate();
1437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return MA_ACTIVATE;
1438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid RenderWidgetHostViewWin::OnAccessibilityNotifications(
14413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) {
14423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!browser_accessibility_manager_.get()) {
14433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Use empty document to process notifications
14443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    webkit_glue::WebAccessibility empty_document;
14453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    empty_document.role = WebAccessibility::ROLE_DOCUMENT;
14463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    empty_document.state = 0;
14473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    browser_accessibility_manager_.reset(
1448731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserAccessibilityManager::Create(m_hWnd, empty_document, this));
1449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  browser_accessibility_manager_->OnAccessibilityNotifications(params);
1452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::Observe(NotificationType type,
1455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      const NotificationSource& source,
1456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      const NotificationDetails& details) {
1457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(type == NotificationType::RENDERER_PROCESS_TERMINATED);
1458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get the RenderProcessHost that posted this notification, and exit
1460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // if it's not the one associated with this host view.
1461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderProcessHost* render_process_host =
1462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Source<RenderProcessHost>(source).ptr();
1463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(render_process_host);
1464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!render_widget_host_ ||
1465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      render_process_host != render_widget_host_->process())
1466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If it was our RenderProcessHost that posted the notification,
1469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // clear the BrowserAccessibilityManager, because the renderer is
1470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // dead and any accessibility information we have is now stale.
1471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser_accessibility_manager_.reset(NULL);
1472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1474201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic void PaintCompositorHostWindow(HWND hWnd) {
1475201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  PAINTSTRUCT paint;
1476201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  BeginPaint(hWnd, &paint);
1477201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1478201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EndPaint(hWnd, &paint);
1479201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1480201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1481201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// WndProc for the compositor host window. We use this instead of Default so
1482201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// we can drop WM_PAINT and WM_ERASEBKGD messages on the floor.
1483201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic LRESULT CALLBACK CompositorHostWindowProc(HWND hWnd, UINT message,
1484201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                                 WPARAM wParam, LPARAM lParam) {
1485201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  switch (message) {
1486201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  case WM_ERASEBKGND:
1487201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return 0;
1488201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  case WM_DESTROY:
1489201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return 0;
1490201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  case WM_PAINT:
1491201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    PaintCompositorHostWindow(hWnd);
1492201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return 0;
1493201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  default:
1494201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return DefWindowProc(hWnd, message, wParam, lParam);
1495201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
1496201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1497201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1498201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Creates a HWND within the RenderWidgetHostView that will serve as a host
1499201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// for a HWND that the GPU process will create. The host window is used
1500201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// to Z-position the GPU's window relative to other plugin windows.
1501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsengfx::PluginWindowHandle RenderWidgetHostViewWin::GetCompositingSurface() {
1502201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // If the window has been created, don't recreate it a second time
1503201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (compositor_host_window_)
1504201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return compositor_host_window_;
1505201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1506201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  static ATOM window_class = 0;
1507201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!window_class) {
1508201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    WNDCLASSEX wcex;
1509201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.cbSize         = sizeof(WNDCLASSEX);
1510201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.style          = 0;
1511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    wcex.lpfnWndProc    =
1512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        base::win::WrappedWindowProc<CompositorHostWindowProc>;
1513201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.cbClsExtra     = 0;
1514201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.cbWndExtra     = 0;
1515201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.hInstance      = GetModuleHandle(NULL);
1516201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.hIcon          = 0;
1517201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.hCursor        = 0;
1518201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.hbrBackground  = NULL;
1519201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.lpszMenuName   = 0;
1520201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.lpszClassName  = L"CompositorHostWindowClass";
1521201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    wcex.hIconSm        = 0;
1522201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    window_class = RegisterClassEx(&wcex);
1523201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    DCHECK(window_class);
1524201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
1525201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1526201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  RECT currentRect;
1527201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  GetClientRect(&currentRect);
1528201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int width = currentRect.right - currentRect.left;
1529201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int height = currentRect.bottom - currentRect.top;
1530201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1531201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  compositor_host_window_ = CreateWindowEx(
1532201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
1533201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    MAKEINTATOM(window_class), 0,
1534201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED,
1535201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    0, 0, width, height, m_hWnd, 0, GetModuleHandle(NULL), 0);
1536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ui::CheckWindowCreated(compositor_host_window_);
1537201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1538201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return static_cast<gfx::PluginWindowHandle>(compositor_host_window_);
1539201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1540201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1541201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid RenderWidgetHostViewWin::ShowCompositorHostWindow(bool show) {
1542201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // When we first create the compositor, we will get a show request from
1543201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // the renderer before we have gotten the create request from the GPU. In this
1544201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // case, simply ignore the show request.
1545201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (compositor_host_window_ == NULL)
1546201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return;
1547201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1548201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (show) {
1549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ::ShowWindow(compositor_host_window_, SW_SHOW);
1550201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1551201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Get all the child windows of this view, including the compositor window.
1552201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    std::vector<HWND> all_child_windows;
1553201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    ::EnumChildWindows(m_hWnd, AddChildWindowToVector,
1554201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        reinterpret_cast<LPARAM>(&all_child_windows));
1555201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1556201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Build a list of just the plugin window handles
1557201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    std::vector<HWND> plugin_windows;
1558201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    bool compositor_host_window_found = false;
1559201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    for (size_t i = 0; i < all_child_windows.size(); ++i) {
1560201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      if (all_child_windows[i] != compositor_host_window_)
1561201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        plugin_windows.push_back(all_child_windows[i]);
1562201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      else
1563201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        compositor_host_window_found = true;
1564201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
1565201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    DCHECK(compositor_host_window_found);
1566201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1567201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Set all the plugin windows to be "after" the compositor window.
1568201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // When the compositor window is created, gets placed above plugins.
1569201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    for (size_t i = 0; i < plugin_windows.size(); ++i) {
1570201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      HWND next;
1571201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      if (i + 1 < plugin_windows.size())
1572201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        next = plugin_windows[i+1];
1573201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      else
1574201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        next = compositor_host_window_;
1575201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      ::SetWindowPos(plugin_windows[i], next, 0, 0, 0, 0,
1576201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
1577201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
1578201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  } else {
1579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    hide_compositor_window_at_next_paint_ = true;
1580201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
1581201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1582201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) {
1584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!browser_accessibility_manager_.get() ||
1585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !render_widget_host_ ||
1586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !render_widget_host_->process() ||
1587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !render_widget_host_->process()->HasConnection()) {
1588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  render_widget_host_->SetAccessibilityFocus(acc_obj_id);
1592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::AccessibilityDoDefaultAction(int acc_obj_id) {
1595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!browser_accessibility_manager_.get() ||
1596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !render_widget_host_ ||
1597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !render_widget_host_->process() ||
1598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !render_widget_host_->process()->HasConnection()) {
1599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  render_widget_host_->AccessibilityDoDefaultAction(acc_obj_id);
1603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1605c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLRESULT RenderWidgetHostViewWin::OnGetObject(UINT message, WPARAM wparam,
1606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             LPARAM lparam, BOOL& handled) {
1607731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (kIdCustom == lparam) {
1608731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // An MSAA client requestes our custom id. Assume that we have detected an
1609731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // active windows screen reader.
161021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BrowserAccessibilityState::GetInstance()->OnScreenReaderDetected();
1611731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    render_widget_host_->EnableRendererAccessibility();
1612731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1613731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Return with failure.
1614731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return static_cast<LRESULT>(0L);
1615731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1616731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (lparam != OBJID_CLIENT) {
1618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handled = false;
1619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return static_cast<LRESULT>(0L);
1620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1622731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (render_widget_host_ && !render_widget_host_->renderer_accessible()) {
1623731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Attempt to detect screen readers by sending an event with our custom id.
1624731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    NotifyWinEvent(EVENT_SYSTEM_ALERT, m_hWnd, kIdCustom, CHILDID_SELF);
1625731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1627731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!browser_accessibility_manager_.get()) {
16283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Return busy document tree while renderer accessibility tree loads.
16293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    webkit_glue::WebAccessibility loading_tree;
16303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    loading_tree.role = WebAccessibility::ROLE_DOCUMENT;
16313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    loading_tree.state = (1 << WebAccessibility::STATE_BUSY);
16323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    browser_accessibility_manager_.reset(
1633731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserAccessibilityManager::Create(m_hWnd, loading_tree, this));
16343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IAccessible> root(
1637731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      browser_accessibility_manager_->GetRoot()->toBrowserAccessibilityWin());
1638731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (root.get())
1639731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return LresultFromObject(IID_IAccessible, wparam, root.Detach());
1640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handled = false;
1642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return static_cast<LRESULT>(0L);
1643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1645dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenLRESULT RenderWidgetHostViewWin::OnParentNotify(UINT message, WPARAM wparam,
1646dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                LPARAM lparam, BOOL& handled) {
1647dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  handled = FALSE;
1648dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1649dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!render_widget_host_)
1650dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return 0;
1651dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1652dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  switch (LOWORD(wparam)) {
1653dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    case WM_LBUTTONDOWN:
1654dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    case WM_RBUTTONDOWN:
1655dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    case WM_MBUTTONDOWN:
1656dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      render_widget_host_->StartUserGesture();
1657dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      break;
1658dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    default:
1659dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      break;
1660dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1661dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return 0;
1662dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1663dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::OnFinalMessage(HWND window) {
1665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When the render widget host is being destroyed, it ends up calling
1666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // WillDestroyRenderWidget (through the RENDER_WIDGET_HOST_DESTROYED
1667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // notification) which NULLs render_widget_host_.
1668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note: the following bug http://crbug.com/24248 seems to report that
1669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // OnFinalMessage is called with a deleted |render_widget_host_|. It is not
1670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // clear how this could happen, hence the NULLing of render_widget_host_
1671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // above.
1672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!render_widget_host_ && !being_destroyed_) {
1673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If you hit this NOTREACHED, please add a comment to report it on
1674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // http://crbug.com/24248, including what you did when it happened and if
1675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // you can repro.
1676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
1677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (render_widget_host_)
1679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->ViewDestroyed();
1680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete this;
1681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::TrackMouseLeave(bool track) {
1684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (track == track_mouse_leave_)
1685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  track_mouse_leave_ = track;
1687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(m_hWnd);
1689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TRACKMOUSEEVENT tme;
1691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tme.cbSize = sizeof(TRACKMOUSEEVENT);
1692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tme.dwFlags = TME_LEAVE;
1693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!track_mouse_leave_)
1694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tme.dwFlags |= TME_CANCEL;
1695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tme.hwndTrack = m_hWnd;
1696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TrackMouseEvent(&tme);
1698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool RenderWidgetHostViewWin::Send(IPC::Message* message) {
1701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!render_widget_host_)
1702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return render_widget_host_->Send(message);
1704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::EnsureTooltip() {
1707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UINT message = TTM_NEWTOOLRECT;
1708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TOOLINFO ti;
1710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ti.cbSize = sizeof(ti);
1711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ti.hwnd = m_hWnd;
1712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ti.uId = 0;
1713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!::IsWindow(tooltip_hwnd_)) {
1714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message = TTM_ADDTOOL;
1715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tooltip_hwnd_ = CreateWindowEx(
1716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        WS_EX_TRANSPARENT | l10n_util::GetExtendedTooltipStyles(),
1717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        TOOLTIPS_CLASS, NULL, TTS_NOPREFIX, 0, 0, 0, 0, m_hWnd, NULL,
1718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NULL, NULL);
1719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ui::CheckWindowCreated(tooltip_hwnd_);
1720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ti.uFlags = TTF_TRANSPARENT;
1721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ti.lpszText = LPSTR_TEXTCALLBACK;
1722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CRect cr;
1725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetClientRect(&ti.rect);
1726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SendMessage(tooltip_hwnd_, message, NULL, reinterpret_cast<LPARAM>(&ti));
1727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::ResetTooltip() {
1730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (::IsWindow(tooltip_hwnd_))
1731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ::DestroyWindow(tooltip_hwnd_);
1732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tooltip_hwnd_ = NULL;
1733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message,
1736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                          WPARAM wparam,
1737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                          LPARAM lparam) {
1738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!render_widget_host_)
1739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebMouseEvent event(
1742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WebInputEventFactory::mouseEvent(m_hWnd, message, wparam, lparam));
1743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Send the event to the renderer before changing mouse capture, so that the
1745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // capturelost event arrives after mouseup.
1746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  render_widget_host_->ForwardMouseEvent(event);
1747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (event.type) {
1749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case WebInputEvent::MouseMove:
1750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TrackMouseLeave(true);
1751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case WebInputEvent::MouseLeave:
1753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TrackMouseLeave(false);
1754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case WebInputEvent::MouseDown:
1756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SetCapture();
1757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case WebInputEvent::MouseUp:
1759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (GetCapture() == m_hWnd)
1760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ReleaseCapture();
1761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (IsActivatable() && event.type == WebInputEvent::MouseDown) {
1765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This is a temporary workaround for bug 765011 to get focus when the
1766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // mouse is clicked. This happens after the mouse down event is sent to
1767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the renderer because normally Windows does a WM_SETFOCUS after
1768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // WM_LBUTTONDOWN.
1769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SetFocus();
1770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RenderWidgetHostViewWin::ShutdownHost() {
1774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  shutdown_factory_.RevokeAll();
1775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (render_widget_host_)
1776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    render_widget_host_->Shutdown();
1777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Do not touch any members at this point, |this| has been deleted.
1778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
1781c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderWidgetHostView*
1782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView(
1783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        gfx::NativeView native_view) {
1784201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return ::IsWindow(native_view) ?
1785201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      reinterpret_cast<RenderWidgetHostView*>(
1786201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          ViewProp::GetValue(native_view, kRenderWidgetHostViewKey)) : NULL;
1787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1788