- add sources.
[platform/framework/web/crosswalk.git] / src / ui / views / widget / native_widget_win.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/views/widget/native_widget_win.h"
6
7 #include <dwmapi.h>
8 #include <shellapi.h>
9
10 #include <algorithm>
11
12 #include "base/bind.h"
13 #include "base/strings/string_util.h"
14 #include "base/win/scoped_gdi_object.h"
15 #include "base/win/win_util.h"
16 #include "base/win/windows_version.h"
17 #include "ui/base/dragdrop/drag_drop_types.h"
18 #include "ui/base/dragdrop/drag_source_win.h"
19 #include "ui/base/dragdrop/os_exchange_data.h"
20 #include "ui/base/dragdrop/os_exchange_data_provider_win.h"
21 #include "ui/base/ime/input_method_factory.h"
22 #include "ui/base/l10n/l10n_util_win.h"
23 #include "ui/base/theme_provider.h"
24 #include "ui/base/view_prop.h"
25 #include "ui/base/win/mouse_wheel_util.h"
26 #include "ui/base/win/shell.h"
27 #include "ui/events/event.h"
28 #include "ui/events/keycodes/keyboard_code_conversion_win.h"
29 #include "ui/gfx/canvas.h"
30 #include "ui/gfx/canvas_skia_paint.h"
31 #include "ui/gfx/path.h"
32 #include "ui/gfx/point_conversions.h"
33 #include "ui/gfx/screen.h"
34 #include "ui/gfx/size_conversions.h"
35 #include "ui/gfx/win/dpi.h"
36 #include "ui/gfx/win/hwnd_util.h"
37 #include "ui/native_theme/native_theme.h"
38 #include "ui/views/controls/native_control_win.h"
39 #include "ui/views/controls/textfield/textfield.h"
40 #include "ui/views/drag_utils.h"
41 #include "ui/views/focus/accelerator_handler.h"
42 #include "ui/views/focus/view_storage.h"
43 #include "ui/views/focus/widget_focus_manager.h"
44 #include "ui/views/ime/input_method_bridge.h"
45 #include "ui/views/widget/aero_tooltip_manager.h"
46 #include "ui/views/widget/drop_target_win.h"
47 #include "ui/views/widget/monitor_win.h"
48 #include "ui/views/widget/native_widget_delegate.h"
49 #include "ui/views/widget/root_view.h"
50 #include "ui/views/widget/widget_delegate.h"
51 #include "ui/views/widget/widget_hwnd_utils.h"
52 #include "ui/views/win/fullscreen_handler.h"
53 #include "ui/views/win/hwnd_message_handler.h"
54 #include "ui/views/window/native_frame_view.h"
55
56 #pragma comment(lib, "dwmapi.lib")
57
58 using ui::ViewProp;
59
60 namespace views {
61
62 namespace {
63
64 // Enumeration callback for NativeWidget::GetAllChildWidgets() and
65 // NativeWidget::GetAllOwnedWidgets. Adds any HWNDs that correspond to
66 // Widgets to a set.
67 BOOL CALLBACK EnumerateNativeWidgets(HWND hwnd, LPARAM l_param) {
68   Widget* widget = Widget::GetWidgetForNativeView(hwnd);
69   if (widget) {
70     Widget::Widgets* widgets = reinterpret_cast<Widget::Widgets*>(l_param);
71     widgets->insert(widget);
72   }
73   return TRUE;
74 }
75
76 // Links the HWND to its NativeWidget.
77 const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
78
79 const int kDragFrameWindowAlpha = 200;
80
81 }  // namespace
82
83 ////////////////////////////////////////////////////////////////////////////////
84 // NativeWidgetWin, public:
85
86 NativeWidgetWin::NativeWidgetWin(internal::NativeWidgetDelegate* delegate)
87     : delegate_(delegate),
88       ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
89       drag_frame_saved_window_style_(0),
90       drag_frame_saved_window_ex_style_(0),
91       has_non_client_view_(false),
92       message_handler_(new HWNDMessageHandler(this)) {
93 }
94
95 NativeWidgetWin::~NativeWidgetWin() {
96   if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
97     delete delegate_;
98   else
99     CloseNow();
100   message_handler_.reset();
101 }
102
103 // static
104 gfx::Font NativeWidgetWin::GetWindowTitleFont() {
105   NONCLIENTMETRICS ncm;
106   base::win::GetNonClientMetrics(&ncm);
107   l10n_util::AdjustUIFont(&(ncm.lfCaptionFont));
108   base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont)));
109   return gfx::Font(caption_font);
110 }
111
112 void NativeWidgetWin::Show(int show_state) {
113   message_handler_->Show(show_state);
114 }
115
116 ////////////////////////////////////////////////////////////////////////////////
117 // NativeWidgetWin, NativeWidget implementation:
118
119 void NativeWidgetWin::InitNativeWidget(const Widget::InitParams& params) {
120   gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(params.bounds);
121   Widget::InitParams params_in_pixel(params);
122   params_in_pixel.bounds = pixel_bounds;
123   SetInitParams(params_in_pixel);
124   message_handler_->Init(params.parent, pixel_bounds);
125 }
126
127 NonClientFrameView* NativeWidgetWin::CreateNonClientFrameView() {
128   return GetWidget()->ShouldUseNativeFrame() ?
129       new NativeFrameView(GetWidget()) : NULL;
130 }
131
132 bool NativeWidgetWin::ShouldUseNativeFrame() const {
133   return ui::win::IsAeroGlassEnabled();
134 }
135
136 void NativeWidgetWin::FrameTypeChanged() {
137   message_handler_->FrameTypeChanged();
138 }
139
140 Widget* NativeWidgetWin::GetWidget() {
141   return delegate_->AsWidget();
142 }
143
144 const Widget* NativeWidgetWin::GetWidget() const {
145   return delegate_->AsWidget();
146 }
147
148 gfx::NativeView NativeWidgetWin::GetNativeView() const {
149   return message_handler_->hwnd();
150 }
151
152 gfx::NativeWindow NativeWidgetWin::GetNativeWindow() const {
153   return message_handler_->hwnd();
154 }
155
156 Widget* NativeWidgetWin::GetTopLevelWidget() {
157   NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView());
158   return native_widget ? native_widget->GetWidget() : NULL;
159 }
160
161 const ui::Compositor* NativeWidgetWin::GetCompositor() const {
162   return NULL;
163 }
164
165 ui::Compositor* NativeWidgetWin::GetCompositor() {
166   return NULL;
167 }
168
169 ui::Layer* NativeWidgetWin::GetLayer() {
170   return NULL;
171 }
172
173 void NativeWidgetWin::ReorderNativeViews() {
174 }
175
176 void NativeWidgetWin::ViewRemoved(View* view) {
177   if (drop_target_.get())
178     drop_target_->ResetTargetViewIfEquals(view);
179 }
180
181 void NativeWidgetWin::SetNativeWindowProperty(const char* name, void* value) {
182   // Remove the existing property (if any).
183   for (ViewProps::iterator i = props_.begin(); i != props_.end(); ++i) {
184     if ((*i)->Key() == name) {
185       props_.erase(i);
186       break;
187     }
188   }
189
190   if (value)
191     props_.push_back(new ViewProp(GetNativeView(), name, value));
192 }
193
194 void* NativeWidgetWin::GetNativeWindowProperty(const char* name) const {
195   return ViewProp::GetValue(GetNativeView(), name);
196 }
197
198 TooltipManager* NativeWidgetWin::GetTooltipManager() const {
199   return tooltip_manager_.get();
200 }
201
202 void NativeWidgetWin::SetCapture() {
203   message_handler_->SetCapture();
204 }
205
206 void NativeWidgetWin::ReleaseCapture() {
207   message_handler_->ReleaseCapture();
208 }
209
210 bool NativeWidgetWin::HasCapture() const {
211   return message_handler_->HasCapture();
212 }
213
214 InputMethod* NativeWidgetWin::CreateInputMethod() {
215   return new InputMethodBridge(GetMessageHandler(), ui::GetSharedInputMethod(),
216                                true);
217 }
218
219 internal::InputMethodDelegate* NativeWidgetWin::GetInputMethodDelegate() {
220   return message_handler_.get();
221 }
222
223 void NativeWidgetWin::CenterWindow(const gfx::Size& size) {
224   gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
225   message_handler_->CenterWindow(size_in_pixels);
226 }
227
228 void NativeWidgetWin::GetWindowPlacement(
229     gfx::Rect* bounds,
230     ui::WindowShowState* show_state) const {
231   message_handler_->GetWindowPlacement(bounds, show_state);
232   *bounds = gfx::win::ScreenToDIPRect(*bounds);
233 }
234
235 void NativeWidgetWin::SetWindowTitle(const string16& title) {
236   message_handler_->SetTitle(title);
237 }
238
239 void NativeWidgetWin::SetWindowIcons(const gfx::ImageSkia& window_icon,
240                                      const gfx::ImageSkia& app_icon) {
241   message_handler_->SetWindowIcons(window_icon, app_icon);
242 }
243
244 void NativeWidgetWin::InitModalType(ui::ModalType modal_type) {
245   message_handler_->InitModalType(modal_type);
246 }
247
248 gfx::Rect NativeWidgetWin::GetWindowBoundsInScreen() const {
249   gfx::Rect bounds_in_pixels = message_handler_->GetWindowBoundsInScreen();
250   return gfx::win::ScreenToDIPRect(bounds_in_pixels);
251 }
252
253 gfx::Rect NativeWidgetWin::GetClientAreaBoundsInScreen() const {
254   gfx::Rect bounds_in_pixels = message_handler_->GetClientAreaBoundsInScreen();
255   return gfx::win::ScreenToDIPRect(bounds_in_pixels);
256 }
257
258 gfx::Rect NativeWidgetWin::GetRestoredBounds() const {
259   gfx::Rect bounds_in_pixels = message_handler_->GetRestoredBounds();
260   return gfx::win::ScreenToDIPRect(bounds_in_pixels);
261 }
262
263 void NativeWidgetWin::SetBounds(const gfx::Rect& bounds) {
264   float scale = gfx::win::GetDeviceScaleFactor();
265   gfx::Rect bounds_in_pixels(
266       gfx::ToCeiledPoint(gfx::ScalePoint(bounds.origin(), scale)),
267       gfx::ToFlooredSize(gfx::ScaleSize(bounds.size(), scale)));
268   message_handler_->SetBounds(bounds_in_pixels);
269 }
270
271 void NativeWidgetWin::SetSize(const gfx::Size& size) {
272   message_handler_->SetSize(size);
273 }
274
275 void NativeWidgetWin::StackAbove(gfx::NativeView native_view) {
276   message_handler_->StackAbove(native_view);
277 }
278
279 void NativeWidgetWin::StackAtTop() {
280   message_handler_->StackAtTop();
281 }
282
283 void NativeWidgetWin::StackBelow(gfx::NativeView native_view) {
284   NOTIMPLEMENTED();
285 }
286
287 void NativeWidgetWin::SetShape(gfx::NativeRegion region) {
288   message_handler_->SetRegion(region);
289 }
290
291 void NativeWidgetWin::Close() {
292   message_handler_->Close();
293 }
294
295 void NativeWidgetWin::CloseNow() {
296   message_handler_->CloseNow();
297 }
298
299 void NativeWidgetWin::Show() {
300   message_handler_->Show();
301 }
302
303 void NativeWidgetWin::Hide() {
304   message_handler_->Hide();
305 }
306
307 void NativeWidgetWin::ShowMaximizedWithBounds(
308     const gfx::Rect& restored_bounds) {
309   gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(restored_bounds);
310   message_handler_->ShowMaximizedWithBounds(pixel_bounds);
311 }
312
313 void NativeWidgetWin::ShowWithWindowState(ui::WindowShowState show_state) {
314   message_handler_->ShowWindowWithState(show_state);
315 }
316
317 bool NativeWidgetWin::IsVisible() const {
318   return message_handler_->IsVisible();
319 }
320
321 void NativeWidgetWin::Activate() {
322   message_handler_->Activate();
323 }
324
325 void NativeWidgetWin::Deactivate() {
326   message_handler_->Deactivate();
327 }
328
329 bool NativeWidgetWin::IsActive() const {
330   return message_handler_->IsActive();
331 }
332
333 void NativeWidgetWin::SetAlwaysOnTop(bool on_top) {
334   message_handler_->SetAlwaysOnTop(on_top);
335 }
336
337 bool NativeWidgetWin::IsAlwaysOnTop() const {
338   return message_handler_->IsAlwaysOnTop();
339 }
340
341 void NativeWidgetWin::Maximize() {
342   message_handler_->Maximize();
343 }
344
345 void NativeWidgetWin::Minimize() {
346   message_handler_->Minimize();
347 }
348
349 bool NativeWidgetWin::IsMaximized() const {
350   return message_handler_->IsMaximized();
351 }
352
353 bool NativeWidgetWin::IsMinimized() const {
354   return message_handler_->IsMinimized();
355 }
356
357 void NativeWidgetWin::Restore() {
358   message_handler_->Restore();
359 }
360
361 void NativeWidgetWin::SetFullscreen(bool fullscreen) {
362   message_handler_->fullscreen_handler()->SetFullscreen(fullscreen);
363 }
364
365 void NativeWidgetWin::SetMetroSnapFullscreen(bool metro_snap) {
366   message_handler_->fullscreen_handler()->SetMetroSnap(metro_snap);
367 }
368
369 bool NativeWidgetWin::IsFullscreen() const {
370   return message_handler_->fullscreen_handler()->fullscreen();
371 }
372
373 bool NativeWidgetWin::IsInMetroSnapMode() const {
374   return message_handler_->fullscreen_handler()->metro_snap();
375 }
376
377 void NativeWidgetWin::SetCanUpdateLayeredWindow(bool can_update) {
378   message_handler_->set_can_update_layered_window(can_update);
379 }
380
381 void NativeWidgetWin::SetOpacity(unsigned char opacity) {
382   message_handler_->SetOpacity(static_cast<BYTE>(opacity));
383   GetWidget()->GetRootView()->SchedulePaint();
384 }
385
386 void NativeWidgetWin::SetUseDragFrame(bool use_drag_frame) {
387   if (use_drag_frame) {
388     // Make the frame slightly transparent during the drag operation.
389     drag_frame_saved_window_style_ = GetWindowLong(GetNativeView(), GWL_STYLE);
390     drag_frame_saved_window_ex_style_ =
391         GetWindowLong(GetNativeView(), GWL_EXSTYLE);
392     SetWindowLong(GetNativeView(), GWL_EXSTYLE,
393                   drag_frame_saved_window_ex_style_ | WS_EX_LAYERED);
394     // Remove the captions tyle so the window doesn't have window controls for a
395     // more "transparent" look.
396     SetWindowLong(GetNativeView(), GWL_STYLE,
397                   drag_frame_saved_window_style_ & ~WS_CAPTION);
398     SetLayeredWindowAttributes(GetNativeView(), RGB(0xFF, 0xFF, 0xFF),
399                                kDragFrameWindowAlpha, LWA_ALPHA);
400   } else {
401     SetWindowLong(GetNativeView(), GWL_STYLE, drag_frame_saved_window_style_);
402     SetWindowLong(GetNativeView(), GWL_EXSTYLE,
403                   drag_frame_saved_window_ex_style_);
404   }
405 }
406
407 void NativeWidgetWin::FlashFrame(bool flash) {
408   message_handler_->FlashFrame(flash);
409 }
410
411 void NativeWidgetWin::RunShellDrag(View* view,
412                                    const ui::OSExchangeData& data,
413                                    const gfx::Point& location,
414                                    int operation,
415                                    ui::DragDropTypes::DragEventSource source) {
416   views::RunShellDrag(NULL, data, location, operation, source);
417 }
418
419 void NativeWidgetWin::SchedulePaintInRect(const gfx::Rect& rect) {
420   gfx::Rect pixel_rect = gfx::win::DIPToScreenRect(rect);
421   message_handler_->SchedulePaintInRect(pixel_rect);
422 }
423
424 void NativeWidgetWin::SetCursor(gfx::NativeCursor cursor) {
425   message_handler_->SetCursor(cursor);
426 }
427
428 bool NativeWidgetWin::IsMouseEventsEnabled() const {
429   return true;
430 }
431
432 void NativeWidgetWin::ClearNativeFocus() {
433   message_handler_->ClearNativeFocus();
434 }
435
436 gfx::Rect NativeWidgetWin::GetWorkAreaBoundsInScreen() const {
437   return gfx::win::ScreenToDIPRect(
438       gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
439       GetNativeView()).work_area());
440 }
441
442 Widget::MoveLoopResult NativeWidgetWin::RunMoveLoop(
443     const gfx::Vector2d& drag_offset,
444     Widget::MoveLoopSource source,
445     Widget::MoveLoopEscapeBehavior escape_behavior) {
446   const bool hide_on_escape =
447       escape_behavior == Widget::MOVE_LOOP_ESCAPE_BEHAVIOR_HIDE;
448   return message_handler_->RunMoveLoop(drag_offset, hide_on_escape) ?
449       Widget::MOVE_LOOP_SUCCESSFUL : Widget::MOVE_LOOP_CANCELED;
450 }
451
452 void NativeWidgetWin::EndMoveLoop() {
453   message_handler_->EndMoveLoop();
454 }
455
456 void NativeWidgetWin::SetVisibilityChangedAnimationsEnabled(bool value) {
457   message_handler_->SetVisibilityChangedAnimationsEnabled(value);
458 }
459
460 ui::NativeTheme* NativeWidgetWin::GetNativeTheme() const {
461   return ui::NativeTheme::instance();
462 }
463
464 void NativeWidgetWin::OnRootViewLayout() const {
465 }
466
467 ////////////////////////////////////////////////////////////////////////////////
468 // NativeWidgetWin, NativeWidget implementation:
469
470 ui::EventHandler* NativeWidgetWin::GetEventHandler() {
471   NOTIMPLEMENTED();
472   return NULL;
473 }
474
475 ////////////////////////////////////////////////////////////////////////////////
476 // NativeWidgetWin, protected:
477
478 void NativeWidgetWin::OnFinalMessage(HWND window) {
479   // We don't destroy props in WM_DESTROY as we may still get messages after
480   // WM_DESTROY that assume the properties are still valid (such as WM_CLOSE).
481   props_.clear();
482   delegate_->OnNativeWidgetDestroyed();
483   if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
484     delete this;
485 }
486
487 ////////////////////////////////////////////////////////////////////////////////
488 // NativeWidgetWin, protected:
489
490 HWNDMessageHandler* NativeWidgetWin::GetMessageHandler() {
491   return message_handler_.get();
492 }
493
494 ////////////////////////////////////////////////////////////////////////////////
495 // NativeWidgetWin, HWNDMessageHandlerDelegate implementation:
496
497 bool NativeWidgetWin::IsWidgetWindow() const {
498   // We don't NULL check GetWidget()->non_client_view() here because this
499   // function can be called before the widget is fully constructed.
500   return has_non_client_view_;
501 }
502
503 bool NativeWidgetWin::IsUsingCustomFrame() const {
504   return !GetWidget()->ShouldUseNativeFrame();
505 }
506
507 void NativeWidgetWin::SchedulePaint() {
508   GetWidget()->GetRootView()->SchedulePaint();
509 }
510
511 void NativeWidgetWin::EnableInactiveRendering() {
512   delegate_->EnableInactiveRendering();
513 }
514
515 bool NativeWidgetWin::IsInactiveRenderingDisabled() {
516   return delegate_->IsInactiveRenderingDisabled();
517 }
518
519 bool NativeWidgetWin::CanResize() const {
520   return GetWidget()->widget_delegate()->CanResize();
521 }
522
523 bool NativeWidgetWin::CanMaximize() const {
524   return GetWidget()->widget_delegate()->CanMaximize();
525 }
526
527 bool NativeWidgetWin::CanActivate() const {
528   return delegate_->CanActivate();
529 }
530
531 bool NativeWidgetWin::WidgetSizeIsClientSize() const {
532   const Widget* widget = GetWidget()->GetTopLevelWidget();
533   return IsZoomed(GetNativeView()) ||
534          (widget && widget->ShouldUseNativeFrame());
535 }
536
537 bool NativeWidgetWin::CanSaveFocus() const {
538   return GetWidget()->is_top_level();
539 }
540
541 void NativeWidgetWin::SaveFocusOnDeactivate() {
542   GetWidget()->GetFocusManager()->StoreFocusedView(true);
543 }
544
545 void NativeWidgetWin::RestoreFocusOnActivate() {
546   // Mysteriously, this only appears to be needed support restoration of focus
547   // to a child hwnd when restoring its top level window from the minimized
548   // state. If we don't do this, then ::SetFocus() to that child HWND returns
549   // ERROR_INVALID_PARAMETER, despite both HWNDs being of the same thread.
550   // See http://crbug.com/125976 and
551   // chrome/browser/ui/views/native_widget_win_interactive_uitest.cc .
552   {
553     // Since this is a synthetic reset, we don't need to tell anyone about it.
554     AutoNativeNotificationDisabler disabler;
555     GetWidget()->GetFocusManager()->ClearFocus();
556   }
557   RestoreFocusOnEnable();
558 }
559
560 void NativeWidgetWin::RestoreFocusOnEnable() {
561   GetWidget()->GetFocusManager()->RestoreFocusedView();
562 }
563
564 bool NativeWidgetWin::IsModal() const {
565   return delegate_->IsModal();
566 }
567
568 int NativeWidgetWin::GetInitialShowState() const {
569   return SW_SHOWNORMAL;
570 }
571
572 bool NativeWidgetWin::WillProcessWorkAreaChange() const {
573   return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
574 }
575
576 int NativeWidgetWin::GetNonClientComponent(const gfx::Point& point) const {
577   gfx::Point point_in_dip = gfx::win::ScreenToDIPPoint(point);
578   return delegate_->GetNonClientComponent(point_in_dip);
579 }
580
581 void NativeWidgetWin::GetWindowMask(const gfx::Size& size, gfx::Path* path) {
582   if (GetWidget()->non_client_view())
583     GetWidget()->non_client_view()->GetWindowMask(size, path);
584 }
585
586 bool NativeWidgetWin::GetClientAreaInsets(gfx::Insets* insets) const {
587   return false;
588 }
589
590 void NativeWidgetWin::GetMinMaxSize(gfx::Size* min_size,
591                                     gfx::Size* max_size) const {
592   *min_size = gfx::win::ScreenToDIPSize(delegate_->GetMinimumSize());
593   *max_size = gfx::win::ScreenToDIPSize(delegate_->GetMaximumSize());
594 }
595
596 gfx::Size NativeWidgetWin::GetRootViewSize() const {
597   gfx::Size pixel_size = GetWidget()->GetRootView()->size();
598   return gfx::win::ScreenToDIPSize(pixel_size);
599 }
600
601 void NativeWidgetWin::ResetWindowControls() {
602   GetWidget()->non_client_view()->ResetWindowControls();
603 }
604
605 void NativeWidgetWin::PaintLayeredWindow(gfx::Canvas* canvas) {
606   GetWidget()->GetRootView()->Paint(canvas);
607 }
608
609 InputMethod* NativeWidgetWin::GetInputMethod() {
610   return GetWidget()->GetInputMethodDirect();
611 }
612
613 gfx::NativeViewAccessible NativeWidgetWin::GetNativeViewAccessible() {
614   return GetWidget()->GetRootView()->GetNativeViewAccessible();
615 }
616
617 bool NativeWidgetWin::ShouldHandleSystemCommands() const {
618   return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
619 }
620
621 void NativeWidgetWin::HandleAppDeactivated() {
622   if (IsInactiveRenderingDisabled()) {
623     delegate_->EnableInactiveRendering();
624   } else {
625     // TODO(pkotwicz): Remove need for SchedulePaint(). crbug.com/165841
626     View* non_client_view = GetWidget()->non_client_view();
627     if (non_client_view)
628       non_client_view->SchedulePaint();
629   }
630 }
631
632 void NativeWidgetWin::HandleActivationChanged(bool active) {
633   delegate_->OnNativeWidgetActivationChanged(active);
634 }
635
636 bool NativeWidgetWin::HandleAppCommand(short command) {
637   // We treat APPCOMMAND ids as an extension of our command namespace, and just
638   // let the delegate figure out what to do...
639   return GetWidget()->widget_delegate() &&
640       GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
641 }
642
643 void NativeWidgetWin::HandleCancelMode() {
644 }
645
646 void NativeWidgetWin::HandleCaptureLost() {
647   delegate_->OnMouseCaptureLost();
648 }
649
650 void NativeWidgetWin::HandleClose() {
651   GetWidget()->Close();
652 }
653
654 bool NativeWidgetWin::HandleCommand(int command) {
655   return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
656 }
657
658 void NativeWidgetWin::HandleAccelerator(const ui::Accelerator& accelerator) {
659   GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
660 }
661
662 void NativeWidgetWin::HandleCreate() {
663   // TODO(beng): much of this could/should maybe move to HWNDMessageHandler.
664
665   SetNativeWindowProperty(kNativeWidgetKey, this);
666   CHECK_EQ(this, GetNativeWidgetForNativeView(GetNativeView()));
667
668   props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(GetNativeView()));
669
670   drop_target_ = new DropTargetWin(
671       static_cast<internal::RootView*>(GetWidget()->GetRootView()));
672
673   // Windows special DWM window frame requires a special tooltip manager so
674   // that window controls in Chrome windows don't flicker when you move your
675   // mouse over them. See comment in aero_tooltip_manager.h.
676   Widget* widget = GetWidget()->GetTopLevelWidget();
677   if (widget && widget->ShouldUseNativeFrame()) {
678     tooltip_manager_.reset(new AeroTooltipManager(GetWidget()));
679   } else {
680     tooltip_manager_.reset(new TooltipManagerWin(GetWidget()));
681   }
682   if (!tooltip_manager_->Init()) {
683     // There was a problem creating the TooltipManager. Common error is 127.
684     // See 82193 for details.
685     LOG_GETLASTERROR(WARNING) << "tooltip creation failed, disabling tooltips";
686     tooltip_manager_.reset();
687   }
688
689   delegate_->OnNativeWidgetCreated(true);
690 }
691
692 void NativeWidgetWin::HandleDestroying() {
693   delegate_->OnNativeWidgetDestroying();
694   if (drop_target_.get()) {
695     RevokeDragDrop(GetNativeView());
696     drop_target_ = NULL;
697   }
698 }
699
700 void NativeWidgetWin::HandleDestroyed() {
701   OnFinalMessage(GetNativeView());
702 }
703
704 bool NativeWidgetWin::HandleInitialFocus() {
705   return GetWidget()->SetInitialFocus();
706 }
707
708 void NativeWidgetWin::HandleDisplayChange() {
709   GetWidget()->widget_delegate()->OnDisplayChanged();
710 }
711
712 void NativeWidgetWin::HandleBeginWMSizeMove() {
713   delegate_->OnNativeWidgetBeginUserBoundsChange();
714 }
715
716 void NativeWidgetWin::HandleEndWMSizeMove() {
717   delegate_->OnNativeWidgetEndUserBoundsChange();
718 }
719
720 void NativeWidgetWin::HandleMove() {
721   delegate_->OnNativeWidgetMove();
722 }
723
724 void NativeWidgetWin::HandleWorkAreaChanged() {
725   GetWidget()->widget_delegate()->OnWorkAreaChanged();
726 }
727
728 void NativeWidgetWin::HandleVisibilityChanging(bool visible) {
729   delegate_->OnNativeWidgetVisibilityChanging(visible);
730 }
731
732 void NativeWidgetWin::HandleVisibilityChanged(bool visible) {
733   delegate_->OnNativeWidgetVisibilityChanged(visible);
734 }
735
736 void NativeWidgetWin::HandleClientSizeChanged(const gfx::Size& new_size) {
737   gfx::Size size_in_dip = gfx::win::ScreenToDIPSize(new_size);
738   delegate_->OnNativeWidgetSizeChanged(size_in_dip);
739 }
740
741 void NativeWidgetWin::HandleFrameChanged() {
742   // Replace the frame and layout the contents.
743   GetWidget()->non_client_view()->UpdateFrame(true);
744 }
745
746 void NativeWidgetWin::HandleNativeFocus(HWND last_focused_window) {
747   delegate_->OnNativeFocus(last_focused_window);
748   InputMethod* input_method = GetInputMethod();
749   if (input_method)
750     input_method->OnFocus();
751 }
752
753 void NativeWidgetWin::HandleNativeBlur(HWND focused_window) {
754   delegate_->OnNativeBlur(focused_window);
755   InputMethod* input_method = GetInputMethod();
756   if (input_method)
757     input_method->OnBlur();
758 }
759
760 bool NativeWidgetWin::HandleMouseEvent(const ui::MouseEvent& event) {
761   static gfx::Transform scale_transform(
762     1/gfx::win::GetDeviceScaleFactor(), 0.0,
763     0.0, 1/gfx::win::GetDeviceScaleFactor(),
764     0.0, 0.0);
765   if (event.IsMouseWheelEvent()) {
766     ui::MouseWheelEvent dpi_event(
767         static_cast<const ui::MouseWheelEvent&>(event));
768     dpi_event.UpdateForRootTransform(scale_transform);
769     delegate_->OnMouseEvent(&dpi_event);
770     return dpi_event.handled();
771   } else if (event.IsMouseEvent()) {
772     CHECK(!event.IsScrollEvent()); // Scroll events don't happen in Windows.
773     ui::MouseEvent dpi_event(event);
774     if (!(dpi_event.flags() & ui::EF_IS_NON_CLIENT))
775       dpi_event.UpdateForRootTransform(scale_transform);
776     delegate_->OnMouseEvent(&dpi_event);
777     return dpi_event.handled();
778   }
779   NOTREACHED();
780   return false;
781 }
782
783 bool NativeWidgetWin::HandleKeyEvent(const ui::KeyEvent& event) {
784   delegate_->OnKeyEvent(const_cast<ui::KeyEvent*>(&event));
785   return event.handled();
786 }
787
788 bool NativeWidgetWin::HandleUntranslatedKeyEvent(const ui::KeyEvent& event) {
789   InputMethod* input_method = GetInputMethod();
790   if (input_method)
791     input_method->DispatchKeyEvent(event);
792   return !!input_method;
793 }
794
795 void NativeWidgetWin::HandleTouchEvent(const ui::TouchEvent& event) {
796   NOTREACHED() << "Touch events are not supported";
797 }
798
799 bool NativeWidgetWin::HandleIMEMessage(UINT message,
800                                        WPARAM w_param,
801                                        LPARAM l_param,
802                                        LRESULT* result) {
803   InputMethod* input_method = GetInputMethod();
804   if (!input_method || input_method->IsMock()) {
805     *result = 0;
806     return false;
807   }
808
809   MSG msg = {};
810   msg.hwnd = message_handler_->hwnd();
811   msg.message = message;
812   msg.wParam = w_param;
813   msg.lParam = l_param;
814   return input_method->OnUntranslatedIMEMessage(msg, result);
815 }
816
817 void NativeWidgetWin::HandleInputLanguageChange(DWORD character_set,
818                                                 HKL input_language_id) {
819   InputMethod* input_method = GetInputMethod();
820   if (input_method && !input_method->IsMock()) {
821     input_method->OnInputLocaleChanged();
822   }
823 }
824
825 bool NativeWidgetWin::HandlePaintAccelerated(const gfx::Rect& invalid_rect) {
826   gfx::Rect dpi_rect = gfx::win::ScreenToDIPRect(invalid_rect);
827   return delegate_->OnNativeWidgetPaintAccelerated(dpi_rect);
828 }
829
830 void NativeWidgetWin::HandlePaint(gfx::Canvas* canvas) {
831   delegate_->OnNativeWidgetPaint(canvas);
832 }
833
834 bool NativeWidgetWin::HandleTooltipNotify(int w_param,
835                                           NMHDR* l_param,
836                                           LRESULT* l_result) {
837   // We can be sent this message before the tooltip manager is created, if a
838   // subclass overrides OnCreate and creates some kind of Windows control there
839   // that sends WM_NOTIFY messages.
840   if (tooltip_manager_.get()) {
841     bool handled;
842     *l_result = tooltip_manager_->OnNotify(w_param, l_param, &handled);
843     return handled;
844   }
845   return false;
846 }
847
848 void NativeWidgetWin::HandleTooltipMouseMove(UINT message,
849                                              WPARAM w_param,
850                                              LPARAM l_param) {
851   if (tooltip_manager_.get())
852     tooltip_manager_->OnMouse(message, w_param, l_param);
853 }
854
855 bool NativeWidgetWin::PreHandleMSG(UINT message,
856                                    WPARAM w_param,
857                                    LPARAM l_param,
858                                    LRESULT* result) {
859   return false;
860 }
861
862 void NativeWidgetWin::PostHandleMSG(UINT message,
863                                     WPARAM w_param,
864                                     LPARAM l_param) {
865 }
866
867 ////////////////////////////////////////////////////////////////////////////////
868 // NativeWidgetWin, private:
869
870 void NativeWidgetWin::SetInitParams(const Widget::InitParams& params) {
871   // Set non-style attributes.
872   ownership_ = params.ownership;
873
874   ConfigureWindowStyles(message_handler_.get(), params,
875                         GetWidget()->widget_delegate(), delegate_);
876
877   has_non_client_view_ = Widget::RequiresNonClientView(params.type);
878   message_handler_->set_remove_standard_frame(params.remove_standard_frame);
879   message_handler_->set_use_system_default_icon(params.use_system_default_icon);
880 }
881
882 ////////////////////////////////////////////////////////////////////////////////
883 // Widget, public:
884
885 // static
886 void Widget::NotifyLocaleChanged() {
887   NOTIMPLEMENTED();
888 }
889
890 namespace {
891 BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
892   Widget* widget = Widget::GetWidgetForNativeView(hwnd);
893   if (widget && widget->is_secondary_widget())
894     widget->Close();
895   return TRUE;
896 }
897 }  // namespace
898
899 // static
900 void Widget::CloseAllSecondaryWidgets() {
901   EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0);
902 }
903
904 bool Widget::ConvertRect(const Widget* source,
905                          const Widget* target,
906                          gfx::Rect* rect) {
907   DCHECK(source);
908   DCHECK(target);
909   DCHECK(rect);
910
911   HWND source_hwnd = source->GetNativeView();
912   HWND target_hwnd = target->GetNativeView();
913   if (source_hwnd == target_hwnd)
914     return true;
915
916   RECT win_rect = gfx::win::DIPToScreenRect(*rect).ToRECT();
917   if (::MapWindowPoints(source_hwnd, target_hwnd,
918                         reinterpret_cast<LPPOINT>(&win_rect),
919                         sizeof(RECT)/sizeof(POINT))) {
920     *rect = gfx::win::ScreenToDIPRect(gfx::Rect(win_rect));
921     return true;
922   }
923   return false;
924 }
925
926 namespace internal {
927
928 ////////////////////////////////////////////////////////////////////////////////
929 // internal::NativeWidgetPrivate, public:
930
931 // static
932 NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget(
933     internal::NativeWidgetDelegate* delegate) {
934   return new NativeWidgetWin(delegate);
935 }
936
937 // static
938 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView(
939     gfx::NativeView native_view) {
940   return reinterpret_cast<NativeWidgetWin*>(
941       ViewProp::GetValue(native_view, kNativeWidgetKey));
942 }
943
944 // static
945 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
946     gfx::NativeWindow native_window) {
947   return GetNativeWidgetForNativeView(native_window);
948 }
949
950 // static
951 NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget(
952     gfx::NativeView native_view) {
953   if (!native_view)
954     return NULL;
955
956   // First, check if the top-level window is a Widget.
957   HWND root = ::GetAncestor(native_view, GA_ROOT);
958   if (!root)
959     return NULL;
960
961   NativeWidgetPrivate* widget = GetNativeWidgetForNativeView(root);
962   if (widget)
963     return widget;
964
965   // Second, try to locate the last Widget window in the parent hierarchy.
966   HWND parent_hwnd = native_view;
967   // If we fail to find the native widget pointer for the root then it probably
968   // means that the root belongs to a different process in which case we walk up
969   // the native view chain looking for a parent window which corresponds to a
970   // valid native widget. We only do this if we fail to find the native widget
971   // for the current native view which means it is being destroyed.
972   if (!widget && !GetNativeWidgetForNativeView(native_view)) {
973     parent_hwnd = ::GetAncestor(parent_hwnd, GA_PARENT);
974     if (!parent_hwnd)
975       return NULL;
976   }
977   NativeWidgetPrivate* parent_widget;
978   do {
979     parent_widget = GetNativeWidgetForNativeView(parent_hwnd);
980     if (parent_widget) {
981       widget = parent_widget;
982       parent_hwnd = ::GetAncestor(parent_hwnd, GA_PARENT);
983     }
984   } while (parent_hwnd != NULL && parent_widget != NULL);
985
986   return widget;
987 }
988
989 // static
990 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view,
991                                              Widget::Widgets* children) {
992   if (!native_view)
993     return;
994
995   Widget* widget = Widget::GetWidgetForNativeView(native_view);
996   if (widget)
997     children->insert(widget);
998   EnumChildWindows(native_view, EnumerateNativeWidgets,
999                    reinterpret_cast<LPARAM>(children));
1000 }
1001
1002 // static
1003 void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view,
1004                                              Widget::Widgets* owned) {
1005   if (!native_view)
1006     return;
1007
1008   Widget::Widgets all;
1009   EnumWindows(EnumerateNativeWidgets, reinterpret_cast<LPARAM>(&all));
1010   for (Widget::Widgets::const_iterator iter = all.begin();
1011            iter != all.end(); ++iter) {
1012     if (native_view == GetWindow((*iter)->GetNativeView(), GW_OWNER))
1013       owned->insert(*iter);
1014   }
1015 }
1016
1017 // static
1018 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view,
1019                                              gfx::NativeView new_parent) {
1020   if (!native_view)
1021     return;
1022
1023   HWND previous_parent = ::GetParent(native_view);
1024   if (previous_parent == new_parent)
1025     return;
1026
1027   Widget::Widgets widgets;
1028   GetAllChildWidgets(native_view, &widgets);
1029
1030   // First notify all the widgets that they are being disassociated
1031   // from their previous parent.
1032   for (Widget::Widgets::iterator it = widgets.begin();
1033        it != widgets.end(); ++it) {
1034     (*it)->NotifyNativeViewHierarchyWillChange();
1035   }
1036
1037   ::SetParent(native_view, new_parent);
1038
1039   // And now, notify them that they have a brand new parent.
1040   for (Widget::Widgets::iterator it = widgets.begin();
1041        it != widgets.end(); ++it) {
1042     (*it)->NotifyNativeViewHierarchyChanged();
1043   }
1044 }
1045
1046 // static
1047 bool NativeWidgetPrivate::IsMouseButtonDown() {
1048   return (GetKeyState(VK_LBUTTON) & 0x80) ||
1049     (GetKeyState(VK_RBUTTON) & 0x80) ||
1050     (GetKeyState(VK_MBUTTON) & 0x80) ||
1051     (GetKeyState(VK_XBUTTON1) & 0x80) ||
1052     (GetKeyState(VK_XBUTTON2) & 0x80);
1053 }
1054
1055 // static
1056 bool NativeWidgetPrivate::IsTouchDown() {
1057   // This currently isn't necessary because we're not generating touch events on
1058   // windows.  When we do, this will need to be updated.
1059   return false;
1060 }
1061
1062 }  // namespace internal
1063
1064 }  // namespace views