summaryrefslogtreecommitdiff
diff options
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2016-09-01 23:56:54 +0000
committerBileto Bot <ci-train-bot@canonical.com>2016-09-01 23:56:54 +0000
commit63fde855174ec025acbaa04b3066ae6647ec8377 (patch)
treeb553bd417b0b5adfc87c7a143730ebe4fdddd42d
parenta856d14e131dc96fb2ccdc50330ed0c62889c841 (diff)
parent610f9301494f991e7cd322069e1367d65f8c7b60 (diff)
PanelView: use InputMonitor to track menu events
Approved by: Andrea Azzarone (bzr r4185)
-rw-r--r--panel/PanelView.cpp85
-rw-r--r--panel/PanelView.h10
-rw-r--r--tests/test_panel_view.cpp2
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())