| 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 |