Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc

Issue 2056583002: Fix glass extension on MD for Win 7 and below. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Resync Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698