Home | History | Annotate | Download | only in frame
      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/dpi.h"
     10 
     11 namespace {
     12 
     13 int GetMinimizeButtonOffsetForWindow(HWND hwnd) {
     14   // The WM_GETTITLEBARINFOEX message can fail if we are not active/visible.
     15   TITLEBARINFOEX titlebar_info = {0};
     16   titlebar_info.cbSize = sizeof(TITLEBARINFOEX);
     17   SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0,
     18               reinterpret_cast<WPARAM>(&titlebar_info));
     19 
     20   // NOTE: TITLEBARINFOEX coordinates are not scaled (they are physical). As
     21   // Chrome is not DPIAware we need to properly scale the coordinates as
     22   // MapWindowPoints() expects scaled coordinates.
     23   POINT minimize_button_corner = { titlebar_info.rgrect[2].left /
     24                                    ui::win::GetUndocumentedDPIScale(),
     25                                    0 };
     26   MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1);
     27   return minimize_button_corner.x / ui::win::GetDeviceScaleFactor();
     28 }
     29 
     30 }  // namespace
     31 
     32 MinimizeButtonMetrics::MinimizeButtonMetrics()
     33     : hwnd_(NULL),
     34       cached_minimize_button_x_delta_(0) {
     35 }
     36 
     37 MinimizeButtonMetrics::~MinimizeButtonMetrics() {
     38 }
     39 
     40 void MinimizeButtonMetrics::Init(HWND hwnd) {
     41   DCHECK(!hwnd_);
     42   hwnd_ = hwnd;
     43 }
     44 
     45 void MinimizeButtonMetrics::OnHWNDActivated() {
     46   int minimize_offset = GetMinimizeButtonOffsetForWindow(hwnd_);
     47 
     48   RECT rect = {0};
     49   GetClientRect(hwnd_, &rect);
     50   // Calculate and cache the value of the minimize button delta, i.e. the
     51   // offset to be applied to the left or right edge of the client rect
     52   // depending on whether the language is RTL or not.
     53   // This cached value is only used if the WM_GETTITLEBARINFOEX message fails
     54   // to get the offset of the minimize button.
     55   if (base::i18n::IsRTL())
     56     cached_minimize_button_x_delta_ = minimize_offset;
     57   else
     58     cached_minimize_button_x_delta_ = rect.right - minimize_offset;
     59 }
     60 
     61 int MinimizeButtonMetrics::GetMinimizeButtonOffsetX() const {
     62   int minimize_button_offset = GetMinimizeButtonOffsetForWindow(hwnd_);
     63   if (minimize_button_offset > 0)
     64     return minimize_button_offset;
     65 
     66   // If we fail to get the minimize button offset via the WM_GETTITLEBARINFOEX
     67   // message then calculate and return this via the
     68   // cached_minimize_button_x_delta_ member value. Please see
     69   // CacheMinimizeButtonDelta() for more details.
     70   DCHECK(cached_minimize_button_x_delta_);
     71 
     72   RECT client_rect = {0};
     73   GetClientRect(hwnd_, &client_rect);
     74 
     75   if (base::i18n::IsRTL())
     76     return cached_minimize_button_x_delta_;
     77   return client_rect.right - cached_minimize_button_x_delta_;
     78 }
     79 
     80