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