| 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 "chrome/browser/ui/views/frame/minimize_button_metrics_win.h" | 5 #include "chrome/browser/ui/views/frame/minimize_button_metrics_win.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/i18n/rtl.h" | 8 #include "base/i18n/rtl.h" |
| 9 #include "base/win/windows_version.h" | 9 #include "base/win/windows_version.h" |
| 10 #include "dwmapi.h" | 10 #include "dwmapi.h" |
| 11 #include "ui/base/win/shell.h" | 11 #include "ui/base/win/shell.h" |
| 12 #include "ui/display/win/dpi.h" | 12 #include "ui/display/win/dpi.h" |
| 13 #include "ui/display/win/screen_win.h" | 13 #include "ui/display/win/screen_win.h" |
| 14 #include "ui/gfx/geometry/point.h" | 14 #include "ui/gfx/geometry/point.h" |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 // These constants were determined by manually adding various offsets | 18 // These constants were determined by manually adding various offsets |
| 19 // until the identity switcher was placed at the same location as before. | 19 // until the identity switcher was placed at the same location as before. |
| 20 // When a new or updated OS version is released, a new constant may need | 20 // When a new or updated OS version is released, a new constant may need |
| 21 // to be added to this list and GetDefaultButtonBoundsOffset() is updated. | 21 // to be added to this list and GetDefaultButtonBoundsOffset() is updated. |
| 22 const int kWin7ButtonBoundsPositionOffset = 1; | 22 const int kWin7ButtonBoundsPositionOffset = 1; |
| 23 const int kWin8ButtonBoundsPositionOffset = 10; | 23 const int kWin8ButtonBoundsPositionOffset = 10; |
| 24 const int kWin10ButtonBoundsPositionOffset = 6; | 24 const int kWin10ButtonBoundsPositionOffset = 6; |
| 25 const int kInvalidOffset = static_cast<int>(0x80000000); | 25 const int kInvalidOffset = static_cast<int>(0x80000000); |
| 26 | 26 |
| 27 // This constant was determined manually by testing on windows 10. |
| 28 const int kWin10ButtonHeight = 30; |
| 29 const int kInvalidHeight = static_cast<int>(0x80000000); |
| 30 |
| 27 using base::win::GetVersion; | 31 using base::win::GetVersion; |
| 28 using display::win::ScreenWin; | 32 using display::win::ScreenWin; |
| 29 | 33 |
| 30 int GetDefaultButtonBoundsOffset() { | 34 int GetDefaultButtonBoundsOffset() { |
| 31 if (GetVersion() >= base::win::VERSION_WIN10) | 35 if (GetVersion() >= base::win::VERSION_WIN10) |
| 32 return kWin10ButtonBoundsPositionOffset; | 36 return kWin10ButtonBoundsPositionOffset; |
| 33 if (GetVersion() >= base::win::VERSION_WIN8) | 37 if (GetVersion() >= base::win::VERSION_WIN8) |
| 34 return kWin8ButtonBoundsPositionOffset; | 38 return kWin8ButtonBoundsPositionOffset; |
| 35 return kWin7ButtonBoundsPositionOffset; | 39 return kWin7ButtonBoundsPositionOffset; |
| 36 } | 40 } |
| 37 | 41 |
| 42 int GetDefaultButtonHeight() { |
| 43 return kWin10ButtonHeight; |
| 44 } |
| 45 |
| 38 } // namespace | 46 } // namespace |
| 39 | 47 |
| 40 // static | 48 // static |
| 41 int MinimizeButtonMetrics::last_cached_minimize_button_x_delta_ = 0; | 49 int MinimizeButtonMetrics::last_cached_minimize_button_x_delta_ = 0; |
| 42 | 50 |
| 43 // static | 51 // static |
| 44 int MinimizeButtonMetrics::button_bounds_position_offset_ = kInvalidOffset; | 52 int MinimizeButtonMetrics::button_bounds_position_offset_ = kInvalidOffset; |
| 45 | 53 |
| 54 // statis |
| 55 int MinimizeButtonMetrics::button_bounds_height_ = kInvalidHeight; |
| 56 |
| 46 MinimizeButtonMetrics::MinimizeButtonMetrics() | 57 MinimizeButtonMetrics::MinimizeButtonMetrics() |
| 47 : hwnd_(nullptr), | 58 : hwnd_(nullptr), |
| 48 cached_minimize_button_x_delta_(last_cached_minimize_button_x_delta_), | 59 cached_minimize_button_x_delta_(last_cached_minimize_button_x_delta_), |
| 49 was_activated_(false) { | 60 was_activated_(false) { |
| 50 } | 61 } |
| 51 | 62 |
| 52 MinimizeButtonMetrics::~MinimizeButtonMetrics() { | 63 MinimizeButtonMetrics::~MinimizeButtonMetrics() { |
| 53 } | 64 } |
| 54 | 65 |
| 55 void MinimizeButtonMetrics::Init(HWND hwnd) { | 66 void MinimizeButtonMetrics::Init(HWND hwnd) { |
| 56 DCHECK(!hwnd_); | 67 DCHECK(!hwnd_); |
| 57 hwnd_ = hwnd; | 68 hwnd_ = hwnd; |
| 58 } | 69 } |
| 59 | 70 |
| 60 void MinimizeButtonMetrics::OnHWNDActivated() { | 71 void MinimizeButtonMetrics::OnHWNDActivated() { |
| 61 was_activated_ = true; | 72 was_activated_ = true; |
| 62 // NOTE: we don't cache here as it seems only after the activate is the value | 73 // NOTE: we don't cache here as it seems only after the activate is the value |
| 63 // correct. | 74 // correct. |
| 64 } | 75 } |
| 65 | 76 |
| 77 void MinimizeButtonMetrics::UpdateButtonBoundsSizes(const RECT& button_bounds, |
| 78 const RECT& window_bounds) const { |
| 79 // LOG(ERROR) << "X BUTTON BOUNDS " << button_bounds.left << ", " << button_bou
nds.top << " - " << button_bounds.right - button_bounds.left << " x " << button_
bounds.top - button_bounds.bottom; |
| 80 |
| 81 if (button_bounds_position_offset_ != kInvalidOffset) { |
| 82 return; |
| 83 } |
| 84 DCHECK_EQ(kInvalidHeight, button_bounds_height_); |
| 85 |
| 86 if (button_bounds.left == button_bounds.right || button_bounds.top == button_b
ounds.left) { |
| 87 return; |
| 88 } |
| 89 if (!was_activated_ || !IsWindowVisible(hwnd_)) { |
| 90 return; |
| 91 } |
| 92 |
| 93 TITLEBARINFOEX info = { 0 }; |
| 94 info.cbSize = sizeof(info); |
| 95 SendMessage(hwnd_, WM_GETTITLEBARINFOEX, 0, |
| 96 reinterpret_cast<LPARAM>(&info)); |
| 97 if (info.rgrect[2].right == info.rgrect[2].left || |
| 98 (info.rgstate[2] & (STATE_SYSTEM_INVISIBLE | STATE_SYSTEM_OFFSCREEN | |
| 99 STATE_SYSTEM_UNAVAILABLE))) { |
| 100 return; |
| 101 } |
| 102 button_bounds_position_offset_ = |
| 103 info.rgrect[2].left - (button_bounds.left + window_bounds.left); |
| 104 button_bounds_height_ = button_bounds.bottom - button_bounds.top; |
| 105 } |
| 106 |
| 66 // This function attempts to calculate the odd and varying difference | 107 // This function attempts to calculate the odd and varying difference |
| 67 // between the results of DwmGetWindowAttribute with the | 108 // between the results of DwmGetWindowAttribute with the |
| 68 // DWMWA_CAPTION_BUTTON_BOUNDS flag and the information from the | 109 // DWMWA_CAPTION_BUTTON_BOUNDS flag and the information from the |
| 69 // WM_GETTITLEBARINFOEX message. It will return an empirically determined | 110 // WM_GETTITLEBARINFOEX message. It will return an empirically determined |
| 70 // offset until the window has been activated and the message returns | 111 // offset until the window has been activated and the message returns |
| 71 // valid rectangles. | 112 // valid rectangles. |
| 72 int MinimizeButtonMetrics::GetButtonBoundsPositionOffset( | 113 int MinimizeButtonMetrics::GetButtonBoundsPositionOffset( |
| 73 const RECT& button_bounds, | 114 const RECT& button_bounds, |
| 74 const RECT& window_bounds) const { | 115 const RECT& window_bounds) const { |
| 75 if (button_bounds_position_offset_ == kInvalidOffset) { | 116 UpdateButtonBoundsSizes(button_bounds, window_bounds); |
| 76 if (!was_activated_ || !IsWindowVisible(hwnd_)) | 117 if (button_bounds_position_offset_ == kInvalidOffset) |
| 77 return GetDefaultButtonBoundsOffset(); | 118 return GetDefaultButtonBoundsOffset(); |
| 78 TITLEBARINFOEX info = {0}; | |
| 79 info.cbSize = sizeof(info); | |
| 80 SendMessage(hwnd_, WM_GETTITLEBARINFOEX, 0, | |
| 81 reinterpret_cast<LPARAM>(&info)); | |
| 82 if (info.rgrect[2].right == info.rgrect[2].left || | |
| 83 (info.rgstate[2] & (STATE_SYSTEM_INVISIBLE | STATE_SYSTEM_OFFSCREEN | | |
| 84 STATE_SYSTEM_UNAVAILABLE))) | |
| 85 return GetDefaultButtonBoundsOffset(); | |
| 86 button_bounds_position_offset_ = | |
| 87 info.rgrect[2].left - (button_bounds.left + window_bounds.left); | |
| 88 } | |
| 89 return button_bounds_position_offset_; | 119 return button_bounds_position_offset_; |
| 90 } | 120 } |
| 91 | 121 |
| 92 int MinimizeButtonMetrics::GetMinimizeButtonOffsetForWindow() const { | 122 int MinimizeButtonMetrics::GetMinimizeButtonOffsetForWindow() const { |
| 93 bool dwm_button_pos = false; | 123 bool dwm_button_pos = false; |
| 94 POINT minimize_button_corner = {0}; | 124 POINT minimize_button_corner = {0}; |
| 95 RECT button_bounds = {0}; | 125 RECT button_bounds = {0}; |
| 96 if (SUCCEEDED(DwmGetWindowAttribute(hwnd_, DWMWA_CAPTION_BUTTON_BOUNDS, | 126 if (SUCCEEDED(DwmGetWindowAttribute(hwnd_, DWMWA_CAPTION_BUTTON_BOUNDS, |
| 97 &button_bounds, sizeof(button_bounds)))) { | 127 &button_bounds, sizeof(button_bounds)))) { |
| 98 if (button_bounds.left != button_bounds.right) { | 128 if (button_bounds.left != button_bounds.right) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 cached_minimize_button_x_delta_ = minimize_button_offset; | 212 cached_minimize_button_x_delta_ = minimize_button_offset; |
| 183 } else { | 213 } else { |
| 184 RECT client_rect = {0}; | 214 RECT client_rect = {0}; |
| 185 GetClientRect(hwnd_, &client_rect); | 215 GetClientRect(hwnd_, &client_rect); |
| 186 cached_minimize_button_x_delta_ = | 216 cached_minimize_button_x_delta_ = |
| 187 client_rect.right - minimize_button_offset; | 217 client_rect.right - minimize_button_offset; |
| 188 } | 218 } |
| 189 last_cached_minimize_button_x_delta_ = cached_minimize_button_x_delta_; | 219 last_cached_minimize_button_x_delta_ = cached_minimize_button_x_delta_; |
| 190 return minimize_button_offset; | 220 return minimize_button_offset; |
| 191 } | 221 } |
| 222 |
| 223 int MinimizeButtonMetrics::GetMinimizeButtonHeight() const { |
| 224 if (button_bounds_height_ == kInvalidHeight) { |
| 225 RECT button_bounds = { 0 }; |
| 226 if (SUCCEEDED(DwmGetWindowAttribute(hwnd_, DWMWA_CAPTION_BUTTON_BOUNDS, |
| 227 &button_bounds, sizeof(button_bounds)))) { |
| 228 // This converts the button coordinate into screen coordinates |
| 229 // thus, ensuring that the identity switcher is placed in the |
| 230 // same location as before. An additional constant is added because |
| 231 // there is a difference between the caption button bounds and |
| 232 // the values obtained through WM_GETTITLEBARINFOEX. This difference |
| 233 // varies between OS versions, and no metric describing this difference |
| 234 // has been located. |
| 235 RECT window_bounds = { 0 }; |
| 236 if (GetWindowRect(hwnd_, &window_bounds)) { |
| 237 UpdateButtonBoundsSizes(button_bounds, window_bounds); |
| 238 } |
| 239 } |
| 240 } |
| 241 |
| 242 if (button_bounds_height_ == kInvalidHeight) |
| 243 return GetDefaultButtonHeight(); |
| 244 return button_bounds_height_; |
| 245 } |
| OLD | NEW |