| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/views/widget/native_widget_win.h" | 5 #include "ui/views/widget/native_widget_win.h" |
| 6 | 6 |
| 7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
| 8 #include <shellapi.h> | 8 #include <shellapi.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 #include "ui/views/ime/input_method_win.h" | 42 #include "ui/views/ime/input_method_win.h" |
| 43 #include "ui/views/views_delegate.h" | 43 #include "ui/views/views_delegate.h" |
| 44 #include "ui/views/widget/aero_tooltip_manager.h" | 44 #include "ui/views/widget/aero_tooltip_manager.h" |
| 45 #include "ui/views/widget/child_window_message_processor.h" | 45 #include "ui/views/widget/child_window_message_processor.h" |
| 46 #include "ui/views/widget/drop_target_win.h" | 46 #include "ui/views/widget/drop_target_win.h" |
| 47 #include "ui/views/widget/monitor_win.h" | 47 #include "ui/views/widget/monitor_win.h" |
| 48 #include "ui/views/widget/native_widget_delegate.h" | 48 #include "ui/views/widget/native_widget_delegate.h" |
| 49 #include "ui/views/widget/root_view.h" | 49 #include "ui/views/widget/root_view.h" |
| 50 #include "ui/views/widget/widget_delegate.h" | 50 #include "ui/views/widget/widget_delegate.h" |
| 51 #include "ui/views/widget/widget_hwnd_utils.h" | 51 #include "ui/views/widget/widget_hwnd_utils.h" |
| 52 #include "ui/views/win/fullscreen_handler.h" |
| 52 #include "ui/views/win/hwnd_message_handler.h" | 53 #include "ui/views/win/hwnd_message_handler.h" |
| 54 #include "ui/views/win/scoped_fullscreen_visibility.h" |
| 53 #include "ui/views/window/native_frame_view.h" | 55 #include "ui/views/window/native_frame_view.h" |
| 54 | 56 |
| 55 #if !defined(USE_AURA) | 57 #if !defined(USE_AURA) |
| 56 #include "base/command_line.h" | 58 #include "base/command_line.h" |
| 57 #include "ui/base/ui_base_switches.h" | 59 #include "ui/base/ui_base_switches.h" |
| 58 #endif | 60 #endif |
| 59 | 61 |
| 60 #pragma comment(lib, "dwmapi.lib") | 62 #pragma comment(lib, "dwmapi.lib") |
| 61 | 63 |
| 62 using ui::ViewProp; | 64 using ui::ViewProp; |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), | 329 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), |
| 328 use_layered_buffer_(false), | 330 use_layered_buffer_(false), |
| 329 layered_alpha_(255), | 331 layered_alpha_(255), |
| 330 ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)), | 332 ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)), |
| 331 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), | 333 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), |
| 332 can_update_layered_window_(true), | 334 can_update_layered_window_(true), |
| 333 restore_focus_when_enabled_(false), | 335 restore_focus_when_enabled_(false), |
| 334 accessibility_view_events_index_(-1), | 336 accessibility_view_events_index_(-1), |
| 335 accessibility_view_events_(kMaxAccessibilityViewEvents), | 337 accessibility_view_events_(kMaxAccessibilityViewEvents), |
| 336 previous_cursor_(NULL), | 338 previous_cursor_(NULL), |
| 337 fullscreen_(false), | |
| 338 metro_snap_(false), | |
| 339 force_hidden_count_(0), | |
| 340 ignore_window_pos_changes_(false), | 339 ignore_window_pos_changes_(false), |
| 341 ALLOW_THIS_IN_INITIALIZER_LIST(ignore_pos_changes_factory_(this)), | 340 ALLOW_THIS_IN_INITIALIZER_LIST(ignore_pos_changes_factory_(this)), |
| 342 last_monitor_(NULL), | 341 last_monitor_(NULL), |
| 343 restored_enabled_(false), | 342 restored_enabled_(false), |
| 344 has_non_client_view_(false), | 343 has_non_client_view_(false), |
| 345 ALLOW_THIS_IN_INITIALIZER_LIST( | 344 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 346 message_handler_(new HWNDMessageHandler(this))) { | 345 message_handler_(new HWNDMessageHandler(this))), |
| 346 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 347 fullscreen_handler_(new FullscreenHandler(GetWidget()))) { |
| 347 } | 348 } |
| 348 | 349 |
| 349 NativeWidgetWin::~NativeWidgetWin() { | 350 NativeWidgetWin::~NativeWidgetWin() { |
| 350 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) | 351 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) |
| 351 delete delegate_; | 352 delete delegate_; |
| 352 else | 353 else |
| 353 CloseNow(); | 354 CloseNow(); |
| 354 } | 355 } |
| 355 | 356 |
| 356 // static | 357 // static |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 | 404 |
| 404 void NativeWidgetWin::ClearAccessibilityViewEvent(View* view) { | 405 void NativeWidgetWin::ClearAccessibilityViewEvent(View* view) { |
| 405 for (std::vector<View*>::iterator it = accessibility_view_events_.begin(); | 406 for (std::vector<View*>::iterator it = accessibility_view_events_.begin(); |
| 406 it != accessibility_view_events_.end(); | 407 it != accessibility_view_events_.end(); |
| 407 ++it) { | 408 ++it) { |
| 408 if (*it == view) | 409 if (*it == view) |
| 409 *it = NULL; | 410 *it = NULL; |
| 410 } | 411 } |
| 411 } | 412 } |
| 412 | 413 |
| 413 void NativeWidgetWin::PushForceHidden() { | |
| 414 if (force_hidden_count_++ == 0) | |
| 415 Hide(); | |
| 416 } | |
| 417 | |
| 418 void NativeWidgetWin::PopForceHidden() { | |
| 419 if (--force_hidden_count_ <= 0) { | |
| 420 force_hidden_count_ = 0; | |
| 421 ShowWindow(SW_SHOW); | |
| 422 } | |
| 423 } | |
| 424 | |
| 425 //////////////////////////////////////////////////////////////////////////////// | 414 //////////////////////////////////////////////////////////////////////////////// |
| 426 // NativeWidgetWin, CompositorDelegate implementation: | 415 // NativeWidgetWin, CompositorDelegate implementation: |
| 427 | 416 |
| 428 //////////////////////////////////////////////////////////////////////////////// | 417 //////////////////////////////////////////////////////////////////////////////// |
| 429 // NativeWidgetWin, NativeWidget implementation: | 418 // NativeWidgetWin, NativeWidget implementation: |
| 430 | 419 |
| 431 void NativeWidgetWin::InitNativeWidget(const Widget::InitParams& params) { | 420 void NativeWidgetWin::InitNativeWidget(const Widget::InitParams& params) { |
| 432 SetInitParams(params); | 421 SetInitParams(params); |
| 433 | 422 |
| 434 GetMonitorAndRects(params.bounds.ToRECT(), &last_monitor_, | 423 GetMonitorAndRects(params.bounds.ToRECT(), &last_monitor_, |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 GetClientRect(&r); | 697 GetClientRect(&r); |
| 709 POINT point = { r.left, r.top }; | 698 POINT point = { r.left, r.top }; |
| 710 ClientToScreen(hwnd(), &point); | 699 ClientToScreen(hwnd(), &point); |
| 711 return gfx::Rect(point.x, point.y, r.right - r.left, r.bottom - r.top); | 700 return gfx::Rect(point.x, point.y, r.right - r.left, r.bottom - r.top); |
| 712 } | 701 } |
| 713 | 702 |
| 714 gfx::Rect NativeWidgetWin::GetRestoredBounds() const { | 703 gfx::Rect NativeWidgetWin::GetRestoredBounds() const { |
| 715 // If we're in fullscreen mode, we've changed the normal bounds to the monitor | 704 // If we're in fullscreen mode, we've changed the normal bounds to the monitor |
| 716 // rect, so return the saved bounds instead. | 705 // rect, so return the saved bounds instead. |
| 717 if (IsFullscreen()) | 706 if (IsFullscreen()) |
| 718 return gfx::Rect(saved_window_info_.window_rect); | 707 return fullscreen_handler_->GetRestoreBounds(); |
| 719 | 708 |
| 720 gfx::Rect bounds; | 709 gfx::Rect bounds; |
| 721 GetWindowPlacement(&bounds, NULL); | 710 GetWindowPlacement(&bounds, NULL); |
| 722 return bounds; | 711 return bounds; |
| 723 } | 712 } |
| 724 | 713 |
| 725 void NativeWidgetWin::SetBounds(const gfx::Rect& bounds) { | 714 void NativeWidgetWin::SetBounds(const gfx::Rect& bounds) { |
| 726 LONG style = GetWindowLong(GWL_STYLE); | 715 LONG style = GetWindowLong(GWL_STYLE); |
| 727 if (style & WS_MAXIMIZE) | 716 if (style & WS_MAXIMIZE) |
| 728 SetWindowLong(GWL_STYLE, style & ~WS_MAXIMIZE); | 717 SetWindowLong(GWL_STYLE, style & ~WS_MAXIMIZE); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 879 | 868 |
| 880 bool NativeWidgetWin::IsMinimized() const { | 869 bool NativeWidgetWin::IsMinimized() const { |
| 881 return message_handler_->IsMinimized(); | 870 return message_handler_->IsMinimized(); |
| 882 } | 871 } |
| 883 | 872 |
| 884 void NativeWidgetWin::Restore() { | 873 void NativeWidgetWin::Restore() { |
| 885 ExecuteSystemMenuCommand(SC_RESTORE); | 874 ExecuteSystemMenuCommand(SC_RESTORE); |
| 886 } | 875 } |
| 887 | 876 |
| 888 void NativeWidgetWin::SetFullscreen(bool fullscreen) { | 877 void NativeWidgetWin::SetFullscreen(bool fullscreen) { |
| 889 if (fullscreen_ == fullscreen) | 878 fullscreen_handler_->SetFullscreen(fullscreen); |
| 890 return; | |
| 891 | |
| 892 SetFullscreenInternal(fullscreen, false); | |
| 893 } | 879 } |
| 894 | 880 |
| 895 void NativeWidgetWin::SetMetroSnapFullscreen(bool metro_snap) { | 881 void NativeWidgetWin::SetMetroSnapFullscreen(bool metro_snap) { |
| 896 if (metro_snap_ == metro_snap) | 882 fullscreen_handler_->SetMetroSnap(metro_snap); |
| 897 return; | |
| 898 | |
| 899 SetFullscreenInternal(metro_snap, true); | |
| 900 | |
| 901 metro_snap_ = metro_snap; | |
| 902 } | |
| 903 | |
| 904 void NativeWidgetWin::SetFullscreenInternal(bool fullscreen, | |
| 905 bool for_metro) { | |
| 906 | |
| 907 // Reduce jankiness during the following position changes by hiding the window | |
| 908 // until it's in the final position. | |
| 909 PushForceHidden(); | |
| 910 | |
| 911 // Save current window state if not already fullscreen. | |
| 912 if (!fullscreen_) { | |
| 913 // Save current window information. We force the window into restored mode | |
| 914 // before going fullscreen because Windows doesn't seem to hide the | |
| 915 // taskbar if the window is in the maximized state. | |
| 916 saved_window_info_.maximized = IsMaximized(); | |
| 917 if (saved_window_info_.maximized) | |
| 918 Restore(); | |
| 919 saved_window_info_.style = GetWindowLong(GWL_STYLE); | |
| 920 saved_window_info_.ex_style = GetWindowLong(GWL_EXSTYLE); | |
| 921 GetWindowRect(&saved_window_info_.window_rect); | |
| 922 } | |
| 923 | |
| 924 fullscreen_ = fullscreen; | |
| 925 | |
| 926 if (fullscreen_) { | |
| 927 // Set new window style and size. | |
| 928 SetWindowLong(GWL_STYLE, | |
| 929 saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME)); | |
| 930 SetWindowLong(GWL_EXSTYLE, | |
| 931 saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME | | |
| 932 WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); | |
| 933 | |
| 934 // On expand, if we're given a window_rect, grow to it, otherwise do | |
| 935 // not resize. | |
| 936 if (!for_metro) { | |
| 937 MONITORINFO monitor_info; | |
| 938 monitor_info.cbSize = sizeof(monitor_info); | |
| 939 GetMonitorInfo(MonitorFromWindow(GetNativeView(), | |
| 940 MONITOR_DEFAULTTONEAREST), | |
| 941 &monitor_info); | |
| 942 gfx::Rect window_rect(monitor_info.rcMonitor); | |
| 943 SetWindowPos(NULL, window_rect.x(), window_rect.y(), | |
| 944 window_rect.width(), window_rect.height(), | |
| 945 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); | |
| 946 } | |
| 947 } else { | |
| 948 // Reset original window style and size. The multiple window size/moves | |
| 949 // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be | |
| 950 // repainted. Better-looking methods welcome. | |
| 951 SetWindowLong(GWL_STYLE, saved_window_info_.style); | |
| 952 SetWindowLong(GWL_EXSTYLE, saved_window_info_.ex_style); | |
| 953 | |
| 954 if (!for_metro) { | |
| 955 // On restore, resize to the previous saved rect size. | |
| 956 gfx::Rect new_rect(saved_window_info_.window_rect); | |
| 957 SetWindowPos(NULL, new_rect.x(), new_rect.y(), new_rect.width(), | |
| 958 new_rect.height(), | |
| 959 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); | |
| 960 } | |
| 961 if (saved_window_info_.maximized) | |
| 962 Maximize(); | |
| 963 } | |
| 964 | |
| 965 // Undo our anti-jankiness hacks. | |
| 966 PopForceHidden(); | |
| 967 } | 883 } |
| 968 | 884 |
| 969 bool NativeWidgetWin::IsFullscreen() const { | 885 bool NativeWidgetWin::IsFullscreen() const { |
| 970 return fullscreen_; | 886 return fullscreen_handler_->fullscreen(); |
| 971 } | 887 } |
| 972 | 888 |
| 973 bool NativeWidgetWin::IsInMetroSnapMode() const { | 889 bool NativeWidgetWin::IsInMetroSnapMode() const { |
| 974 return metro_snap_; | 890 return fullscreen_handler_->metro_snap(); |
| 975 } | 891 } |
| 976 | 892 |
| 977 void NativeWidgetWin::SetOpacity(unsigned char opacity) { | 893 void NativeWidgetWin::SetOpacity(unsigned char opacity) { |
| 978 layered_alpha_ = static_cast<BYTE>(opacity); | 894 layered_alpha_ = static_cast<BYTE>(opacity); |
| 979 GetWidget()->GetRootView()->SchedulePaint(); | 895 GetWidget()->GetRootView()->SchedulePaint(); |
| 980 } | 896 } |
| 981 | 897 |
| 982 void NativeWidgetWin::SetUseDragFrame(bool use_drag_frame) { | 898 void NativeWidgetWin::SetUseDragFrame(bool use_drag_frame) { |
| 983 if (use_drag_frame) { | 899 if (use_drag_frame) { |
| 984 // Make the frame slightly transparent during the drag operation. | 900 // Make the frame slightly transparent during the drag operation. |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1622 } | 1538 } |
| 1623 } else if (!GetParent()) { | 1539 } else if (!GetParent()) { |
| 1624 CRect window_rect; | 1540 CRect window_rect; |
| 1625 HMONITOR monitor; | 1541 HMONITOR monitor; |
| 1626 gfx::Rect monitor_rect, work_area; | 1542 gfx::Rect monitor_rect, work_area; |
| 1627 if (GetWindowRect(&window_rect) && | 1543 if (GetWindowRect(&window_rect) && |
| 1628 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { | 1544 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { |
| 1629 bool work_area_changed = (monitor_rect == last_monitor_rect_) && | 1545 bool work_area_changed = (monitor_rect == last_monitor_rect_) && |
| 1630 (work_area != last_work_area_); | 1546 (work_area != last_work_area_); |
| 1631 if (monitor && (monitor == last_monitor_) && | 1547 if (monitor && (monitor == last_monitor_) && |
| 1632 ((IsFullscreen() && !metro_snap_) || work_area_changed)) { | 1548 ((IsFullscreen() && !fullscreen_handler_->metro_snap()) || |
| 1549 work_area_changed)) { |
| 1633 // A rect for the monitor we're on changed. Normally Windows notifies | 1550 // A rect for the monitor we're on changed. Normally Windows notifies |
| 1634 // us about this (and thus we're reaching here due to the SetWindowPos() | 1551 // us about this (and thus we're reaching here due to the SetWindowPos() |
| 1635 // call in OnSettingChange() above), but with some software (e.g. | 1552 // call in OnSettingChange() above), but with some software (e.g. |
| 1636 // nVidia's nView desktop manager) the work area can change asynchronous | 1553 // nVidia's nView desktop manager) the work area can change asynchronous |
| 1637 // to any notification, and we're just sent a SetWindowPos() call with a | 1554 // to any notification, and we're just sent a SetWindowPos() call with a |
| 1638 // new (frequently incorrect) position/size. In either case, the best | 1555 // new (frequently incorrect) position/size. In either case, the best |
| 1639 // response is to throw away the existing position/size information in | 1556 // response is to throw away the existing position/size information in |
| 1640 // |window_pos| and recalculate it based on the new work rect. | 1557 // |window_pos| and recalculate it based on the new work rect. |
| 1641 gfx::Rect new_window_rect; | 1558 gfx::Rect new_window_rect; |
| 1642 if (IsFullscreen()) { | 1559 if (IsFullscreen()) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1666 FROM_HERE, | 1583 FROM_HERE, |
| 1667 base::Bind(&NativeWidgetWin::StopIgnoringPosChanges, | 1584 base::Bind(&NativeWidgetWin::StopIgnoringPosChanges, |
| 1668 ignore_pos_changes_factory_.GetWeakPtr())); | 1585 ignore_pos_changes_factory_.GetWeakPtr())); |
| 1669 } | 1586 } |
| 1670 last_monitor_ = monitor; | 1587 last_monitor_ = monitor; |
| 1671 last_monitor_rect_ = monitor_rect; | 1588 last_monitor_rect_ = monitor_rect; |
| 1672 last_work_area_ = work_area; | 1589 last_work_area_ = work_area; |
| 1673 } | 1590 } |
| 1674 } | 1591 } |
| 1675 | 1592 |
| 1676 if (force_hidden_count_) { | 1593 if (ScopedFullscreenVisibility::IsHiddenForFullscreen(GetNativeView())) { |
| 1677 // Prevent the window from being made visible if we've been asked to do so. | 1594 // Prevent the window from being made visible if we've been asked to do so. |
| 1678 // See comment in header as to why we might want this. | 1595 // See comment in header as to why we might want this. |
| 1679 window_pos->flags &= ~SWP_SHOWWINDOW; | 1596 window_pos->flags &= ~SWP_SHOWWINDOW; |
| 1680 } | 1597 } |
| 1681 | 1598 |
| 1682 // When WM_WINDOWPOSCHANGING message is handled by DefWindowProc, it will | 1599 // When WM_WINDOWPOSCHANGING message is handled by DefWindowProc, it will |
| 1683 // enforce (cx, cy) not to be smaller than (6, 6) for any non-popup window. | 1600 // enforce (cx, cy) not to be smaller than (6, 6) for any non-popup window. |
| 1684 // We work around this by changing cy back to our intended value. | 1601 // We work around this by changing cy back to our intended value. |
| 1685 if (!GetParent() && !(window_pos->flags & SWP_NOSIZE) && window_pos->cy < 6) { | 1602 if (!GetParent() && !(window_pos->flags & SWP_NOSIZE) && window_pos->cy < 6) { |
| 1686 LONG old_cy = window_pos->cy; | 1603 LONG old_cy = window_pos->cy; |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2343 // static | 2260 // static |
| 2344 bool NativeWidgetPrivate::IsTouchDown() { | 2261 bool NativeWidgetPrivate::IsTouchDown() { |
| 2345 // This currently isn't necessary because we're not generating touch events on | 2262 // This currently isn't necessary because we're not generating touch events on |
| 2346 // windows. When we do, this will need to be updated. | 2263 // windows. When we do, this will need to be updated. |
| 2347 return false; | 2264 return false; |
| 2348 } | 2265 } |
| 2349 | 2266 |
| 2350 } // namespace internal | 2267 } // namespace internal |
| 2351 | 2268 |
| 2352 } // namespace views | 2269 } // namespace views |
| OLD | NEW |