| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.h" | 5 #include "chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.h" |
| 6 | 6 |
| 7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
| 8 | 8 |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/process/process_handle.h" | 10 #include "base/process/process_handle.h" |
| 11 #include "base/win/windows_version.h" | 11 #include "base/win/windows_version.h" |
| 12 #include "chrome/browser/lifetime/application_lifetime.h" | 12 #include "chrome/browser/lifetime/application_lifetime.h" |
| 13 #include "chrome/browser/themes/theme_service.h" | 13 #include "chrome/browser/themes/theme_service.h" |
| 14 #include "chrome/browser/themes/theme_service_factory.h" | 14 #include "chrome/browser/themes/theme_service_factory.h" |
| 15 #include "chrome/browser/ui/views/frame/browser_frame.h" | 15 #include "chrome/browser/ui/views/frame/browser_frame.h" |
| 16 #include "chrome/browser/ui/views/frame/browser_view.h" | 16 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 17 #include "chrome/browser/ui/views/frame/browser_window_property_manager_win.h" | 17 #include "chrome/browser/ui/views/frame/browser_window_property_manager_win.h" |
| 18 #include "chrome/browser/ui/views/frame/system_menu_insertion_delegate_win.h" | 18 #include "chrome/browser/ui/views/frame/system_menu_insertion_delegate_win.h" |
| 19 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 19 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
| 20 #include "chrome/common/chrome_constants.h" | 20 #include "chrome/common/chrome_constants.h" |
| 21 #include "ui/base/material_design/material_design_controller.h" | 21 #include "ui/base/material_design/material_design_controller.h" |
| 22 #include "ui/base/theme_provider.h" | 22 #include "ui/base/theme_provider.h" |
| 23 #include "ui/display/win/screen_win.h" | 23 #include "ui/display/win/screen_win.h" |
| 24 #include "ui/gfx/geometry/point.h" | 24 #include "ui/gfx/geometry/point.h" |
| 25 #include "ui/views/controls/menu/native_menu_win.h" | 25 #include "ui/views/controls/menu/native_menu_win.h" |
| 26 | 26 #include "ui/views/resources/grit/views_resources.h" |
| 27 namespace { | |
| 28 | |
| 29 // The amount of additional non-client area to draw beyond what we have Windows | |
| 30 // draw, in DIPs. Only used pre-Win 10. | |
| 31 const int kDWMFrameBorderExtensionDips = 3; | |
| 32 | |
| 33 } // namespace | |
| 34 | 27 |
| 35 //////////////////////////////////////////////////////////////////////////////// | 28 //////////////////////////////////////////////////////////////////////////////// |
| 36 // BrowserDesktopWindowTreeHostWin, public: | 29 // BrowserDesktopWindowTreeHostWin, public: |
| 37 | 30 |
| 38 BrowserDesktopWindowTreeHostWin::BrowserDesktopWindowTreeHostWin( | 31 BrowserDesktopWindowTreeHostWin::BrowserDesktopWindowTreeHostWin( |
| 39 views::internal::NativeWidgetDelegate* native_widget_delegate, | 32 views::internal::NativeWidgetDelegate* native_widget_delegate, |
| 40 views::DesktopNativeWidgetAura* desktop_native_widget_aura, | 33 views::DesktopNativeWidgetAura* desktop_native_widget_aura, |
| 41 BrowserView* browser_view, | 34 BrowserView* browser_view, |
| 42 BrowserFrame* browser_frame) | 35 BrowserFrame* browser_frame) |
| 43 : DesktopWindowTreeHostWin(native_widget_delegate, | 36 : DesktopWindowTreeHostWin(native_widget_delegate, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 | 83 |
| 91 bool BrowserDesktopWindowTreeHostWin::GetClientAreaInsets( | 84 bool BrowserDesktopWindowTreeHostWin::GetClientAreaInsets( |
| 92 gfx::Insets* insets) const { | 85 gfx::Insets* insets) const { |
| 93 // Use the default client insets for an opaque frame or a glass popup/app | 86 // Use the default client insets for an opaque frame or a glass popup/app |
| 94 // frame. | 87 // frame. |
| 95 if (!GetWidget()->ShouldUseNativeFrame() || | 88 if (!GetWidget()->ShouldUseNativeFrame() || |
| 96 !browser_view_->IsBrowserTypeNormal()) { | 89 !browser_view_->IsBrowserTypeNormal()) { |
| 97 return false; | 90 return false; |
| 98 } | 91 } |
| 99 | 92 |
| 100 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); | |
| 101 if (GetWidget()->IsFullscreen()) { | 93 if (GetWidget()->IsFullscreen()) { |
| 102 // In fullscreen mode there is no frame. | 94 // In fullscreen mode there is no frame. |
| 103 border_thickness = 0; | 95 *insets = gfx::Insets(); |
| 104 } else if (!IsMaximized() && | 96 } else { |
| 105 base::win::GetVersion() < base::win::VERSION_WIN10) { | 97 const int frame_thickness = GetSystemMetrics(SM_CXSIZEFRAME); |
| 106 // Reduce the Windows non-client border size because we extended the border | 98 // Reduce the Windows non-client border size because we extend the border |
| 107 // into our client area in UpdateDWMFrame(). | 99 // into our client area in UpdateDWMFrame(). |
| 108 border_thickness -= kDWMFrameBorderExtensionDips; | 100 *insets = gfx::Insets(0, frame_thickness, frame_thickness, |
| 101 frame_thickness) - GetClientEdgeThicknesses(); |
| 109 } | 102 } |
| 110 insets->Set(0, border_thickness, border_thickness, border_thickness); | |
| 111 return true; | 103 return true; |
| 112 } | 104 } |
| 113 | 105 |
| 114 void BrowserDesktopWindowTreeHostWin::HandleCreate() { | 106 void BrowserDesktopWindowTreeHostWin::HandleCreate() { |
| 115 DesktopWindowTreeHostWin::HandleCreate(); | 107 DesktopWindowTreeHostWin::HandleCreate(); |
| 116 browser_window_property_manager_ = | 108 browser_window_property_manager_ = |
| 117 BrowserWindowPropertyManager::CreateBrowserWindowPropertyManager( | 109 BrowserWindowPropertyManager::CreateBrowserWindowPropertyManager( |
| 118 browser_view_, GetHWND()); | 110 browser_view_, GetHWND()); |
| 119 } | 111 } |
| 120 | 112 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 150 GetSystemMenu()->UpdateStates(); | 142 GetSystemMenu()->UpdateStates(); |
| 151 return true; | 143 return true; |
| 152 } | 144 } |
| 153 return DesktopWindowTreeHostWin::PreHandleMSG( | 145 return DesktopWindowTreeHostWin::PreHandleMSG( |
| 154 message, w_param, l_param, result); | 146 message, w_param, l_param, result); |
| 155 } | 147 } |
| 156 | 148 |
| 157 void BrowserDesktopWindowTreeHostWin::PostHandleMSG(UINT message, | 149 void BrowserDesktopWindowTreeHostWin::PostHandleMSG(UINT message, |
| 158 WPARAM w_param, | 150 WPARAM w_param, |
| 159 LPARAM l_param) { | 151 LPARAM l_param) { |
| 152 HWND hwnd = GetHWND(); |
| 160 switch (message) { | 153 switch (message) { |
| 161 case WM_CREATE: | 154 case WM_CREATE: |
| 162 minimize_button_metrics_.Init(GetHWND()); | 155 minimize_button_metrics_.Init(hwnd); |
| 163 break; | 156 break; |
| 164 case WM_WINDOWPOSCHANGED: { | 157 case WM_WINDOWPOSCHANGED: { |
| 165 UpdateDWMFrame(); | 158 UpdateDWMFrame(); |
| 166 | 159 |
| 167 // Windows lies to us about the position of the minimize button before a | 160 // Windows lies to us about the position of the minimize button before a |
| 168 // window is visible. We use this position to place the OTR avatar in RTL | 161 // window is visible. We use this position to place the OTR avatar in RTL |
| 169 // mode, so when the window is shown, we need to re-layout and schedule a | 162 // mode, so when the window is shown, we need to re-layout and schedule a |
| 170 // paint for the non-client frame view so that the icon top has the | 163 // paint for the non-client frame view so that the icon top has the |
| 171 // correct | 164 // correct |
| 172 // position when the window becomes visible. This fixes bugs where the | 165 // position when the window becomes visible. This fixes bugs where the |
| (...skipping 12 matching lines...) Expand all Loading... |
| 185 GetWidget()->non_client_view()->SchedulePaint(); | 178 GetWidget()->non_client_view()->SchedulePaint(); |
| 186 } | 179 } |
| 187 break; | 180 break; |
| 188 } | 181 } |
| 189 case WM_ERASEBKGND: { | 182 case WM_ERASEBKGND: { |
| 190 gfx::Insets insets; | 183 gfx::Insets insets; |
| 191 if (!did_gdi_clear_ && GetClientAreaInsets(&insets)) { | 184 if (!did_gdi_clear_ && GetClientAreaInsets(&insets)) { |
| 192 // This is necessary to avoid white flashing in the titlebar area around | 185 // This is necessary to avoid white flashing in the titlebar area around |
| 193 // the minimize/maximize/close buttons. | 186 // the minimize/maximize/close buttons. |
| 194 DCHECK_EQ(0, insets.top()); | 187 DCHECK_EQ(0, insets.top()); |
| 195 HDC dc = GetDC(GetHWND()); | 188 HDC dc = GetDC(hwnd); |
| 196 MARGINS margins = GetDWMFrameMargins(); | 189 MARGINS margins = GetDWMFrameMargins(); |
| 197 RECT client_rect; | 190 RECT client_rect; |
| 198 GetClientRect(GetHWND(), &client_rect); | 191 GetClientRect(hwnd, &client_rect); |
| 199 HBRUSH brush = CreateSolidBrush(0); | 192 HBRUSH brush = CreateSolidBrush(0); |
| 200 RECT rect = {0, 0, client_rect.right, margins.cyTopHeight}; | 193 RECT rect = {0, 0, client_rect.right, margins.cyTopHeight}; |
| 201 FillRect(dc, &rect, brush); | 194 FillRect(dc, &rect, brush); |
| 202 DeleteObject(brush); | 195 DeleteObject(brush); |
| 203 ReleaseDC(GetHWND(), dc); | 196 ReleaseDC(hwnd, dc); |
| 204 did_gdi_clear_ = true; | 197 did_gdi_clear_ = true; |
| 205 } | 198 } |
| 206 break; | 199 break; |
| 207 } | 200 } |
| 208 } | 201 } |
| 209 } | 202 } |
| 210 | 203 |
| 211 views::FrameMode BrowserDesktopWindowTreeHostWin::GetFrameMode() const { | 204 views::FrameMode BrowserDesktopWindowTreeHostWin::GetFrameMode() const { |
| 212 // We don't theme popup or app windows, so regardless of whether or not a | 205 // We don't theme popup or app windows, so regardless of whether or not a |
| 213 // theme is active for normal browser windows, we don't want to use the custom | 206 // theme is active for normal browser windows, we don't want to use the custom |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 // frame is currently native or opaque. | 254 // frame is currently native or opaque. |
| 262 if (!GetWidget()->client_view() || !browser_view_->IsBrowserTypeNormal() || | 255 if (!GetWidget()->client_view() || !browser_view_->IsBrowserTypeNormal() || |
| 263 !DesktopWindowTreeHostWin::ShouldUseNativeFrame()) | 256 !DesktopWindowTreeHostWin::ShouldUseNativeFrame()) |
| 264 return; | 257 return; |
| 265 | 258 |
| 266 MARGINS margins = GetDWMFrameMargins(); | 259 MARGINS margins = GetDWMFrameMargins(); |
| 267 | 260 |
| 268 DwmExtendFrameIntoClientArea(GetHWND(), &margins); | 261 DwmExtendFrameIntoClientArea(GetHWND(), &margins); |
| 269 } | 262 } |
| 270 | 263 |
| 264 gfx::Insets |
| 265 BrowserDesktopWindowTreeHostWin::GetClientEdgeThicknesses() const { |
| 266 // Maximized windows have no visible client edge; the content goes to |
| 267 // the edge of the screen. Restored windows on Windows 10 don't paint |
| 268 // the full 3D client edge, but paint content right to the edge of the |
| 269 // client area. |
| 270 if (IsMaximized() || |
| 271 (base::win::GetVersion() >= base::win::VERSION_WIN10)) |
| 272 return gfx::Insets(); |
| 273 |
| 274 const ui::ThemeProvider* const tp = GetWidget()->GetThemeProvider(); |
| 275 return gfx::Insets( |
| 276 0, tp->GetImageSkiaNamed(IDR_CONTENT_LEFT_SIDE)->width(), |
| 277 tp->GetImageSkiaNamed(IDR_CONTENT_BOTTOM_CENTER)->height(), |
| 278 tp->GetImageSkiaNamed(IDR_CONTENT_RIGHT_SIDE)->width()); |
| 279 } |
| 280 |
| 271 MARGINS BrowserDesktopWindowTreeHostWin::GetDWMFrameMargins() const { | 281 MARGINS BrowserDesktopWindowTreeHostWin::GetDWMFrameMargins() const { |
| 272 MARGINS margins = { 0 }; | |
| 273 | |
| 274 // If we're using the opaque frame or we're fullscreen we don't extend the | 282 // If we're using the opaque frame or we're fullscreen we don't extend the |
| 275 // glass in at all because it won't be visible. | 283 // glass in at all because it won't be visible. |
| 276 if (!GetWidget()->ShouldUseNativeFrame() || GetWidget()->IsFullscreen()) | 284 if (!GetWidget()->ShouldUseNativeFrame() || GetWidget()->IsFullscreen()) |
| 277 return margins; | 285 return MARGINS{0}; |
| 278 | 286 |
| 279 if (!IsMaximized()) { | 287 // The glass should extend to the bottom of the tabstrip. |
| 280 if (base::win::GetVersion() < base::win::VERSION_WIN10) { | 288 HWND hwnd = GetHWND(); |
| 281 gfx::Point dip_margin(kDWMFrameBorderExtensionDips, | |
| 282 kDWMFrameBorderExtensionDips); | |
| 283 gfx::Point pixel_margin = | |
| 284 display::win::ScreenWin::DIPToScreenPoint(dip_margin); | |
| 285 margins.cxLeftWidth = pixel_margin.x(); | |
| 286 margins.cxRightWidth = pixel_margin.x(); | |
| 287 margins.cyBottomHeight = pixel_margin.y(); | |
| 288 | |
| 289 const bool md = ui::MaterialDesignController::IsModeMaterial(); | |
| 290 if (!md) { | |
| 291 // Since the toolbar in non-md has rounded corners that show the glass | |
| 292 // frame behind, the extension of the glass area to the bottom of the | |
| 293 // tabstrip below isn't sufficient. We need to go down further to the | |
| 294 // bottom of the rounded corner region. | |
| 295 margins.cyTopHeight = pixel_margin.y(); | |
| 296 } | |
| 297 } | |
| 298 // Else, on Windows 10, we don't need extra border thickness because we draw | |
| 299 // right up to the edge of the client area and there are no rounded corners | |
| 300 // anywhere that we need to make sure are covered. | |
| 301 } | |
| 302 | |
| 303 // Extend top for the tabstrip background. | |
| 304 gfx::Rect tabstrip_bounds( | 289 gfx::Rect tabstrip_bounds( |
| 305 browser_frame_->GetBoundsForTabStrip(browser_view_->tabstrip())); | 290 browser_frame_->GetBoundsForTabStrip(browser_view_->tabstrip())); |
| 306 tabstrip_bounds = | 291 tabstrip_bounds = |
| 307 display::win::ScreenWin::DIPToClientRect(GetHWND(), tabstrip_bounds); | 292 display::win::ScreenWin::DIPToClientRect(hwnd, tabstrip_bounds); |
| 308 margins.cyTopHeight += tabstrip_bounds.bottom(); | |
| 309 | 293 |
| 310 return margins; | 294 // Extend inwards far enough to go under the semitransparent client edges. |
| 295 const gfx::Insets thicknesses = GetClientEdgeThicknesses(); |
| 296 gfx::Point left_top = display::win::ScreenWin::DIPToClientPoint( |
| 297 hwnd, gfx::Point(thicknesses.left(), thicknesses.top())); |
| 298 gfx::Point right_bottom = display::win::ScreenWin::DIPToClientPoint( |
| 299 hwnd, gfx::Point(thicknesses.right(), thicknesses.bottom())); |
| 300 |
| 301 if (base::win::GetVersion() <= base::win::VERSION_WIN7) { |
| 302 // The 2 px (not DIP) at the inner edges of the glass are a light and |
| 303 // dark line, so we must inset further to account for those. |
| 304 constexpr gfx::Vector2d kDWMEdgeThickness(2, 2); |
| 305 left_top += kDWMEdgeThickness; |
| 306 right_bottom += kDWMEdgeThickness; |
| 307 } |
| 308 |
| 309 return MARGINS{left_top.x(), right_bottom.x(), |
| 310 tabstrip_bounds.bottom() + left_top.y(), right_bottom.y()}; |
| 311 } | 311 } |
| 312 | 312 |
| 313 //////////////////////////////////////////////////////////////////////////////// | 313 //////////////////////////////////////////////////////////////////////////////// |
| 314 // BrowserDesktopWindowTreeHost, public: | 314 // BrowserDesktopWindowTreeHost, public: |
| 315 | 315 |
| 316 // static | 316 // static |
| 317 BrowserDesktopWindowTreeHost* | 317 BrowserDesktopWindowTreeHost* |
| 318 BrowserDesktopWindowTreeHost::CreateBrowserDesktopWindowTreeHost( | 318 BrowserDesktopWindowTreeHost::CreateBrowserDesktopWindowTreeHost( |
| 319 views::internal::NativeWidgetDelegate* native_widget_delegate, | 319 views::internal::NativeWidgetDelegate* native_widget_delegate, |
| 320 views::DesktopNativeWidgetAura* desktop_native_widget_aura, | 320 views::DesktopNativeWidgetAura* desktop_native_widget_aura, |
| 321 BrowserView* browser_view, | 321 BrowserView* browser_view, |
| 322 BrowserFrame* browser_frame) { | 322 BrowserFrame* browser_frame) { |
| 323 return new BrowserDesktopWindowTreeHostWin(native_widget_delegate, | 323 return new BrowserDesktopWindowTreeHostWin(native_widget_delegate, |
| 324 desktop_native_widget_aura, | 324 desktop_native_widget_aura, |
| 325 browser_view, | 325 browser_view, |
| 326 browser_frame); | 326 browser_frame); |
| 327 } | 327 } |
| OLD | NEW |