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