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 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 use_layered_buffer_(false), | 415 use_layered_buffer_(false), |
416 layered_alpha_(255), | 416 layered_alpha_(255), |
417 ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)), | 417 ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)), |
418 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), | 418 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), |
419 can_update_layered_window_(true), | 419 can_update_layered_window_(true), |
420 restore_focus_when_enabled_(false), | 420 restore_focus_when_enabled_(false), |
421 accessibility_view_events_index_(-1), | 421 accessibility_view_events_index_(-1), |
422 accessibility_view_events_(kMaxAccessibilityViewEvents), | 422 accessibility_view_events_(kMaxAccessibilityViewEvents), |
423 previous_cursor_(NULL), | 423 previous_cursor_(NULL), |
424 fullscreen_(false), | 424 fullscreen_(false), |
| 425 metro_snap_(false), |
425 force_hidden_count_(0), | 426 force_hidden_count_(0), |
426 lock_updates_count_(0), | 427 lock_updates_count_(0), |
427 ignore_window_pos_changes_(false), | 428 ignore_window_pos_changes_(false), |
428 ALLOW_THIS_IN_INITIALIZER_LIST(ignore_pos_changes_factory_(this)), | 429 ALLOW_THIS_IN_INITIALIZER_LIST(ignore_pos_changes_factory_(this)), |
429 last_monitor_(NULL), | 430 last_monitor_(NULL), |
430 is_right_mouse_pressed_on_caption_(false), | 431 is_right_mouse_pressed_on_caption_(false), |
431 restored_enabled_(false), | 432 restored_enabled_(false), |
432 destroyed_(NULL), | 433 destroyed_(NULL), |
433 has_non_client_view_(false) { | 434 has_non_client_view_(false) { |
434 } | 435 } |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 bool NativeWidgetWin::IsMinimized() const { | 984 bool NativeWidgetWin::IsMinimized() const { |
984 return !!::IsIconic(GetNativeView()); | 985 return !!::IsIconic(GetNativeView()); |
985 } | 986 } |
986 | 987 |
987 void NativeWidgetWin::Restore() { | 988 void NativeWidgetWin::Restore() { |
988 ExecuteSystemMenuCommand(SC_RESTORE); | 989 ExecuteSystemMenuCommand(SC_RESTORE); |
989 } | 990 } |
990 | 991 |
991 void NativeWidgetWin::SetFullscreen(bool fullscreen) { | 992 void NativeWidgetWin::SetFullscreen(bool fullscreen) { |
992 if (fullscreen_ == fullscreen) | 993 if (fullscreen_ == fullscreen) |
993 return; // Nothing to do. | 994 return; |
| 995 |
| 996 gfx::Rect window_rect; |
| 997 if (fullscreen) { |
| 998 MONITORINFO monitor_info; |
| 999 monitor_info.cbSize = sizeof(monitor_info); |
| 1000 GetMonitorInfo(MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), |
| 1001 &monitor_info); |
| 1002 window_rect = monitor_info.rcMonitor; |
| 1003 } |
| 1004 |
| 1005 SetFullscreenInternal(fullscreen, window_rect); |
| 1006 } |
| 1007 |
| 1008 void NativeWidgetWin::SetMetroSnapFullscreen(bool metro_snap) { |
| 1009 if (metro_snap_ == metro_snap) |
| 1010 return; |
| 1011 |
| 1012 metro_snap_ = metro_snap; |
| 1013 |
| 1014 gfx::Rect window_rect; |
| 1015 if (!metro_snap) { |
| 1016 MONITORINFO monitor_info; |
| 1017 monitor_info.cbSize = sizeof(monitor_info); |
| 1018 GetMonitorInfo(MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), |
| 1019 &monitor_info); |
| 1020 window_rect = monitor_info.rcMonitor; |
| 1021 } |
| 1022 |
| 1023 SetFullscreenInternal(metro_snap, window_rect); |
| 1024 } |
| 1025 |
| 1026 void NativeWidgetWin::SetFullscreenInternal(bool fullscreen, |
| 1027 const gfx::Rect& window_rect) { |
994 | 1028 |
995 // Reduce jankiness during the following position changes by hiding the window | 1029 // Reduce jankiness during the following position changes by hiding the window |
996 // until it's in the final position. | 1030 // until it's in the final position. |
997 PushForceHidden(); | 1031 PushForceHidden(); |
998 | 1032 |
999 // Size/position/style window appropriately. | 1033 // Size/position/style window appropriately. |
1000 if (!fullscreen_) { | 1034 if (!fullscreen_) { |
1001 // Save current window information. We force the window into restored mode | 1035 // Save current window information. We force the window into restored mode |
1002 // before going fullscreen because Windows doesn't seem to hide the | 1036 // before going fullscreen because Windows doesn't seem to hide the |
1003 // taskbar if the window is in the maximized state. | 1037 // taskbar if the window is in the maximized state. |
1004 saved_window_info_.maximized = IsMaximized(); | 1038 saved_window_info_.maximized = IsMaximized(); |
1005 if (saved_window_info_.maximized) | 1039 if (saved_window_info_.maximized) |
1006 Restore(); | 1040 Restore(); |
1007 saved_window_info_.style = GetWindowLong(GWL_STYLE); | 1041 saved_window_info_.style = GetWindowLong(GWL_STYLE); |
1008 saved_window_info_.ex_style = GetWindowLong(GWL_EXSTYLE); | 1042 saved_window_info_.ex_style = GetWindowLong(GWL_EXSTYLE); |
1009 GetWindowRect(&saved_window_info_.window_rect); | 1043 GetWindowRect(&saved_window_info_.window_rect); |
1010 } | 1044 } |
1011 | 1045 |
1012 fullscreen_ = fullscreen; | 1046 fullscreen_ = fullscreen; |
1013 | 1047 |
1014 if (fullscreen_) { | 1048 if (fullscreen_) { |
1015 // Set new window style and size. | 1049 // Set new window style and size. |
1016 MONITORINFO monitor_info; | |
1017 monitor_info.cbSize = sizeof(monitor_info); | |
1018 GetMonitorInfo(MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), | |
1019 &monitor_info); | |
1020 gfx::Rect monitor_rect(monitor_info.rcMonitor); | |
1021 SetWindowLong(GWL_STYLE, | 1050 SetWindowLong(GWL_STYLE, |
1022 saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME)); | 1051 saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME)); |
1023 SetWindowLong(GWL_EXSTYLE, | 1052 SetWindowLong(GWL_EXSTYLE, |
1024 saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME | | 1053 saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME | |
1025 WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); | 1054 WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); |
1026 SetWindowPos(NULL, monitor_rect.x(), monitor_rect.y(), | 1055 |
1027 monitor_rect.width(), monitor_rect.height(), | 1056 // On expand, if we're given a window_rect, grow to it, otherwise do |
1028 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); | 1057 // not resize. |
| 1058 if (window_rect.width() > 0) { |
| 1059 SetWindowPos(NULL, window_rect.x(), window_rect.y(), |
| 1060 window_rect.width(), window_rect.height(), |
| 1061 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); |
| 1062 } |
1029 } else { | 1063 } else { |
1030 // Reset original window style and size. The multiple window size/moves | 1064 // Reset original window style and size. The multiple window size/moves |
1031 // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be | 1065 // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be |
1032 // repainted. Better-looking methods welcome. | 1066 // repainted. Better-looking methods welcome. |
1033 gfx::Rect new_rect(saved_window_info_.window_rect); | |
1034 SetWindowLong(GWL_STYLE, saved_window_info_.style); | 1067 SetWindowLong(GWL_STYLE, saved_window_info_.style); |
1035 SetWindowLong(GWL_EXSTYLE, saved_window_info_.ex_style); | 1068 SetWindowLong(GWL_EXSTYLE, saved_window_info_.ex_style); |
| 1069 |
| 1070 // On restore, if we're given a window_rect resize to that, otherwise |
| 1071 // resize to the previous saved rect size. |
| 1072 gfx::Rect new_rect; |
| 1073 if (window_rect.width() > 0) { |
| 1074 new_rect = window_rect; |
| 1075 } else { |
| 1076 new_rect = saved_window_info_.window_rect; |
| 1077 } |
| 1078 |
1036 SetWindowPos(NULL, new_rect.x(), new_rect.y(), new_rect.width(), | 1079 SetWindowPos(NULL, new_rect.x(), new_rect.y(), new_rect.width(), |
1037 new_rect.height(), | 1080 new_rect.height(), |
1038 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); | 1081 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); |
1039 if (saved_window_info_.maximized) | 1082 if (saved_window_info_.maximized) |
1040 Maximize(); | 1083 Maximize(); |
1041 } | 1084 } |
1042 | 1085 |
1043 // Undo our anti-jankiness hacks. | 1086 // Undo our anti-jankiness hacks. |
1044 PopForceHidden(); | 1087 PopForceHidden(); |
1045 } | 1088 } |
1046 | 1089 |
1047 bool NativeWidgetWin::IsFullscreen() const { | 1090 bool NativeWidgetWin::IsFullscreen() const { |
1048 return fullscreen_; | 1091 return fullscreen_; |
1049 } | 1092 } |
1050 | 1093 |
| 1094 bool NativeWidgetWin::IsInMetroSnapMode() const { |
| 1095 return metro_snap_; |
| 1096 } |
| 1097 |
1051 void NativeWidgetWin::SetOpacity(unsigned char opacity) { | 1098 void NativeWidgetWin::SetOpacity(unsigned char opacity) { |
1052 layered_alpha_ = static_cast<BYTE>(opacity); | 1099 layered_alpha_ = static_cast<BYTE>(opacity); |
1053 GetWidget()->GetRootView()->SchedulePaint(); | 1100 GetWidget()->GetRootView()->SchedulePaint(); |
1054 } | 1101 } |
1055 | 1102 |
1056 void NativeWidgetWin::SetUseDragFrame(bool use_drag_frame) { | 1103 void NativeWidgetWin::SetUseDragFrame(bool use_drag_frame) { |
1057 if (use_drag_frame) { | 1104 if (use_drag_frame) { |
1058 // Make the frame slightly transparent during the drag operation. | 1105 // Make the frame slightly transparent during the drag operation. |
1059 drag_frame_saved_window_style_ = GetWindowLong(GWL_STYLE); | 1106 drag_frame_saved_window_style_ = GetWindowLong(GWL_STYLE); |
1060 drag_frame_saved_window_ex_style_ = GetWindowLong(GWL_EXSTYLE); | 1107 drag_frame_saved_window_ex_style_ = GetWindowLong(GWL_EXSTYLE); |
(...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2100 // Just sizing/moving the window; ignore. | 2147 // Just sizing/moving the window; ignore. |
2101 window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW; | 2148 window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW; |
2102 window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW); | 2149 window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW); |
2103 } | 2150 } |
2104 } else if (!GetParent()) { | 2151 } else if (!GetParent()) { |
2105 CRect window_rect; | 2152 CRect window_rect; |
2106 HMONITOR monitor; | 2153 HMONITOR monitor; |
2107 gfx::Rect monitor_rect, work_area; | 2154 gfx::Rect monitor_rect, work_area; |
2108 if (GetWindowRect(&window_rect) && | 2155 if (GetWindowRect(&window_rect) && |
2109 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { | 2156 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { |
| 2157 bool work_area_changed = (monitor_rect == last_monitor_rect_) && |
| 2158 (work_area != last_work_area_); |
2110 if (monitor && (monitor == last_monitor_) && | 2159 if (monitor && (monitor == last_monitor_) && |
2111 (IsFullscreen() || ((monitor_rect == last_monitor_rect_) && | 2160 ((IsFullscreen() && !metro_snap_) || work_area_changed)) { |
2112 (work_area != last_work_area_)))) { | |
2113 // A rect for the monitor we're on changed. Normally Windows notifies | 2161 // A rect for the monitor we're on changed. Normally Windows notifies |
2114 // us about this (and thus we're reaching here due to the SetWindowPos() | 2162 // us about this (and thus we're reaching here due to the SetWindowPos() |
2115 // call in OnSettingChange() above), but with some software (e.g. | 2163 // call in OnSettingChange() above), but with some software (e.g. |
2116 // nVidia's nView desktop manager) the work area can change asynchronous | 2164 // nVidia's nView desktop manager) the work area can change asynchronous |
2117 // to any notification, and we're just sent a SetWindowPos() call with a | 2165 // to any notification, and we're just sent a SetWindowPos() call with a |
2118 // new (frequently incorrect) position/size. In either case, the best | 2166 // new (frequently incorrect) position/size. In either case, the best |
2119 // response is to throw away the existing position/size information in | 2167 // response is to throw away the existing position/size information in |
2120 // |window_pos| and recalculate it based on the new work rect. | 2168 // |window_pos| and recalculate it based on the new work rect. |
2121 gfx::Rect new_window_rect; | 2169 gfx::Rect new_window_rect; |
2122 if (IsFullscreen()) { | 2170 if (IsFullscreen()) { |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2732 // static | 2780 // static |
2733 bool NativeWidgetPrivate::IsTouchDown() { | 2781 bool NativeWidgetPrivate::IsTouchDown() { |
2734 // This currently isn't necessary because we're not generating touch events on | 2782 // This currently isn't necessary because we're not generating touch events on |
2735 // windows. When we do, this will need to be updated. | 2783 // windows. When we do, this will need to be updated. |
2736 return false; | 2784 return false; |
2737 } | 2785 } |
2738 | 2786 |
2739 } // namespace internal | 2787 } // namespace internal |
2740 | 2788 |
2741 } // namespace views | 2789 } // namespace views |
OLD | NEW |