diff options
| author | Marco Trevisan (TreviƱo) <mail@3v1n0.net> | 2016-09-01 23:56:54 +0000 |
|---|---|---|
| committer | Bileto Bot <ci-train-bot@canonical.com> | 2016-09-01 23:56:54 +0000 |
| commit | 63fde855174ec025acbaa04b3066ae6647ec8377 (patch) | |
| tree | b553bd417b0b5adfc87c7a143730ebe4fdddd42d | |
| parent | a856d14e131dc96fb2ccdc50330ed0c62889c841 (diff) | |
| parent | 610f9301494f991e7cd322069e1367d65f8c7b60 (diff) | |
PanelView: use InputMonitor to track menu events
Approved by: Andrea Azzarone (bzr r4185)
| -rw-r--r-- | panel/PanelView.cpp | 85 | ||||
| -rw-r--r-- | panel/PanelView.h | 10 | ||||
| -rw-r--r-- | tests/test_panel_view.cpp | 2 |
3 files changed, 44 insertions, 53 deletions
diff --git a/panel/PanelView.cpp b/panel/PanelView.cpp index 3bf0c691e..e40ac82b6 100644 --- a/panel/PanelView.cpp +++ b/panel/PanelView.cpp @@ -23,6 +23,7 @@ #include <UnityCore/GLibWrapper.h> +#include "unity-shared/InputMonitor.h" #include "unity-shared/PanelStyle.h" #include "unity-shared/RawPixel.h" #include "unity-shared/TextureCache.h" @@ -42,6 +43,7 @@ namespace panel namespace { const RawPixel TRIANGLE_THRESHOLD = 5_em; +const double SCRUB_VELOCITY_THRESHOLD = 0.05; const int refine_gradient_midpoint = 959; } @@ -52,6 +54,7 @@ PanelView::PanelView(MockableBaseWindow* parent, menu::Manager::Ptr const& menus : View(NUX_FILE_LINE_PARAM) , parent_(parent) , remote_(menus->Indicators()) + , last_pointer_time_(0) , is_dirty_(true) , opacity_maximized_toggle_(false) , needs_geo_sync_(false) @@ -648,7 +651,9 @@ void PanelView::OnMenuPointerMoved(int x, int y) } } -static bool PointInTriangle(nux::Point const& p, nux::Point const& t0, nux::Point const& t1, nux::Point const& t2) +namespace +{ +bool PointInTriangle(nux::Point const& p, nux::Point const& t0, nux::Point const& t1, nux::Point const& t2) { int s = t0.y * t2.x - t0.x * t2.y + (t2.y - t0.y) * p.x + (t0.x - t2.x) * p.y; int t = t0.x * t1.y - t0.y * t1.x + (t0.y - t1.y) * p.x + (t1.x - t0.x) * p.y; @@ -667,47 +672,43 @@ static bool PointInTriangle(nux::Point const& p, nux::Point const& t0, nux::Poin return s > 0 && t > 0 && (s + t) < A; } -static double GetMouseVelocity(nux::Point const& p0, nux::Point const& p1, util::Timer &timer) +double GetMouseVelocity(nux::Point const& p0, nux::Point const& p1, Time time_delta) { int dx, dy; double speed; - auto millis = timer.ElapsedMicroSeconds(); - if (millis == 0) + if (time_delta == 0) return 1; dx = p0.x - p1.x; dy = p0.y - p1.y; - speed = sqrt(dx * dx + dy * dy) / millis * 1000; + speed = sqrt(dx * dx + dy * dy) / time_delta; return speed; } +} // anonymous namespace -bool PanelView::TrackMenuPointer() +void PanelView::OnActiveEntryEvent(XEvent const& e) { - nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord(); - double speed = GetMouseVelocity(mouse, tracked_pointer_pos_, mouse_tracker_timer_); - - mouse_tracker_timer_.Reset(); - tracked_pointer_pos_ = mouse; + if (e.type != MotionNotify) + return; double scale = Settings::Instance().em(monitor_)->DPIScale(); - if (speed > 0 && PointInTriangle(mouse, - nux::Point(triangle_top_corner_.x, std::max(triangle_top_corner_.y - TRIANGLE_THRESHOLD.CP(scale), 0)), - nux::Point(menu_geo_.x, menu_geo_.y), - nux::Point(menu_geo_.x + menu_geo_.width, menu_geo_.y))) - { - return true; - } + nux::Point mouse(e.xmotion.x_root, e.xmotion.y_root); + double speed = GetMouseVelocity(mouse, tracked_pointer_pos_, e.xmotion.time - last_pointer_time_); + + tracked_pointer_pos_ = mouse; + last_pointer_time_ = e.xmotion.time; - if (mouse != triangle_top_corner_) + if (speed > SCRUB_VELOCITY_THRESHOLD && + PointInTriangle(mouse, {mouse.x, std::max(mouse.y - TRIANGLE_THRESHOLD.CP(scale), 0)}, + menu_geo_.GetPosition(), {menu_geo_.x + menu_geo_.width, menu_geo_.y})) { - triangle_top_corner_ = mouse; - OnMenuPointerMoved(mouse.x, mouse.y); + return; } - return true; + OnMenuPointerMoved(mouse.x, mouse.y); } void PanelView::OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& menu_geo) @@ -715,41 +716,33 @@ void PanelView::OnEntryActivated(std::string const& panel, std::string const& en if (!panel.empty() && panel != GetPanelName()) return; + bool active = !entry_id.empty(); + auto const& activation_cb = sigc::mem_fun(this, &PanelView::OnActiveEntryEvent); menu_geo_ = menu_geo; - bool active = !entry_id.empty(); - if (active && !track_menu_pointer_timeout_) + if (active) { - // - // Track menus being scrubbed at 60Hz (about every 16 millisec) - // It might sound ugly, but it's far nicer (and more responsive) than the - // code it replaces which used to capture motion events in another process - // (unity-panel-service) and send them to us over dbus. - // NOTE: The reason why we have to use a timer instead of tracking motion - // events is because the motion events will never be delivered to this - // process. All the motion events will go to unity-panel-service while - // scrubbing because the active panel menu has (needs) the pointer grab. - // - mouse_tracker_timer_.Reset(); - triangle_top_corner_ = nux::GetGraphicsDisplay()->GetMouseScreenCoord(); - track_menu_pointer_timeout_.reset(new glib::Timeout(16)); - track_menu_pointer_timeout_->Run(sigc::mem_fun(this, &PanelView::TrackMenuPointer)); + auto& im = input::Monitor::Get(); + if (im.RegisterClient(input::Events::POINTER, activation_cb)) + { + last_pointer_time_ = 0; + ActivateEntry(entry_id); + } + + if (overlay_is_open_) + ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST); } - else if (!active) + else { - track_menu_pointer_timeout_.reset(); + input::Monitor::Get().UnregisterClient(activation_cb); menu_view_->NotifyAllMenusClosed(); - tracked_pointer_pos_ = {-1, -1}; } - - if (overlay_is_open_) - ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST); } void PanelView::OnEntryShowMenu(std::string const& entry_id, unsigned xid, int x, int y, unsigned button) { - if (!track_menu_pointer_timeout_) + if (menu_geo_.IsNull()) { // This is ugly... But Nux fault! menu_view_->IgnoreLeaveEvents(true); @@ -768,7 +761,6 @@ bool PanelView::ActivateFirstSensitive() { // Since this only happens on keyboard events, we need to prevent that the // pointer tracker would select another entry. - tracked_pointer_pos_ = nux::GetGraphicsDisplay()->GetMouseScreenCoord(); return true; } @@ -785,7 +777,6 @@ bool PanelView::ActivateEntry(std::string const& entry_id) { // Since this only happens on keyboard events, we need to prevent that the // pointer tracker would select another entry. - tracked_pointer_pos_ = nux::GetGraphicsDisplay()->GetMouseScreenCoord(); return true; } diff --git a/panel/PanelView.h b/panel/PanelView.h index c25d251e5..5532e0faa 100644 --- a/panel/PanelView.h +++ b/panel/PanelView.h @@ -35,7 +35,6 @@ #include "unity-shared/Introspectable.h" #include "unity-shared/MenuManager.h" #include "unity-shared/MockableBaseWindow.h" -#include "unity-shared/Timer.h" #include "PanelMenuView.h" #include "PanelTray.h" #include "PanelIndicatorsView.h" @@ -88,7 +87,6 @@ protected: void OnObjectAdded(indicator::Indicator::Ptr const& proxy); void OnObjectRemoved(indicator::Indicator::Ptr const& proxy); void OnIndicatorViewUpdated(); - void OnMenuPointerMoved(int x, int y); void OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& geo); void OnEntryShowMenu(std::string const& entry_id, unsigned xid, int x, int y, unsigned button); @@ -100,6 +98,8 @@ private: void OnSpreadInitiate(); void OnSpreadTerminate(); void OnLowGfxChanged(); + void OnMenuPointerMoved(int x, int y); + void OnActiveEntryEvent(XEvent const&); void EnableOverlayMode(bool); void LoadTextures(); @@ -109,7 +109,6 @@ private: bool IsTransparent(); void UpdateBackground(); void ForceUpdateBackground(); - bool TrackMenuPointer(); void SyncGeometries(); void AddPanelView(PanelIndicatorsView* child, unsigned int stretchFactor); @@ -134,8 +133,8 @@ private: std::unique_ptr<nux::AbstractPaintLayer> bg_refine_single_column_layer_; std::string active_overlay_; - nux::Point tracked_pointer_pos_, triangle_top_corner_; - util::Timer mouse_tracker_timer_; + nux::Point tracked_pointer_pos_; + Time last_pointer_time_; bool is_dirty_; bool opacity_maximized_toggle_; @@ -152,7 +151,6 @@ private: BackgroundEffectHelper bg_effect_helper_; nux::ObjectPtr<nux::IOpenGLBaseTexture> bg_blur_texture_; UBusManager ubus_manager_; - glib::Source::UniquePtr track_menu_pointer_timeout_; }; } // namespace panel diff --git a/tests/test_panel_view.cpp b/tests/test_panel_view.cpp index 82fdf55b3..4eeb37993 100644 --- a/tests/test_panel_view.cpp +++ b/tests/test_panel_view.cpp @@ -25,6 +25,7 @@ #include "unity-shared/PanelStyle.h" #include "unity-shared/UBusMessages.h" #include "unity-shared/UBusWrapper.h" + #include "InputMonitor.h" #include "mock_menu_manager.h" #include "test_standalone_wm.h" @@ -43,6 +44,7 @@ public: nux::ObjectPtr<MockableBaseWindow> window_; nux::ObjectPtr<PanelView> panel_view_; testwrapper::StandaloneWM WM; + input::Monitor im; TestPanelView() : window_(new MockableBaseWindow()) |
