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