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

Side by Side Diff: ash/system/tray/system_tray.cc

Issue 2961313003: Touch gestures for System Tray/ IME/ Stylus/ Notifications (Closed)
Patch Set: Fixed UT. Created 3 years, 5 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
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 "ash/system/tray/system_tray.h" 5 #include "ash/system/tray/system_tray.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include "ash/system/tray/tray_bubble_wrapper.h" 45 #include "ash/system/tray/tray_bubble_wrapper.h"
46 #include "ash/system/tray/tray_constants.h" 46 #include "ash/system/tray/tray_constants.h"
47 #include "ash/system/tray/tray_container.h" 47 #include "ash/system/tray/tray_container.h"
48 #include "ash/system/tray_accessibility.h" 48 #include "ash/system/tray_accessibility.h"
49 #include "ash/system/tray_caps_lock.h" 49 #include "ash/system/tray_caps_lock.h"
50 #include "ash/system/tray_tracing.h" 50 #include "ash/system/tray_tracing.h"
51 #include "ash/system/update/tray_update.h" 51 #include "ash/system/update/tray_update.h"
52 #include "ash/system/user/tray_user.h" 52 #include "ash/system/user/tray_user.h"
53 #include "ash/system/web_notification/web_notification_tray.h" 53 #include "ash/system/web_notification/web_notification_tray.h"
54 #include "ash/wm/container_finder.h" 54 #include "ash/wm/container_finder.h"
55 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
56 #include "ash/wm/widget_finder.h" 55 #include "ash/wm/widget_finder.h"
57 #include "base/logging.h" 56 #include "base/logging.h"
58 #include "base/memory/ptr_util.h" 57 #include "base/memory/ptr_util.h"
59 #include "base/metrics/histogram_macros.h" 58 #include "base/metrics/histogram_macros.h"
60 #include "base/timer/timer.h" 59 #include "base/timer/timer.h"
61 #include "ui/base/accelerators/accelerator.h" 60 #include "ui/base/accelerators/accelerator.h"
62 #include "ui/base/l10n/l10n_util.h" 61 #include "ui/base/l10n/l10n_util.h"
63 #include "ui/compositor/layer.h" 62 #include "ui/compositor/layer.h"
64 #include "ui/display/display.h" 63 #include "ui/display/display.h"
65 #include "ui/display/screen.h" 64 #include "ui/display/screen.h"
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 } 190 }
192 191
193 private: 192 private:
194 SystemTray* tray_; 193 SystemTray* tray_;
195 194
196 DISALLOW_COPY_AND_ASSIGN(ActivationObserver); 195 DISALLOW_COPY_AND_ASSIGN(ActivationObserver);
197 }; 196 };
198 197
199 // SystemTray 198 // SystemTray
200 199
201 SystemTray::SystemTray(Shelf* shelf) 200 SystemTray::SystemTray(Shelf* shelf) : TrayBackgroundView(shelf) {
202 : TrayBackgroundView(shelf), shelf_(shelf) {
203 SetInkDropMode(InkDropMode::ON); 201 SetInkDropMode(InkDropMode::ON);
204 202
205 // Since user avatar is on the right hand side of System tray of a 203 // Since user avatar is on the right hand side of System tray of a
206 // horizontal shelf and that is sufficient to indicate separation, no 204 // horizontal shelf and that is sufficient to indicate separation, no
207 // separator is required. 205 // separator is required.
208 set_separator_visibility(false); 206 set_separator_visibility(false);
209 } 207 }
210 208
211 SystemTray::~SystemTray() { 209 SystemTray::~SystemTray() {
212 // Destroy any child views that might have back pointers before ~View(). 210 // Destroy any child views that might have back pointers before ~View().
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 shelf()->UpdateAutoHideState(); 549 shelf()->UpdateAutoHideState();
552 } 550 }
553 } 551 }
554 552
555 void SystemTray::ClickedOutsideBubble() { 553 void SystemTray::ClickedOutsideBubble() {
556 if (!system_bubble_ || system_bubble_->is_persistent()) 554 if (!system_bubble_ || system_bubble_->is_persistent())
557 return; 555 return;
558 HideBubbleWithView(system_bubble_->bubble_view()); 556 HideBubbleWithView(system_bubble_->bubble_view());
559 } 557 }
560 558
559 bool SystemTray::PerformAction(const ui::Event& event) {
560 // If we're already showing a full system tray menu, either default or
561 // detailed menu, hide it; otherwise, show it (and hide any popup that's
562 // currently shown).
563 if (HasSystemBubble() && full_system_tray_menu_) {
564 system_bubble_->bubble()->Close();
565 } else {
566 ShowDefaultView(BUBBLE_CREATE_NEW);
567 if (event.IsKeyEvent() || (event.flags() & ui::EF_TOUCH_ACCESSIBILITY))
568 ActivateBubble();
569 }
570 return true;
571 }
572
573 // TODO(minch): Remove CloseSystemBubble which is redundant with CloseBubble.
msw 2017/07/14 02:00:45 nit: move this to the header file.
minch1 2017/07/14 19:45:17 Done.
574 // http://crbug.com/741953
575 void SystemTray::CloseBubble() {
576 CloseSystemBubble();
577 }
578
579 void SystemTray::ShowBubble() {
580 ShowDefaultView(BUBBLE_CREATE_NEW);
581 }
582
583 views::TrayBubbleView* SystemTray::GetBubbleView() {
584 return system_bubble_ && full_system_tray_menu_
msw 2017/07/14 02:00:45 Please add a comment here like "Only return the bu
minch1 2017/07/14 19:45:17 Done.
585 ? system_bubble_->bubble_view()
586 : nullptr;
587 }
588
589 void SystemTray::OnGestureEvent(ui::GestureEvent* event) {
590 if (!drag_controller()->ProcessGestureEvent(event, this))
591 TrayBackgroundView::OnGestureEvent(event);
592 }
593
561 void SystemTray::BubbleViewDestroyed() { 594 void SystemTray::BubbleViewDestroyed() {
562 if (system_bubble_) { 595 if (system_bubble_) {
563 system_bubble_->bubble()->DestroyItemViews(); 596 system_bubble_->bubble()->DestroyItemViews();
564 system_bubble_->bubble()->BubbleViewDestroyed(); 597 system_bubble_->bubble()->BubbleViewDestroyed();
565 } 598 }
566 } 599 }
567 600
568 void SystemTray::OnMouseEnteredView() { 601 void SystemTray::OnMouseEnteredView() {
569 if (system_bubble_) 602 if (system_bubble_)
570 system_bubble_->bubble()->StopAutoCloseTimer(); 603 system_bubble_->bubble()->StopAutoCloseTimer();
(...skipping 25 matching lines...) Expand all
596 // e.g. volume slider. Persistent system bubble is a bubble which is not 629 // e.g. volume slider. Persistent system bubble is a bubble which is not
597 // closed even if user clicks outside of the bubble. 630 // closed even if user clicks outside of the bubble.
598 return system_bubble_ && !system_bubble_->is_persistent() && 631 return system_bubble_ && !system_bubble_->is_persistent() &&
599 Shell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled(); 632 Shell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled();
600 } 633 }
601 634
602 void SystemTray::HideBubble(const TrayBubbleView* bubble_view) { 635 void SystemTray::HideBubble(const TrayBubbleView* bubble_view) {
603 HideBubbleWithView(bubble_view); 636 HideBubbleWithView(bubble_view);
604 } 637 }
605 638
639 bool SystemTray::ProcessGestureEventForBubble(ui::GestureEvent* event) {
640 return drag_controller()->ProcessGestureEvent(event, this);
641 }
642
606 void SystemTray::ActivateAndStartNavigation(const ui::KeyEvent& key_event) { 643 void SystemTray::ActivateAndStartNavigation(const ui::KeyEvent& key_event) {
607 if (!system_bubble_) 644 if (!system_bubble_)
608 return; 645 return;
609 ActivateBubble(); 646 ActivateBubble();
610 647
611 views::Widget* widget = GetSystemBubble()->bubble_view()->GetWidget(); 648 views::Widget* widget = GetSystemBubble()->bubble_view()->GetWidget();
612 widget->GetFocusManager()->OnKeyEvent(key_event); 649 widget->GetFocusManager()->OnKeyEvent(key_event);
613 } 650 }
614 651
615 void SystemTray::ActivateBubble() { 652 void SystemTray::ActivateBubble() {
616 TrayBubbleView* bubble_view = GetSystemBubble()->bubble_view(); 653 TrayBubbleView* bubble_view = GetSystemBubble()->bubble_view();
617 // If system tray bubble is in the process of closing, do not try to activate 654 // If system tray bubble is in the process of closing, do not try to activate
618 // bubble. 655 // bubble.
619 if (bubble_view->GetWidget()->IsClosed()) 656 if (bubble_view->GetWidget()->IsClosed())
620 return; 657 return;
621 bubble_view->set_can_activate(true); 658 bubble_view->set_can_activate(true);
622 bubble_view->GetWidget()->Activate(); 659 bubble_view->GetWidget()->Activate();
623 } 660 }
624 661
625 void SystemTray::OnGestureEvent(ui::GestureEvent* event) {
626 if (Shell::Get()
627 ->maximize_mode_controller()
628 ->IsMaximizeModeWindowManagerEnabled() &&
629 shelf_->IsHorizontalAlignment() && ProcessGestureEvent(*event)) {
630 event->SetHandled();
631 } else {
632 TrayBackgroundView::OnGestureEvent(event);
633 }
634 }
635
636 gfx::Rect SystemTray::GetWorkAreaBoundsInScreen() const {
637 return shelf_->GetUserWorkAreaBounds();
638 }
639
640 bool SystemTray::PerformAction(const ui::Event& event) {
641 // If we're already showing a full system tray menu, either default or
642 // detailed menu, hide it; otherwise, show it (and hide any popup that's
643 // currently shown).
644 if (HasSystemBubble() && full_system_tray_menu_) {
645 system_bubble_->bubble()->Close();
646 } else {
647 ShowDefaultView(BUBBLE_CREATE_NEW);
648 if (event.IsKeyEvent() || (event.flags() & ui::EF_TOUCH_ACCESSIBILITY))
649 ActivateBubble();
650 }
651 return true;
652 }
653
654 bool SystemTray::ProcessGestureEvent(const ui::GestureEvent& event) {
655 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN)
656 return StartGestureDrag(event);
657
658 if (!HasSystemBubble() || !is_in_drag_)
659 return false;
660
661 if (event.type() == ui::ET_GESTURE_SCROLL_UPDATE) {
662 UpdateGestureDrag(event);
663 return true;
664 }
665
666 if (event.type() == ui::ET_GESTURE_SCROLL_END ||
667 event.type() == ui::ET_SCROLL_FLING_START) {
668 CompleteGestureDrag(event);
669 return true;
670 }
671
672 // Unexpected event. Reset the drag state and close the bubble.
673 is_in_drag_ = false;
674 CloseSystemBubble();
675 return false;
676 }
677
678 bool SystemTray::StartGestureDrag(const ui::GestureEvent& gesture) {
679 // Close the system bubble if there is already a full one opened. And return
680 // false to let shelf handle the event.
681 if (HasSystemBubble() && full_system_tray_menu_) {
682 system_bubble_->bubble()->Close();
683 return false;
684 }
685
686 // If the scroll sequence begins to scroll downward, return false so that the
687 // event will instead by handled by the shelf.
688 if (gesture.details().scroll_y_hint() > 0)
689 return false;
690
691 is_in_drag_ = true;
692 gesture_drag_amount_ = 0.f;
693 ShowDefaultView(BUBBLE_CREATE_NEW);
694 system_tray_bubble_bounds_ =
695 system_bubble_->bubble_view()->GetWidget()->GetWindowBoundsInScreen();
696 SetBubbleBounds(gesture.location());
697 return true;
698 }
699
700 void SystemTray::UpdateGestureDrag(const ui::GestureEvent& gesture) {
701 SetBubbleBounds(gesture.location());
702 gesture_drag_amount_ += gesture.details().scroll_y();
703 }
704
705 void SystemTray::CompleteGestureDrag(const ui::GestureEvent& gesture) {
706 const bool hide_bubble = !ShouldShowSystemBubbleAfterScrollSequence(gesture);
707 gfx::Rect target_bounds = system_tray_bubble_bounds_;
708
709 if (hide_bubble)
710 target_bounds.set_y(shelf_->GetIdealBounds().y());
711
712 system_bubble_->bubble()->AnimateToTargetBounds(target_bounds, hide_bubble);
713 is_in_drag_ = false;
714 }
715
716 void SystemTray::SetBubbleBounds(const gfx::Point& location) {
717 gfx::Point location_in_screen_coordinates(location);
718 View::ConvertPointToScreen(this, &location_in_screen_coordinates);
719
720 // System tray bubble should not be dragged higher than its original height.
721 if (location_in_screen_coordinates.y() < system_tray_bubble_bounds_.y())
722 location_in_screen_coordinates.set_y(system_tray_bubble_bounds_.y());
723
724 gfx::Rect bounds_on_location = system_tray_bubble_bounds_;
725 bounds_on_location.set_y(location_in_screen_coordinates.y());
726 system_bubble_->bubble_view()->GetWidget()->SetBounds(bounds_on_location);
727 }
728
729 bool SystemTray::ShouldShowSystemBubbleAfterScrollSequence(
730 const ui::GestureEvent& sequence_end) {
731 // If the scroll sequence terminates with a fling, show the system menu if the
732 // fling was fast enough and in the correct direction.
733 if (sequence_end.type() == ui::ET_SCROLL_FLING_START &&
734 fabs(sequence_end.details().velocity_y()) > kFlingVelocity) {
735 return sequence_end.details().velocity_y() < 0;
736 }
737
738 DCHECK(sequence_end.type() == ui::ET_GESTURE_SCROLL_END ||
739 sequence_end.type() == ui::ET_SCROLL_FLING_START);
740 // Show the system menu if it is already at least one-third visible.
741 return -gesture_drag_amount_ >= system_tray_bubble_bounds_.height() / 3.0;
742 }
743
744 void SystemTray::CloseSystemBubbleAndDeactivateSystemTray() { 662 void SystemTray::CloseSystemBubbleAndDeactivateSystemTray() {
745 activation_observer_.reset(); 663 activation_observer_.reset();
746 system_bubble_.reset(); 664 system_bubble_.reset();
747 // When closing a system bubble with the alternate shelf layout, we need to 665 // When closing a system bubble with the alternate shelf layout, we need to
748 // turn off the active tinting of the shelf. 666 // turn off the active tinting of the shelf.
749 if (full_system_tray_menu_) { 667 if (full_system_tray_menu_) {
750 SetIsActive(false); 668 SetIsActive(false);
751 full_system_tray_menu_ = false; 669 full_system_tray_menu_ = false;
752 } 670 }
753 } 671 }
(...skipping 19 matching lines...) Expand all
773 .work_area() 691 .work_area()
774 .height(); 692 .height();
775 if (work_area_height > 0) { 693 if (work_area_height > 0) {
776 UMA_HISTOGRAM_CUSTOM_COUNTS( 694 UMA_HISTOGRAM_CUSTOM_COUNTS(
777 "Ash.SystemMenu.PercentageOfWorkAreaHeightCoveredByMenu", 695 "Ash.SystemMenu.PercentageOfWorkAreaHeightCoveredByMenu",
778 100 * bubble_view->height() / work_area_height, 1, 300, 100); 696 100 * bubble_view->height() / work_area_height, 1, 300, 100);
779 } 697 }
780 } 698 }
781 699
782 } // namespace ash 700 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698