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