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 |