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