Merge lp:~unity-team/unity/edge-barrier-autohide-fix into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Brandon Schaefer
Approved revision: no longer in the source branch.
Merged at revision: 3140
Proposed branch: lp:~unity-team/unity/edge-barrier-autohide-fix
Merge into: lp:unity
Diff against target: 776 lines (+320/-117)
9 files modified
launcher/EdgeBarrierController.cpp (+55/-48)
launcher/EdgeBarrierController.h (+10/-4)
launcher/EdgeBarrierControllerPrivate.h (+57/-0)
launcher/Launcher.cpp (+9/-7)
launcher/Launcher.h (+1/-1)
launcher/PointerBarrier.cpp (+1/-0)
launcher/PointerBarrier.h (+1/-0)
tests/test_edge_barrier_controller.cpp (+114/-41)
tests/test_launcher.cpp (+72/-16)
To merge this branch: bzr merge lp:~unity-team/unity/edge-barrier-autohide-fix
Reviewer Review Type Date Requested Status
Brandon Schaefer (community) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+147252@code.launchpad.net

This proposal supersedes a proposal from 2013-02-06.

Commit message

EdgeBarrierController: add multiple types of subscriber results, fix edges on autohide

Now when sticky keys are disabled, and the launcher is set to autohide, the mouse will hit both sides of the screen (instead of just the left side of the barrier); at that point we'll release the events coming from the launcher-less side of the monitor, but we'll use them to temporary keep the barrier "broken".

Description of the change

=== Problem ===
When sticky keys are set to off only the left side of the barrier blocks the mouse. This means when moving the mouse from the LEFT screen to the RIGHT screen it will skip the barrier.

=== Fix ===
Just use direction::BOTH for both cases.
So we'll release the events coming from the launcher-less side of the monitor, but we'll use them to temporary keep the barrier "broken".

Initially based on lp:~brandontschaefer/unity/lp.1064945-fix

=== Test ===
Added new unit tests, updated old ones.

To post a comment you must log in.
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Awesome, looks good, and works well :).

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/EdgeBarrierController.cpp'
2--- launcher/EdgeBarrierController.cpp 2012-12-11 23:38:30 +0000
3+++ launcher/EdgeBarrierController.cpp 2013-02-08 01:02:23 +0000
4@@ -19,6 +19,7 @@
5 */
6
7 #include "EdgeBarrierController.h"
8+#include "EdgeBarrierControllerPrivate.h"
9 #include "Decaymulator.h"
10 #include "unity-shared/UScreen.h"
11 #include "UnityCore/GLibSource.h"
12@@ -26,23 +27,6 @@
13 namespace unity {
14 namespace ui {
15
16-struct EdgeBarrierController::Impl
17-{
18- Impl(EdgeBarrierController *parent);
19-
20- void ResizeBarrierList(std::vector<nux::Geometry> const& layout);
21- void SetupBarriers(std::vector<nux::Geometry> const& layout);
22-
23- void OnPointerBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event);
24- void BarrierRelease(PointerBarrierWrapper* owner, int event);
25-
26- std::vector<PointerBarrierWrapper::Ptr> barriers_;
27- std::vector<EdgeBarrierSubscriber*> subscribers_;
28- Decaymulator decaymulator_;
29- glib::Source::UniquePtr release_timeout_;
30- float edge_overcome_pressure_;
31- EdgeBarrierController* parent_;
32-};
33
34 EdgeBarrierController::Impl::Impl(EdgeBarrierController *parent)
35 : edge_overcome_pressure_(0)
36@@ -106,7 +90,7 @@
37
38 barrier->DestroyBarrier();
39
40- if (!edge_resist && (subscribers_[i] == nullptr || parent_->options()->hide_mode() == launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER))
41+ if (!edge_resist && parent_->options()->hide_mode() == launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER)
42 continue;
43
44 barrier->x1 = monitor.x;
45@@ -118,11 +102,6 @@
46 barrier->threshold = parent_->options()->edge_stop_velocity();
47 barrier->max_velocity_multiplier = parent_->options()->edge_responsiveness();
48
49- if (edge_resist)
50- barrier->direction = BarrierDirection::BOTH;
51- else
52- barrier->direction = BarrierDirection::LEFT;
53-
54 barrier->ConstructBarrier();
55 }
56
57@@ -133,7 +112,22 @@
58 edge_overcome_pressure_ = parent_->options()->edge_overcome_pressure() * overcome_responsiveness_mult;
59 }
60
61-void EdgeBarrierController::Impl::OnPointerBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event)
62+void EdgeBarrierController::Impl::BarrierReset()
63+{
64+ decaymulator_.value = 0;
65+}
66+
67+void EdgeBarrierController::Impl::BarrierPush(PointerBarrierWrapper* owner, BarrierEvent::Ptr const& event)
68+{
69+ decaymulator_.value = decaymulator_.value + event->velocity;
70+
71+ if (decaymulator_.value > edge_overcome_pressure_)
72+ {
73+ BarrierRelease(owner, event->event_id);
74+ }
75+}
76+
77+void EdgeBarrierController::Impl::OnPointerBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr const& event)
78 {
79 if (owner->released)
80 {
81@@ -142,28 +136,41 @@
82 }
83
84 unsigned int monitor = owner->index;
85- bool process = true;
86+ auto result = EdgeBarrierSubscriber::Result::IGNORED;
87
88 if (monitor < subscribers_.size())
89 {
90 auto subscriber = subscribers_[monitor];
91
92- if (subscriber && subscriber->HandleBarrierEvent(owner, event))
93- process = false;
94+ if (subscriber)
95+ result = subscriber->HandleBarrierEvent(owner, event);
96 }
97
98- if (process && owner->x1 > 0)
99+ switch (result)
100 {
101- decaymulator_.value = decaymulator_.value + event->velocity;
102-
103- if (decaymulator_.value > edge_overcome_pressure_ || (!parent_->sticky_edges() && !subscribers_[monitor]))
104- {
105+ case EdgeBarrierSubscriber::Result::HANDLED:
106+ BarrierReset();
107+ break;
108+
109+ case EdgeBarrierSubscriber::Result::ALREADY_HANDLED:
110+ BarrierPush(owner, event);
111+ break;
112+
113+ case EdgeBarrierSubscriber::Result::IGNORED:
114+ if (parent_->sticky_edges())
115+ {
116+ BarrierPush(owner, event);
117+ }
118+ else
119+ {
120+ owner->release_once = true;
121+ BarrierRelease(owner, event->event_id);
122+ }
123+ break;
124+
125+ case EdgeBarrierSubscriber::Result::NEEDS_RELEASE:
126 BarrierRelease(owner, event->event_id);
127- }
128- }
129- else
130- {
131- decaymulator_.value = 0;
132+ break;
133 }
134 }
135
136@@ -171,13 +178,18 @@
137 {
138 owner->ReleaseBarrier(event);
139 owner->released = true;
140- decaymulator_.value = 0;
141+ BarrierReset();
142
143- unsigned duration = parent_->options()->edge_passed_disabled_ms;
144- release_timeout_.reset(new glib::Timeout(duration, [owner] {
145- owner->released = false;
146- return false;
147- }));
148+ if (!owner->release_once() ||
149+ (owner->release_once() && (!release_timeout_ || !release_timeout_->IsRunning())))
150+ {
151+ unsigned duration = parent_->options()->edge_passed_disabled_ms;
152+ release_timeout_.reset(new glib::Timeout(duration, [owner] {
153+ owner->released = false;
154+ owner->release_once = false;
155+ return false;
156+ }));
157+ }
158 }
159
160 EdgeBarrierController::EdgeBarrierController()
161@@ -217,10 +229,5 @@
162 return pimpl->subscribers_[monitor];
163 }
164
165-void EdgeBarrierController::ProcessBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event)
166-{
167- pimpl->OnPointerBarrierEvent(owner, event);
168-}
169-
170 }
171 }
172
173=== modified file 'launcher/EdgeBarrierController.h'
174--- launcher/EdgeBarrierController.h 2012-11-23 02:11:30 +0000
175+++ launcher/EdgeBarrierController.h 2013-02-08 01:02:23 +0000
176@@ -28,7 +28,15 @@
177
178 struct EdgeBarrierSubscriber
179 {
180- virtual bool HandleBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event) = 0;
181+ enum class Result
182+ {
183+ IGNORED,
184+ HANDLED,
185+ ALREADY_HANDLED,
186+ NEEDS_RELEASE
187+ };
188+
189+ virtual Result HandleBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event) = 0;
190 };
191
192 class EdgeBarrierController : public sigc::trackable
193@@ -44,12 +52,10 @@
194 void Unsubscribe(EdgeBarrierSubscriber* subscriber, unsigned int monitor);
195 EdgeBarrierSubscriber* GetSubscriber(unsigned int monitor);
196
197-protected:
198- void ProcessBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event);
199-
200 private:
201 struct Impl;
202 std::unique_ptr<Impl> pimpl;
203+ friend class TestEdgeBarrierController;
204 };
205
206 }
207
208=== added file 'launcher/EdgeBarrierControllerPrivate.h'
209--- launcher/EdgeBarrierControllerPrivate.h 1970-01-01 00:00:00 +0000
210+++ launcher/EdgeBarrierControllerPrivate.h 2013-02-08 01:02:23 +0000
211@@ -0,0 +1,57 @@
212+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
213+/*
214+ * Copyright (C) 2012-2013 Canonical Ltd
215+ *
216+ * This program is free software: you can redistribute it and/or modify
217+ * it under the terms of the GNU General Public License version 3 as
218+ * published by the Free Software Foundation.
219+ *
220+ * This program is distributed in the hope that it will be useful,
221+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
222+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
223+ * GNU General Public License for more details.
224+ *
225+ * You should have received a copy of the GNU General Public License
226+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
227+ *
228+ * Authored by: Jason Smith <jason.smith@canonical.com>
229+ * Marco Trevisan <marco.trevisan@canonical.com>
230+ */
231+
232+#ifndef EDGE_BARRIER_CONTROLLER_IMPL_PRIVATE
233+#define EDGE_BARRIER_CONTROLLER_IMPL_PRIVATE
234+
235+#include "Decaymulator.h"
236+#include "UnityCore/GLibSource.h"
237+
238+namespace unity
239+{
240+namespace ui
241+{
242+
243+// NOTE: This private header is not part of the public interface
244+struct EdgeBarrierController::Impl
245+{
246+ Impl(EdgeBarrierController *parent);
247+
248+ void ResizeBarrierList(std::vector<nux::Geometry> const& layout);
249+ void SetupBarriers(std::vector<nux::Geometry> const& layout);
250+
251+ void OnPointerBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr const& event);
252+ void BarrierPush(PointerBarrierWrapper* owner, BarrierEvent::Ptr const& event);
253+ void BarrierRelease(PointerBarrierWrapper* owner, int event);
254+ void BarrierReset();
255+
256+ std::vector<PointerBarrierWrapper::Ptr> barriers_;
257+ std::vector<EdgeBarrierSubscriber*> subscribers_;
258+ Decaymulator decaymulator_;
259+ glib::Source::UniquePtr release_timeout_;
260+ float edge_overcome_pressure_;
261+ EdgeBarrierController* parent_;
262+};
263+
264+} //namespace ui
265+} //namespace unity
266+
267+
268+#endif // EDGE_BARRIER_CONTROLLER_IMPL_PRIVATE
269
270=== modified file 'launcher/Launcher.cpp'
271--- launcher/Launcher.cpp 2013-02-01 22:53:42 +0000
272+++ launcher/Launcher.cpp 2013-02-08 01:02:23 +0000
273@@ -2252,19 +2252,21 @@
274
275 #ifdef USE_X11
276
277-bool Launcher::HandleBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event)
278+ui::EdgeBarrierSubscriber::Result Launcher::HandleBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event)
279 {
280 if (_hide_machine.GetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE))
281 {
282- owner->ReleaseBarrier(event->event_id);
283- return true;
284+ return ui::EdgeBarrierSubscriber::Result::NEEDS_RELEASE;
285 }
286
287 nux::Geometry const& abs_geo = GetAbsoluteGeometry();
288
289 bool apply_to_reveal = false;
290- if (_hidden && event->x >= abs_geo.x && event->x <= abs_geo.x + abs_geo.width)
291+ if (event->x >= abs_geo.x && event->x <= abs_geo.x + abs_geo.width)
292 {
293+ if (!_hidden)
294+ return ui::EdgeBarrierSubscriber::Result::ALREADY_HANDLED;
295+
296 if (options()->reveal_trigger == RevealTrigger::EDGE)
297 {
298 if (event->y >= abs_geo.y)
299@@ -2288,15 +2290,15 @@
300 &root_y_return, &win_x_return, &win_y_return, &mask_return))
301 {
302 if (mask_return & (Button1Mask | Button3Mask))
303- apply_to_reveal = false;
304+ return ui::EdgeBarrierSubscriber::Result::NEEDS_RELEASE;
305 }
306 }
307
308 if (!apply_to_reveal)
309- return false;
310+ return ui::EdgeBarrierSubscriber::Result::IGNORED;
311
312 _hide_machine.AddRevealPressure(event->velocity);
313- return true;
314+ return ui::EdgeBarrierSubscriber::Result::HANDLED;
315 }
316
317 #endif
318
319=== modified file 'launcher/Launcher.h'
320--- launcher/Launcher.h 2013-02-01 22:53:42 +0000
321+++ launcher/Launcher.h 2013-02-08 01:02:23 +0000
322@@ -210,7 +210,7 @@
323 #endif
324
325 #ifdef USE_X11
326- bool HandleBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event);
327+ ui::EdgeBarrierSubscriber::Result HandleBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event);
328 #endif
329
330 void OnPluginStateChanged();
331
332=== modified file 'launcher/PointerBarrier.cpp'
333--- launcher/PointerBarrier.cpp 2012-07-19 01:22:13 +0000
334+++ launcher/PointerBarrier.cpp 2013-02-08 01:02:23 +0000
335@@ -38,6 +38,7 @@
336 PointerBarrierWrapper::PointerBarrierWrapper()
337 : active(false)
338 , released(false)
339+ , release_once(false)
340 , smoothing(75)
341 , max_velocity_multiplier(1.0f)
342 , direction(BOTH)
343
344=== modified file 'launcher/PointerBarrier.h'
345--- launcher/PointerBarrier.h 2012-07-19 01:22:13 +0000
346+++ launcher/PointerBarrier.h 2013-02-08 01:02:23 +0000
347@@ -70,6 +70,7 @@
348
349 nux::Property<bool> active;
350 nux::Property<bool> released;
351+ nux::Property<bool> release_once;
352
353 nux::Property<int> smoothing;
354
355
356=== modified file 'tests/test_edge_barrier_controller.cpp'
357--- tests/test_edge_barrier_controller.cpp 2012-09-13 10:56:42 +0000
358+++ tests/test_edge_barrier_controller.cpp 2013-02-08 01:02:23 +0000
359@@ -23,6 +23,7 @@
360 #include "test_uscreen_mock.h"
361
362 #include "EdgeBarrierController.h"
363+#include "EdgeBarrierControllerPrivate.h"
364
365 using namespace unity;
366 using namespace unity::ui;
367@@ -46,35 +47,25 @@
368 MOCK_METHOD1(ReleaseBarrier, void(int));
369 };
370
371-class MockEdgeBarrierController : public EdgeBarrierController
372-{
373-public:
374- void ProcessBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event)
375- {
376- EdgeBarrierController::ProcessBarrierEvent(owner, event);
377- }
378-
379- EdgeBarrierSubscriber* GetSubscriber(unsigned int monitor)
380- {
381- return EdgeBarrierController::GetSubscriber(monitor);
382- }
383-};
384-
385 class TestBarrierSubscriber : public EdgeBarrierSubscriber
386 {
387 public:
388- TestBarrierSubscriber(bool handles = false)
389- : handles_(handles)
390+ TestBarrierSubscriber(EdgeBarrierSubscriber::Result result = EdgeBarrierSubscriber::Result::IGNORED)
391+ : handle_result_(result)
392 {}
393
394- bool HandleBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event)
395+ EdgeBarrierSubscriber::Result HandleBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event)
396 {
397- return handles_;
398+ return handle_result_;
399 }
400
401- bool handles_;
402+ EdgeBarrierSubscriber::Result handle_result_;
403 };
404
405+} // namespace
406+
407+namespace unity {
408+namespace ui {
409 class TestEdgeBarrierController : public Test
410 {
411 public:
412@@ -93,16 +84,32 @@
413 }
414 }
415
416+ void ProcessBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event)
417+ {
418+ GetPrivateImpl()->OnPointerBarrierEvent(owner, event);
419+ }
420+
421+ EdgeBarrierController::Impl* GetPrivateImpl() const
422+ {
423+ return bc.pimpl.get();
424+ }
425+
426 BarrierEvent::Ptr MakeBarrierEvent(int id, bool breaker)
427 {
428 int velocity = breaker ? std::numeric_limits<int>::max() : bc.options()->edge_overcome_pressure() - 1;
429 return std::make_shared<BarrierEvent>(0, 1, velocity, id);
430 }
431
432+
433 TestBarrierSubscriber subscribers_[max_num_monitors];
434 MockUScreen uscreen;
435- MockEdgeBarrierController bc;
436+ EdgeBarrierController bc;
437 };
438+} // namespace ui
439+} // namespace unity
440+
441+namespace
442+{
443
444 TEST_F(TestEdgeBarrierController, Construction)
445 {
446@@ -129,7 +136,7 @@
447
448 TEST_F(TestEdgeBarrierController, SubscriberReplace)
449 {
450- TestBarrierSubscriber handling_subscriber(true);
451+ TestBarrierSubscriber handling_subscriber(EdgeBarrierSubscriber::Result::HANDLED);
452 bc.Subscribe(&handling_subscriber, 0);
453 EXPECT_EQ(bc.GetSubscriber(0), &handling_subscriber);
454 }
455@@ -138,28 +145,29 @@
456 {
457 int monitor = 0;
458
459- TestBarrierSubscriber handling_subscriber(true);
460+ TestBarrierSubscriber handling_subscriber(EdgeBarrierSubscriber::Result::HANDLED);
461 bc.Subscribe(&handling_subscriber, monitor);
462
463 MockPointerBarrier owner(monitor);
464 auto breaking_barrier_event = MakeBarrierEvent(0, true);
465
466 EXPECT_CALL(owner, ReleaseBarrier(_)).Times(0);
467- bc.ProcessBarrierEvent(&owner, breaking_barrier_event);
468+ ProcessBarrierEvent(&owner, breaking_barrier_event);
469+ EXPECT_EQ(GetPrivateImpl()->decaymulator_.value(), 0);
470 }
471
472 TEST_F(TestEdgeBarrierController, ProcessHandledEventOnReleasedBarrier)
473 {
474 int monitor = max_num_monitors-1;
475
476- TestBarrierSubscriber handling_subscriber(true);
477+ TestBarrierSubscriber handling_subscriber(EdgeBarrierSubscriber::Result::HANDLED);
478 bc.Subscribe(&handling_subscriber, monitor);
479
480 MockPointerBarrier owner(monitor, true);
481 auto breaking_barrier_event = MakeBarrierEvent(5, true);
482
483 EXPECT_CALL(owner, ReleaseBarrier(5)).Times(1);
484- bc.ProcessBarrierEvent(&owner, breaking_barrier_event);
485+ ProcessBarrierEvent(&owner, breaking_barrier_event);
486 }
487
488 TEST_F(TestEdgeBarrierController, ProcessUnHandledEventBreakingBarrier)
489@@ -171,7 +179,7 @@
490 auto breaking_barrier_event = MakeBarrierEvent(breaking_id, true);
491
492 EXPECT_CALL(owner, ReleaseBarrier(breaking_id));
493- bc.ProcessBarrierEvent(&owner, breaking_barrier_event);
494+ ProcessBarrierEvent(&owner, breaking_barrier_event);
495 }
496
497 TEST_F(TestEdgeBarrierController, ProcessUnHandledEventBreakingBarrierOnMaxMonitor)
498@@ -181,11 +189,8 @@
499 MockPointerBarrier owner(monitor);
500 auto breaking_barrier_event = MakeBarrierEvent(0, true);
501
502- // This was leading to a crash, see bug #1020075
503- // you can reproduce this repeating this test multiple times using the
504- // --gtest_repeat=X command line
505 EXPECT_CALL(owner, ReleaseBarrier(_));
506- bc.ProcessBarrierEvent(&owner, breaking_barrier_event);
507+ ProcessBarrierEvent(&owner, breaking_barrier_event);
508 }
509
510 TEST_F(TestEdgeBarrierController, ProcessUnHandledEventNotBreakingBarrier)
511@@ -197,7 +202,7 @@
512 auto not_breaking_barrier_event = MakeBarrierEvent(not_breaking_id, false);
513
514 EXPECT_CALL(owner, ReleaseBarrier(not_breaking_id)).Times(0);
515- bc.ProcessBarrierEvent(&owner, not_breaking_barrier_event);
516+ ProcessBarrierEvent(&owner, not_breaking_barrier_event);
517 }
518
519 TEST_F(TestEdgeBarrierController, ProcessUnHandledEventOnReleasedBarrier)
520@@ -209,7 +214,69 @@
521 auto not_breaking_barrier_event = MakeBarrierEvent(not_breaking_id, false);
522
523 EXPECT_CALL(owner, ReleaseBarrier(not_breaking_id));
524- bc.ProcessBarrierEvent(&owner, not_breaking_barrier_event);
525+ ProcessBarrierEvent(&owner, not_breaking_barrier_event);
526+}
527+
528+TEST_F(TestEdgeBarrierController, ProcessAlreadyHandledEvent)
529+{
530+ int monitor = g_random_int_range(0, max_num_monitors);
531+
532+ MockPointerBarrier owner(monitor);
533+ subscribers_[monitor].handle_result_ = EdgeBarrierSubscriber::Result::ALREADY_HANDLED;
534+
535+ auto event = MakeBarrierEvent(g_random_int(), false);
536+
537+ EXPECT_CALL(owner, ReleaseBarrier(_)).Times(0);
538+ ProcessBarrierEvent(&owner, event);
539+ EXPECT_EQ(GetPrivateImpl()->decaymulator_.value(), event->velocity);
540+}
541+
542+TEST_F(TestEdgeBarrierController, ProcessIgnoredEventWithStickyEdges)
543+{
544+ int monitor = g_random_int_range(0, max_num_monitors);
545+
546+ bc.sticky_edges = true;
547+ MockPointerBarrier owner(monitor);
548+ subscribers_[monitor].handle_result_ = EdgeBarrierSubscriber::Result::IGNORED;
549+
550+ auto event = MakeBarrierEvent(g_random_int(), false);
551+
552+ EXPECT_CALL(owner, ReleaseBarrier(_)).Times(0);
553+ ProcessBarrierEvent(&owner, event);
554+ EXPECT_FALSE(owner.released());
555+ EXPECT_FALSE(owner.release_once());
556+ EXPECT_EQ(GetPrivateImpl()->decaymulator_.value(), event->velocity);
557+}
558+
559+TEST_F(TestEdgeBarrierController, ProcessIgnoredEventWithOutStickyEdges)
560+{
561+ int monitor = g_random_int_range(0, max_num_monitors);
562+
563+ bc.sticky_edges = false;
564+ MockPointerBarrier owner(monitor);
565+ subscribers_[monitor].handle_result_ = EdgeBarrierSubscriber::Result::IGNORED;
566+
567+ auto event = MakeBarrierEvent(g_random_int(), false);
568+
569+ EXPECT_CALL(owner, ReleaseBarrier(event->event_id));
570+ ProcessBarrierEvent(&owner, event);
571+ EXPECT_TRUE(owner.released());
572+ EXPECT_TRUE(owner.release_once());
573+ EXPECT_EQ(GetPrivateImpl()->decaymulator_.value(), 0);
574+}
575+
576+TEST_F(TestEdgeBarrierController, ProcessNeedsReleaseEvent)
577+{
578+ int monitor = g_random_int_range(0, max_num_monitors);
579+
580+ MockPointerBarrier owner(monitor);
581+ subscribers_[monitor].handle_result_ = EdgeBarrierSubscriber::Result::NEEDS_RELEASE;
582+
583+ auto event = MakeBarrierEvent(g_random_int(), false);
584+
585+ EXPECT_CALL(owner, ReleaseBarrier(event->event_id));
586+ ProcessBarrierEvent(&owner, event);
587+ EXPECT_EQ(GetPrivateImpl()->decaymulator_.value(), 0);
588 }
589
590 TEST_F(TestEdgeBarrierController, BreakingEdgeTemporaryReleasesBarrier)
591@@ -217,7 +284,7 @@
592 MockPointerBarrier owner;
593
594 EXPECT_CALL(owner, ReleaseBarrier(1));
595- bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(1, true));
596+ ProcessBarrierEvent(&owner, MakeBarrierEvent(1, true));
597 ASSERT_TRUE(owner.released());
598
599 Utils::WaitForTimeoutMSec(bc.options()->edge_passed_disabled_ms);
600@@ -228,30 +295,30 @@
601 {
602 MockPointerBarrier owner;
603 int monitor = 0;
604- subscribers_[monitor].handles_ = false;
605+ subscribers_[monitor].handle_result_ = EdgeBarrierSubscriber::Result::IGNORED;
606
607 EXPECT_CALL(owner, ReleaseBarrier(5));
608- bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(5, true));
609+ ProcessBarrierEvent(&owner, MakeBarrierEvent(5, true));
610 ASSERT_TRUE(owner.released());
611
612- subscribers_[monitor].handles_ = false;
613+ subscribers_[monitor].handle_result_ = EdgeBarrierSubscriber::Result::IGNORED;
614 EXPECT_CALL(owner, ReleaseBarrier(6));
615- bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(6, false));
616+ ProcessBarrierEvent(&owner, MakeBarrierEvent(6, false));
617 }
618
619 TEST_F(TestEdgeBarrierController, BreakingEdgeTemporaryReleasesBarrierForHandledEvents)
620 {
621 MockPointerBarrier owner;
622 int monitor = 0;
623- subscribers_[monitor].handles_ = false;
624+ subscribers_[monitor].handle_result_ = EdgeBarrierSubscriber::Result::IGNORED;
625
626 EXPECT_CALL(owner, ReleaseBarrier(5));
627- bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(5, true));
628+ ProcessBarrierEvent(&owner, MakeBarrierEvent(5, true));
629 ASSERT_TRUE(owner.released());
630
631- subscribers_[monitor].handles_ = true;
632+ subscribers_[monitor].handle_result_ = EdgeBarrierSubscriber::Result::HANDLED;
633 EXPECT_CALL(owner, ReleaseBarrier(6)).Times(1);
634- bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(6, true));
635+ ProcessBarrierEvent(&owner, MakeBarrierEvent(6, true));
636 }
637
638 TEST_F(TestEdgeBarrierController, StickyEdgePropertyProxiesLauncherOption)
639@@ -269,4 +336,10 @@
640 EXPECT_TRUE(bc.options()->edge_resist());
641 }
642
643+TEST_F(TestEdgeBarrierController, TestTheDirectionIsAlawysSetToBothSides)
644+{
645+ for (auto barrier : GetPrivateImpl()->barriers_)
646+ ASSERT_EQ(barrier->direction, BarrierDirection::BOTH);
647+}
648+
649 }
650
651=== modified file 'tests/test_launcher.cpp'
652--- tests/test_launcher.cpp 2013-02-01 22:53:42 +0000
653+++ tests/test_launcher.cpp 2013-02-08 01:02:23 +0000
654@@ -54,11 +54,6 @@
655 MOCK_METHOD1(Stick, void(bool));
656 };
657
658-struct MockPointerBarrierWrapper : ui::PointerBarrierWrapper
659-{
660- MOCK_METHOD1(ReleaseBarrier, void(int event_id));
661-};
662-
663 }
664
665 class TestLauncher : public Test
666@@ -96,10 +91,12 @@
667 using Launcher::ProcessDndLeave;
668 using Launcher::ProcessDndMove;
669 using Launcher::ProcessDndDrop;
670- using Launcher::_drag_icon_position;
671-
672 using Launcher::IconStartingBlinkValue;
673 using Launcher::IconStartingPulseValue;
674+ using Launcher::HandleBarrierEvent;
675+ using Launcher::SetHidden;
676+ using Launcher::_drag_icon_position;
677+
678
679 void FakeProcessDndMove(int x, int y, std::list<std::string> uris)
680 {
681@@ -119,11 +116,6 @@
682
683 _dnd_hovered_icon = MouseIconIntersection(x, y);
684 }
685-
686- bool HandleBarrierEvent(ui::PointerBarrierWrapper* barrier, ui::BarrierEvent::Ptr event)
687- {
688- return Launcher::HandleBarrierEvent(barrier, event);
689- }
690 };
691
692 TestLauncher()
693@@ -454,15 +446,79 @@
694 EXPECT_FALSE(mouse_entered);
695 }
696
697-TEST_F(TestLauncher, EdgeResistDuringDnd)
698+TEST_F(TestLauncher, EdgeReleasesDuringDnd)
699 {
700- auto barrier = std::make_shared<MockPointerBarrierWrapper>();
701+ auto barrier = std::make_shared<ui::PointerBarrierWrapper>();
702 auto event = std::make_shared<ui::BarrierEvent>(0, 0, 0, 100);
703
704 launcher_->DndStarted("");
705
706- EXPECT_CALL(*barrier, ReleaseBarrier(100));
707- EXPECT_TRUE(launcher_->HandleBarrierEvent(barrier.get(), event));
708+ EXPECT_EQ(launcher_->HandleBarrierEvent(barrier.get(), event),
709+ ui::EdgeBarrierSubscriber::Result::NEEDS_RELEASE);
710+}
711+
712+TEST_F(TestLauncher, EdgeBarriersIgnoreEvents)
713+{
714+ auto const& launcher_geo = launcher_->GetAbsoluteGeometry();
715+ auto barrier = std::make_shared<ui::PointerBarrierWrapper>();
716+ auto event = std::make_shared<ui::BarrierEvent>(0, 0, 0, 100);
717+ launcher_->SetHidden(true);
718+
719+ event->x = launcher_geo.x-1;
720+ event->y = launcher_geo.y;
721+ EXPECT_EQ(launcher_->HandleBarrierEvent(barrier.get(), event),
722+ ui::EdgeBarrierSubscriber::Result::IGNORED);
723+
724+ event->x = launcher_geo.x+launcher_geo.width+1;
725+ event->y = launcher_geo.y;
726+ EXPECT_EQ(launcher_->HandleBarrierEvent(barrier.get(), event),
727+ ui::EdgeBarrierSubscriber::Result::IGNORED);
728+
729+ options_->reveal_trigger = RevealTrigger::EDGE;
730+ event->x = launcher_geo.x+launcher_geo.width/2;
731+ event->y = launcher_geo.y - 1;
732+ EXPECT_EQ(launcher_->HandleBarrierEvent(barrier.get(), event),
733+ ui::EdgeBarrierSubscriber::Result::IGNORED);
734+
735+ options_->reveal_trigger = RevealTrigger::CORNER;
736+ event->x = launcher_geo.x+launcher_geo.width/2;
737+ event->y = launcher_geo.y;
738+ EXPECT_EQ(launcher_->HandleBarrierEvent(barrier.get(), event),
739+ ui::EdgeBarrierSubscriber::Result::IGNORED);
740+}
741+
742+TEST_F(TestLauncher, EdgeBarriersHandlesEvent)
743+{
744+ auto const& launcher_geo = launcher_->GetAbsoluteGeometry();
745+ auto barrier = std::make_shared<ui::PointerBarrierWrapper>();
746+ auto event = std::make_shared<ui::BarrierEvent>(0, 0, 0, 100);
747+ launcher_->SetHidden(true);
748+
749+ options_->reveal_trigger = RevealTrigger::EDGE;
750+
751+ for (int x = launcher_geo.x; x < launcher_geo.x+launcher_geo.width; ++x)
752+ {
753+ for (int y = launcher_geo.y; y < launcher_geo.y+launcher_geo.height; ++y)
754+ {
755+ event->x = x;
756+ event->y = y;
757+ ASSERT_EQ(launcher_->HandleBarrierEvent(barrier.get(), event),
758+ ui::EdgeBarrierSubscriber::Result::HANDLED);
759+ }
760+ }
761+
762+ options_->reveal_trigger = RevealTrigger::CORNER;
763+
764+ for (int x = launcher_geo.x; x < launcher_geo.x+launcher_geo.width; ++x)
765+ {
766+ for (int y = launcher_geo.y-10; y < launcher_geo.y; ++y)
767+ {
768+ event->x = x;
769+ event->y = y;
770+ ASSERT_EQ(launcher_->HandleBarrierEvent(barrier.get(), event),
771+ ui::EdgeBarrierSubscriber::Result::HANDLED);
772+ }
773+ }
774 }
775
776 TEST_F(TestLauncher, DndIsSpecialRequest)