- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / frame / minimize_button_metrics_win.cc
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.
4
5 #include "chrome/browser/ui/views/frame/minimize_button_metrics_win.h"
6
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"
11
12 namespace {
13
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));
20
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(),
26                                    0 };
27   MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1);
28   return minimize_button_corner.x / gfx::win::GetDeviceScaleFactor();
29 }
30
31 }  // namespace
32
33 // static
34 int MinimizeButtonMetrics::last_cached_minimize_button_x_delta_ = 0;
35
36 MinimizeButtonMetrics::MinimizeButtonMetrics()
37     : hwnd_(NULL),
38       cached_minimize_button_x_delta_(last_cached_minimize_button_x_delta_),
39       was_activated_(false) {
40 }
41
42 MinimizeButtonMetrics::~MinimizeButtonMetrics() {
43 }
44
45 void MinimizeButtonMetrics::Init(HWND hwnd) {
46   DCHECK(!hwnd_);
47   hwnd_ = hwnd;
48 }
49
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
53   // correct.
54 }
55
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;
66   }
67
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_);
73
74   if (base::i18n::IsRTL())
75     return cached_minimize_button_x_delta_;
76
77   RECT client_rect = {0};
78   GetClientRect(hwnd_, &client_rect);
79   return client_rect.right - cached_minimize_button_x_delta_;
80 }
81
82 int MinimizeButtonMetrics::GetAndCacheMinimizeButtonOffsetX() const {
83   const int minimize_button_offset = GetMinimizeButtonOffsetForWindow(hwnd_);
84   if (minimize_button_offset <= 0)
85     return 0;
86
87   if (base::i18n::IsRTL()) {
88     cached_minimize_button_x_delta_ = minimize_button_offset;
89   } else {
90     RECT client_rect = {0};
91     GetClientRect(hwnd_, &client_rect);
92     cached_minimize_button_x_delta_ =
93         client_rect.right - minimize_button_offset;
94   }
95   last_cached_minimize_button_x_delta_ = cached_minimize_button_x_delta_;
96   return minimize_button_offset;
97 }