~ci-train-bot/unity/unity-ubuntu-yakkety-landing-089

« back to all changes in this revision

Viewing changes to panel/PanelView.cpp

  • Committer: Bileto Bot
  • Author(s): Marco Trevisan (Treviño)
  • Date: 2016-09-01 23:56:54 UTC
  • mfrom: (3788.9.2 input-monitor-panel)
  • Revision ID: ci-train-bot@canonical.com-20160901235654-zhq2e9a0rn8ps1uq
PanelView: use InputMonitor to track menu events

Approved by: Andrea Azzarone

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
#include <UnityCore/GLibWrapper.h>
25
25
 
 
26
#include "unity-shared/InputMonitor.h"
26
27
#include "unity-shared/PanelStyle.h"
27
28
#include "unity-shared/RawPixel.h"
28
29
#include "unity-shared/TextureCache.h"
42
43
namespace
43
44
{
44
45
const RawPixel TRIANGLE_THRESHOLD = 5_em;
 
46
const double SCRUB_VELOCITY_THRESHOLD = 0.05;
45
47
const int refine_gradient_midpoint = 959;
46
48
}
47
49
 
52
54
  : View(NUX_FILE_LINE_PARAM)
53
55
  , parent_(parent)
54
56
  , remote_(menus->Indicators())
 
57
  , last_pointer_time_(0)
55
58
  , is_dirty_(true)
56
59
  , opacity_maximized_toggle_(false)
57
60
  , needs_geo_sync_(false)
648
651
  }
649
652
}
650
653
 
651
 
static bool PointInTriangle(nux::Point const& p, nux::Point const& t0, nux::Point const& t1, nux::Point const& t2)
 
654
namespace
 
655
{
 
656
bool PointInTriangle(nux::Point const& p, nux::Point const& t0, nux::Point const& t1, nux::Point const& t2)
652
657
{
653
658
  int s = t0.y * t2.x - t0.x * t2.y + (t2.y - t0.y) * p.x + (t0.x - t2.x) * p.y;
654
659
  int t = t0.x * t1.y - t0.y * t1.x + (t0.y - t1.y) * p.x + (t1.x - t0.x) * p.y;
667
672
  return s > 0 && t > 0 && (s + t) < A;
668
673
}
669
674
 
670
 
static double GetMouseVelocity(nux::Point const& p0, nux::Point const& p1, util::Timer &timer)
 
675
double GetMouseVelocity(nux::Point const& p0, nux::Point const& p1, Time time_delta)
671
676
{
672
677
  int dx, dy;
673
678
  double speed;
674
 
  auto millis = timer.ElapsedMicroSeconds();
675
679
 
676
 
  if (millis == 0)
 
680
  if (time_delta == 0)
677
681
    return 1;
678
682
 
679
683
  dx = p0.x - p1.x;
680
684
  dy = p0.y - p1.y;
681
685
 
682
 
  speed = sqrt(dx * dx + dy * dy) / millis * 1000;
 
686
  speed = sqrt(dx * dx + dy * dy) / time_delta;
683
687
 
684
688
  return speed;
685
689
}
 
690
} // anonymous namespace
686
691
 
687
 
bool PanelView::TrackMenuPointer()
 
692
void PanelView::OnActiveEntryEvent(XEvent const& e)
688
693
{
689
 
  nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
690
 
  double speed = GetMouseVelocity(mouse, tracked_pointer_pos_, mouse_tracker_timer_);
691
 
 
692
 
  mouse_tracker_timer_.Reset();
 
694
  if (e.type != MotionNotify)
 
695
    return;
 
696
 
 
697
  double scale = Settings::Instance().em(monitor_)->DPIScale();
 
698
  nux::Point mouse(e.xmotion.x_root, e.xmotion.y_root);
 
699
  double speed = GetMouseVelocity(mouse, tracked_pointer_pos_, e.xmotion.time - last_pointer_time_);
 
700
 
693
701
  tracked_pointer_pos_ = mouse;
694
 
 
695
 
  double scale = Settings::Instance().em(monitor_)->DPIScale();
696
 
  if (speed > 0 && PointInTriangle(mouse,
697
 
                                   nux::Point(triangle_top_corner_.x, std::max(triangle_top_corner_.y - TRIANGLE_THRESHOLD.CP(scale), 0)),
698
 
                                   nux::Point(menu_geo_.x, menu_geo_.y),
699
 
                                   nux::Point(menu_geo_.x + menu_geo_.width, menu_geo_.y)))
700
 
  {
701
 
    return true;
702
 
  }
703
 
 
704
 
  if (mouse != triangle_top_corner_)
705
 
  {
706
 
    triangle_top_corner_ = mouse;
707
 
    OnMenuPointerMoved(mouse.x, mouse.y);
708
 
  }
709
 
 
710
 
  return true;
 
702
  last_pointer_time_ = e.xmotion.time;
 
703
 
 
704
  if (speed > SCRUB_VELOCITY_THRESHOLD &&
 
705
      PointInTriangle(mouse, {mouse.x, std::max(mouse.y - TRIANGLE_THRESHOLD.CP(scale), 0)},
 
706
                      menu_geo_.GetPosition(), {menu_geo_.x + menu_geo_.width, menu_geo_.y}))
 
707
  {
 
708
    return;
 
709
  }
 
710
 
 
711
  OnMenuPointerMoved(mouse.x, mouse.y);
711
712
}
712
713
 
713
714
void PanelView::OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& menu_geo)
715
716
  if (!panel.empty() && panel != GetPanelName())
716
717
    return;
717
718
 
 
719
  bool active = !entry_id.empty();
 
720
  auto const& activation_cb = sigc::mem_fun(this, &PanelView::OnActiveEntryEvent);
718
721
  menu_geo_ = menu_geo;
719
722
 
720
 
  bool active = !entry_id.empty();
721
 
  if (active && !track_menu_pointer_timeout_)
 
723
  if (active)
722
724
  {
723
 
    //
724
 
    // Track menus being scrubbed at 60Hz (about every 16 millisec)
725
 
    // It might sound ugly, but it's far nicer (and more responsive) than the
726
 
    // code it replaces which used to capture motion events in another process
727
 
    // (unity-panel-service) and send them to us over dbus.
728
 
    // NOTE: The reason why we have to use a timer instead of tracking motion
729
 
    // events is because the motion events will never be delivered to this
730
 
    // process. All the motion events will go to unity-panel-service while
731
 
    // scrubbing because the active panel menu has (needs) the pointer grab.
732
 
    //
733
 
    mouse_tracker_timer_.Reset();
734
 
    triangle_top_corner_ = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
735
 
    track_menu_pointer_timeout_.reset(new glib::Timeout(16));
736
 
    track_menu_pointer_timeout_->Run(sigc::mem_fun(this, &PanelView::TrackMenuPointer));
 
725
    auto& im = input::Monitor::Get();
 
726
    if (im.RegisterClient(input::Events::POINTER, activation_cb))
 
727
    {
 
728
      last_pointer_time_ = 0;
 
729
      ActivateEntry(entry_id);
 
730
    }
 
731
 
 
732
    if (overlay_is_open_)
 
733
      ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
737
734
  }
738
 
  else if (!active)
 
735
  else
739
736
  {
740
 
    track_menu_pointer_timeout_.reset();
 
737
    input::Monitor::Get().UnregisterClient(activation_cb);
741
738
    menu_view_->NotifyAllMenusClosed();
742
 
    tracked_pointer_pos_ = {-1, -1};
743
739
  }
744
 
 
745
 
  if (overlay_is_open_)
746
 
    ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
747
740
}
748
741
 
749
742
void PanelView::OnEntryShowMenu(std::string const& entry_id, unsigned xid,
750
743
                                int x, int y, unsigned button)
751
744
{
752
 
  if (!track_menu_pointer_timeout_)
 
745
  if (menu_geo_.IsNull())
753
746
  {
754
747
    // This is ugly... But Nux fault!
755
748
    menu_view_->IgnoreLeaveEvents(true);
768
761
  {
769
762
    // Since this only happens on keyboard events, we need to prevent that the
770
763
    // pointer tracker would select another entry.
771
 
    tracked_pointer_pos_ = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
772
764
    return true;
773
765
  }
774
766
 
785
777
  {
786
778
    // Since this only happens on keyboard events, we need to prevent that the
787
779
    // pointer tracker would select another entry.
788
 
    tracked_pointer_pos_ = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
789
780
    return true;
790
781
  }
791
782