Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / frame / minimize_button_metrics_win.cc
blob7d161f31974bd7f88e5cd8e32c42894f578f6cf4
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 // WM_GETTITLEBARINFOEX returns rects in screen coordinates in pixels.
31 // We need to convert the minimize button corner offset to DIP before
32 // returning it.
33 POINT minimize_button_corner = { titlebar_info.rgrect[2].left, 0 };
34 MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1);
35 return minimize_button_corner.x / gfx::GetDPIScale();
38 } // namespace
40 // static
41 int MinimizeButtonMetrics::last_cached_minimize_button_x_delta_ = 0;
43 MinimizeButtonMetrics::MinimizeButtonMetrics()
44 : hwnd_(nullptr),
45 cached_minimize_button_x_delta_(last_cached_minimize_button_x_delta_),
46 was_activated_(false) {
49 MinimizeButtonMetrics::~MinimizeButtonMetrics() {
52 void MinimizeButtonMetrics::Init(HWND hwnd) {
53 DCHECK(!hwnd_);
54 hwnd_ = hwnd;
57 void MinimizeButtonMetrics::OnHWNDActivated() {
58 was_activated_ = true;
59 // NOTE: we don't cache here as it seems only after the activate is the value
60 // correct.
63 int MinimizeButtonMetrics::GetMinimizeButtonOffsetX() const {
64 // Under DWM WM_GETTITLEBARINFOEX won't return the right thing until after
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();
71 if (minimize_button_offset > 0)
72 return minimize_button_offset;
75 // If we fail to get the minimize button offset via the WM_GETTITLEBARINFOEX
76 // message then calculate and return this via the
77 // cached_minimize_button_x_delta_ member value. Please see
78 // CacheMinimizeButtonDelta() for more details.
79 DCHECK(cached_minimize_button_x_delta_);
81 if (base::i18n::IsRTL())
82 return cached_minimize_button_x_delta_;
84 RECT client_rect = {0};
85 GetClientRect(hwnd_, &client_rect);
86 return client_rect.right - cached_minimize_button_x_delta_;
89 int MinimizeButtonMetrics::GetAndCacheMinimizeButtonOffsetX() const {
90 const int minimize_button_offset = GetMinimizeButtonOffsetForWindow(hwnd_);
91 if (minimize_button_offset <= 0)
92 return 0;
94 if (base::i18n::IsRTL()) {
95 cached_minimize_button_x_delta_ = minimize_button_offset;
96 } else {
97 RECT client_rect = {0};
98 GetClientRect(hwnd_, &client_rect);
99 cached_minimize_button_x_delta_ =
100 client_rect.right - minimize_button_offset;
102 last_cached_minimize_button_x_delta_ = cached_minimize_button_x_delta_;
103 return minimize_button_offset;