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