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"
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")
64 // Enumeration callback for NativeWidget::GetAllChildWidgets() and
65 // NativeWidget::GetAllOwnedWidgets. Adds any HWNDs that correspond to
67 BOOL CALLBACK
EnumerateNativeWidgets(HWND hwnd
, LPARAM l_param
) {
68 Widget
* widget
= Widget::GetWidgetForNativeView(hwnd
);
70 Widget::Widgets
* widgets
= reinterpret_cast<Widget::Widgets
*>(l_param
);
71 widgets
->insert(widget
);
76 // Links the HWND to its NativeWidget.
77 const char* const kNativeWidgetKey
= "__VIEWS_NATIVE_WIDGET__";
79 const int kDragFrameWindowAlpha
= 200;
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
)
100 message_handler_
.reset();
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 {
165 ui::Compositor
* NativeWidgetWin::GetCompositor() {
169 ui::Layer
* NativeWidgetWin::GetLayer() {
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
) {
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(),
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(
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
) {
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
);
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
,
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 {
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() {
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).
482 delegate_
->OnNativeWidgetDestroyed();
483 if (ownership_
== Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET
)
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 {
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();
625 // TODO(pkotwicz): Remove need for SchedulePaint(). crbug.com/165841
626 View
* non_client_view
= GetWidget()->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()));
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());
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();
750 input_method
->OnFocus();
753 void NativeWidgetWin::HandleNativeBlur(HWND focused_window
) {
754 delegate_
->OnNativeBlur(focused_window
);
755 InputMethod
* input_method
= GetInputMethod();
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(),
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();
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();
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
,
803 InputMethod
* input_method
= GetInputMethod();
804 if (!input_method
|| input_method
->IsMock()) {
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
,
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()) {
842 *l_result
= tooltip_manager_
->OnNotify(w_param
, l_param
, &handled
);
848 void NativeWidgetWin::HandleTooltipMouseMove(UINT message
,
851 if (tooltip_manager_
.get())
852 tooltip_manager_
->OnMouse(message
, w_param
, l_param
);
855 bool NativeWidgetWin::PreHandleMSG(UINT message
,
862 void NativeWidgetWin::PostHandleMSG(UINT message
,
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 ////////////////////////////////////////////////////////////////////////////////
886 void Widget::NotifyLocaleChanged() {
891 BOOL CALLBACK
WindowCallbackProc(HWND hwnd
, LPARAM lParam
) {
892 Widget
* widget
= Widget::GetWidgetForNativeView(hwnd
);
893 if (widget
&& widget
->is_secondary_widget())
900 void Widget::CloseAllSecondaryWidgets() {
901 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc
, 0);
904 bool Widget::ConvertRect(const Widget
* source
,
905 const Widget
* target
,
911 HWND source_hwnd
= source
->GetNativeView();
912 HWND target_hwnd
= target
->GetNativeView();
913 if (source_hwnd
== target_hwnd
)
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
));
928 ////////////////////////////////////////////////////////////////////////////////
929 // internal::NativeWidgetPrivate, public:
932 NativeWidgetPrivate
* NativeWidgetPrivate::CreateNativeWidget(
933 internal::NativeWidgetDelegate
* delegate
) {
934 return new NativeWidgetWin(delegate
);
938 NativeWidgetPrivate
* NativeWidgetPrivate::GetNativeWidgetForNativeView(
939 gfx::NativeView native_view
) {
940 return reinterpret_cast<NativeWidgetWin
*>(
941 ViewProp::GetValue(native_view
, kNativeWidgetKey
));
945 NativeWidgetPrivate
* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
946 gfx::NativeWindow native_window
) {
947 return GetNativeWidgetForNativeView(native_window
);
951 NativeWidgetPrivate
* NativeWidgetPrivate::GetTopLevelNativeWidget(
952 gfx::NativeView native_view
) {
956 // First, check if the top-level window is a Widget.
957 HWND root
= ::GetAncestor(native_view
, GA_ROOT
);
961 NativeWidgetPrivate
* widget
= GetNativeWidgetForNativeView(root
);
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
);
977 NativeWidgetPrivate
* parent_widget
;
979 parent_widget
= GetNativeWidgetForNativeView(parent_hwnd
);
981 widget
= parent_widget
;
982 parent_hwnd
= ::GetAncestor(parent_hwnd
, GA_PARENT
);
984 } while (parent_hwnd
!= NULL
&& parent_widget
!= NULL
);
990 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view
,
991 Widget::Widgets
* children
) {
995 Widget
* widget
= Widget::GetWidgetForNativeView(native_view
);
997 children
->insert(widget
);
998 EnumChildWindows(native_view
, EnumerateNativeWidgets
,
999 reinterpret_cast<LPARAM
>(children
));
1003 void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view
,
1004 Widget::Widgets
* owned
) {
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
);
1018 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view
,
1019 gfx::NativeView new_parent
) {
1023 HWND previous_parent
= ::GetParent(native_view
);
1024 if (previous_parent
== new_parent
)
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();
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);
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.
1062 } // namespace internal
1064 } // namespace views