Correct blacklist entry message
[chromium-blink-merge.git] / ui / views / widget / native_widget_win.cc
blobf9102fa4bea1a9c647a149a476ea03b89f1ecccd
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.
5 #include "ui/views/widget/native_widget_win.h"
7 #include <dwmapi.h>
8 #include <shellapi.h>
10 #include <algorithm>
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"
56 #pragma comment(lib, "dwmapi.lib")
58 using ui::ViewProp;
60 namespace views {
62 namespace {
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);
73 return TRUE;
76 // Links the HWND to its NativeWidget.
77 const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
79 const int kDragFrameWindowAlpha = 200;
81 } // namespace
83 ////////////////////////////////////////////////////////////////////////////////
84 // NativeWidgetWin, public:
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)) {
95 NativeWidgetWin::~NativeWidgetWin() {
96 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
97 delete delegate_;
98 else
99 CloseNow();
100 message_handler_.reset();
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);
112 void NativeWidgetWin::Show(int show_state) {
113 message_handler_->Show(show_state);
116 ////////////////////////////////////////////////////////////////////////////////
117 // NativeWidgetWin, NativeWidget implementation:
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);
127 NonClientFrameView* NativeWidgetWin::CreateNonClientFrameView() {
128 return GetWidget()->ShouldUseNativeFrame() ?
129 new NativeFrameView(GetWidget()) : NULL;
132 bool NativeWidgetWin::ShouldUseNativeFrame() const {
133 return ui::win::IsAeroGlassEnabled();
136 void NativeWidgetWin::FrameTypeChanged() {
137 message_handler_->FrameTypeChanged();
140 Widget* NativeWidgetWin::GetWidget() {
141 return delegate_->AsWidget();
144 const Widget* NativeWidgetWin::GetWidget() const {
145 return delegate_->AsWidget();
148 gfx::NativeView NativeWidgetWin::GetNativeView() const {
149 return message_handler_->hwnd();
152 gfx::NativeWindow NativeWidgetWin::GetNativeWindow() const {
153 return message_handler_->hwnd();
156 Widget* NativeWidgetWin::GetTopLevelWidget() {
157 NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView());
158 return native_widget ? native_widget->GetWidget() : NULL;
161 const ui::Compositor* NativeWidgetWin::GetCompositor() const {
162 return NULL;
165 ui::Compositor* NativeWidgetWin::GetCompositor() {
166 return NULL;
169 ui::Layer* NativeWidgetWin::GetLayer() {
170 return NULL;
173 void NativeWidgetWin::ReorderNativeViews() {
176 void NativeWidgetWin::ViewRemoved(View* view) {
177 if (drop_target_.get())
178 drop_target_->ResetTargetViewIfEquals(view);
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;
190 if (value)
191 props_.push_back(new ViewProp(GetNativeView(), name, value));
194 void* NativeWidgetWin::GetNativeWindowProperty(const char* name) const {
195 return ViewProp::GetValue(GetNativeView(), name);
198 TooltipManager* NativeWidgetWin::GetTooltipManager() const {
199 return tooltip_manager_.get();
202 void NativeWidgetWin::SetCapture() {
203 message_handler_->SetCapture();
206 void NativeWidgetWin::ReleaseCapture() {
207 message_handler_->ReleaseCapture();
210 bool NativeWidgetWin::HasCapture() const {
211 return message_handler_->HasCapture();
214 InputMethod* NativeWidgetWin::CreateInputMethod() {
215 return new InputMethodBridge(GetMessageHandler(), ui::GetSharedInputMethod(),
216 true);
219 internal::InputMethodDelegate* NativeWidgetWin::GetInputMethodDelegate() {
220 return message_handler_.get();
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);
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);
235 void NativeWidgetWin::SetWindowTitle(const string16& title) {
236 message_handler_->SetTitle(title);
239 void NativeWidgetWin::SetWindowIcons(const gfx::ImageSkia& window_icon,
240 const gfx::ImageSkia& app_icon) {
241 message_handler_->SetWindowIcons(window_icon, app_icon);
244 void NativeWidgetWin::InitModalType(ui::ModalType modal_type) {
245 message_handler_->InitModalType(modal_type);
248 gfx::Rect NativeWidgetWin::GetWindowBoundsInScreen() const {
249 gfx::Rect bounds_in_pixels = message_handler_->GetWindowBoundsInScreen();
250 return gfx::win::ScreenToDIPRect(bounds_in_pixels);
253 gfx::Rect NativeWidgetWin::GetClientAreaBoundsInScreen() const {
254 gfx::Rect bounds_in_pixels = message_handler_->GetClientAreaBoundsInScreen();
255 return gfx::win::ScreenToDIPRect(bounds_in_pixels);
258 gfx::Rect NativeWidgetWin::GetRestoredBounds() const {
259 gfx::Rect bounds_in_pixels = message_handler_->GetRestoredBounds();
260 return gfx::win::ScreenToDIPRect(bounds_in_pixels);
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);
271 void NativeWidgetWin::SetSize(const gfx::Size& size) {
272 message_handler_->SetSize(size);
275 void NativeWidgetWin::StackAbove(gfx::NativeView native_view) {
276 message_handler_->StackAbove(native_view);
279 void NativeWidgetWin::StackAtTop() {
280 message_handler_->StackAtTop();
283 void NativeWidgetWin::StackBelow(gfx::NativeView native_view) {
284 NOTIMPLEMENTED();
287 void NativeWidgetWin::SetShape(gfx::NativeRegion region) {
288 message_handler_->SetRegion(region);
291 void NativeWidgetWin::Close() {
292 message_handler_->Close();
295 void NativeWidgetWin::CloseNow() {
296 message_handler_->CloseNow();
299 void NativeWidgetWin::Show() {
300 message_handler_->Show();
303 void NativeWidgetWin::Hide() {
304 message_handler_->Hide();
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);
313 void NativeWidgetWin::ShowWithWindowState(ui::WindowShowState show_state) {
314 message_handler_->ShowWindowWithState(show_state);
317 bool NativeWidgetWin::IsVisible() const {
318 return message_handler_->IsVisible();
321 void NativeWidgetWin::Activate() {
322 message_handler_->Activate();
325 void NativeWidgetWin::Deactivate() {
326 message_handler_->Deactivate();
329 bool NativeWidgetWin::IsActive() const {
330 return message_handler_->IsActive();
333 void NativeWidgetWin::SetAlwaysOnTop(bool on_top) {
334 message_handler_->SetAlwaysOnTop(on_top);
337 bool NativeWidgetWin::IsAlwaysOnTop() const {
338 return message_handler_->IsAlwaysOnTop();
341 void NativeWidgetWin::Maximize() {
342 message_handler_->Maximize();
345 void NativeWidgetWin::Minimize() {
346 message_handler_->Minimize();
349 bool NativeWidgetWin::IsMaximized() const {
350 return message_handler_->IsMaximized();
353 bool NativeWidgetWin::IsMinimized() const {
354 return message_handler_->IsMinimized();
357 void NativeWidgetWin::Restore() {
358 message_handler_->Restore();
361 void NativeWidgetWin::SetFullscreen(bool fullscreen) {
362 message_handler_->fullscreen_handler()->SetFullscreen(fullscreen);
365 void NativeWidgetWin::SetMetroSnapFullscreen(bool metro_snap) {
366 message_handler_->fullscreen_handler()->SetMetroSnap(metro_snap);
369 bool NativeWidgetWin::IsFullscreen() const {
370 return message_handler_->fullscreen_handler()->fullscreen();
373 bool NativeWidgetWin::IsInMetroSnapMode() const {
374 return message_handler_->fullscreen_handler()->metro_snap();
377 void NativeWidgetWin::SetCanUpdateLayeredWindow(bool can_update) {
378 message_handler_->set_can_update_layered_window(can_update);
381 void NativeWidgetWin::SetOpacity(unsigned char opacity) {
382 message_handler_->SetOpacity(static_cast<BYTE>(opacity));
383 GetWidget()->GetRootView()->SchedulePaint();
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_);
407 void NativeWidgetWin::FlashFrame(bool flash) {
408 message_handler_->FlashFrame(flash);
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);
419 void NativeWidgetWin::SchedulePaintInRect(const gfx::Rect& rect) {
420 gfx::Rect pixel_rect = gfx::win::DIPToScreenRect(rect);
421 message_handler_->SchedulePaintInRect(pixel_rect);
424 void NativeWidgetWin::SetCursor(gfx::NativeCursor cursor) {
425 message_handler_->SetCursor(cursor);
428 bool NativeWidgetWin::IsMouseEventsEnabled() const {
429 return true;
432 void NativeWidgetWin::ClearNativeFocus() {
433 message_handler_->ClearNativeFocus();
436 gfx::Rect NativeWidgetWin::GetWorkAreaBoundsInScreen() const {
437 return gfx::win::ScreenToDIPRect(
438 gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(
439 GetNativeView()).work_area());
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;
452 void NativeWidgetWin::EndMoveLoop() {
453 message_handler_->EndMoveLoop();
456 void NativeWidgetWin::SetVisibilityChangedAnimationsEnabled(bool value) {
457 message_handler_->SetVisibilityChangedAnimationsEnabled(value);
460 ui::NativeTheme* NativeWidgetWin::GetNativeTheme() const {
461 return ui::NativeTheme::instance();
464 void NativeWidgetWin::OnRootViewLayout() const {
467 ////////////////////////////////////////////////////////////////////////////////
468 // NativeWidgetWin, NativeWidget implementation:
470 ui::EventHandler* NativeWidgetWin::GetEventHandler() {
471 NOTIMPLEMENTED();
472 return NULL;
475 ////////////////////////////////////////////////////////////////////////////////
476 // NativeWidgetWin, protected:
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;
487 ////////////////////////////////////////////////////////////////////////////////
488 // NativeWidgetWin, protected:
490 HWNDMessageHandler* NativeWidgetWin::GetMessageHandler() {
491 return message_handler_.get();
494 ////////////////////////////////////////////////////////////////////////////////
495 // NativeWidgetWin, HWNDMessageHandlerDelegate implementation:
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_;
503 bool NativeWidgetWin::IsUsingCustomFrame() const {
504 return !GetWidget()->ShouldUseNativeFrame();
507 void NativeWidgetWin::SchedulePaint() {
508 GetWidget()->GetRootView()->SchedulePaint();
511 void NativeWidgetWin::EnableInactiveRendering() {
512 delegate_->EnableInactiveRendering();
515 bool NativeWidgetWin::IsInactiveRenderingDisabled() {
516 return delegate_->IsInactiveRenderingDisabled();
519 bool NativeWidgetWin::CanResize() const {
520 return GetWidget()->widget_delegate()->CanResize();
523 bool NativeWidgetWin::CanMaximize() const {
524 return GetWidget()->widget_delegate()->CanMaximize();
527 bool NativeWidgetWin::CanActivate() const {
528 return delegate_->CanActivate();
531 bool NativeWidgetWin::WidgetSizeIsClientSize() const {
532 const Widget* widget = GetWidget()->GetTopLevelWidget();
533 return IsZoomed(GetNativeView()) ||
534 (widget && widget->ShouldUseNativeFrame());
537 bool NativeWidgetWin::CanSaveFocus() const {
538 return GetWidget()->is_top_level();
541 void NativeWidgetWin::SaveFocusOnDeactivate() {
542 GetWidget()->GetFocusManager()->StoreFocusedView(true);
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 .
553 // Since this is a synthetic reset, we don't need to tell anyone about it.
554 AutoNativeNotificationDisabler disabler;
555 GetWidget()->GetFocusManager()->ClearFocus();
557 RestoreFocusOnEnable();
560 void NativeWidgetWin::RestoreFocusOnEnable() {
561 GetWidget()->GetFocusManager()->RestoreFocusedView();
564 bool NativeWidgetWin::IsModal() const {
565 return delegate_->IsModal();
568 int NativeWidgetWin::GetInitialShowState() const {
569 return SW_SHOWNORMAL;
572 bool NativeWidgetWin::WillProcessWorkAreaChange() const {
573 return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
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);
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);
586 bool NativeWidgetWin::GetClientAreaInsets(gfx::Insets* insets) const {
587 return false;
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());
596 gfx::Size NativeWidgetWin::GetRootViewSize() const {
597 gfx::Size pixel_size = GetWidget()->GetRootView()->size();
598 return gfx::win::ScreenToDIPSize(pixel_size);
601 void NativeWidgetWin::ResetWindowControls() {
602 GetWidget()->non_client_view()->ResetWindowControls();
605 void NativeWidgetWin::PaintLayeredWindow(gfx::Canvas* canvas) {
606 GetWidget()->GetRootView()->Paint(canvas);
609 InputMethod* NativeWidgetWin::GetInputMethod() {
610 return GetWidget()->GetInputMethodDirect();
613 gfx::NativeViewAccessible NativeWidgetWin::GetNativeViewAccessible() {
614 return GetWidget()->GetRootView()->GetNativeViewAccessible();
617 bool NativeWidgetWin::ShouldHandleSystemCommands() const {
618 return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
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();
632 void NativeWidgetWin::HandleActivationChanged(bool active) {
633 delegate_->OnNativeWidgetActivationChanged(active);
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);
643 void NativeWidgetWin::HandleCancelMode() {
646 void NativeWidgetWin::HandleCaptureLost() {
647 delegate_->OnMouseCaptureLost();
650 void NativeWidgetWin::HandleClose() {
651 GetWidget()->Close();
654 bool NativeWidgetWin::HandleCommand(int command) {
655 return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
658 void NativeWidgetWin::HandleAccelerator(const ui::Accelerator& accelerator) {
659 GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator);
662 void NativeWidgetWin::HandleCreate() {
663 // TODO(beng): much of this could/should maybe move to HWNDMessageHandler.
665 SetNativeWindowProperty(kNativeWidgetKey, this);
666 CHECK_EQ(this, GetNativeWidgetForNativeView(GetNativeView()));
668 props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(GetNativeView()));
670 drop_target_ = new DropTargetWin(
671 static_cast<internal::RootView*>(GetWidget()->GetRootView()));
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()));
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();
689 delegate_->OnNativeWidgetCreated(true);
692 void NativeWidgetWin::HandleDestroying() {
693 delegate_->OnNativeWidgetDestroying();
694 if (drop_target_.get()) {
695 RevokeDragDrop(GetNativeView());
696 drop_target_ = NULL;
700 void NativeWidgetWin::HandleDestroyed() {
701 OnFinalMessage(GetNativeView());
704 bool NativeWidgetWin::HandleInitialFocus() {
705 return GetWidget()->SetInitialFocus();
708 void NativeWidgetWin::HandleDisplayChange() {
709 GetWidget()->widget_delegate()->OnDisplayChanged();
712 void NativeWidgetWin::HandleBeginWMSizeMove() {
713 delegate_->OnNativeWidgetBeginUserBoundsChange();
716 void NativeWidgetWin::HandleEndWMSizeMove() {
717 delegate_->OnNativeWidgetEndUserBoundsChange();
720 void NativeWidgetWin::HandleMove() {
721 delegate_->OnNativeWidgetMove();
724 void NativeWidgetWin::HandleWorkAreaChanged() {
725 GetWidget()->widget_delegate()->OnWorkAreaChanged();
728 void NativeWidgetWin::HandleVisibilityChanging(bool visible) {
729 delegate_->OnNativeWidgetVisibilityChanging(visible);
732 void NativeWidgetWin::HandleVisibilityChanged(bool visible) {
733 delegate_->OnNativeWidgetVisibilityChanged(visible);
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);
741 void NativeWidgetWin::HandleFrameChanged() {
742 // Replace the frame and layout the contents.
743 GetWidget()->non_client_view()->UpdateFrame(true);
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();
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();
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();
779 NOTREACHED();
780 return false;
783 bool NativeWidgetWin::HandleKeyEvent(const ui::KeyEvent& event) {
784 delegate_->OnKeyEvent(const_cast<ui::KeyEvent*>(&event));
785 return event.handled();
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;
795 void NativeWidgetWin::HandleTouchEvent(const ui::TouchEvent& event) {
796 NOTREACHED() << "Touch events are not supported";
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;
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);
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();
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);
830 void NativeWidgetWin::HandlePaint(gfx::Canvas* canvas) {
831 delegate_->OnNativeWidgetPaint(canvas);
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;
845 return false;
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);
855 bool NativeWidgetWin::PreHandleMSG(UINT message,
856 WPARAM w_param,
857 LPARAM l_param,
858 LRESULT* result) {
859 return false;
862 void NativeWidgetWin::PostHandleMSG(UINT message,
863 WPARAM w_param,
864 LPARAM l_param) {
867 ////////////////////////////////////////////////////////////////////////////////
868 // NativeWidgetWin, private:
870 void NativeWidgetWin::SetInitParams(const Widget::InitParams& params) {
871 // Set non-style attributes.
872 ownership_ = params.ownership;
874 ConfigureWindowStyles(message_handler_.get(), params,
875 GetWidget()->widget_delegate(), delegate_);
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);
882 ////////////////////////////////////////////////////////////////////////////////
883 // Widget, public:
885 // static
886 void Widget::NotifyLocaleChanged() {
887 NOTIMPLEMENTED();
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;
897 } // namespace
899 // static
900 void Widget::CloseAllSecondaryWidgets() {
901 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0);
904 bool Widget::ConvertRect(const Widget* source,
905 const Widget* target,
906 gfx::Rect* rect) {
907 DCHECK(source);
908 DCHECK(target);
909 DCHECK(rect);
911 HWND source_hwnd = source->GetNativeView();
912 HWND target_hwnd = target->GetNativeView();
913 if (source_hwnd == target_hwnd)
914 return true;
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;
923 return false;
926 namespace internal {
928 ////////////////////////////////////////////////////////////////////////////////
929 // internal::NativeWidgetPrivate, public:
931 // static
932 NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget(
933 internal::NativeWidgetDelegate* delegate) {
934 return new NativeWidgetWin(delegate);
937 // static
938 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView(
939 gfx::NativeView native_view) {
940 return reinterpret_cast<NativeWidgetWin*>(
941 ViewProp::GetValue(native_view, kNativeWidgetKey));
944 // static
945 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
946 gfx::NativeWindow native_window) {
947 return GetNativeWidgetForNativeView(native_window);
950 // static
951 NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget(
952 gfx::NativeView native_view) {
953 if (!native_view)
954 return NULL;
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;
961 NativeWidgetPrivate* widget = GetNativeWidgetForNativeView(root);
962 if (widget)
963 return widget;
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;
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);
984 } while (parent_hwnd != NULL && parent_widget != NULL);
986 return widget;
989 // static
990 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view,
991 Widget::Widgets* children) {
992 if (!native_view)
993 return;
995 Widget* widget = Widget::GetWidgetForNativeView(native_view);
996 if (widget)
997 children->insert(widget);
998 EnumChildWindows(native_view, EnumerateNativeWidgets,
999 reinterpret_cast<LPARAM>(children));
1002 // static
1003 void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view,
1004 Widget::Widgets* owned) {
1005 if (!native_view)
1006 return;
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);
1017 // static
1018 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view,
1019 gfx::NativeView new_parent) {
1020 if (!native_view)
1021 return;
1023 HWND previous_parent = ::GetParent(native_view);
1024 if (previous_parent == new_parent)
1025 return;
1027 Widget::Widgets widgets;
1028 GetAllChildWidgets(native_view, &widgets);
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();
1037 ::SetParent(native_view, new_parent);
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();
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);
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;
1062 } // namespace internal
1064 } // namespace views