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"
14 int GetMinimizeButtonOffsetForWindow(HWND hwnd) {
15 // The WM_GETTITLEBARINFOEX message can fail if we are not active/visible.
16 TITLEBARINFOEX titlebar_info = {0};
17 titlebar_info.cbSize = sizeof(TITLEBARINFOEX);
18 SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0,
19 reinterpret_cast<WPARAM>(&titlebar_info));
21 // NOTE: TITLEBARINFOEX coordinates are not scaled (they are physical). As
22 // Chrome is not DPIAware we need to properly scale the coordinates as
23 // MapWindowPoints() expects scaled coordinates.
24 POINT minimize_button_corner = { titlebar_info.rgrect[2].left /
25 gfx::win::GetUndocumentedDPIScale(),
27 MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1);
28 return minimize_button_corner.x / gfx::win::GetDeviceScaleFactor();
34 int MinimizeButtonMetrics::last_cached_minimize_button_x_delta_ = 0;
36 MinimizeButtonMetrics::MinimizeButtonMetrics()
38 cached_minimize_button_x_delta_(last_cached_minimize_button_x_delta_),
39 was_activated_(false) {
42 MinimizeButtonMetrics::~MinimizeButtonMetrics() {
45 void MinimizeButtonMetrics::Init(HWND hwnd) {
50 void MinimizeButtonMetrics::OnHWNDActivated() {
51 was_activated_ = true;
52 // NOTE: we don't cache here as it seems only after the activate is the value
56 int MinimizeButtonMetrics::GetMinimizeButtonOffsetX() const {
57 // Under DWM WM_GETTITLEBARINFOEX won't return the right thing until after
58 // WM_NCACTIVATE (maybe it returns classic values?). In an attempt to return a
59 // consistant value we cache the last value across instances and use it until
60 // we get the activate.
61 if (was_activated_ || !ui::win::IsAeroGlassEnabled() ||
62 cached_minimize_button_x_delta_ == 0) {
63 const int minimize_button_offset = GetAndCacheMinimizeButtonOffsetX();
64 if (minimize_button_offset > 0)
65 return minimize_button_offset;
68 // If we fail to get the minimize button offset via the WM_GETTITLEBARINFOEX
69 // message then calculate and return this via the
70 // cached_minimize_button_x_delta_ member value. Please see
71 // CacheMinimizeButtonDelta() for more details.
72 DCHECK(cached_minimize_button_x_delta_);
74 if (base::i18n::IsRTL())
75 return cached_minimize_button_x_delta_;
77 RECT client_rect = {0};
78 GetClientRect(hwnd_, &client_rect);
79 return client_rect.right - cached_minimize_button_x_delta_;
82 int MinimizeButtonMetrics::GetAndCacheMinimizeButtonOffsetX() const {
83 const int minimize_button_offset = GetMinimizeButtonOffsetForWindow(hwnd_);
84 if (minimize_button_offset <= 0)
87 if (base::i18n::IsRTL()) {
88 cached_minimize_button_x_delta_ = minimize_button_offset;
90 RECT client_rect = {0};
91 GetClientRect(hwnd_, &client_rect);
92 cached_minimize_button_x_delta_ =
93 client_rect.right - minimize_button_offset;
95 last_cached_minimize_button_x_delta_ = cached_minimize_button_x_delta_;
96 return minimize_button_offset;