Chromium Code Reviews| 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" | |
| 6 | |
| 7 #include "base/logging.h" | 5 #include "base/logging.h" |
| 8 #include "base/i18n/rtl.h" | 6 #include "base/i18n/rtl.h" |
| 7 #include "chrome/browser/ui/views/frame/minimize_button_metrics_win.h" | |
|
Ilya Kulshin
2016/05/03 23:40:52
Keep this as the first include. In general, Chromi
kylix_rd
2016/05/04 00:05:46
Ok, thanks.
| |
| 8 #include "dwmapi.h" | |
| 9 #include "ui/base/win/shell.h" | 9 #include "ui/base/win/shell.h" |
| 10 #include "ui/display/win/dpi.h" | 10 #include "ui/display/win/dpi.h" |
| 11 #include "ui/display/win/screen_win.h" | |
| 11 | 12 |
| 12 namespace { | 13 namespace { |
| 13 | 14 |
| 14 int GetMinimizeButtonOffsetForWindow(HWND hwnd) { | 15 using display::win::ScreenWin; |
| 16 | |
| 17 int GetMinimizeButtonOffsetForWindow(HWND hwnd, bool was_activated) { | |
| 18 bool dwm_button_pos = false; | |
| 19 POINT minimize_button_corner = { 0 }; | |
|
sky
2016/05/03 23:40:47
POINT->gfx::Point
kylix_rd
2016/05/04 14:25:10
This is a POINT because it is used down in MapWind
sky
2016/05/04 17:42:03
Got it.
| |
| 20 RECT button_bounds = { 0 }; | |
| 21 if (SUCCEEDED(DwmGetWindowAttribute(hwnd, DWMWA_CAPTION_BUTTON_BOUNDS, | |
| 22 reinterpret_cast<PVOID>(&button_bounds), sizeof(button_bounds)))) { | |
| 23 if (button_bounds.left != button_bounds.right) { | |
| 24 // This converts the button coordinate into screen coordinates | |
| 25 // thus, ensuring that the identity switcher is placed in the | |
| 26 // same location as before. | |
| 27 RECT window_bounds = { 0 }; | |
| 28 if (GetWindowRect(hwnd, reinterpret_cast<LPRECT>(&window_bounds))) | |
|
sky
2016/05/03 23:40:47
Why do you need a reinterpret_cast here?
Ilya Kulshin
2016/05/03 23:40:52
Do you actually need the reinterpret_cast here? Al
kylix_rd
2016/05/04 00:05:46
My C++ skills are clearly lacking here... You're p
| |
| 29 { | |
|
sky
2016/05/03 23:40:47
nit: { on previous line
| |
| 30 minimize_button_corner = | |
| 31 { button_bounds.left + window_bounds.left, 0 }; | |
| 32 dwm_button_pos = true; | |
| 33 } | |
| 34 } | |
| 35 } | |
| 36 if (!dwm_button_pos) { | |
| 15 // The WM_GETTITLEBARINFOEX message can fail if we are not active/visible. By | 37 // The WM_GETTITLEBARINFOEX message can fail if we are not active/visible. By |
| 16 // fail we get a location of 0; the return status code is always the same and | 38 // fail we get a location of 0; the return status code is always the same and |
| 17 // similarly the state never seems to change (titlebar_info.rgstate). | 39 // similarly the state never seems to change (titlebar_info.rgstate). |
|
Ilya Kulshin
2016/05/03 23:40:52
Indent comment to be aligned with the code, or mov
| |
| 18 TITLEBARINFOEX titlebar_info = {0}; | 40 TITLEBARINFOEX titlebar_info = { 0 }; |
| 19 titlebar_info.cbSize = sizeof(TITLEBARINFOEX); | 41 titlebar_info.cbSize = sizeof(TITLEBARINFOEX); |
| 20 SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0, | 42 SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0, |
|
Ilya Kulshin
2016/05/03 23:40:52
Do we still need this fallback? In what cases does
kylix_rd
2016/05/04 00:05:46
When DWM composing is disable globally or even on
| |
| 21 reinterpret_cast<WPARAM>(&titlebar_info)); | 43 reinterpret_cast<WPARAM>(&titlebar_info)); |
| 22 | 44 |
| 23 if (titlebar_info.rgrect[2].left == titlebar_info.rgrect[2].right || | 45 // Under DWM WM_GETTITLEBARINFOEX won't return the right thing until after |
| 46 // WM_NCACTIVATE (maybe it returns classic values?). In an attempt to | |
| 47 // return a consistant value we cache the last value across instances and | |
| 48 // use it until we get the activate. | |
| 49 if (!was_activated || | |
| 50 titlebar_info.rgrect[2].left == titlebar_info.rgrect[2].right || | |
| 24 (titlebar_info.rgstate[2] & (STATE_SYSTEM_INVISIBLE | | 51 (titlebar_info.rgstate[2] & (STATE_SYSTEM_INVISIBLE | |
| 25 STATE_SYSTEM_OFFSCREEN | | 52 STATE_SYSTEM_OFFSCREEN | |
| 26 STATE_SYSTEM_UNAVAILABLE))) { | 53 STATE_SYSTEM_UNAVAILABLE))) { |
| 27 return 0; | 54 return 0; |
| 55 } | |
| 56 minimize_button_corner = { titlebar_info.rgrect[2].left, 0 }; | |
| 28 } | 57 } |
| 29 | 58 |
| 30 // WM_GETTITLEBARINFOEX returns rects in screen coordinates in pixels. | 59 // WM_GETTITLEBARINFOEX returns rects in screen coordinates in pixels. |
| 31 // We need to convert the minimize button corner offset to DIP before | 60 // DWMNA_CAPTION_BUTTON_BOUNDS is in window (not client) coordinates, |
| 32 // returning it. | 61 // but it has been converted to screen coordinates above. We need to |
| 33 POINT minimize_button_corner = { titlebar_info.rgrect[2].left, 0 }; | 62 // convert the minimize button corner offset to DIP before returning it. |
| 34 MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1); | 63 MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1); |
| 35 return minimize_button_corner.x / display::win::GetDPIScale(); | 64 gfx::Point pixel_point = { minimize_button_corner.x, 0 }; |
| 65 gfx::Point dip_point = ScreenWin::ClientToDIPPoint(hwnd, pixel_point); | |
| 66 return dip_point.x(); | |
| 36 } | 67 } |
| 37 | 68 |
| 38 } // namespace | 69 } // namespace |
| 39 | 70 |
| 40 // static | 71 // static |
| 41 int MinimizeButtonMetrics::last_cached_minimize_button_x_delta_ = 0; | 72 int MinimizeButtonMetrics::last_cached_minimize_button_x_delta_ = 0; |
| 42 | 73 |
| 43 MinimizeButtonMetrics::MinimizeButtonMetrics() | 74 MinimizeButtonMetrics::MinimizeButtonMetrics() |
| 44 : hwnd_(nullptr), | 75 : hwnd_(nullptr), |
| 45 cached_minimize_button_x_delta_(last_cached_minimize_button_x_delta_), | 76 cached_minimize_button_x_delta_(last_cached_minimize_button_x_delta_), |
| 46 was_activated_(false) { | 77 was_activated_(false) { |
| 47 } | 78 } |
| 48 | 79 |
| 49 MinimizeButtonMetrics::~MinimizeButtonMetrics() { | 80 MinimizeButtonMetrics::~MinimizeButtonMetrics() { |
| 50 } | 81 } |
| 51 | 82 |
| 52 void MinimizeButtonMetrics::Init(HWND hwnd) { | 83 void MinimizeButtonMetrics::Init(HWND hwnd) { |
| 53 DCHECK(!hwnd_); | 84 DCHECK(!hwnd_); |
| 54 hwnd_ = hwnd; | 85 hwnd_ = hwnd; |
| 55 } | 86 } |
| 56 | 87 |
| 57 void MinimizeButtonMetrics::OnHWNDActivated() { | 88 void MinimizeButtonMetrics::OnHWNDActivated() { |
| 58 was_activated_ = true; | 89 was_activated_ = true; |
| 59 // NOTE: we don't cache here as it seems only after the activate is the value | 90 // NOTE: we don't cache here as it seems only after the activate is the |
| 60 // correct. | 91 // value correct. |
| 61 } | 92 } |
| 62 | 93 |
| 63 int MinimizeButtonMetrics::GetMinimizeButtonOffsetX() const { | 94 int MinimizeButtonMetrics::GetMinimizeButtonOffsetX() const { |
| 64 // Under DWM WM_GETTITLEBARINFOEX won't return the right thing until after | 95 if (!ui::win::IsAeroGlassEnabled() || cached_minimize_button_x_delta_ == 0) { |
| 65 // WM_NCACTIVATE (maybe it returns classic values?). In an attempt to return a | |
| 66 // consistant value we cache the last value across instances and use it until | |
| 67 // we get the activate. | |
| 68 if (was_activated_ || !ui::win::IsAeroGlassEnabled() || | |
| 69 cached_minimize_button_x_delta_ == 0) { | |
| 70 const int minimize_button_offset = GetAndCacheMinimizeButtonOffsetX(); | 96 const int minimize_button_offset = GetAndCacheMinimizeButtonOffsetX(); |
| 71 if (minimize_button_offset > 0) | 97 if (minimize_button_offset > 0) |
| 72 return minimize_button_offset; | 98 return minimize_button_offset; |
| 73 } | 99 } |
| 74 | 100 |
| 75 // If we fail to get the minimize button offset via the WM_GETTITLEBARINFOEX | 101 // If we fail to get the minimize button offset via the WM_GETTITLEBARINFOEX |
| 76 // message then calculate and return this via the | 102 // message or DwmGetWindowAttribute then calculate and return this via the |
| 77 // cached_minimize_button_x_delta_ member value. Please see | 103 // cached_minimize_button_x_delta_ member value. Please see |
| 78 // CacheMinimizeButtonDelta() for more details. | 104 // CacheMinimizeButtonDelta() for more details. |
| 79 DCHECK(cached_minimize_button_x_delta_); | 105 DCHECK(cached_minimize_button_x_delta_); |
| 80 | 106 |
| 81 if (base::i18n::IsRTL()) | 107 if (base::i18n::IsRTL()) |
| 82 return cached_minimize_button_x_delta_; | 108 return cached_minimize_button_x_delta_; |
| 83 | 109 |
| 84 RECT client_rect = {0}; | 110 RECT client_rect = {0}; |
| 85 GetClientRect(hwnd_, &client_rect); | 111 GetClientRect(hwnd_, &client_rect); |
| 86 return client_rect.right - cached_minimize_button_x_delta_; | 112 return client_rect.right - cached_minimize_button_x_delta_; |
| 87 } | 113 } |
| 88 | 114 |
| 89 int MinimizeButtonMetrics::GetAndCacheMinimizeButtonOffsetX() const { | 115 int MinimizeButtonMetrics::GetAndCacheMinimizeButtonOffsetX() const { |
| 90 const int minimize_button_offset = GetMinimizeButtonOffsetForWindow(hwnd_); | 116 const int minimize_button_offset = |
| 117 GetMinimizeButtonOffsetForWindow(hwnd_, was_activated_); | |
| 91 if (minimize_button_offset <= 0) | 118 if (minimize_button_offset <= 0) |
| 92 return 0; | 119 return 0; |
| 93 | 120 |
| 94 if (base::i18n::IsRTL()) { | 121 if (base::i18n::IsRTL()) { |
| 95 cached_minimize_button_x_delta_ = minimize_button_offset; | 122 cached_minimize_button_x_delta_ = minimize_button_offset; |
| 96 } else { | 123 } else { |
| 97 RECT client_rect = {0}; | 124 RECT client_rect = {0}; |
| 98 GetClientRect(hwnd_, &client_rect); | 125 GetClientRect(hwnd_, &client_rect); |
| 99 cached_minimize_button_x_delta_ = | 126 cached_minimize_button_x_delta_ = |
| 100 client_rect.right - minimize_button_offset; | 127 client_rect.right - minimize_button_offset; |
| 101 } | 128 } |
| 102 last_cached_minimize_button_x_delta_ = cached_minimize_button_x_delta_; | 129 last_cached_minimize_button_x_delta_ = cached_minimize_button_x_delta_; |
| 103 return minimize_button_offset; | 130 return minimize_button_offset; |
| 104 } | 131 } |
| OLD | NEW |