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

Side by Side Diff: ui/app_list/views/app_list_view.cc

Issue 2588103004: Apply new WM shadows to app list. (Closed)
Patch Set: Created 3 years, 12 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
« no previous file with comments | « ui/app_list/views/app_list_view.h ('k') | ui/app_list/views/app_list_view_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "ui/app_list/views/app_list_view.h" 5 #include "ui/app_list/views/app_list_view.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/profiler/scoped_tracker.h" 12 #include "base/profiler/scoped_tracker.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/win/windows_version.h" 14 #include "base/win/windows_version.h"
15 #include "build/build_config.h" 15 #include "build/build_config.h"
16 #include "ui/app_list/app_list_constants.h" 16 #include "ui/app_list/app_list_constants.h"
17 #include "ui/app_list/app_list_model.h" 17 #include "ui/app_list/app_list_model.h"
18 #include "ui/app_list/app_list_switches.h" 18 #include "ui/app_list/app_list_switches.h"
19 #include "ui/app_list/app_list_view_delegate.h" 19 #include "ui/app_list/app_list_view_delegate.h"
20 #include "ui/app_list/speech_ui_model.h" 20 #include "ui/app_list/speech_ui_model.h"
21 #include "ui/app_list/views/app_list_background.h"
22 #include "ui/app_list/views/app_list_folder_view.h" 21 #include "ui/app_list/views/app_list_folder_view.h"
23 #include "ui/app_list/views/app_list_main_view.h" 22 #include "ui/app_list/views/app_list_main_view.h"
24 #include "ui/app_list/views/app_list_view_observer.h" 23 #include "ui/app_list/views/app_list_view_observer.h"
25 #include "ui/app_list/views/apps_container_view.h" 24 #include "ui/app_list/views/apps_container_view.h"
26 #include "ui/app_list/views/contents_view.h" 25 #include "ui/app_list/views/contents_view.h"
27 #include "ui/app_list/views/custom_launcher_page_view.h" 26 #include "ui/app_list/views/custom_launcher_page_view.h"
28 #include "ui/app_list/views/search_box_view.h" 27 #include "ui/app_list/views/search_box_view.h"
29 #include "ui/app_list/views/speech_view.h" 28 #include "ui/app_list/views/speech_view.h"
30 #include "ui/app_list/views/start_page_view.h" 29 #include "ui/app_list/views/start_page_view.h"
30 #include "ui/aura/window.h"
31 #include "ui/aura/window_tree_host.h"
31 #include "ui/base/ui_base_switches.h" 32 #include "ui/base/ui_base_switches.h"
32 #include "ui/compositor/layer.h" 33 #include "ui/compositor/layer.h"
33 #include "ui/compositor/layer_animation_observer.h" 34 #include "ui/compositor/layer_animation_observer.h"
34 #include "ui/compositor/scoped_layer_animation_settings.h" 35 #include "ui/compositor/scoped_layer_animation_settings.h"
35 #include "ui/gfx/canvas.h" 36 #include "ui/gfx/canvas.h"
36 #include "ui/gfx/geometry/insets.h" 37 #include "ui/gfx/geometry/insets.h"
37 #include "ui/gfx/image/image_skia.h" 38 #include "ui/gfx/image/image_skia.h"
38 #include "ui/gfx/path.h" 39 #include "ui/gfx/path.h"
39 #include "ui/gfx/skia_util.h" 40 #include "ui/gfx/skia_util.h"
40 #include "ui/resources/grit/ui_resources.h" 41 #include "ui/resources/grit/ui_resources.h"
41 #include "ui/views/bubble/bubble_frame_view.h" 42 #include "ui/views/bubble/bubble_frame_view.h"
43 #include "ui/views/bubble/bubble_window_targeter.h"
42 #include "ui/views/controls/image_view.h" 44 #include "ui/views/controls/image_view.h"
43 #include "ui/views/controls/textfield/textfield.h" 45 #include "ui/views/controls/textfield/textfield.h"
44 #include "ui/views/layout/fill_layout.h" 46 #include "ui/views/layout/fill_layout.h"
45 #include "ui/views/views_delegate.h" 47 #include "ui/views/views_delegate.h"
46 #include "ui/views/widget/widget.h" 48 #include "ui/views/widget/widget.h"
47
48 #if defined(USE_AURA)
49 #include "ui/aura/window.h"
50 #include "ui/aura/window_tree_host.h"
51 #include "ui/views/bubble/bubble_window_targeter.h"
52 #include "ui/wm/core/masked_window_targeter.h" 49 #include "ui/wm/core/masked_window_targeter.h"
53 #if !defined(OS_CHROMEOS)
54 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
55 #endif
56 #endif // defined(USE_AURA)
57 50
58 namespace app_list { 51 namespace app_list {
59 52
60 namespace { 53 namespace {
61 54
62 // The margin from the edge to the speech UI. 55 // The margin from the edge to the speech UI.
63 const int kSpeechUIMargin = 12; 56 const int kSpeechUIMargin = 12;
64 57
65 // The vertical position for the appearing animation of the speech UI. 58 // The vertical position for the appearing animation of the speech UI.
66 const float kSpeechUIAppearingPosition = 12; 59 const float kSpeechUIAppearingPosition = 12;
67 60
68 // The distance between the arrow tip and edge of the anchor view.
69 const int kArrowOffset = 10;
70
71 // Determines whether the current environment supports shadows bubble borders.
72 bool SupportsShadow() {
73 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
74 // Shadows are not supported on (non-ChromeOS) Linux.
75 return false;
76 #endif
77 return true;
78 }
79
80 // This view forwards the focus to the search box widget by providing it as a 61 // This view forwards the focus to the search box widget by providing it as a
81 // FocusTraversable when a focus search is provided. 62 // FocusTraversable when a focus search is provided.
82 class SearchBoxFocusHost : public views::View { 63 class SearchBoxFocusHost : public views::View {
83 public: 64 public:
84 explicit SearchBoxFocusHost(views::Widget* search_box_widget) 65 explicit SearchBoxFocusHost(views::Widget* search_box_widget)
85 : search_box_widget_(search_box_widget) {} 66 : search_box_widget_(search_box_widget) {}
86 67
87 ~SearchBoxFocusHost() override {} 68 ~SearchBoxFocusHost() override {}
88 69
89 views::FocusTraversable* GetFocusTraversable() override { 70 views::FocusTraversable* GetFocusTraversable() override {
(...skipping 26 matching lines...) Expand all
116 paint.setColor(SK_ColorWHITE); 97 paint.setColor(SK_ColorWHITE);
117 canvas->DrawRoundRect(GetContentsBounds(), corner_radius_, paint); 98 canvas->DrawRoundRect(GetContentsBounds(), corner_radius_, paint);
118 } 99 }
119 100
120 private: 101 private:
121 const int corner_radius_; 102 const int corner_radius_;
122 103
123 DISALLOW_COPY_AND_ASSIGN(AppListOverlayView); 104 DISALLOW_COPY_AND_ASSIGN(AppListOverlayView);
124 }; 105 };
125 106
126 #if defined(USE_AURA)
127 // An event targeter for the search box widget which will ignore events that 107 // An event targeter for the search box widget which will ignore events that
128 // are on the search box's shadow. 108 // are on the search box's shadow.
129 class SearchBoxWindowTargeter : public wm::MaskedWindowTargeter { 109 class SearchBoxWindowTargeter : public wm::MaskedWindowTargeter {
130 public: 110 public:
131 explicit SearchBoxWindowTargeter(views::View* search_box) 111 explicit SearchBoxWindowTargeter(views::View* search_box)
132 : wm::MaskedWindowTargeter(search_box->GetWidget()->GetNativeWindow()), 112 : wm::MaskedWindowTargeter(search_box->GetWidget()->GetNativeWindow()),
133 search_box_(search_box) {} 113 search_box_(search_box) {}
134 ~SearchBoxWindowTargeter() override {} 114 ~SearchBoxWindowTargeter() override {}
135 115
136 private: 116 private:
137 // wm::MaskedWindowTargeter: 117 // wm::MaskedWindowTargeter:
138 bool GetHitTestMask(aura::Window* window, gfx::Path* mask) const override { 118 bool GetHitTestMask(aura::Window* window, gfx::Path* mask) const override {
139 mask->addRect(gfx::RectToSkRect(search_box_->GetContentsBounds())); 119 mask->addRect(gfx::RectToSkRect(search_box_->GetContentsBounds()));
140 return true; 120 return true;
141 } 121 }
142 122
143 views::View* search_box_; 123 views::View* search_box_;
144 124
145 DISALLOW_COPY_AND_ASSIGN(SearchBoxWindowTargeter); 125 DISALLOW_COPY_AND_ASSIGN(SearchBoxWindowTargeter);
146 }; 126 };
147 #endif
148 127
149 } // namespace 128 } // namespace
150 129
151 // An animation observer to hide the view at the end of the animation. 130 // An animation observer to hide the view at the end of the animation.
152 class HideViewAnimationObserver : public ui::ImplicitAnimationObserver { 131 class HideViewAnimationObserver : public ui::ImplicitAnimationObserver {
153 public: 132 public:
154 HideViewAnimationObserver() 133 HideViewAnimationObserver()
155 : frame_(NULL), 134 : frame_(NULL),
156 target_(NULL) { 135 target_(NULL) {
157 } 136 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 delegate_->GetSpeechUI()->AddObserver(this); 184 delegate_->GetSpeechUI()->AddObserver(this);
206 } 185 }
207 186
208 AppListView::~AppListView() { 187 AppListView::~AppListView() {
209 delegate_->GetSpeechUI()->RemoveObserver(this); 188 delegate_->GetSpeechUI()->RemoveObserver(this);
210 animation_observer_.reset(); 189 animation_observer_.reset();
211 // Remove child views first to ensure no remaining dependencies on delegate_. 190 // Remove child views first to ensure no remaining dependencies on delegate_.
212 RemoveAllChildViews(true); 191 RemoveAllChildViews(true);
213 } 192 }
214 193
215 void AppListView::InitAsBubbleAtFixedLocation( 194 void AppListView::InitAsBubble(gfx::NativeView parent, int initial_apps_page) {
216 gfx::NativeView parent, 195 base::Time start_time = base::Time::Now();
217 int initial_apps_page, 196
218 const gfx::Point& anchor_point_in_screen, 197 InitContents(parent, initial_apps_page);
219 views::BubbleBorder::Arrow arrow, 198
220 bool border_accepts_events) { 199 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
221 SetAnchorRect(gfx::Rect(anchor_point_in_screen, gfx::Size())); 200 set_margins(gfx::Insets());
222 // TODO(mgiuca): Inline InitAsBubbleInternal, since there is only one caller. 201 set_parent_window(parent);
223 InitAsBubbleInternal( 202 set_close_on_deactivate(false);
224 parent, initial_apps_page, arrow, border_accepts_events, gfx::Vector2d()); 203 set_shadow(views::BubbleBorder::NO_ASSETS);
204 set_color(kContentsBackgroundColor);
205 // This creates the app list widget. (Before this, child widgets cannot be
206 // created.)
207 views::BubbleDialogDelegateView::CreateBubble(this);
208
209 SetBubbleArrow(views::BubbleBorder::FLOAT);
210 // We can now create the internal widgets.
211 InitChildWidgets();
212
213 aura::Window* window = GetWidget()->GetNativeWindow();
214 window->SetEventTargeter(std::unique_ptr<ui::EventTargeter>(
msw 2016/12/20 15:58:10 nit: MakeUnique
Evan Stade 2016/12/20 17:51:57 Done.
msw 2016/12/20 19:16:10 You changed line 433, please update this one [too]
Evan Stade 2016/12/21 17:00:57 oops
215 new views::BubbleWindowTargeter(this)));
216
217 const int kOverlayCornerRadius =
msw 2016/12/20 15:58:10 q: Do we still need AppListOverlayView?
Evan Stade 2016/12/20 17:51:57 This patch doesn't affect whether we need that or
218 GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius();
219 overlay_view_ = new AppListOverlayView(kOverlayCornerRadius);
220 overlay_view_->SetBoundsRect(GetContentsBounds());
221 AddChildView(overlay_view_);
222
223 if (delegate_)
224 delegate_->ViewInitialized();
225
226 UMA_HISTOGRAM_TIMES("Apps.AppListCreationTime",
227 base::Time::Now() - start_time);
225 } 228 }
226 229
227 void AppListView::InitAsFramelessWindow(gfx::NativeView parent, 230 void AppListView::InitAsFramelessWindow(gfx::NativeView parent,
228 int initial_apps_page, 231 int initial_apps_page,
229 gfx::Rect bounds) { 232 gfx::Rect bounds) {
233 set_color(kContentsBackgroundColor);
230 InitContents(parent, initial_apps_page); 234 InitContents(parent, initial_apps_page);
231 overlay_view_ = new AppListOverlayView(0 /* no corners */); 235 overlay_view_ = new AppListOverlayView(0 /* no corners */);
232 AddChildView(overlay_view_); 236 AddChildView(overlay_view_);
233 237
234 views::Widget* widget = new views::Widget(); 238 views::Widget* widget = new views::Widget();
235 views::Widget::InitParams params( 239 views::Widget::InitParams params(
236 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); 240 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
237 params.parent = parent; 241 params.parent = parent;
238 params.delegate = this; 242 params.delegate = this;
239 widget->Init(params); 243 widget->Init(params);
240 widget->SetBounds(bounds); 244 widget->SetBounds(bounds);
241 // This needs to be set *after* Widget::Init() because
242 // BubbleDialogDelegateView sets its own background at OnNativeThemeChanged(),
243 // which is called in View::AddChildView() which is called at
244 // Widget::SetContentsView() to build the views hierarchy in the widget.
245 set_background(new AppListBackground(0));
246 245
247 InitChildWidgets(); 246 InitChildWidgets();
248 } 247 }
249 248
250 void AppListView::SetBubbleArrow(views::BubbleBorder::Arrow arrow) { 249 void AppListView::SetBubbleArrow(views::BubbleBorder::Arrow arrow) {
251 GetBubbleFrameView()->bubble_border()->set_arrow(arrow); 250 GetBubbleFrameView()->bubble_border()->set_arrow(arrow);
252 SizeToContents(); // Recalcuates with new border. 251 SizeToContents(); // Recalcuates with new border.
253 GetBubbleFrameView()->SchedulePaint(); 252 GetBubbleFrameView()->SchedulePaint();
254 } 253 }
255 254
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 429
431 // The search box will not naturally receive focus by itself (because it is in 430 // The search box will not naturally receive focus by itself (because it is in
432 // a separate widget). Create this SearchBoxFocusHost in the main widget to 431 // a separate widget). Create this SearchBoxFocusHost in the main widget to
433 // forward the focus search into to the search box. 432 // forward the focus search into to the search box.
434 search_box_focus_host_ = new SearchBoxFocusHost(search_box_widget_); 433 search_box_focus_host_ = new SearchBoxFocusHost(search_box_widget_);
435 AddChildView(search_box_focus_host_); 434 AddChildView(search_box_focus_host_);
436 search_box_widget_->SetFocusTraversableParentView(search_box_focus_host_); 435 search_box_widget_->SetFocusTraversableParentView(search_box_focus_host_);
437 search_box_widget_->SetFocusTraversableParent( 436 search_box_widget_->SetFocusTraversableParent(
438 GetWidget()->GetFocusTraversable()); 437 GetWidget()->GetFocusTraversable());
439 438
440 #if defined(USE_AURA)
441 // Mouse events on the search box shadow should not be captured. 439 // Mouse events on the search box shadow should not be captured.
442 aura::Window* window = search_box_widget_->GetNativeWindow(); 440 aura::Window* window = search_box_widget_->GetNativeWindow();
443 window->SetEventTargeter(std::unique_ptr<ui::EventTargeter>( 441 window->SetEventTargeter(std::unique_ptr<ui::EventTargeter>(
444 new SearchBoxWindowTargeter(search_box_view_))); 442 new SearchBoxWindowTargeter(search_box_view_)));
445 #endif
446 443
447 app_list_main_view_->contents_view()->Layout(); 444 app_list_main_view_->contents_view()->Layout();
448 } 445 }
449 446
450 void AppListView::InitAsBubbleInternal(gfx::NativeView parent,
451 int initial_apps_page,
452 views::BubbleBorder::Arrow arrow,
453 bool border_accepts_events,
454 const gfx::Vector2d& anchor_offset) {
455 base::Time start_time = base::Time::Now();
456
457 InitContents(parent, initial_apps_page);
458
459 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
460 set_color(kContentsBackgroundColor);
461 set_margins(gfx::Insets());
462 set_parent_window(parent);
463 set_close_on_deactivate(false);
464 set_anchor_view_insets(gfx::Insets(kArrowOffset + anchor_offset.y(),
465 kArrowOffset + anchor_offset.x(),
466 kArrowOffset - anchor_offset.y(),
467 kArrowOffset - anchor_offset.x()));
468 set_border_accepts_events(border_accepts_events);
469 set_shadow(SupportsShadow() ? views::BubbleBorder::BIG_SHADOW
470 : views::BubbleBorder::NO_SHADOW_OPAQUE_BORDER);
471
472 {
473 // TODO(tapted): Remove ScopedTracker below once crbug.com/431326 is fixed.
474 tracked_objects::ScopedTracker tracking_profile(
475 FROM_HERE_WITH_EXPLICIT_FUNCTION(
476 "431326 views::BubbleDialogDelegateView::CreateBubble()"));
477
478 // This creates the app list widget. (Before this, child widgets cannot be
479 // created.)
480 views::BubbleDialogDelegateView::CreateBubble(this);
481 }
482
483 SetBubbleArrow(arrow);
484
485 // We can now create the internal widgets.
486 InitChildWidgets();
487
488 #if defined(USE_AURA)
489 aura::Window* window = GetWidget()->GetNativeWindow();
490 window->layer()->SetMasksToBounds(true);
491 GetBubbleFrameView()->set_background(new AppListBackground(
492 GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius()));
493 set_background(NULL);
494 window->SetEventTargeter(std::unique_ptr<ui::EventTargeter>(
495 new views::BubbleWindowTargeter(this)));
496 #else
497 set_background(new AppListBackground(
498 GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius()));
499
500 // On non-aura the bubble has two widgets, and it's possible for the border
501 // to be shown independently in odd situations. Explicitly hide the bubble
502 // widget to ensure that any WM_WINDOWPOSCHANGED messages triggered by the
503 // window manager do not have the SWP_SHOWWINDOW flag set which would cause
504 // the border to be shown. See http://crbug.com/231687 .
505 GetWidget()->Hide();
506 #endif
507
508 // On platforms that don't support a shadow, the rounded border of the app
509 // list is constructed _inside_ the view, so a rectangular background goes
510 // over the border in the rounded corners. To fix this, give the background a
511 // corner radius 1px smaller than the outer border, so it just reaches but
512 // doesn't cover it.
513 const int kOverlayCornerRadius =
514 GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius();
515 overlay_view_ =
516 new AppListOverlayView(kOverlayCornerRadius - (SupportsShadow() ? 0 : 1));
517 overlay_view_->SetBoundsRect(GetContentsBounds());
518 AddChildView(overlay_view_);
519
520 if (delegate_)
521 delegate_->ViewInitialized();
522
523 UMA_HISTOGRAM_TIMES("Apps.AppListCreationTime",
524 base::Time::Now() - start_time);
525 }
526
527 void AppListView::OnBeforeBubbleWidgetInit( 447 void AppListView::OnBeforeBubbleWidgetInit(
528 views::Widget::InitParams* params, 448 views::Widget::InitParams* params,
529 views::Widget* widget) const { 449 views::Widget* widget) const {
530 if (!params->native_widget) { 450 if (!params->native_widget) {
531 views::ViewsDelegate* views_delegate = views::ViewsDelegate::GetInstance(); 451 views::ViewsDelegate* views_delegate = views::ViewsDelegate::GetInstance();
532 if (views_delegate && !views_delegate->native_widget_factory().is_null()) { 452 if (views_delegate && !views_delegate->native_widget_factory().is_null()) {
533 params->native_widget = 453 params->native_widget =
534 views_delegate->native_widget_factory().Run(*params, widget); 454 views_delegate->native_widget_factory().Run(*params, widget);
535 } 455 }
536 } 456 }
537 #if defined(USE_AURA) && !defined(OS_CHROMEOS) 457 // Apply a WM-provided shadow (see ui/wm/core/).
538 if (!params->native_widget && delegate_ && delegate_->ForceNativeDesktop()) 458 params->shadow_type = views::Widget::InitParams::SHADOW_TYPE_DROP;
539 params->native_widget = new views::DesktopNativeWidgetAura(widget);
540 #endif
541 #if defined(OS_LINUX)
542 // Set up a custom WM_CLASS for the app launcher window. This allows task
543 // switchers in X11 environments to distinguish it from main browser windows.
544 params->wm_class_name = kAppListWMClass;
545 // Show the window in the taskbar, even though it is a bubble, which would not
546 // normally be shown.
547 params->force_show_in_taskbar = true;
548 #endif
549 } 459 }
550 460
551 int AppListView::GetDialogButtons() const { 461 int AppListView::GetDialogButtons() const {
552 return ui::DIALOG_BUTTON_NONE; 462 return ui::DIALOG_BUTTON_NONE;
553 } 463 }
554 464
555 views::View* AppListView::GetInitiallyFocusedView() { 465 views::View* AppListView::GetInitiallyFocusedView() {
556 return app_list_main_view_->search_box_view()->search_box(); 466 return app_list_main_view_->search_box_view()->search_box();
557 } 467 }
558 468
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 app_list_main_view_->SetVisible(true); 610 app_list_main_view_->SetVisible(true);
701 // Refocus the search box. However, if the app list widget does not have 611 // Refocus the search box. However, if the app list widget does not have
702 // focus, it means another window has already taken focus, and we *must not* 612 // focus, it means another window has already taken focus, and we *must not*
703 // focus the search box (or we would steal focus back into the app list). 613 // focus the search box (or we would steal focus back into the app list).
704 if (GetWidget()->IsActive()) 614 if (GetWidget()->IsActive())
705 search_box_view_->search_box()->RequestFocus(); 615 search_box_view_->search_box()->RequestFocus();
706 } 616 }
707 } 617 }
708 618
709 } // namespace app_list 619 } // namespace app_list
OLDNEW
« no previous file with comments | « ui/app_list/views/app_list_view.h ('k') | ui/app_list/views/app_list_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698