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

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

Issue 2961313003: Touch gestures for System Tray/ IME/ Stylus/ Notifications (Closed)
Patch Set: 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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 private: 193 private:
194 SystemTray* tray_; 194 SystemTray* tray_;
195 195
196 DISALLOW_COPY_AND_ASSIGN(ActivationObserver); 196 DISALLOW_COPY_AND_ASSIGN(ActivationObserver);
197 }; 197 };
198 198
199 // SystemTray 199 // SystemTray
200 200
201 SystemTray::SystemTray(Shelf* shelf) 201 SystemTray::SystemTray(Shelf* shelf)
202 : TrayBackgroundView(shelf), shelf_(shelf) { 202 : TrayBackgroundView(shelf), shelf_(shelf) {
203 target_view_ = this;
204
203 SetInkDropMode(InkDropMode::ON); 205 SetInkDropMode(InkDropMode::ON);
204 206
205 // Since user avatar is on the right hand side of System tray of a 207 // 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 208 // horizontal shelf and that is sufficient to indicate separation, no
207 // separator is required. 209 // separator is required.
208 set_separator_visibility(false); 210 set_separator_visibility(false);
209 } 211 }
210 212
211 SystemTray::~SystemTray() { 213 SystemTray::~SystemTray() {
212 // Destroy any child views that might have back pointers before ~View(). 214 // Destroy any child views that might have back pointers before ~View().
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 // e.g. volume slider. Persistent system bubble is a bubble which is not 596 // e.g. volume slider. Persistent system bubble is a bubble which is not
595 // closed even if user clicks outside of the bubble. 597 // closed even if user clicks outside of the bubble.
596 return system_bubble_ && !system_bubble_->is_persistent() && 598 return system_bubble_ && !system_bubble_->is_persistent() &&
597 Shell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled(); 599 Shell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled();
598 } 600 }
599 601
600 void SystemTray::HideBubble(const TrayBubbleView* bubble_view) { 602 void SystemTray::HideBubble(const TrayBubbleView* bubble_view) {
601 HideBubbleWithView(bubble_view); 603 HideBubbleWithView(bubble_view);
602 } 604 }
603 605
606 bool SystemTray::ProcessGestureEventOnBubbleView(ui::GestureEvent* event,
607 View* target) {
608 target_view_ = target;
609 return ProcessGestureEvent(*event);
610 }
611
604 void SystemTray::CloseBubble(const ui::KeyEvent& key_event) { 612 void SystemTray::CloseBubble(const ui::KeyEvent& key_event) {
605 CloseSystemBubble(); 613 CloseSystemBubble();
606 } 614 }
607 615
608 void SystemTray::ActivateAndStartNavigation(const ui::KeyEvent& key_event) { 616 void SystemTray::ActivateAndStartNavigation(const ui::KeyEvent& key_event) {
609 if (!system_bubble_) 617 if (!system_bubble_)
610 return; 618 return;
611 ActivateBubble(); 619 ActivateBubble();
612 620
613 views::Widget* widget = GetSystemBubble()->bubble_view()->GetWidget(); 621 views::Widget* widget = GetSystemBubble()->bubble_view()->GetWidget();
614 widget->GetFocusManager()->OnKeyEvent(key_event); 622 widget->GetFocusManager()->OnKeyEvent(key_event);
615 } 623 }
616 624
617 void SystemTray::ActivateBubble() { 625 void SystemTray::ActivateBubble() {
618 TrayBubbleView* bubble_view = GetSystemBubble()->bubble_view(); 626 TrayBubbleView* bubble_view = GetSystemBubble()->bubble_view();
619 // If system tray bubble is in the process of closing, do not try to activate 627 // If system tray bubble is in the process of closing, do not try to activate
620 // bubble. 628 // bubble.
621 if (bubble_view->GetWidget()->IsClosed()) 629 if (bubble_view->GetWidget()->IsClosed())
622 return; 630 return;
623 bubble_view->set_can_activate(true); 631 bubble_view->set_can_activate(true);
624 bubble_view->GetWidget()->Activate(); 632 bubble_view->GetWidget()->Activate();
625 } 633 }
626 634
627 void SystemTray::OnGestureEvent(ui::GestureEvent* event) { 635 void SystemTray::OnGestureEvent(ui::GestureEvent* event) {
628 if (Shell::Get() 636 target_view_ = this;
629 ->maximize_mode_controller() 637 if (ProcessGestureEvent(*event))
630 ->IsMaximizeModeWindowManagerEnabled() &&
631 shelf_->IsHorizontalAlignment() && ProcessGestureEvent(*event)) {
632 event->SetHandled(); 638 event->SetHandled();
633 } else { 639 else
634 TrayBackgroundView::OnGestureEvent(event); 640 TrayBackgroundView::OnGestureEvent(event);
635 }
636 } 641 }
637 642
638 gfx::Rect SystemTray::GetWorkAreaBoundsInScreen() const { 643 gfx::Rect SystemTray::GetWorkAreaBoundsInScreen() const {
639 return shelf_->GetUserWorkAreaBounds(); 644 return shelf_->GetUserWorkAreaBounds();
640 } 645 }
641 646
642 bool SystemTray::PerformAction(const ui::Event& event) { 647 bool SystemTray::PerformAction(const ui::Event& event) {
643 // If we're already showing a full system tray menu, either default or 648 // If we're already showing a full system tray menu, either default or
644 // detailed menu, hide it; otherwise, show it (and hide any popup that's 649 // detailed menu, hide it; otherwise, show it (and hide any popup that's
645 // currently shown). 650 // currently shown).
646 if (HasSystemBubble() && full_system_tray_menu_) { 651 if (HasSystemBubble() && full_system_tray_menu_) {
647 system_bubble_->bubble()->Close(); 652 system_bubble_->bubble()->Close();
648 } else { 653 } else {
649 ShowDefaultView(BUBBLE_CREATE_NEW); 654 ShowDefaultView(BUBBLE_CREATE_NEW);
650 if (event.IsKeyEvent() || (event.flags() & ui::EF_TOUCH_ACCESSIBILITY)) 655 if (event.IsKeyEvent() || (event.flags() & ui::EF_TOUCH_ACCESSIBILITY))
651 ActivateBubble(); 656 ActivateBubble();
652 } 657 }
653 return true; 658 return true;
654 } 659 }
655 660
656 bool SystemTray::ProcessGestureEvent(const ui::GestureEvent& event) { 661 bool SystemTray::ProcessGestureEvent(const ui::GestureEvent& event) {
662 if (!Shell::Get()
663 ->maximize_mode_controller()
664 ->IsMaximizeModeWindowManagerEnabled() ||
665 !shelf_->IsHorizontalAlignment()) {
666 return false;
667 }
668
657 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) 669 if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN)
658 return StartGestureDrag(event); 670 return StartGestureDrag(event);
659 671
660 if (!HasSystemBubble() || !is_in_drag_) 672 if (!HasSystemBubble() || !is_in_drag_)
661 return false; 673 return false;
662 674
663 if (event.type() == ui::ET_GESTURE_SCROLL_UPDATE) { 675 if (event.type() == ui::ET_GESTURE_SCROLL_UPDATE) {
664 UpdateGestureDrag(event); 676 UpdateGestureDrag(event);
665 return true; 677 return true;
666 } 678 }
667 679
668 if (event.type() == ui::ET_GESTURE_SCROLL_END || 680 if (event.type() == ui::ET_GESTURE_SCROLL_END ||
669 event.type() == ui::ET_SCROLL_FLING_START) { 681 event.type() == ui::ET_SCROLL_FLING_START) {
670 CompleteGestureDrag(event); 682 CompleteGestureDrag(event);
671 return true; 683 return true;
672 } 684 }
673 685
674 // Unexpected event. Reset the drag state and close the bubble. 686 // Unexpected event. Reset the drag state and close the bubble.
675 is_in_drag_ = false; 687 is_in_drag_ = false;
676 CloseSystemBubble(); 688 CloseSystemBubble();
677 return false; 689 return false;
678 } 690 }
679 691
680 bool SystemTray::StartGestureDrag(const ui::GestureEvent& gesture) { 692 bool SystemTray::StartGestureDrag(const ui::GestureEvent& gesture) {
681 // Close the system bubble if there is already a full one opened. And return 693 if (target_view_ == this) {
682 // false to let shelf handle the event. 694 // Dragging happens on the system tray. Close the system bubble if there is
683 if (HasSystemBubble() && full_system_tray_menu_) { 695 // already a full one opened. And return false to let shelf handle the
684 system_bubble_->bubble()->Close(); 696 // event.
685 return false; 697 if (HasSystemBubble() && full_system_tray_menu_) {
698 system_bubble_->bubble()->Close();
699 return false;
700 }
701
702 // If the scroll sequence begins to scroll downward, return false so that
703 // the event will instead by handled by the shelf.
704 if (gesture.details().scroll_y_hint() > 0)
705 return false;
706
707 ShowDefaultView(BUBBLE_CREATE_NEW);
686 } 708 }
687 709
688 // If the scroll sequence begins to scroll downward, return false so that the
689 // event will instead by handled by the shelf.
690 if (gesture.details().scroll_y_hint() > 0)
691 return false;
692
693 is_in_drag_ = true; 710 is_in_drag_ = true;
694 gesture_drag_amount_ = 0.f; 711 gesture_drag_amount_ = 0.f;
695 ShowDefaultView(BUBBLE_CREATE_NEW);
696 system_tray_bubble_bounds_ = 712 system_tray_bubble_bounds_ =
697 system_bubble_->bubble_view()->GetWidget()->GetWindowBoundsInScreen(); 713 system_bubble_->bubble_view()->GetWidget()->GetWindowBoundsInScreen();
698 SetBubbleBounds(gesture.location()); 714 SetBubbleBounds(gesture.location());
699 return true; 715 return true;
700 } 716 }
701 717
702 void SystemTray::UpdateGestureDrag(const ui::GestureEvent& gesture) { 718 void SystemTray::UpdateGestureDrag(const ui::GestureEvent& gesture) {
703 SetBubbleBounds(gesture.location()); 719 SetBubbleBounds(gesture.location());
704 gesture_drag_amount_ += gesture.details().scroll_y(); 720 gesture_drag_amount_ += gesture.details().scroll_y();
705 } 721 }
706 722
707 void SystemTray::CompleteGestureDrag(const ui::GestureEvent& gesture) { 723 void SystemTray::CompleteGestureDrag(const ui::GestureEvent& gesture) {
708 const bool hide_bubble = !ShouldShowSystemBubbleAfterScrollSequence(gesture); 724 const bool hide_bubble = !ShouldShowSystemBubbleAfterScrollSequence(gesture);
709 gfx::Rect target_bounds = system_tray_bubble_bounds_; 725 gfx::Rect target_bounds = system_tray_bubble_bounds_;
710 726
711 if (hide_bubble) 727 if (hide_bubble)
712 target_bounds.set_y(shelf_->GetIdealBounds().y()); 728 target_bounds.set_y(shelf_->GetIdealBounds().y());
713 729
714 system_bubble_->bubble()->AnimateToTargetBounds(target_bounds, hide_bubble); 730 system_bubble_->bubble()->AnimateToTargetBounds(target_bounds, hide_bubble);
715 is_in_drag_ = false; 731 is_in_drag_ = false;
716 } 732 }
717 733
718 void SystemTray::SetBubbleBounds(const gfx::Point& location) { 734 void SystemTray::SetBubbleBounds(const gfx::Point& location) {
719 gfx::Point location_in_screen_coordinates(location); 735 gfx::Point location_in_screen_coordinates(location);
720 View::ConvertPointToScreen(this, &location_in_screen_coordinates); 736 View::ConvertPointToScreen(target_view_, &location_in_screen_coordinates);
721
722 // System tray bubble should not be dragged higher than its original height.
723 if (location_in_screen_coordinates.y() < system_tray_bubble_bounds_.y())
724 location_in_screen_coordinates.set_y(system_tray_bubble_bounds_.y());
725 737
726 gfx::Rect bounds_on_location = system_tray_bubble_bounds_; 738 gfx::Rect bounds_on_location = system_tray_bubble_bounds_;
727 bounds_on_location.set_y(location_in_screen_coordinates.y()); 739 // System tray bubble should not be dragged higher than its original height.
740 int bounds_y = (target_view_ == this ? shelf_->GetIdealBounds().y()
741 : system_tray_bubble_bounds_.y()) +
742 gesture_drag_amount_;
743 bounds_on_location.set_y(std::max(bounds_y, system_tray_bubble_bounds_.y()));
728 system_bubble_->bubble_view()->GetWidget()->SetBounds(bounds_on_location); 744 system_bubble_->bubble_view()->GetWidget()->SetBounds(bounds_on_location);
729 } 745 }
730 746
731 bool SystemTray::ShouldShowSystemBubbleAfterScrollSequence( 747 bool SystemTray::ShouldShowSystemBubbleAfterScrollSequence(
732 const ui::GestureEvent& sequence_end) { 748 const ui::GestureEvent& sequence_end) {
733 // If the scroll sequence terminates with a fling, show the system menu if the 749 // If the scroll sequence terminates with a fling, show the system menu if the
734 // fling was fast enough and in the correct direction. 750 // fling was fast enough and in the correct direction.
735 if (sequence_end.type() == ui::ET_SCROLL_FLING_START && 751 if (sequence_end.type() == ui::ET_SCROLL_FLING_START &&
736 fabs(sequence_end.details().velocity_y()) > kFlingVelocity) { 752 fabs(sequence_end.details().velocity_y()) > kFlingVelocity) {
737 return sequence_end.details().velocity_y() < 0; 753 return sequence_end.details().velocity_y() < 0;
738 } 754 }
739 755
740 DCHECK(sequence_end.type() == ui::ET_GESTURE_SCROLL_END || 756 DCHECK(sequence_end.type() == ui::ET_GESTURE_SCROLL_END ||
741 sequence_end.type() == ui::ET_SCROLL_FLING_START); 757 sequence_end.type() == ui::ET_SCROLL_FLING_START);
742 // Show the system menu if it is already at least one-third visible. 758
743 return -gesture_drag_amount_ >= system_tray_bubble_bounds_.height() / 3.0; 759 // Keep the bubble's original status if the |gesture_drag_amount_| doesn't
760 // exceed one-third of the bubble's height.
761 if (target_view_ == this)
762 return -gesture_drag_amount_ >= system_tray_bubble_bounds_.height() / 3.0;
763 else
764 return gesture_drag_amount_ < system_tray_bubble_bounds_.height() / 3.0;
sammiequon 2017/06/29 21:28:19 nit: if (target_view == this) return ...; retu
minch1 2017/06/30 17:02:29 Done.
744 } 765 }
745 766
746 void SystemTray::CloseSystemBubbleAndDeactivateSystemTray() { 767 void SystemTray::CloseSystemBubbleAndDeactivateSystemTray() {
747 activation_observer_.reset(); 768 activation_observer_.reset();
748 system_bubble_.reset(); 769 system_bubble_.reset();
749 // When closing a system bubble with the alternate shelf layout, we need to 770 // When closing a system bubble with the alternate shelf layout, we need to
750 // turn off the active tinting of the shelf. 771 // turn off the active tinting of the shelf.
751 if (full_system_tray_menu_) { 772 if (full_system_tray_menu_) {
752 SetIsActive(false); 773 SetIsActive(false);
753 full_system_tray_menu_ = false; 774 full_system_tray_menu_ = false;
(...skipping 21 matching lines...) Expand all
775 .work_area() 796 .work_area()
776 .height(); 797 .height();
777 if (work_area_height > 0) { 798 if (work_area_height > 0) {
778 UMA_HISTOGRAM_CUSTOM_COUNTS( 799 UMA_HISTOGRAM_CUSTOM_COUNTS(
779 "Ash.SystemMenu.PercentageOfWorkAreaHeightCoveredByMenu", 800 "Ash.SystemMenu.PercentageOfWorkAreaHeightCoveredByMenu",
780 100 * bubble_view->height() / work_area_height, 1, 300, 100); 801 100 * bubble_view->height() / work_area_height, 1, 300, 100);
781 } 802 }
782 } 803 }
783 804
784 } // namespace ash 805 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698