Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(431)

Side by Side Diff: chrome/browser/ui/views/frame/minimize_button_metrics_win.cc

Issue 1952473002: Fix for 504133 - wandering identity switcher button (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed unnecessary 'using' statement. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "dwmapi.h" 10 #include "dwmapi.h"
10 #include "ui/base/win/shell.h" 11 #include "ui/base/win/shell.h"
11 #include "ui/display/win/dpi.h" 12 #include "ui/display/win/dpi.h"
12 #include "ui/display/win/screen_win.h" 13 #include "ui/display/win/screen_win.h"
13 14
14 namespace { 15 namespace {
15 16
17 const int kWin7ButtonBoundsPositionOffset = 1;
18 const int kWin8ButtonBoundsPositionOffset = 10;
19 const int kWin10ButtonBoundsPositionOffset = 6;
20 const int kInvalidOffset = (int)0x80000000;
21
22 using base::win::GetVersion;
16 using display::win::ScreenWin; 23 using display::win::ScreenWin;
17 24
25 static int gButtonBoundsPositionOffset = kInvalidOffset;
26
27 int GetDefaultButtonBoundsOffset() {
Ilya Kulshin 2016/05/09 19:53:23 Add a comment describing how to determine the offs
kylix_rd 2016/05/09 21:54:23 I think that adding a DCHECK may be too aggressive
28 return (GetVersion() >= base::win::VERSION_WIN10)
Ilya Kulshin 2016/05/09 19:53:23 I think this code would be more readable as a seri
kylix_rd 2016/05/09 21:54:23 Done.
29 ? kWin10ButtonBoundsPositionOffset
30 : (GetVersion() >= base::win::VERSION_WIN8)
31 ? kWin8ButtonBoundsPositionOffset
32 : kWin7ButtonBoundsPositionOffset;
33 }
34
35 // This function attempts to calculate the odd and varying difference
36 // between the results of DwmGetWindowAttribute with the
37 // DWMWA_CAPTION_BUTTON_BOUNDS flag and the information from the
38 // WM_GETTITLEBARINFOEX message. It will return an empirically determined
39 // offset until the window has been activated and the message returns
40 // valid rectangles.
41 int GetButtonBoundsPositionOffset(HWND hwnd,
42 const RECT& button_bounds,
43 const RECT& window_bounds,
44 bool was_activated) {
Ilya Kulshin 2016/05/09 19:53:23 Consider making these into member functions so you
kylix_rd 2016/05/09 21:54:23 Done.
45 if (gButtonBoundsPositionOffset == kInvalidOffset) {
46 if (!was_activated)
47 return GetDefaultButtonBoundsOffset();
48 TITLEBARINFOEX info = {0};
49 info.cbSize = sizeof(info);
50 SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0, reinterpret_cast<LPARAM>(&info));
51 if (info.rgrect[2].right == info.rgrect[2].left ||
52 (info.rgstate[2] & (STATE_SYSTEM_INVISIBLE | STATE_SYSTEM_OFFSCREEN |
53 STATE_SYSTEM_UNAVAILABLE)))
54 return GetDefaultButtonBoundsOffset();
55 gButtonBoundsPositionOffset =
56 info.rgrect[2].left - (button_bounds.left + window_bounds.left);
57 }
58 return gButtonBoundsPositionOffset;
59 }
60
18 int GetMinimizeButtonOffsetForWindow(HWND hwnd, bool was_activated) { 61 int GetMinimizeButtonOffsetForWindow(HWND hwnd, bool was_activated) {
19 bool dwm_button_pos = false; 62 bool dwm_button_pos = false;
20 POINT minimize_button_corner = {0}; 63 POINT minimize_button_corner = {0};
21 RECT button_bounds = {0}; 64 RECT button_bounds = {0};
22 if (SUCCEEDED(DwmGetWindowAttribute(hwnd, DWMWA_CAPTION_BUTTON_BOUNDS, 65 if (SUCCEEDED(DwmGetWindowAttribute(hwnd, DWMWA_CAPTION_BUTTON_BOUNDS,
23 &button_bounds, sizeof(button_bounds)))) { 66 &button_bounds, sizeof(button_bounds)))) {
24 if (button_bounds.left != button_bounds.right) { 67 if (button_bounds.left != button_bounds.right) {
25 // This converts the button coordinate into screen coordinates 68 // This converts the button coordinate into screen coordinates
26 // thus, ensuring that the identity switcher is placed in the 69 // thus, ensuring that the identity switcher is placed in the
27 // same location as before. 70 // same location as before. An additional constant is added because
71 // there is a difference between the caption button bounds and
72 // the values obtained through WM_GETTITLEBARINFOEX. This difference
73 // varies between OS versions, and no metric describing this difference
74 // has been located.
28 RECT window_bounds = {0}; 75 RECT window_bounds = {0};
29 if (GetWindowRect(hwnd, &window_bounds)) { 76 if (GetWindowRect(hwnd, &window_bounds)) {
30 minimize_button_corner = {button_bounds.left + window_bounds.left, 0}; 77 int offset = GetButtonBoundsPositionOffset(
78 hwnd, button_bounds, window_bounds, was_activated);
79 minimize_button_corner = {
80 button_bounds.left + window_bounds.left + offset, 0};
31 dwm_button_pos = true; 81 dwm_button_pos = true;
32 } 82 }
33 } 83 }
34 } 84 }
35 if (!dwm_button_pos) { 85 if (!dwm_button_pos) {
36 // Fallback to using the message for the titlebar info only if the above 86 // Fallback to using the message for the titlebar info only if the above
37 // code fails. It can fail if DWM is disabled globally or only for the 87 // code fails. It can fail if DWM is disabled globally or only for the
38 // given HWND. The WM_GETTITLEBARINFOEX message can fail if we are not 88 // given HWND. The WM_GETTITLEBARINFOEX message can fail if we are not
39 // active/visible. By fail we get a location of 0; the return status 89 // active/visible. By fail we get a location of 0; the return status
40 // code is always the same and similarly the state never seems to change 90 // code is always the same and similarly the state never seems to change
41 // (titlebar_info.rgstate). 91 // (titlebar_info.rgstate).
42 TITLEBARINFOEX titlebar_info = {0}; 92 TITLEBARINFOEX titlebar_info = {0};
43 titlebar_info.cbSize = sizeof(TITLEBARINFOEX); 93 titlebar_info.cbSize = sizeof(TITLEBARINFOEX);
44 SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0, 94 SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0,
45 reinterpret_cast<WPARAM>(&titlebar_info)); 95 reinterpret_cast<WPARAM>(&titlebar_info));
46 96
47 // Under DWM WM_GETTITLEBARINFOEX won't return the right thing until after 97 // Under DWM WM_GETTITLEBARINFOEX won't return the right thing until after
48 // WM_NCACTIVATE (maybe it returns classic values?). In an attempt to 98 // WM_NCACTIVATE (maybe it returns classic values?). In an attempt to
49 // return a consistant value we cache the last value across instances and 99 // return a consistant value we cache the last value across instances and
50 // use it until we get the activate. 100 // use it until we get the activate.
51 if (!was_activated || 101 if (titlebar_info.rgrect[2].left == titlebar_info.rgrect[2].right ||
52 titlebar_info.rgrect[2].left == titlebar_info.rgrect[2].right ||
53 (titlebar_info.rgstate[2] & 102 (titlebar_info.rgstate[2] &
54 (STATE_SYSTEM_INVISIBLE | STATE_SYSTEM_OFFSCREEN | 103 (STATE_SYSTEM_INVISIBLE | STATE_SYSTEM_OFFSCREEN |
55 STATE_SYSTEM_UNAVAILABLE))) { 104 STATE_SYSTEM_UNAVAILABLE)))
56 return 0; 105 return 0;
57 }
58 minimize_button_corner = {titlebar_info.rgrect[2].left, 0}; 106 minimize_button_corner = {titlebar_info.rgrect[2].left, 0};
59 } 107 }
60 108
61 // WM_GETTITLEBARINFOEX returns rects in screen coordinates in pixels. 109 // WM_GETTITLEBARINFOEX returns rects in screen coordinates in pixels.
62 // DWMNA_CAPTION_BUTTON_BOUNDS is in window (not client) coordinates, 110 // DWMNA_CAPTION_BUTTON_BOUNDS is in window (not client) coordinates,
63 // but it has been converted to screen coordinates above. We need to 111 // but it has been converted to screen coordinates above. We need to
64 // convert the minimize button corner offset to DIP before returning it. 112 // convert the minimize button corner offset to DIP before returning it.
65 MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1); 113 MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1);
66 gfx::Point pixel_point = {minimize_button_corner.x, 0}; 114 gfx::Point pixel_point = {minimize_button_corner.x, 0};
67 gfx::Point dip_point = ScreenWin::ClientToDIPPoint(hwnd, pixel_point); 115 gfx::Point dip_point = ScreenWin::ClientToDIPPoint(hwnd, pixel_point);
(...skipping 19 matching lines...) Expand all
87 hwnd_ = hwnd; 135 hwnd_ = hwnd;
88 } 136 }
89 137
90 void MinimizeButtonMetrics::OnHWNDActivated() { 138 void MinimizeButtonMetrics::OnHWNDActivated() {
91 was_activated_ = true; 139 was_activated_ = true;
92 // NOTE: we don't cache here as it seems only after the activate is the 140 // NOTE: we don't cache here as it seems only after the activate is the
93 // value correct. 141 // value correct.
94 } 142 }
95 143
96 int MinimizeButtonMetrics::GetMinimizeButtonOffsetX() const { 144 int MinimizeButtonMetrics::GetMinimizeButtonOffsetX() const {
97 if (!ui::win::IsAeroGlassEnabled() || cached_minimize_button_x_delta_ == 0) { 145 if (was_activated_ || !ui::win::IsAeroGlassEnabled() ||
kylix_rd 2016/05/09 18:24:52 This was the cause of the regression. The code was
146 cached_minimize_button_x_delta_ == 0) {
98 const int minimize_button_offset = GetAndCacheMinimizeButtonOffsetX(); 147 const int minimize_button_offset = GetAndCacheMinimizeButtonOffsetX();
99 if (minimize_button_offset > 0) 148 if (minimize_button_offset > 0)
100 return minimize_button_offset; 149 return minimize_button_offset;
101 } 150 }
102 151
103 // If we fail to get the minimize button offset via the WM_GETTITLEBARINFOEX 152 // If we fail to get the minimize button offset via the WM_GETTITLEBARINFOEX
104 // message or DwmGetWindowAttribute then calculate and return this via the 153 // message or DwmGetWindowAttribute then calculate and return this via the
105 // cached_minimize_button_x_delta_ member value. Please see 154 // cached_minimize_button_x_delta_ member value. Please see
106 // CacheMinimizeButtonDelta() for more details. 155 // CacheMinimizeButtonDelta() for more details.
107 DCHECK(cached_minimize_button_x_delta_); 156 DCHECK(cached_minimize_button_x_delta_);
(...skipping 16 matching lines...) Expand all
124 cached_minimize_button_x_delta_ = minimize_button_offset; 173 cached_minimize_button_x_delta_ = minimize_button_offset;
125 } else { 174 } else {
126 RECT client_rect = {0}; 175 RECT client_rect = {0};
127 GetClientRect(hwnd_, &client_rect); 176 GetClientRect(hwnd_, &client_rect);
128 cached_minimize_button_x_delta_ = 177 cached_minimize_button_x_delta_ =
129 client_rect.right - minimize_button_offset; 178 client_rect.right - minimize_button_offset;
130 } 179 }
131 last_cached_minimize_button_x_delta_ = cached_minimize_button_x_delta_; 180 last_cached_minimize_button_x_delta_ = cached_minimize_button_x_delta_;
132 return minimize_button_offset; 181 return minimize_button_offset;
133 } 182 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698