Chromium Code Reviews| 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_frame_common_win.h" | |
| 17 #include "chrome/browser/ui/views/frame/browser_view.h" | 16 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 18 #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" |
| 19 #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" |
| 20 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 19 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
| 21 #include "chrome/common/chrome_constants.h" | 20 #include "chrome/common/chrome_constants.h" |
| 22 #include "ui/base/theme_provider.h" | 21 #include "ui/base/theme_provider.h" |
| 22 #include "ui/gfx/geometry/point.h" | |
| 23 #include "ui/gfx/win/dpi.h" | 23 #include "ui/gfx/win/dpi.h" |
| 24 #include "ui/views/controls/menu/native_menu_win.h" | 24 #include "ui/views/controls/menu/native_menu_win.h" |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 const int kClientEdgeThickness = 3; | 28 // The amount of additional non-client area to draw beyond what we have Windows |
| 29 // draw, in DIPs. Only used in Windows versions pre-10. | |
| 30 const int kDWMFrameBorderExtension = 3; | |
|
ananta
2016/04/11 21:12:11
Please add the DIPs suffix to the constant. It wou
Bret
2016/04/11 23:44:47
Done.
| |
| 29 | 31 |
| 30 } // namespace | 32 } // namespace |
| 31 | 33 |
| 32 //////////////////////////////////////////////////////////////////////////////// | 34 //////////////////////////////////////////////////////////////////////////////// |
| 33 // BrowserDesktopWindowTreeHostWin, public: | 35 // BrowserDesktopWindowTreeHostWin, public: |
| 34 | 36 |
| 35 BrowserDesktopWindowTreeHostWin::BrowserDesktopWindowTreeHostWin( | 37 BrowserDesktopWindowTreeHostWin::BrowserDesktopWindowTreeHostWin( |
| 36 views::internal::NativeWidgetDelegate* native_widget_delegate, | 38 views::internal::NativeWidgetDelegate* native_widget_delegate, |
| 37 views::DesktopNativeWidgetAura* desktop_native_widget_aura, | 39 views::DesktopNativeWidgetAura* desktop_native_widget_aura, |
| 38 BrowserView* browser_view, | 40 BrowserView* browser_view, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 88 bool BrowserDesktopWindowTreeHostWin::GetClientAreaInsets( | 90 bool BrowserDesktopWindowTreeHostWin::GetClientAreaInsets( |
| 89 gfx::Insets* insets) const { | 91 gfx::Insets* insets) const { |
| 90 // Use the default client insets for an opaque frame or a glass popup/app | 92 // Use the default client insets for an opaque frame or a glass popup/app |
| 91 // frame. | 93 // frame. |
| 92 if (!GetWidget()->ShouldUseNativeFrame() || | 94 if (!GetWidget()->ShouldUseNativeFrame() || |
| 93 !browser_view_->IsBrowserTypeNormal()) { | 95 !browser_view_->IsBrowserTypeNormal()) { |
| 94 return false; | 96 return false; |
| 95 } | 97 } |
| 96 | 98 |
| 97 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); | 99 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); |
| 98 // In fullscreen mode, we have no frame. In restored mode, we draw our own | 100 if (GetWidget()->IsFullscreen()) { |
| 99 // client edge over part of the default frame. | 101 // In fullscreen mode there is no frame. |
| 100 if (GetWidget()->IsFullscreen()) | |
| 101 border_thickness = 0; | 102 border_thickness = 0; |
| 102 else if (!IsMaximized() && base::win::GetVersion() < base::win::VERSION_WIN10) | 103 } else if (!IsMaximized() && |
| 103 border_thickness -= kClientEdgeThickness; | 104 base::win::GetVersion() < base::win::VERSION_WIN10) { |
| 105 // Reduce the Windows non-client border size because we extended the border | |
| 106 // into our client area in ::UpdateDWMFrame(). | |
| 107 border_thickness -= kDWMFrameBorderExtension; | |
| 108 } | |
| 104 insets->Set(0, border_thickness, border_thickness, border_thickness); | 109 insets->Set(0, border_thickness, border_thickness, border_thickness); |
| 105 return true; | 110 return true; |
| 106 } | 111 } |
| 107 | 112 |
| 108 void BrowserDesktopWindowTreeHostWin::HandleCreate() { | 113 void BrowserDesktopWindowTreeHostWin::HandleCreate() { |
| 109 DesktopWindowTreeHostWin::HandleCreate(); | 114 DesktopWindowTreeHostWin::HandleCreate(); |
| 110 browser_window_property_manager_ = | 115 browser_window_property_manager_ = |
| 111 BrowserWindowPropertyManager::CreateBrowserWindowPropertyManager( | 116 BrowserWindowPropertyManager::CreateBrowserWindowPropertyManager( |
| 112 browser_view_, GetHWND()); | 117 browser_view_, GetHWND()); |
| 113 } | 118 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 : views::FrameMode::CUSTOM_DRAWN; | 224 : views::FrameMode::CUSTOM_DRAWN; |
| 220 } | 225 } |
| 221 | 226 |
| 222 bool BrowserDesktopWindowTreeHostWin::ShouldUseNativeFrame() const { | 227 bool BrowserDesktopWindowTreeHostWin::ShouldUseNativeFrame() const { |
| 223 if (!views::DesktopWindowTreeHostWin::ShouldUseNativeFrame()) | 228 if (!views::DesktopWindowTreeHostWin::ShouldUseNativeFrame()) |
| 224 return false; | 229 return false; |
| 225 // This function can get called when the Browser window is closed i.e. in the | 230 // This function can get called when the Browser window is closed i.e. in the |
| 226 // context of the BrowserView destructor. | 231 // context of the BrowserView destructor. |
| 227 if (!browser_view_->browser()) | 232 if (!browser_view_->browser()) |
| 228 return false; | 233 return false; |
| 229 return chrome::ShouldUseNativeFrame(browser_view_, | 234 // We don't theme popup or app windows, so regardless of whether or not a |
| 230 GetWidget()->GetThemeProvider()); | 235 // theme is active for normal browser windows, we don't want to use the custom |
| 236 // frame for popups/apps. | |
| 237 if (!browser_view_->IsBrowserTypeNormal()) | |
| 238 return true; | |
| 239 // Otherwise, we use the native frame when we're told we should by the theme | |
| 240 // provider (e.g. no custom theme is active). | |
| 241 return GetWidget()->GetThemeProvider()->ShouldUseNativeFrame(); | |
| 231 } | 242 } |
| 232 | 243 |
| 233 void BrowserDesktopWindowTreeHostWin::FrameTypeChanged() { | 244 void BrowserDesktopWindowTreeHostWin::FrameTypeChanged() { |
| 234 views::DesktopWindowTreeHostWin::FrameTypeChanged(); | 245 views::DesktopWindowTreeHostWin::FrameTypeChanged(); |
| 235 did_gdi_clear_ = false; | 246 did_gdi_clear_ = false; |
| 236 } | 247 } |
| 237 | 248 |
| 238 //////////////////////////////////////////////////////////////////////////////// | 249 //////////////////////////////////////////////////////////////////////////////// |
| 239 // BrowserDesktopWindowTreeHostWin, private: | 250 // BrowserDesktopWindowTreeHostWin, private: |
| 240 | 251 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 252 return; | 263 return; |
| 253 | 264 |
| 254 MARGINS margins = GetDWMFrameMargins(); | 265 MARGINS margins = GetDWMFrameMargins(); |
| 255 | 266 |
| 256 DwmExtendFrameIntoClientArea(GetHWND(), &margins); | 267 DwmExtendFrameIntoClientArea(GetHWND(), &margins); |
| 257 } | 268 } |
| 258 | 269 |
| 259 MARGINS BrowserDesktopWindowTreeHostWin::GetDWMFrameMargins() const { | 270 MARGINS BrowserDesktopWindowTreeHostWin::GetDWMFrameMargins() const { |
| 260 MARGINS margins = { 0 }; | 271 MARGINS margins = { 0 }; |
| 261 | 272 |
| 262 // If the opaque frame is visible, we use the default (zero) margins. | 273 // If the opaque frame is visible or we're fullscreen, we don't extend the |
| 263 // Otherwise, we need to figure out how to extend the glass in. | 274 // glass in at all because it won't be visible. |
| 264 if (GetWidget()->ShouldUseNativeFrame()) { | 275 if (!GetWidget()->ShouldUseNativeFrame() || GetWidget()->IsFullscreen()) |
| 265 // In fullscreen mode, we don't extend glass into the client area at all, | 276 return margins; |
| 266 // because the GDI-drawn text in the web content composited over it will | |
| 267 // become semi-transparent over any glass area. | |
| 268 if (!IsMaximized() && !GetWidget()->IsFullscreen()) { | |
| 269 margins.cyTopHeight = kClientEdgeThickness + 1; | |
| 270 // On Windows 10, we don't draw our own window border, so don't extend the | |
| 271 // nonclient area in for it. The top is extended so that the MARGINS isn't | |
| 272 // treated as an empty (ignored) extension. | |
| 273 if (base::win::GetVersion() >= base::win::VERSION_WIN10) { | |
| 274 margins.cxLeftWidth = 0; | |
| 275 margins.cxRightWidth = 0; | |
| 276 margins.cyBottomHeight = 0; | |
| 277 } else { | |
| 278 margins.cxLeftWidth = kClientEdgeThickness + 1; | |
| 279 margins.cxRightWidth = kClientEdgeThickness + 1; | |
| 280 margins.cyBottomHeight = kClientEdgeThickness + 1; | |
| 281 } | |
| 282 } | |
| 283 // In maximized mode, we only have a titlebar strip of glass, no side/bottom | |
| 284 // borders. | |
| 285 if (!browser_view_->IsFullscreen()) { | |
| 286 gfx::Rect tabstrip_bounds( | |
| 287 browser_frame_->GetBoundsForTabStrip(browser_view_->tabstrip())); | |
| 288 tabstrip_bounds = gfx::win::DIPToScreenRect(tabstrip_bounds); | |
| 289 margins.cyTopHeight = tabstrip_bounds.bottom(); | |
| 290 | 277 |
| 291 // On pre-Win 10, we need to offset the DWM frame into the toolbar so that | 278 if (!IsMaximized()) { |
| 292 // the blackness doesn't show up on our rounded toolbar corners. In Win | 279 if (base::win::GetVersion() < base::win::VERSION_WIN10) { |
| 293 // 10 and above there are no rounded corners, so this is unnecessary. | 280 gfx::Point dip_margin(kDWMFrameBorderExtension, kDWMFrameBorderExtension); |
| 294 const int kDWMFrameTopOffset = 3; | 281 gfx::Point pixel_margin = gfx::win::DIPToScreenPoint(dip_margin); |
|
ananta
2016/04/11 21:12:11
Please make sure that this works as expected for f
Bret
2016/04/11 23:44:47
I tested it and it looks fine at 1.25 and 1.5.
| |
| 295 if (base::win::GetVersion() < base::win::VERSION_WIN10) | 282 margins.cxLeftWidth = pixel_margin.x(); |
| 296 margins.cyTopHeight += kDWMFrameTopOffset; | 283 margins.cxRightWidth = pixel_margin.x(); |
| 284 margins.cyBottomHeight = pixel_margin.y(); | |
| 285 | |
| 286 // Even though we're extending the frame to the bottom of the tabstrip | |
| 287 // below we need to offset the DWM frame into the toolbar so that the | |
| 288 // blackness doesn't show up on our rounded toolbar corners. | |
| 289 margins.cyTopHeight = pixel_margin.y(); | |
| 290 } else { | |
| 291 // On Windows 10 we don't need extra border thickness because we draw | |
| 292 // right up to the edge of the client area and there are no rounded | |
| 293 // corners anywhere that we need to make sure are covered. | |
| 294 margins.cxLeftWidth = 0; | |
| 295 margins.cxRightWidth = 0; | |
| 296 margins.cyTopHeight = 0; | |
| 297 margins.cyBottomHeight = 0; | |
| 297 } | 298 } |
| 298 } | 299 } |
| 300 | |
| 301 // Extend top for the tabstrip background. | |
| 302 gfx::Rect tabstrip_bounds( | |
| 303 browser_frame_->GetBoundsForTabStrip(browser_view_->tabstrip())); | |
| 304 tabstrip_bounds = gfx::win::DIPToScreenRect(tabstrip_bounds); | |
| 305 margins.cyTopHeight += tabstrip_bounds.bottom(); | |
| 306 | |
| 299 return margins; | 307 return margins; |
| 300 } | 308 } |
| 301 | 309 |
| 302 //////////////////////////////////////////////////////////////////////////////// | 310 //////////////////////////////////////////////////////////////////////////////// |
| 303 // BrowserDesktopWindowTreeHost, public: | 311 // BrowserDesktopWindowTreeHost, public: |
| 304 | 312 |
| 305 // static | 313 // static |
| 306 BrowserDesktopWindowTreeHost* | 314 BrowserDesktopWindowTreeHost* |
| 307 BrowserDesktopWindowTreeHost::CreateBrowserDesktopWindowTreeHost( | 315 BrowserDesktopWindowTreeHost::CreateBrowserDesktopWindowTreeHost( |
| 308 views::internal::NativeWidgetDelegate* native_widget_delegate, | 316 views::internal::NativeWidgetDelegate* native_widget_delegate, |
| 309 views::DesktopNativeWidgetAura* desktop_native_widget_aura, | 317 views::DesktopNativeWidgetAura* desktop_native_widget_aura, |
| 310 BrowserView* browser_view, | 318 BrowserView* browser_view, |
| 311 BrowserFrame* browser_frame) { | 319 BrowserFrame* browser_frame) { |
| 312 return new BrowserDesktopWindowTreeHostWin(native_widget_delegate, | 320 return new BrowserDesktopWindowTreeHostWin(native_widget_delegate, |
| 313 desktop_native_widget_aura, | 321 desktop_native_widget_aura, |
| 314 browser_view, | 322 browser_view, |
| 315 browser_frame); | 323 browser_frame); |
| 316 } | 324 } |
| OLD | NEW |