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 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 bool NativeWidgetWin::IsMinimized() const { | 977 bool NativeWidgetWin::IsMinimized() const { |
978 return !!::IsIconic(GetNativeView()); | 978 return !!::IsIconic(GetNativeView()); |
979 } | 979 } |
980 | 980 |
981 void NativeWidgetWin::Restore() { | 981 void NativeWidgetWin::Restore() { |
982 ExecuteSystemMenuCommand(SC_RESTORE); | 982 ExecuteSystemMenuCommand(SC_RESTORE); |
983 } | 983 } |
984 | 984 |
985 void NativeWidgetWin::SetFullscreen(bool fullscreen) { | 985 void NativeWidgetWin::SetFullscreen(bool fullscreen) { |
986 if (fullscreen_ == fullscreen) | 986 if (fullscreen_ == fullscreen) |
987 return; // Nothing to do. | 987 return; |
| 988 |
| 989 gfx::Rect window_rect; |
| 990 if (fullscreen) { |
| 991 MONITORINFO monitor_info; |
| 992 monitor_info.cbSize = sizeof(monitor_info); |
| 993 GetMonitorInfo(MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), |
| 994 &monitor_info); |
| 995 window_rect = monitor_info.rcMonitor; |
| 996 } |
| 997 |
| 998 SetFullscreenInternal(fullscreen, window_rect); |
| 999 } |
| 1000 |
| 1001 void NativeWidgetWin::SetMetroSnapFullscreen(bool metro_snap) { |
| 1002 if (metro_snap_ == metro_snap) |
| 1003 return; |
| 1004 |
| 1005 metro_snap_ = metro_snap; |
| 1006 |
| 1007 gfx::Rect window_rect; |
| 1008 if (!metro_snap) { |
| 1009 MONITORINFO monitor_info; |
| 1010 monitor_info.cbSize = sizeof(monitor_info); |
| 1011 GetMonitorInfo(MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), |
| 1012 &monitor_info); |
| 1013 window_rect = monitor_info.rcMonitor; |
| 1014 } |
| 1015 |
| 1016 SetFullscreenInternal(metro_snap, window_rect); |
| 1017 } |
| 1018 |
| 1019 void NativeWidgetWin::SetFullscreenInternal(bool fullscreen, |
| 1020 const gfx::Rect& window_rect) { |
988 | 1021 |
989 // Reduce jankiness during the following position changes by hiding the window | 1022 // Reduce jankiness during the following position changes by hiding the window |
990 // until it's in the final position. | 1023 // until it's in the final position. |
991 PushForceHidden(); | 1024 PushForceHidden(); |
992 | 1025 |
993 // Size/position/style window appropriately. | 1026 // Size/position/style window appropriately. |
994 if (!fullscreen_) { | 1027 if (!fullscreen_) { |
995 // Save current window information. We force the window into restored mode | 1028 // Save current window information. We force the window into restored mode |
996 // before going fullscreen because Windows doesn't seem to hide the | 1029 // before going fullscreen because Windows doesn't seem to hide the |
997 // taskbar if the window is in the maximized state. | 1030 // taskbar if the window is in the maximized state. |
998 saved_window_info_.maximized = IsMaximized(); | 1031 saved_window_info_.maximized = IsMaximized(); |
999 if (saved_window_info_.maximized) | 1032 if (saved_window_info_.maximized) |
1000 Restore(); | 1033 Restore(); |
1001 saved_window_info_.style = GetWindowLong(GWL_STYLE); | 1034 saved_window_info_.style = GetWindowLong(GWL_STYLE); |
1002 saved_window_info_.ex_style = GetWindowLong(GWL_EXSTYLE); | 1035 saved_window_info_.ex_style = GetWindowLong(GWL_EXSTYLE); |
1003 GetWindowRect(&saved_window_info_.window_rect); | 1036 GetWindowRect(&saved_window_info_.window_rect); |
1004 } | 1037 } |
1005 | 1038 |
1006 fullscreen_ = fullscreen; | 1039 fullscreen_ = fullscreen; |
1007 | 1040 |
1008 if (fullscreen_) { | 1041 if (fullscreen_) { |
1009 // Set new window style and size. | 1042 // Set new window style and size. |
1010 MONITORINFO monitor_info; | |
1011 monitor_info.cbSize = sizeof(monitor_info); | |
1012 GetMonitorInfo(MonitorFromWindow(GetNativeView(), MONITOR_DEFAULTTONEAREST), | |
1013 &monitor_info); | |
1014 gfx::Rect monitor_rect(monitor_info.rcMonitor); | |
1015 SetWindowLong(GWL_STYLE, | 1043 SetWindowLong(GWL_STYLE, |
1016 saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME)); | 1044 saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME)); |
1017 SetWindowLong(GWL_EXSTYLE, | 1045 SetWindowLong(GWL_EXSTYLE, |
1018 saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME | | 1046 saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME | |
1019 WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); | 1047 WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); |
1020 SetWindowPos(NULL, monitor_rect.x(), monitor_rect.y(), | 1048 |
1021 monitor_rect.width(), monitor_rect.height(), | 1049 // On expand, if we're given a window_rect, grow to it, otherwise do |
1022 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); | 1050 // not resize. |
| 1051 if (window_rect.width() > 0) { |
| 1052 SetWindowPos(NULL, window_rect.x(), window_rect.y(), |
| 1053 window_rect.width(), window_rect.height(), |
| 1054 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); |
| 1055 } |
1023 } else { | 1056 } else { |
1024 // Reset original window style and size. The multiple window size/moves | 1057 // Reset original window style and size. The multiple window size/moves |
1025 // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be | 1058 // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be |
1026 // repainted. Better-looking methods welcome. | 1059 // repainted. Better-looking methods welcome. |
1027 gfx::Rect new_rect(saved_window_info_.window_rect); | |
1028 SetWindowLong(GWL_STYLE, saved_window_info_.style); | 1060 SetWindowLong(GWL_STYLE, saved_window_info_.style); |
1029 SetWindowLong(GWL_EXSTYLE, saved_window_info_.ex_style); | 1061 SetWindowLong(GWL_EXSTYLE, saved_window_info_.ex_style); |
| 1062 |
| 1063 // On restore, if we're given a window_rect resize to that, otherwise |
| 1064 // resize to the previous saved rect size. |
| 1065 gfx::Rect new_rect; |
| 1066 if (window_rect.width() > 0) { |
| 1067 new_rect = window_rect; |
| 1068 } else { |
| 1069 new_rect = saved_window_info_.window_rect; |
| 1070 } |
| 1071 |
1030 SetWindowPos(NULL, new_rect.x(), new_rect.y(), new_rect.width(), | 1072 SetWindowPos(NULL, new_rect.x(), new_rect.y(), new_rect.width(), |
1031 new_rect.height(), | 1073 new_rect.height(), |
1032 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); | 1074 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); |
1033 if (saved_window_info_.maximized) | 1075 if (saved_window_info_.maximized) |
1034 Maximize(); | 1076 Maximize(); |
1035 } | 1077 } |
1036 | 1078 |
1037 // Undo our anti-jankiness hacks. | 1079 // Undo our anti-jankiness hacks. |
1038 PopForceHidden(); | 1080 PopForceHidden(); |
1039 } | 1081 } |
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2094 // Just sizing/moving the window; ignore. | 2136 // Just sizing/moving the window; ignore. |
2095 window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW; | 2137 window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW; |
2096 window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW); | 2138 window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW); |
2097 } | 2139 } |
2098 } else if (!GetParent()) { | 2140 } else if (!GetParent()) { |
2099 CRect window_rect; | 2141 CRect window_rect; |
2100 HMONITOR monitor; | 2142 HMONITOR monitor; |
2101 gfx::Rect monitor_rect, work_area; | 2143 gfx::Rect monitor_rect, work_area; |
2102 if (GetWindowRect(&window_rect) && | 2144 if (GetWindowRect(&window_rect) && |
2103 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { | 2145 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { |
| 2146 bool work_area_changed = (monitor_rect == last_monitor_rect_) && |
| 2147 (work_area != last_work_area_); |
2104 if (monitor && (monitor == last_monitor_) && | 2148 if (monitor && (monitor == last_monitor_) && |
2105 (IsFullscreen() || ((monitor_rect == last_monitor_rect_) && | 2149 ((IsFullscreen() && !metro_snap_) || work_area_changed)) { |
2106 (work_area != last_work_area_)))) { | |
2107 // A rect for the monitor we're on changed. Normally Windows notifies | 2150 // A rect for the monitor we're on changed. Normally Windows notifies |
2108 // us about this (and thus we're reaching here due to the SetWindowPos() | 2151 // us about this (and thus we're reaching here due to the SetWindowPos() |
2109 // call in OnSettingChange() above), but with some software (e.g. | 2152 // call in OnSettingChange() above), but with some software (e.g. |
2110 // nVidia's nView desktop manager) the work area can change asynchronous | 2153 // nVidia's nView desktop manager) the work area can change asynchronous |
2111 // to any notification, and we're just sent a SetWindowPos() call with a | 2154 // to any notification, and we're just sent a SetWindowPos() call with a |
2112 // new (frequently incorrect) position/size. In either case, the best | 2155 // new (frequently incorrect) position/size. In either case, the best |
2113 // response is to throw away the existing position/size information in | 2156 // response is to throw away the existing position/size information in |
2114 // |window_pos| and recalculate it based on the new work rect. | 2157 // |window_pos| and recalculate it based on the new work rect. |
2115 gfx::Rect new_window_rect; | 2158 gfx::Rect new_window_rect; |
2116 if (IsFullscreen()) { | 2159 if (IsFullscreen()) { |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2726 // static | 2769 // static |
2727 bool NativeWidgetPrivate::IsTouchDown() { | 2770 bool NativeWidgetPrivate::IsTouchDown() { |
2728 // This currently isn't necessary because we're not generating touch events on | 2771 // This currently isn't necessary because we're not generating touch events on |
2729 // windows. When we do, this will need to be updated. | 2772 // windows. When we do, this will need to be updated. |
2730 return false; | 2773 return false; |
2731 } | 2774 } |
2732 | 2775 |
2733 } // namespace internal | 2776 } // namespace internal |
2734 | 2777 |
2735 } // namespace views | 2778 } // namespace views |
OLD | NEW |