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 "ash/shelf/shelf_widget.h" 6 7 #include "ash/focus_cycler.h" 8 #include "ash/launcher/launcher_delegate.h" 9 #include "ash/launcher/launcher_model.h" 10 #include "ash/launcher/launcher_navigator.h" 11 #include "ash/launcher/launcher_view.h" 12 #include "ash/root_window_controller.h" 13 #include "ash/session_state_delegate.h" 14 #include "ash/shelf/shelf_layout_manager.h" 15 #include "ash/shelf/shelf_widget.h" 16 #include "ash/shell.h" 17 #include "ash/shell_window_ids.h" 18 #include "ash/wm/property_util.h" 19 #include "ash/wm/status_area_layout_manager.h" 20 #include "ash/wm/window_properties.h" 21 #include "ash/wm/workspace_controller.h" 22 #include "grit/ash_resources.h" 23 #include "ui/aura/client/activation_client.h" 24 #include "ui/aura/root_window.h" 25 #include "ui/aura/window.h" 26 #include "ui/aura/window_observer.h" 27 #include "ui/base/events/event_constants.h" 28 #include "ui/base/resource/resource_bundle.h" 29 #include "ui/compositor/layer.h" 30 #include "ui/compositor/scoped_layer_animation_settings.h" 31 #include "ui/gfx/canvas.h" 32 #include "ui/gfx/image/image.h" 33 #include "ui/gfx/image/image_skia_operations.h" 34 #include "ui/gfx/skbitmap_operations.h" 35 #include "ui/views/accessible_pane_view.h" 36 #include "ui/views/widget/widget.h" 37 #include "ui/views/widget/widget_delegate.h" 38 39 namespace { 40 // Size of black border at bottom (or side) of launcher. 41 const int kNumBlackPixels = 3; 42 // Alpha to paint dimming image with. 43 const int kDimAlpha = 128; 44 45 // The time to dim and un-dim. 46 const int kTimeToDimMs = 3000; // Slow in dimming. 47 const int kTimeToUnDimMs = 200; // Fast in activating. 48 const int kTimeToSwitchBackgroundMs = 1000; 49 50 // Class used to slightly dim shelf items when maximized and visible. 51 class DimmerView : public views::View, 52 public views::WidgetDelegate, 53 ash::internal::BackgroundAnimatorDelegate { 54 public: 55 // If |disable_dimming_animations_for_test| is set, all alpha animations will 56 // be performed instantly. 57 DimmerView(ash::ShelfWidget* shelf_widget, 58 bool disable_dimming_animations_for_test); 59 virtual ~DimmerView(); 60 61 // Called by |DimmerEventFilter| when the mouse |hovered| state changes. 62 void SetHovered(bool hovered); 63 64 // Force the dimmer to be undimmed. 65 void ForceUndimming(bool force); 66 67 // views::WidgetDelegate overrides: 68 virtual views::Widget* GetWidget() OVERRIDE { 69 return View::GetWidget(); 70 } 71 virtual const views::Widget* GetWidget() const OVERRIDE { 72 return View::GetWidget(); 73 } 74 75 // ash::internal::BackgroundAnimatorDelegate overrides: 76 virtual void UpdateBackground(int alpha) OVERRIDE { 77 alpha_ = alpha; 78 SchedulePaint(); 79 } 80 81 // views::View overrides: 82 virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE; 83 84 // A function to test the current alpha used. 85 int get_dimming_alpha_for_test() { return alpha_; } 86 87 private: 88 // This class monitors mouse events to see if it is on top of the launcher. 89 class DimmerEventFilter : public ui::EventHandler { 90 public: 91 explicit DimmerEventFilter(DimmerView* owner); 92 virtual ~DimmerEventFilter(); 93 94 // Overridden from ui::EventHandler: 95 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE; 96 virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE; 97 98 private: 99 // The owning class. 100 DimmerView* owner_; 101 102 // TRUE if the mouse is inside the shelf. 103 bool mouse_inside_; 104 105 // TRUE if a touch event is inside the shelf. 106 bool touch_inside_; 107 108 DISALLOW_COPY_AND_ASSIGN(DimmerEventFilter); 109 }; 110 111 // The owning shelf. 112 ash::ShelfWidget* shelf_; 113 114 // The alpha to use for covering the shelf. 115 int alpha_; 116 117 // True if the event filter claims that we should not be dimmed. 118 bool is_hovered_; 119 120 // True if someone forces us not to be dimmed (e.g. a menu is open). 121 bool force_hovered_; 122 123 // True if animations should be suppressed for a test. 124 bool disable_dimming_animations_for_test_; 125 126 // The animator for the background transitions. 127 ash::internal::BackgroundAnimator background_animator_; 128 129 // Notification of entering / exiting of the shelf area by mouse. 130 scoped_ptr<DimmerEventFilter> event_filter_; 131 132 DISALLOW_COPY_AND_ASSIGN(DimmerView); 133 }; 134 135 DimmerView::DimmerView(ash::ShelfWidget* shelf_widget, 136 bool disable_dimming_animations_for_test) 137 : shelf_(shelf_widget), 138 alpha_(kDimAlpha), 139 is_hovered_(false), 140 force_hovered_(false), 141 disable_dimming_animations_for_test_(disable_dimming_animations_for_test), 142 background_animator_(this, 0, kDimAlpha) { 143 event_filter_.reset(new DimmerEventFilter(this)); 144 // Make sure it is undimmed at the beginning and then fire off the dimming 145 // animation. 146 background_animator_.SetPaintsBackground(false, 147 ash::internal::BackgroundAnimator::CHANGE_IMMEDIATE); 148 SetHovered(false); 149 } 150 151 DimmerView::~DimmerView() { 152 } 153 154 void DimmerView::SetHovered(bool hovered) { 155 // Remember the hovered state so that we can correct the state once a 156 // possible force state has disappeared. 157 is_hovered_ = hovered; 158 // Undimm also if we were forced to by e.g. an open menu. 159 hovered |= force_hovered_; 160 background_animator_.SetDuration(hovered ? kTimeToUnDimMs : kTimeToDimMs); 161 background_animator_.SetPaintsBackground(!hovered, 162 disable_dimming_animations_for_test_ ? 163 ash::internal::BackgroundAnimator::CHANGE_IMMEDIATE : 164 ash::internal::BackgroundAnimator::CHANGE_ANIMATE); 165 } 166 167 void DimmerView::ForceUndimming(bool force) { 168 bool previous = force_hovered_; 169 force_hovered_ = force; 170 // If the forced change does change the result we apply the change. 171 if (is_hovered_ || force_hovered_ != is_hovered_ || previous) 172 SetHovered(is_hovered_); 173 } 174 175 void DimmerView::OnPaintBackground(gfx::Canvas* canvas) { 176 SkPaint paint; 177 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 178 gfx::ImageSkia launcher_background = 179 *rb.GetImageNamed(IDR_AURA_LAUNCHER_DIMMING).ToImageSkia(); 180 181 if (shelf_->GetAlignment() != ash::SHELF_ALIGNMENT_BOTTOM) { 182 launcher_background = gfx::ImageSkiaOperations::CreateRotatedImage( 183 launcher_background, 184 shelf_->shelf_layout_manager()->SelectValueForShelfAlignment( 185 SkBitmapOperations::ROTATION_90_CW, 186 SkBitmapOperations::ROTATION_90_CW, 187 SkBitmapOperations::ROTATION_270_CW, 188 SkBitmapOperations::ROTATION_180_CW)); 189 } 190 paint.setAlpha(alpha_); 191 canvas->DrawImageInt( 192 launcher_background, 193 0, 0, launcher_background.width(), launcher_background.height(), 194 0, 0, width(), height(), 195 false, 196 paint); 197 } 198 199 DimmerView::DimmerEventFilter::DimmerEventFilter(DimmerView* owner) 200 : owner_(owner), 201 mouse_inside_(false), 202 touch_inside_(false) { 203 ash::Shell::GetInstance()->AddPreTargetHandler(this); 204 } 205 206 DimmerView::DimmerEventFilter::~DimmerEventFilter() { 207 ash::Shell::GetInstance()->RemovePreTargetHandler(this); 208 } 209 210 void DimmerView::DimmerEventFilter::OnMouseEvent(ui::MouseEvent* event) { 211 if (event->type() != ui::ET_MOUSE_MOVED && 212 event->type() != ui::ET_MOUSE_DRAGGED) 213 return; 214 bool inside = owner_->GetBoundsInScreen().Contains(event->root_location()); 215 if (mouse_inside_ || touch_inside_ != inside || touch_inside_) 216 owner_->SetHovered(inside || touch_inside_); 217 mouse_inside_ = inside; 218 } 219 220 void DimmerView::DimmerEventFilter::OnTouchEvent(ui::TouchEvent* event) { 221 bool touch_inside = false; 222 if (event->type() != ui::ET_TOUCH_RELEASED && 223 event->type() != ui::ET_TOUCH_CANCELLED) 224 touch_inside = owner_->GetBoundsInScreen().Contains(event->root_location()); 225 226 if (mouse_inside_ || touch_inside_ != mouse_inside_ || touch_inside) 227 owner_->SetHovered(mouse_inside_ || touch_inside); 228 touch_inside_ = touch_inside; 229 } 230 231 } // namespace 232 233 namespace ash { 234 235 // The contents view of the Shelf. This view contains LauncherView and 236 // sizes it to the width of the shelf minus the size of the status area. 237 class ShelfWidget::DelegateView : public views::WidgetDelegate, 238 public views::AccessiblePaneView, 239 public internal::BackgroundAnimatorDelegate { 240 public: 241 explicit DelegateView(ShelfWidget* shelf); 242 virtual ~DelegateView(); 243 244 void set_focus_cycler(internal::FocusCycler* focus_cycler) { 245 focus_cycler_ = focus_cycler; 246 } 247 internal::FocusCycler* focus_cycler() { 248 return focus_cycler_; 249 } 250 251 ui::Layer* opaque_background() { return &opaque_background_; } 252 253 // Set if the shelf area is dimmed (eg when a window is maximized). 254 void SetDimmed(bool dimmed); 255 bool GetDimmed() const; 256 257 // Set the bounds of the widget. 258 void SetWidgetBounds(const gfx::Rect bounds); 259 260 void SetParentLayer(ui::Layer* layer); 261 262 // views::View overrides: 263 virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE; 264 265 // views::WidgetDelegateView overrides: 266 virtual views::Widget* GetWidget() OVERRIDE { 267 return View::GetWidget(); 268 } 269 virtual const views::Widget* GetWidget() const OVERRIDE { 270 return View::GetWidget(); 271 } 272 273 virtual bool CanActivate() const OVERRIDE; 274 virtual void Layout() OVERRIDE; 275 virtual void ReorderChildLayers(ui::Layer* parent_layer) OVERRIDE; 276 virtual void OnBoundsChanged(const gfx::Rect& old_bounds) OVERRIDE; 277 278 // BackgroundAnimatorDelegate overrides: 279 virtual void UpdateBackground(int alpha) OVERRIDE; 280 281 // Force the shelf to be presented in an undimmed state. 282 void ForceUndimming(bool force); 283 284 // A function to test the current alpha used by the dimming bar. If there is 285 // no dimmer active, the function will return -1. 286 int GetDimmingAlphaForTest(); 287 288 // A function to test the bounds of the dimming bar. Returns gfx::Rect() if 289 // the dimmer is inactive. 290 gfx::Rect GetDimmerBoundsForTest(); 291 292 // Disable dimming animations for running tests. This needs to be called 293 // prior to the creation of of the |dimmer_|. 294 void disable_dimming_animations_for_test() { 295 disable_dimming_animations_for_test_ = true; 296 } 297 298 private: 299 ShelfWidget* shelf_; 300 scoped_ptr<views::Widget> dimmer_; 301 internal::FocusCycler* focus_cycler_; 302 int alpha_; 303 ui::Layer opaque_background_; 304 305 // The view which does the dimming. 306 DimmerView* dimmer_view_; 307 308 // True if dimming animations should be turned off. 309 bool disable_dimming_animations_for_test_; 310 311 DISALLOW_COPY_AND_ASSIGN(DelegateView); 312 }; 313 314 ShelfWidget::DelegateView::DelegateView(ShelfWidget* shelf) 315 : shelf_(shelf), 316 focus_cycler_(NULL), 317 alpha_(0), 318 opaque_background_(ui::LAYER_SOLID_COLOR), 319 dimmer_view_(NULL), 320 disable_dimming_animations_for_test_(false) { 321 set_allow_deactivate_on_esc(true); 322 opaque_background_.SetColor(SK_ColorBLACK); 323 opaque_background_.SetBounds(GetLocalBounds()); 324 opaque_background_.SetOpacity(0.0f); 325 } 326 327 ShelfWidget::DelegateView::~DelegateView() { 328 } 329 330 void ShelfWidget::DelegateView::SetDimmed(bool value) { 331 if (value == (dimmer_.get() != NULL)) 332 return; 333 334 if (value) { 335 dimmer_.reset(new views::Widget); 336 views::Widget::InitParams params( 337 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); 338 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 339 params.can_activate = false; 340 params.accept_events = false; 341 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 342 params.parent = shelf_->GetNativeView(); 343 dimmer_->Init(params); 344 dimmer_->GetNativeWindow()->SetName("ShelfDimmer"); 345 dimmer_->SetBounds(shelf_->GetWindowBoundsInScreen()); 346 // The launcher should not take focus when it is initially shown. 347 dimmer_->set_focus_on_creation(false); 348 dimmer_view_ = new DimmerView(shelf_, disable_dimming_animations_for_test_); 349 dimmer_->SetContentsView(dimmer_view_); 350 dimmer_->GetNativeView()->SetName("ShelfDimmerView"); 351 dimmer_->Show(); 352 } else { 353 dimmer_view_ = NULL; 354 dimmer_.reset(NULL); 355 } 356 } 357 358 bool ShelfWidget::DelegateView::GetDimmed() const { 359 return dimmer_.get() && dimmer_->IsVisible(); 360 } 361 362 void ShelfWidget::DelegateView::SetWidgetBounds(const gfx::Rect bounds) { 363 if (dimmer_) 364 dimmer_->SetBounds(bounds); 365 } 366 367 void ShelfWidget::DelegateView::SetParentLayer(ui::Layer* layer) { 368 layer->Add(&opaque_background_); 369 ReorderLayers(); 370 } 371 372 void ShelfWidget::DelegateView::OnPaintBackground(gfx::Canvas* canvas) { 373 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 374 gfx::ImageSkia launcher_background = 375 *rb.GetImageSkiaNamed(IDR_AURA_LAUNCHER_BACKGROUND); 376 if (SHELF_ALIGNMENT_BOTTOM != shelf_->GetAlignment()) 377 launcher_background = gfx::ImageSkiaOperations::CreateRotatedImage( 378 launcher_background, 379 shelf_->shelf_layout_manager()->SelectValueForShelfAlignment( 380 SkBitmapOperations::ROTATION_90_CW, 381 SkBitmapOperations::ROTATION_90_CW, 382 SkBitmapOperations::ROTATION_270_CW, 383 SkBitmapOperations::ROTATION_180_CW)); 384 385 gfx::Rect black_rect = 386 shelf_->shelf_layout_manager()->SelectValueForShelfAlignment( 387 gfx::Rect(0, height() - kNumBlackPixels, width(), kNumBlackPixels), 388 gfx::Rect(0, 0, kNumBlackPixels, height()), 389 gfx::Rect(width() - kNumBlackPixels, 0, kNumBlackPixels, height()), 390 gfx::Rect(0, 0, width(), kNumBlackPixels)); 391 392 SkPaint paint; 393 paint.setAlpha(alpha_); 394 canvas->DrawImageInt( 395 launcher_background, 396 0, 0, launcher_background.width(), launcher_background.height(), 397 0, 0, width(), height(), 398 false, 399 paint); 400 canvas->FillRect(black_rect, SK_ColorBLACK); 401 } 402 403 bool ShelfWidget::DelegateView::CanActivate() const { 404 // Allow to activate as fallback. 405 if (shelf_->activating_as_fallback_) 406 return true; 407 // Allow to activate from the focus cycler. 408 if (focus_cycler_ && focus_cycler_->widget_activating() == GetWidget()) 409 return true; 410 // Disallow activating in other cases, especially when using mouse. 411 return false; 412 } 413 414 void ShelfWidget::DelegateView::Layout() { 415 for(int i = 0; i < child_count(); ++i) { 416 if (shelf_->shelf_layout_manager()->IsHorizontalAlignment()) { 417 child_at(i)->SetBounds(child_at(i)->x(), child_at(i)->y(), 418 child_at(i)->width(), height()); 419 } else { 420 child_at(i)->SetBounds(child_at(i)->x(), child_at(i)->y(), 421 width(), child_at(i)->height()); 422 } 423 } 424 } 425 426 void ShelfWidget::DelegateView::ReorderChildLayers(ui::Layer* parent_layer) { 427 views::View::ReorderChildLayers(parent_layer); 428 parent_layer->StackAtBottom(&opaque_background_); 429 } 430 431 void ShelfWidget::DelegateView::OnBoundsChanged(const gfx::Rect& old_bounds) { 432 opaque_background_.SetBounds(GetLocalBounds()); 433 } 434 435 void ShelfWidget::DelegateView::ForceUndimming(bool force) { 436 if (GetDimmed()) 437 dimmer_view_->ForceUndimming(force); 438 } 439 440 int ShelfWidget::DelegateView::GetDimmingAlphaForTest() { 441 if (GetDimmed()) 442 return dimmer_view_->get_dimming_alpha_for_test(); 443 return -1; 444 } 445 446 gfx::Rect ShelfWidget::DelegateView::GetDimmerBoundsForTest() { 447 if (GetDimmed()) 448 return dimmer_view_->GetBoundsInScreen(); 449 return gfx::Rect(); 450 } 451 452 void ShelfWidget::DelegateView::UpdateBackground(int alpha) { 453 alpha_ = alpha; 454 SchedulePaint(); 455 } 456 457 ShelfWidget::ShelfWidget(aura::Window* shelf_container, 458 aura::Window* status_container, 459 internal::WorkspaceController* workspace_controller) 460 : delegate_view_(new DelegateView(this)), 461 background_animator_(delegate_view_, 0, kLauncherBackgroundAlpha), 462 activating_as_fallback_(false), 463 window_container_(shelf_container) { 464 views::Widget::InitParams params( 465 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); 466 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 467 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 468 params.parent = shelf_container; 469 params.delegate = delegate_view_; 470 Init(params); 471 472 // The shelf should not take focus when initially shown. 473 set_focus_on_creation(false); 474 SetContentsView(delegate_view_); 475 delegate_view_->SetParentLayer(GetLayer()); 476 477 status_area_widget_ = new internal::StatusAreaWidget(status_container); 478 status_area_widget_->CreateTrayViews(); 479 if (Shell::GetInstance()->session_state_delegate()-> 480 IsActiveUserSessionStarted()) { 481 status_area_widget_->Show(); 482 } 483 Shell::GetInstance()->focus_cycler()->AddWidget(status_area_widget_); 484 485 shelf_layout_manager_ = new internal::ShelfLayoutManager(this); 486 shelf_container->SetLayoutManager(shelf_layout_manager_); 487 shelf_layout_manager_->set_workspace_controller(workspace_controller); 488 workspace_controller->SetShelf(shelf_layout_manager_); 489 490 status_container->SetLayoutManager( 491 new internal::StatusAreaLayoutManager(this)); 492 493 views::Widget::AddObserver(this); 494 } 495 496 ShelfWidget::~ShelfWidget() { 497 RemoveObserver(this); 498 } 499 500 void ShelfWidget::SetPaintsBackground( 501 ShelfBackgroundType background_type, 502 internal::BackgroundAnimator::ChangeType change_type) { 503 ui::Layer* opaque_background = delegate_view_->opaque_background(); 504 float target_opacity = 505 (background_type == SHELF_BACKGROUND_MAXIMIZED) ? 1.0f : 0.0f; 506 scoped_ptr<ui::ScopedLayerAnimationSettings> opaque_background_animation; 507 if (change_type != internal::BackgroundAnimator::CHANGE_IMMEDIATE) { 508 opaque_background_animation.reset(new ui::ScopedLayerAnimationSettings( 509 opaque_background->GetAnimator())); 510 opaque_background_animation->SetTransitionDuration( 511 base::TimeDelta::FromMilliseconds(kTimeToSwitchBackgroundMs)); 512 } 513 opaque_background->SetOpacity(target_opacity); 514 515 // TODO(mukai): use ui::Layer on both opaque_background and normal background 516 // retire background_animator_ at all. It would be simpler. 517 background_animator_.SetPaintsBackground( 518 background_type != SHELF_BACKGROUND_DEFAULT, 519 change_type); 520 } 521 522 ShelfBackgroundType ShelfWidget::GetBackgroundType() const { 523 if (delegate_view_->opaque_background()->GetTargetOpacity() == 1.0f) 524 return SHELF_BACKGROUND_MAXIMIZED; 525 if (background_animator_.paints_background()) 526 return SHELF_BACKGROUND_OVERLAP; 527 528 return SHELF_BACKGROUND_DEFAULT; 529 } 530 531 ShelfAlignment ShelfWidget::GetAlignment() const { 532 return shelf_layout_manager_->GetAlignment(); 533 } 534 535 void ShelfWidget::SetAlignment(ShelfAlignment alignment) { 536 if (launcher_) 537 launcher_->SetAlignment(alignment); 538 status_area_widget_->SetShelfAlignment(alignment); 539 delegate_view_->SchedulePaint(); 540 } 541 542 void ShelfWidget::SetDimsShelf(bool dimming) { 543 delegate_view_->SetDimmed(dimming); 544 // Repaint all children, allowing updates to reflect dimmed state eg: 545 // status area background, app list button and overflow button. 546 if (launcher_) 547 launcher_->SchedulePaint(); 548 status_area_widget_->GetContentsView()->SchedulePaint(); 549 } 550 551 bool ShelfWidget::GetDimsShelf() const { 552 return delegate_view_->GetDimmed(); 553 } 554 555 void ShelfWidget::CreateLauncher() { 556 if (launcher_) 557 return; 558 559 Shell* shell = Shell::GetInstance(); 560 // This needs to be called before launcher_model(). 561 LauncherDelegate* launcher_delegate = shell->GetLauncherDelegate(); 562 if (!launcher_delegate) 563 return; // Not ready to create Launcher 564 565 launcher_.reset(new Launcher(shell->launcher_model(), 566 shell->GetLauncherDelegate(), 567 this)); 568 SetFocusCycler(shell->focus_cycler()); 569 570 // Inform the root window controller. 571 internal::RootWindowController::ForWindow(window_container_)-> 572 OnLauncherCreated(); 573 574 launcher_->SetVisible( 575 shell->session_state_delegate()->IsActiveUserSessionStarted()); 576 shelf_layout_manager_->LayoutShelf(); 577 Show(); 578 } 579 580 bool ShelfWidget::IsLauncherVisible() const { 581 return launcher_.get() && launcher_->IsVisible(); 582 } 583 584 void ShelfWidget::SetLauncherVisibility(bool visible) { 585 if (launcher_) 586 launcher_->SetVisible(visible); 587 } 588 589 void ShelfWidget::SetFocusCycler(internal::FocusCycler* focus_cycler) { 590 delegate_view_->set_focus_cycler(focus_cycler); 591 if (focus_cycler) 592 focus_cycler->AddWidget(this); 593 } 594 595 internal::FocusCycler* ShelfWidget::GetFocusCycler() { 596 return delegate_view_->focus_cycler(); 597 } 598 599 void ShelfWidget::ShutdownStatusAreaWidget() { 600 if (status_area_widget_) 601 status_area_widget_->Shutdown(); 602 status_area_widget_ = NULL; 603 } 604 605 void ShelfWidget::SetWidgetBounds(const gfx::Rect& rect) { 606 Widget::SetBounds(rect); 607 delegate_view_->SetWidgetBounds(rect); 608 } 609 610 void ShelfWidget::ForceUndimming(bool force) { 611 delegate_view_->ForceUndimming(force); 612 } 613 614 void ShelfWidget::OnWidgetActivationChanged(views::Widget* widget, 615 bool active) { 616 activating_as_fallback_ = false; 617 if (active) 618 delegate_view_->SetPaneFocusAndFocusDefault(); 619 else 620 delegate_view_->GetFocusManager()->ClearFocus(); 621 } 622 623 int ShelfWidget::GetDimmingAlphaForTest() { 624 if (delegate_view_) 625 return delegate_view_->GetDimmingAlphaForTest(); 626 return -1; 627 } 628 629 gfx::Rect ShelfWidget::GetDimmerBoundsForTest() { 630 if (delegate_view_) 631 return delegate_view_->GetDimmerBoundsForTest(); 632 return gfx::Rect(); 633 } 634 635 void ShelfWidget::DisableDimmingAnimationsForTest() { 636 DCHECK(delegate_view_); 637 return delegate_view_->disable_dimming_animations_for_test(); 638 } 639 640 } // namespace ash 641