browser_non_client_frame_view_ash.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h" 6 7#include "ash/ash_switches.h" 8#include "ash/wm/caption_buttons/frame_caption_button_container_view.h" 9#include "ash/wm/frame_border_hit_test_controller.h" 10#include "ash/wm/header_painter.h" 11#include "base/command_line.h" 12#include "chrome/browser/themes/theme_properties.h" 13#include "chrome/browser/ui/browser.h" 14#include "chrome/browser/ui/views/avatar_label.h" 15#include "chrome/browser/ui/views/avatar_menu_button.h" 16#include "chrome/browser/ui/views/frame/browser_frame.h" 17#include "chrome/browser/ui/views/frame/browser_view.h" 18#include "chrome/browser/ui/views/frame/immersive_mode_controller.h" 19#include "chrome/browser/ui/views/tab_icon_view.h" 20#include "chrome/browser/ui/views/tabs/tab_strip.h" 21#include "chrome/common/chrome_switches.h" 22#include "content/public/browser/web_contents.h" 23#include "grit/ash_resources.h" 24#include "grit/theme_resources.h" 25#include "ui/aura/client/aura_constants.h" 26#include "ui/aura/window.h" 27#include "ui/base/accessibility/accessible_view_state.h" 28#include "ui/base/hit_test.h" 29#include "ui/base/l10n/l10n_util.h" 30#include "ui/base/layout.h" 31#include "ui/base/resource/resource_bundle.h" 32#include "ui/base/theme_provider.h" 33#include "ui/compositor/layer_animator.h" 34#include "ui/gfx/canvas.h" 35#include "ui/gfx/image/image_skia.h" 36#include "ui/gfx/rect_conversions.h" 37#include "ui/views/controls/label.h" 38#include "ui/views/layout/layout_constants.h" 39#include "ui/views/widget/widget.h" 40#include "ui/views/widget/widget_delegate.h" 41 42namespace { 43 44// The avatar ends 2 px above the bottom of the tabstrip (which, given the 45// way the tabstrip draws its bottom edge, will appear like a 1 px gap to the 46// user). 47const int kAvatarBottomSpacing = 2; 48// There are 2 px on each side of the avatar (between the frame border and 49// it on the left, and between it and the tabstrip on the right). 50const int kAvatarSideSpacing = 2; 51// Space between left edge of window and tabstrip. 52const int kTabstripLeftSpacing = 0; 53// Space between right edge of tabstrip and maximize button. 54const int kTabstripRightSpacing = 10; 55// Height of the shadow of the content area, at the top of the toolbar. 56const int kContentShadowHeight = 1; 57// Space between top of window and top of tabstrip for tall headers, such as 58// for restored windows, apps, etc. 59const int kTabstripTopSpacingTall = 7; 60// Space between top of window and top of tabstrip for short headers, such as 61// for maximized windows, pop-ups, etc. 62const int kTabstripTopSpacingShort = 0; 63// Height of the shadow in the tab image, used to ensure clicks in the shadow 64// area still drag restored windows. This keeps the clickable area large enough 65// to hit easily. 66const int kTabShadowHeight = 4; 67 68} // namespace 69 70/////////////////////////////////////////////////////////////////////////////// 71// BrowserNonClientFrameViewAsh, public: 72 73// static 74const char BrowserNonClientFrameViewAsh::kViewClassName[] = 75 "BrowserNonClientFrameViewAsh"; 76 77BrowserNonClientFrameViewAsh::BrowserNonClientFrameViewAsh( 78 BrowserFrame* frame, BrowserView* browser_view) 79 : BrowserNonClientFrameView(frame, browser_view), 80 caption_button_container_(NULL), 81 window_icon_(NULL), 82 header_painter_(new ash::HeaderPainter), 83 frame_border_hit_test_controller_( 84 new ash::FrameBorderHitTestController(frame)) { 85} 86 87BrowserNonClientFrameViewAsh::~BrowserNonClientFrameViewAsh() { 88} 89 90void BrowserNonClientFrameViewAsh::Init() { 91 caption_button_container_ = new ash::FrameCaptionButtonContainerView(frame(), 92 ash::FrameCaptionButtonContainerView::MINIMIZE_ALLOWED); 93 AddChildView(caption_button_container_); 94 95 // Initializing the TabIconView is expensive, so only do it if we need to. 96 if (browser_view()->ShouldShowWindowIcon()) { 97 window_icon_ = new TabIconView(this, NULL); 98 window_icon_->set_is_light(true); 99 AddChildView(window_icon_); 100 window_icon_->Update(); 101 } 102 103 // Create incognito icon if necessary. 104 UpdateAvatarInfo(); 105 106 // HeaderPainter handles layout. 107 header_painter_->Init(frame(), this, window_icon_, caption_button_container_); 108} 109 110/////////////////////////////////////////////////////////////////////////////// 111// BrowserNonClientFrameView overrides: 112 113gfx::Rect BrowserNonClientFrameViewAsh::GetBoundsForTabStrip( 114 views::View* tabstrip) const { 115 if (!tabstrip) 116 return gfx::Rect(); 117 118 // When the tab strip is painted in the immersive fullscreen light bar style, 119 // the caption buttons and the avatar button are not visible. However, their 120 // bounds are still used to compute the tab strip bounds so that the tabs have 121 // the same horizontal position when the tab strip is painted in the immersive 122 // light bar style as when the top-of-window views are revealed. 123 int left_inset = GetTabStripLeftInset(); 124 int right_inset = GetTabStripRightInset(); 125 return gfx::Rect(left_inset, 126 GetTopInset(), 127 std::max(0, width() - left_inset - right_inset), 128 tabstrip->GetPreferredSize().height()); 129} 130 131int BrowserNonClientFrameViewAsh::GetTopInset() const { 132 if (!ShouldPaint() || UseImmersiveLightbarHeaderStyle()) 133 return 0; 134 135 if (browser_view()->IsTabStripVisible()) { 136 if (frame()->IsMaximized() || frame()->IsFullscreen()) 137 return kTabstripTopSpacingShort; 138 else 139 return kTabstripTopSpacingTall; 140 } 141 142 int caption_buttons_bottom = caption_button_container_->bounds().bottom(); 143 144 // The toolbar partially overlaps the caption buttons. 145 if (browser_view()->IsToolbarVisible()) 146 return caption_buttons_bottom - kContentShadowHeight; 147 148 int separator_thickness = UsePackagedAppHeaderStyle() ? 149 header_painter_->HeaderContentSeparatorSize() : kClientEdgeThickness; 150 return caption_buttons_bottom + separator_thickness; 151} 152 153int BrowserNonClientFrameViewAsh::GetThemeBackgroundXInset() const { 154 return header_painter_->GetThemeBackgroundXInset(); 155} 156 157void BrowserNonClientFrameViewAsh::UpdateThrobber(bool running) { 158 if (window_icon_) 159 window_icon_->Update(); 160} 161 162/////////////////////////////////////////////////////////////////////////////// 163// views::NonClientFrameView overrides: 164 165gfx::Rect BrowserNonClientFrameViewAsh::GetBoundsForClientView() const { 166 // The ClientView must be flush with the top edge of the widget so that the 167 // web contents can take up the entire screen in immersive fullscreen (with 168 // or without the top-of-window views revealed). When in immersive fullscreen 169 // and the top-of-window views are revealed, the TopContainerView paints the 170 // window header by redirecting paints from its background to 171 // BrowserNonClientFrameViewAsh. 172 return ash::HeaderPainter::GetBoundsForClientView(0, bounds()); 173} 174 175gfx::Rect BrowserNonClientFrameViewAsh::GetWindowBoundsForClientBounds( 176 const gfx::Rect& client_bounds) const { 177 return ash::HeaderPainter::GetWindowBoundsForClientBounds(0, client_bounds); 178} 179 180int BrowserNonClientFrameViewAsh::NonClientHitTest(const gfx::Point& point) { 181 int hit_test = ash::FrameBorderHitTestController::NonClientHitTest(this, 182 header_painter_.get(), point); 183 184 // See if the point is actually within the avatar menu button or within 185 // the avatar label. 186 if (hit_test == HTCAPTION && ((avatar_button() && 187 avatar_button()->GetMirroredBounds().Contains(point)) || 188 (avatar_label() && avatar_label()->GetMirroredBounds().Contains(point)))) 189 return HTCLIENT; 190 191 // When the window is restored we want a large click target above the tabs 192 // to drag the window, so redirect clicks in the tab's shadow to caption. 193 if (hit_test == HTCLIENT && 194 !(frame()->IsMaximized() || frame()->IsFullscreen())) { 195 // Convert point to client coordinates. 196 gfx::Point client_point(point); 197 View::ConvertPointToTarget(this, frame()->client_view(), &client_point); 198 // Report hits in shadow at top of tabstrip as caption. 199 gfx::Rect tabstrip_bounds(browser_view()->tabstrip()->bounds()); 200 if (client_point.y() < tabstrip_bounds.y() + kTabShadowHeight) 201 hit_test = HTCAPTION; 202 } 203 return hit_test; 204} 205 206void BrowserNonClientFrameViewAsh::GetWindowMask(const gfx::Size& size, 207 gfx::Path* window_mask) { 208 // Aura does not use window masks. 209} 210 211void BrowserNonClientFrameViewAsh::ResetWindowControls() { 212 // Hide the caption buttons in immersive fullscreen when the tab light bar 213 // is visible because it's confusing when the user hovers or clicks in the 214 // top-right of the screen and hits one. 215 bool button_visibility = !UseImmersiveLightbarHeaderStyle(); 216 caption_button_container_->SetVisible(button_visibility); 217 218 caption_button_container_->ResetWindowControls(); 219} 220 221void BrowserNonClientFrameViewAsh::UpdateWindowIcon() { 222 if (window_icon_) 223 window_icon_->SchedulePaint(); 224} 225 226void BrowserNonClientFrameViewAsh::UpdateWindowTitle() { 227 if (!frame()->IsFullscreen()) 228 header_painter_->SchedulePaintForTitle(BrowserFrame::GetTitleFontList()); 229} 230 231/////////////////////////////////////////////////////////////////////////////// 232// views::View overrides: 233 234void BrowserNonClientFrameViewAsh::OnPaint(gfx::Canvas* canvas) { 235 if (!ShouldPaint()) 236 return; 237 238 if (UseImmersiveLightbarHeaderStyle()) { 239 PaintImmersiveLightbarStyleHeader(canvas); 240 return; 241 } 242 243 // The primary header image changes based on window activation state and 244 // theme, so we look it up for each paint. 245 int theme_frame_image_id = GetThemeFrameImageId(); 246 int theme_frame_overlay_image_id = GetThemeFrameOverlayImageId(); 247 248 ui::ThemeProvider* theme_provider = GetThemeProvider(); 249 if (!theme_provider->HasCustomImage(theme_frame_image_id) && 250 (theme_frame_overlay_image_id == 0 || 251 !theme_provider->HasCustomImage(theme_frame_overlay_image_id))) { 252 if (frame()->IsMaximized() || frame()->IsFullscreen()) 253 theme_frame_image_id = IDR_AURA_WINDOW_HEADER_BASE_MINIMAL; 254 } 255 header_painter_->PaintHeader( 256 canvas, 257 theme_frame_image_id, 258 theme_frame_overlay_image_id); 259 if (browser_view()->ShouldShowWindowTitle()) 260 header_painter_->PaintTitleBar(canvas, BrowserFrame::GetTitleFontList()); 261 if (browser_view()->IsToolbarVisible()) 262 PaintToolbarBackground(canvas); 263 else 264 PaintContentEdge(canvas); 265} 266 267void BrowserNonClientFrameViewAsh::Layout() { 268 // The header must be laid out before computing |header_height| because the 269 // computation of |header_height| for app and popup windows depends on the 270 // position of the window controls. 271 header_painter_->LayoutHeader(UsePackagedAppHeaderStyle() || 272 frame()->IsMaximized() || 273 frame()->IsFullscreen()); 274 275 int header_height = 0; 276 if (browser_view()->IsTabStripVisible()) { 277 header_height = GetTopInset() + 278 browser_view()->tabstrip()->GetPreferredSize().height(); 279 } else if (browser_view()->IsToolbarVisible()) { 280 // Set the header's height so that it overlaps with the toolbar because the 281 // top few pixels of the toolbar are not opaque. 282 header_height = GetTopInset() + kFrameShadowThickness * 2; 283 } else { 284 header_height = GetTopInset(); 285 } 286 header_painter_->set_header_height(header_height); 287 if (avatar_button()) 288 LayoutAvatar(); 289 BrowserNonClientFrameView::Layout(); 290} 291 292const char* BrowserNonClientFrameViewAsh::GetClassName() const { 293 return kViewClassName; 294} 295 296bool BrowserNonClientFrameViewAsh::HitTestRect(const gfx::Rect& rect) const { 297 if (!views::View::HitTestRect(rect)) { 298 // |rect| is outside BrowserNonClientFrameViewAsh's bounds. 299 return false; 300 } 301 302 TabStrip* tabstrip = browser_view()->tabstrip(); 303 if (tabstrip && browser_view()->IsTabStripVisible()) { 304 // Claim |rect| only if it is above the bottom of the tabstrip in a non-tab 305 // portion. 306 gfx::RectF rect_in_tabstrip_coords_f(rect); 307 View::ConvertRectToTarget(this, tabstrip, &rect_in_tabstrip_coords_f); 308 gfx::Rect rect_in_tabstrip_coords = gfx::ToEnclosingRect( 309 rect_in_tabstrip_coords_f); 310 311 if (rect_in_tabstrip_coords.y() > tabstrip->height()) 312 return false; 313 314 return !tabstrip->HitTestRect(rect_in_tabstrip_coords) || 315 tabstrip->IsRectInWindowCaption(rect_in_tabstrip_coords); 316 } 317 318 // Claim |rect| if it is above the top of the topmost view in the client area. 319 return rect.y() < GetTopInset(); 320} 321 322void BrowserNonClientFrameViewAsh::GetAccessibleState( 323 ui::AccessibleViewState* state) { 324 state->role = ui::AccessibilityTypes::ROLE_TITLEBAR; 325} 326 327gfx::Size BrowserNonClientFrameViewAsh::GetMinimumSize() { 328 gfx::Size min_client_view_size(frame()->client_view()->GetMinimumSize()); 329 int min_width = std::max(header_painter_->GetMinimumHeaderWidth(), 330 min_client_view_size.width()); 331 if (browser_view()->IsTabStripVisible()) { 332 // Ensure that the minimum width is enough to hold a minimum width tab strip 333 // at its usual insets. 334 int min_tabstrip_width = 335 browser_view()->tabstrip()->GetMinimumSize().width(); 336 min_width = std::max(min_width, 337 min_tabstrip_width + GetTabStripLeftInset() + GetTabStripRightInset()); 338 } 339 return gfx::Size(min_width, min_client_view_size.height()); 340} 341 342void BrowserNonClientFrameViewAsh::OnThemeChanged() { 343 BrowserNonClientFrameView::OnThemeChanged(); 344 header_painter_->OnThemeChanged(); 345} 346 347/////////////////////////////////////////////////////////////////////////////// 348// chrome::TabIconViewModel overrides: 349 350bool BrowserNonClientFrameViewAsh::ShouldTabIconViewAnimate() const { 351 // This function is queried during the creation of the window as the 352 // TabIconView we host is initialized, so we need to NULL check the selected 353 // WebContents because in this condition there is not yet a selected tab. 354 content::WebContents* current_tab = browser_view()->GetActiveWebContents(); 355 return current_tab ? current_tab->IsLoading() : false; 356} 357 358gfx::ImageSkia BrowserNonClientFrameViewAsh::GetFaviconForTabIconView() { 359 views::WidgetDelegate* delegate = frame()->widget_delegate(); 360 if (!delegate) 361 return gfx::ImageSkia(); 362 return delegate->GetWindowIcon(); 363} 364 365/////////////////////////////////////////////////////////////////////////////// 366// BrowserNonClientFrameViewAsh, private: 367 368int BrowserNonClientFrameViewAsh::GetTabStripLeftInset() const { 369 return avatar_button() ? kAvatarSideSpacing + 370 browser_view()->GetOTRAvatarIcon().width() + kAvatarSideSpacing : 371 kTabstripLeftSpacing; 372} 373 374int BrowserNonClientFrameViewAsh::GetTabStripRightInset() const { 375 return header_painter_->GetRightInset() + kTabstripRightSpacing; 376} 377 378bool BrowserNonClientFrameViewAsh::UseImmersiveLightbarHeaderStyle() const { 379 ImmersiveModeController* immersive_controller = 380 browser_view()->immersive_mode_controller(); 381 return immersive_controller->IsEnabled() && 382 !immersive_controller->IsRevealed() && 383 browser_view()->IsTabStripVisible(); 384} 385 386bool BrowserNonClientFrameViewAsh::UsePackagedAppHeaderStyle() const { 387 // Non streamlined hosted apps do not have a toolbar or tabstrip. Their header 388 // should look the same as the header for packaged apps. Streamlined hosted 389 // apps have a toolbar so should use the browser header style. 390 return browser_view()->browser()->is_app() && 391 !CommandLine::ForCurrentProcess()->HasSwitch( 392 switches::kEnableStreamlinedHostedApps); 393} 394 395void BrowserNonClientFrameViewAsh::LayoutAvatar() { 396 DCHECK(avatar_button()); 397 DCHECK(browser_view()->IsTabStripVisible()); 398 gfx::ImageSkia incognito_icon = browser_view()->GetOTRAvatarIcon(); 399 400 int avatar_bottom = GetTopInset() + 401 browser_view()->GetTabStripHeight() - kAvatarBottomSpacing; 402 int avatar_restored_y = avatar_bottom - incognito_icon.height(); 403 int avatar_y = (frame()->IsMaximized() || frame()->IsFullscreen()) ? 404 GetTopInset() + kContentShadowHeight : avatar_restored_y; 405 406 // Hide the incognito icon in immersive fullscreen when the tab light bar is 407 // visible because the header is too short for the icognito icon to be 408 // recognizable. 409 bool avatar_visible = !UseImmersiveLightbarHeaderStyle(); 410 int avatar_height = avatar_visible ? avatar_bottom - avatar_y : 0; 411 412 gfx::Rect avatar_bounds(kAvatarSideSpacing, 413 avatar_y, 414 incognito_icon.width(), 415 avatar_height); 416 avatar_button()->SetBoundsRect(avatar_bounds); 417 avatar_button()->SetVisible(avatar_visible); 418} 419 420bool BrowserNonClientFrameViewAsh::ShouldPaint() const { 421 if (!frame()->IsFullscreen()) 422 return true; 423 424 // We need to paint when in immersive fullscreen and either: 425 // - The top-of-window views are revealed. 426 // - The lightbar style tabstrip is visible. 427 ImmersiveModeController* immersive_mode_controller = 428 browser_view()->immersive_mode_controller(); 429 return immersive_mode_controller->IsEnabled() && 430 (immersive_mode_controller->IsRevealed() || 431 UseImmersiveLightbarHeaderStyle()); 432} 433 434void BrowserNonClientFrameViewAsh::PaintImmersiveLightbarStyleHeader( 435 gfx::Canvas* canvas) { 436 // The light bar header is not themed because theming it does not look good. 437 gfx::ImageSkia* frame_image = GetThemeProvider()->GetImageSkiaNamed( 438 IDR_AURA_WINDOW_HEADER_BASE_MINIMAL); 439 canvas->TileImageInt(*frame_image, 0, 0, width(), frame_image->height()); 440} 441 442void BrowserNonClientFrameViewAsh::PaintToolbarBackground(gfx::Canvas* canvas) { 443 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); 444 if (toolbar_bounds.IsEmpty()) 445 return; 446 gfx::Point toolbar_origin(toolbar_bounds.origin()); 447 View::ConvertPointToTarget(browser_view(), this, &toolbar_origin); 448 toolbar_bounds.set_origin(toolbar_origin); 449 450 int x = toolbar_bounds.x(); 451 int w = toolbar_bounds.width(); 452 int y = toolbar_bounds.y(); 453 int h = toolbar_bounds.height(); 454 455 // Gross hack: We split the toolbar images into two pieces, since sometimes 456 // (popup mode) the toolbar isn't tall enough to show the whole image. The 457 // split happens between the top shadow section and the bottom gradient 458 // section so that we never break the gradient. 459 // NOTE(pkotwicz): If the computation for |bottom_y| is changed, Layout() must 460 // be changed as well. 461 int split_point = kFrameShadowThickness * 2; 462 int bottom_y = y + split_point; 463 ui::ThemeProvider* tp = GetThemeProvider(); 464 int bottom_edge_height = h - split_point; 465 466 canvas->FillRect(gfx::Rect(x, bottom_y, w, bottom_edge_height), 467 tp->GetColor(ThemeProperties::COLOR_TOOLBAR)); 468 469 // Paint the main toolbar image. Since this image is also used to draw the 470 // tab background, we must use the tab strip offset to compute the image 471 // source y position. If you have to debug this code use an image editor 472 // to paint a diagonal line through the toolbar image and ensure it lines up 473 // across the tab and toolbar. 474 gfx::ImageSkia* theme_toolbar = tp->GetImageSkiaNamed(IDR_THEME_TOOLBAR); 475 canvas->TileImageInt( 476 *theme_toolbar, 477 x + GetThemeBackgroundXInset(), 478 bottom_y - GetTopInset(), 479 x, bottom_y, 480 w, theme_toolbar->height()); 481 482 // The content area line has a shadow that extends a couple of pixels above 483 // the toolbar bounds. 484 const int kContentShadowHeight = 2; 485 gfx::ImageSkia* toolbar_top = tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_TOP); 486 canvas->TileImageInt(*toolbar_top, 487 0, 0, 488 x, y - kContentShadowHeight, 489 w, split_point + kContentShadowHeight + 1); 490 491 // Draw the "lightening" shade line around the edges of the toolbar. 492 gfx::ImageSkia* toolbar_left = tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_LEFT); 493 canvas->TileImageInt(*toolbar_left, 494 0, 0, 495 x + kClientEdgeThickness, 496 y + kClientEdgeThickness + kContentShadowHeight, 497 toolbar_left->width(), theme_toolbar->height()); 498 gfx::ImageSkia* toolbar_right = 499 tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_RIGHT); 500 canvas->TileImageInt(*toolbar_right, 501 0, 0, 502 w - toolbar_right->width() - 2 * kClientEdgeThickness, 503 y + kClientEdgeThickness + kContentShadowHeight, 504 toolbar_right->width(), theme_toolbar->height()); 505 506 // Draw the content/toolbar separator. 507 canvas->FillRect( 508 gfx::Rect(x + kClientEdgeThickness, 509 toolbar_bounds.bottom() - kClientEdgeThickness, 510 w - (2 * kClientEdgeThickness), 511 kClientEdgeThickness), 512 ThemeProperties::GetDefaultColor( 513 ThemeProperties::COLOR_TOOLBAR_SEPARATOR)); 514} 515 516void BrowserNonClientFrameViewAsh::PaintContentEdge(gfx::Canvas* canvas) { 517 if (UsePackagedAppHeaderStyle()) { 518 header_painter_->PaintHeaderContentSeparator(canvas); 519 } else { 520 canvas->FillRect(gfx::Rect(0, caption_button_container_->bounds().bottom(), 521 width(), kClientEdgeThickness), 522 ThemeProperties::GetDefaultColor( 523 ThemeProperties::COLOR_TOOLBAR_SEPARATOR)); 524 } 525} 526 527int BrowserNonClientFrameViewAsh::GetThemeFrameImageId() const { 528 bool is_incognito = !browser_view()->IsRegularOrGuestSession(); 529 if (browser_view()->IsBrowserTypeNormal()) { 530 // Use the standard resource ids to allow users to theme the frames. 531 if (ShouldPaintAsActive()) { 532 return is_incognito ? 533 IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME; 534 } 535 return is_incognito ? 536 IDR_THEME_FRAME_INCOGNITO_INACTIVE : IDR_THEME_FRAME_INACTIVE; 537 } 538 // Never theme app and popup windows. 539 if (ShouldPaintAsActive()) { 540 return is_incognito ? 541 IDR_AURA_WINDOW_HEADER_BASE_INCOGNITO_ACTIVE : 542 IDR_AURA_WINDOW_HEADER_BASE_ACTIVE; 543 } 544 return is_incognito ? 545 IDR_AURA_WINDOW_HEADER_BASE_INCOGNITO_INACTIVE : 546 IDR_AURA_WINDOW_HEADER_BASE_INACTIVE; 547} 548 549int BrowserNonClientFrameViewAsh::GetThemeFrameOverlayImageId() const { 550 ui::ThemeProvider* tp = GetThemeProvider(); 551 if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && 552 browser_view()->IsBrowserTypeNormal() && 553 !browser_view()->IsOffTheRecord()) { 554 return ShouldPaintAsActive() ? 555 IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE; 556 } 557 return 0; 558} 559