[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / ui / views / frame / minimize_button_metrics_win.cc
blob19e4baab5d3feb13ffa0f4bb778d7edc8edc696b
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/frame/minimize_button_metrics_win.h"
7 #include "base/logging.h"
8 #include "base/i18n/rtl.h"
9 #include "ui/base/win/shell.h"
10 #include "ui/gfx/win/dpi.h"
12 namespace {
14 int GetMinimizeButtonOffsetForWindow(HWND hwnd) {
15 // 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
17 // similarly the state never seems to change (titlebar_info.rgstate).
18 TITLEBARINFOEX titlebar_info = {0};
19 titlebar_info.cbSize = sizeof(TITLEBARINFOEX);
20 SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0,
21 reinterpret_cast<WPARAM>(&titlebar_info));
23 if (titlebar_info.rgrect[2].left == titlebar_info.rgrect[2].right ||
24 (titlebar_info.rgstate[2] & (STATE_SYSTEM_INVISIBLE |
25 STATE_SYSTEM_OFFSCREEN |
26 STATE_SYSTEM_UNAVAILABLE))) {
27 return 0;
30 // Most versions of Windows return screen coordinates for
31 // WM_GETTITLEBARINFOEX. Since chrome is not dpi aware (currently) we need to
32 // unscale these coordinates. Surface Pro seems to be unique, in that it
33 // returns local coordinates (eg they don't need to be scaled). There doesn't
34 // appear to be a clear way to detect this, so we assume that if the minimize
35 // button is outside the bounds of the window coordinates are scaled.
36 RECT window_rect = {0};
37 GetWindowRect(hwnd, &window_rect);
38 POINT minimize_button_corner = { titlebar_info.rgrect[2].left, 0 };
39 if (minimize_button_corner.x > window_rect.right) {
40 minimize_button_corner.x =
41 static_cast<int>(minimize_button_corner.x /
42 gfx::win::GetUndocumentedDPIScale());
44 MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1);
45 return minimize_button_corner.x / gfx::win::GetDeviceScaleFactor();
48 } // namespace
50 // static
51 int MinimizeButtonMetrics::last_cached_minimize_button_x_delta_ = 0;
53 MinimizeButtonMetrics::MinimizeButtonMetrics()
54 : hwnd_(NULL),
55 cached_minimize_button_x_delta_(last_cached_minimize_button_x_delta_),
56 was_activated_(false) {
59 MinimizeButtonMetrics::~MinimizeButtonMetrics() {
62 void MinimizeButtonMetrics::Init(HWND hwnd) {
63 DCHECK(!hwnd_);
64 hwnd_ = hwnd;
67 void MinimizeButtonMetrics::OnHWNDActivated() {
68 was_activated_ = true;
69 // NOTE: we don't cache here as it seems only after the activate is the value
70 // correct.
73 int MinimizeButtonMetrics::GetMinimizeButtonOffsetX() const {
74 // Under DWM WM_GETTITLEBARINFOEX won't return the right thing until after
75 // WM_NCACTIVATE (maybe it returns classic values?). In an attempt to return a
76 // consistant value we cache the last value across instances and use it until
77 // we get the activate.
78 if (was_activated_ || !ui::win::IsAeroGlassEnabled() ||
79 cached_minimize_button_x_delta_ == 0) {
80 const int minimize_button_offset = GetAndCacheMinimizeButtonOffsetX();
81 if (minimize_button_offset > 0)
82 return minimize_button_offset;
85 // If we fail to get the minimize button offset via the WM_GETTITLEBARINFOEX
86 // message then calculate and return this via the
87 // cached_minimize_button_x_delta_ member value. Please see
88 // CacheMinimizeButtonDelta() for more details.
89 DCHECK(cached_minimize_button_x_delta_);
91 if (base::i18n::IsRTL())
92 return cached_minimize_button_x_delta_;
94 RECT client_rect = {0};
95 GetClientRect(hwnd_, &client_rect);
96 return client_rect.right - cached_minimize_button_x_delta_;
99 int MinimizeButtonMetrics::GetAndCacheMinimizeButtonOffsetX() const {
100 const int minimize_button_offset = GetMinimizeButtonOffsetForWindow(hwnd_);
101 if (minimize_button_offset <= 0)
102 return 0;
104 if (base::i18n::IsRTL()) {
105 cached_minimize_button_x_delta_ = minimize_button_offset;
106 } else {
107 RECT client_rect = {0};
108 GetClientRect(hwnd_, &client_rect);
109 cached_minimize_button_x_delta_ =
110 client_rect.right - minimize_button_offset;
112 last_cached_minimize_button_x_delta_ = cached_minimize_button_x_delta_;
113 return minimize_button_offset;