app_window_desktop_window_tree_host_win.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1// Copyright 2014 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/apps/app_window_desktop_window_tree_host_win.h"
6
7#include <dwmapi.h>
8
9#include "chrome/browser/ui/views/apps/chrome_native_app_window_views_win.h"
10#include "chrome/browser/ui/views/apps/glass_app_window_frame_view_win.h"
11#include "grit/theme_resources.h"
12#include "ui/base/theme_provider.h"
13#include "ui/gfx/win/dpi.h"
14#include "ui/views/controls/menu/native_menu_win.h"
15
16#pragma comment(lib, "dwmapi.lib")
17
18AppWindowDesktopWindowTreeHostWin::AppWindowDesktopWindowTreeHostWin(
19    ChromeNativeAppWindowViewsWin* app_window,
20    views::DesktopNativeWidgetAura* desktop_native_widget_aura)
21    : DesktopWindowTreeHostWin(app_window->widget(),
22                               desktop_native_widget_aura),
23      app_window_(app_window) {
24}
25
26AppWindowDesktopWindowTreeHostWin::~AppWindowDesktopWindowTreeHostWin() {
27}
28
29bool AppWindowDesktopWindowTreeHostWin::GetClientAreaInsets(
30    gfx::Insets* insets) const {
31  // Use the default client insets for an opaque frame or a glass popup/app
32  // frame.
33  if (!app_window_->glass_frame_view())
34    return false;
35
36  // This tells Windows that most of the window is a client area, meaning Chrome
37  // will draw it. Windows still fills in the glass bits because of the
38  // DwmExtendFrameIntoClientArea call in |UpdateDWMFrame|.
39  // The 1 pixel edge is left on the sides and bottom as without this
40  //   * windows paint in a more standard way, and
41  //   * get weird black bars at the top when maximized in multiple monitor
42  //     configurations.
43  int border_thickness = 1;
44  insets->Set(0, border_thickness, border_thickness, border_thickness);
45  return true;
46}
47
48void AppWindowDesktopWindowTreeHostWin::HandleFrameChanged() {
49  // We need to update the glass region on or off before the base class adjusts
50  // the window region.
51  app_window_->OnCanHaveAlphaEnabledChanged();
52  UpdateDWMFrame();
53  DesktopWindowTreeHostWin::HandleFrameChanged();
54}
55
56void AppWindowDesktopWindowTreeHostWin::PostHandleMSG(UINT message,
57                                                      WPARAM w_param,
58                                                      LPARAM l_param) {
59  switch (message) {
60    case WM_WINDOWPOSCHANGED: {
61      UpdateDWMFrame();
62      break;
63    }
64  }
65}
66
67void AppWindowDesktopWindowTreeHostWin::UpdateDWMFrame() {
68  if (!GetWidget()->client_view() || !app_window_->glass_frame_view())
69    return;
70
71  MARGINS margins = {0};
72
73  // If the opaque frame is visible, we use the default (zero) margins.
74  // Otherwise, we need to figure out how to extend the glass in.
75  if (app_window_->glass_frame_view()) {
76    gfx::Insets insets = app_window_->glass_frame_view()->GetGlassInsets();
77    // The DWM API's expect values in pixels. We need to convert from DIP to
78    // pixels here.
79    insets = insets.Scale(gfx::win::GetDeviceScaleFactor());
80    margins.cxLeftWidth = insets.left();
81    margins.cxRightWidth = insets.right();
82    margins.cyBottomHeight = insets.bottom();
83    margins.cyTopHeight = insets.top();
84  }
85
86  DwmExtendFrameIntoClientArea(GetHWND(), &margins);
87}
88