Merge lp:~jassmith/unity/unity.sticky-edges into lp:unity
- unity.sticky-edges
- Merge into trunk
Proposed by
Jason Smith
Status: | Merged |
---|---|
Approved by: | Jason Smith |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2222 |
Proposed branch: | lp:~jassmith/unity/unity.sticky-edges |
Merge into: | lp:unity |
Diff against target: |
606 lines (+394/-50) 8 files modified
plugins/unityshell/src/EdgeBarrierController.cpp (+189/-0) plugins/unityshell/src/EdgeBarrierController.h (+57/-0) plugins/unityshell/src/Launcher.cpp (+12/-44) plugins/unityshell/src/Launcher.h (+3/-5) plugins/unityshell/src/LauncherController.cpp (+12/-0) plugins/unityshell/src/PointerBarrier.cpp (+2/-1) plugins/unityshell/src/PointerBarrier.h (+13/-0) tests/autopilot/autopilot/tests/test_launcher.py (+106/-0) |
To merge this branch: | bzr merge lp:~jassmith/unity/unity.sticky-edges |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Thomi Richards (community) | Approve | ||
Review via email: mp+100844@code.launchpad.net |
Commit message
Implement sticky edge behavior as requested by design. Add EdgeBarrierCont
Description of the change
== Problem ==
Launcher behavior with edge stickiness is inconsisten with design. Further details available with bug #961285
== Solution ==
Implement behavior consisten with design. A new class was created to control all barrier edges and launchers are subscribed to that class as needed.
== Testing ==
Autopilot tests are in place to test new behavior.
To post a comment you must log in.
Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote : | # |
review:
Needs Fixing
Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote : | # |
Looks good to me.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'plugins/unityshell/src/EdgeBarrierController.cpp' |
2 | --- plugins/unityshell/src/EdgeBarrierController.cpp 1970-01-01 00:00:00 +0000 |
3 | +++ plugins/unityshell/src/EdgeBarrierController.cpp 2012-04-04 23:48:21 +0000 |
4 | @@ -0,0 +1,189 @@ |
5 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
6 | +/* |
7 | + * Copyright (C) 2012 Canonical Ltd |
8 | + * |
9 | + * This program is free software: you can redistribute it and/or modify |
10 | + * it under the terms of the GNU General Public License version 3 as |
11 | + * published by the Free Software Foundation. |
12 | + * |
13 | + * This program is distributed in the hope that it will be useful, |
14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | + * GNU General Public License for more details. |
17 | + * |
18 | + * You should have received a copy of the GNU General Public License |
19 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | + * |
21 | + * Authored by: Jason Smith <jason.smith@canonical.com> |
22 | + */ |
23 | + |
24 | +#include "EdgeBarrierController.h" |
25 | +#include "Decaymulator.h" |
26 | +#include "UScreen.h" |
27 | + |
28 | +namespace unity { |
29 | +namespace ui { |
30 | + |
31 | +struct EdgeBarrierController::Impl |
32 | +{ |
33 | + Impl(EdgeBarrierController *parent); |
34 | + ~Impl(); |
35 | + |
36 | + void ResizeBarrierList(std::vector<nux::Geometry> const& layout); |
37 | + void SetupBarriers(std::vector<nux::Geometry> const& layout); |
38 | + |
39 | + void OnPointerBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event); |
40 | + |
41 | + std::vector<PointerBarrierWrapper::Ptr> barriers_; |
42 | + Decaymulator::Ptr decaymulator_; |
43 | + float edge_overcome_pressure_; |
44 | + EdgeBarrierController* parent_; |
45 | + std::vector<EdgeBarrierSubscriber*> subscribers_; |
46 | +}; |
47 | + |
48 | +EdgeBarrierController::Impl::Impl(EdgeBarrierController *parent) |
49 | + : decaymulator_(Decaymulator::Ptr(new Decaymulator())) |
50 | + , edge_overcome_pressure_(0) |
51 | + , parent_(parent) |
52 | +{ |
53 | + UScreen *uscreen = UScreen::GetDefault(); |
54 | + |
55 | + auto monitors = uscreen->GetMonitors(); |
56 | + ResizeBarrierList(monitors); |
57 | + |
58 | + uscreen->changed.connect([&](int primary, std::vector<nux::Geometry>& layout) { |
59 | + ResizeBarrierList(layout); |
60 | + SetupBarriers(layout); |
61 | + }); |
62 | + |
63 | + parent_->sticky_edges.changed.connect([&](bool value) { |
64 | + SetupBarriers(UScreen::GetDefault()->GetMonitors()); |
65 | + }); |
66 | + |
67 | + parent_->options.changed.connect([&](launcher::Options::Ptr options) { |
68 | + options->option_changed.connect([&]() { |
69 | + SetupBarriers(UScreen::GetDefault()->GetMonitors()); |
70 | + }); |
71 | + SetupBarriers(UScreen::GetDefault()->GetMonitors()); |
72 | + }); |
73 | +} |
74 | + |
75 | +EdgeBarrierController::Impl::~Impl() |
76 | +{ |
77 | + |
78 | +} |
79 | + |
80 | +void EdgeBarrierController::Impl::ResizeBarrierList(std::vector<nux::Geometry> const& layout) |
81 | +{ |
82 | + size_t num_monitors = layout.size(); |
83 | + if (barriers_.size() > num_monitors) |
84 | + { |
85 | + barriers_.resize(num_monitors); |
86 | + } |
87 | + |
88 | + while (barriers_.size() < num_monitors) |
89 | + { |
90 | + auto barrier = PointerBarrierWrapper::Ptr(new PointerBarrierWrapper()); |
91 | + barrier->barrier_event.connect(sigc::mem_fun(this, &EdgeBarrierController::Impl::OnPointerBarrierEvent)); |
92 | + barriers_.push_back(barrier); |
93 | + } |
94 | +} |
95 | + |
96 | +void EdgeBarrierController::Impl::SetupBarriers(std::vector<nux::Geometry> const& layout) |
97 | +{ |
98 | + bool edge_resist = parent_->options()->edge_resist(); |
99 | + |
100 | + size_t size = layout.size(); |
101 | + for (size_t i = 0; i < size; i++) |
102 | + { |
103 | + auto barrier = barriers_[i]; |
104 | + auto monitor = layout[i]; |
105 | + |
106 | + barrier->DestroyBarrier(); |
107 | + |
108 | + if (!edge_resist && (subscribers_[i] == nullptr || parent_->options()->hide_mode() == launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER)) |
109 | + continue; |
110 | + |
111 | + barrier->x1 = monitor.x; |
112 | + barrier->x2 = monitor.x; |
113 | + barrier->y1 = monitor.y; |
114 | + barrier->y2 = monitor.y + monitor.height; |
115 | + barrier->index = i; |
116 | + |
117 | + barrier->threshold = parent_->options()->edge_stop_velocity(); |
118 | + barrier->max_velocity_multiplier = parent_->options()->edge_responsiveness(); |
119 | + |
120 | + if (edge_resist) |
121 | + barrier->direction = BarrierDirection::BOTH; |
122 | + else |
123 | + barrier->direction = BarrierDirection::LEFT; |
124 | + |
125 | + barrier->ConstructBarrier(); |
126 | + } |
127 | + |
128 | + float decay_responsiveness_mult = ((parent_->options()->edge_responsiveness() - 1) * .3f) + 1; |
129 | + decaymulator_->rate_of_decay = parent_->options()->edge_decay_rate() * decay_responsiveness_mult; |
130 | + |
131 | + float overcome_responsiveness_mult = ((parent_->options()->edge_responsiveness() - 1) * 1.0f) + 1; |
132 | + edge_overcome_pressure_ = parent_->options()->edge_overcome_pressure() * overcome_responsiveness_mult; |
133 | +} |
134 | + |
135 | +void EdgeBarrierController::Impl::OnPointerBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event) |
136 | +{ |
137 | + int monitor = owner->index; |
138 | + bool process = true; |
139 | + |
140 | + if ((size_t)monitor <= subscribers_.size()) |
141 | + { |
142 | + auto subscriber = subscribers_[monitor]; |
143 | + if (subscriber && subscriber->HandleBarrierEvent(owner, event)) |
144 | + process = false; |
145 | + } |
146 | + |
147 | + if (process && owner->x1 > 0) |
148 | + { |
149 | + decaymulator_->value = decaymulator_->value + event->velocity; |
150 | + if (decaymulator_->value > edge_overcome_pressure_ || !parent_->options()->edge_resist()) |
151 | + { |
152 | + owner->ReleaseBarrier(event->event_id); |
153 | + decaymulator_->value = 0; |
154 | + } |
155 | + } |
156 | + else |
157 | + { |
158 | + decaymulator_->value = 0; |
159 | + } |
160 | +} |
161 | + |
162 | +EdgeBarrierController::EdgeBarrierController() |
163 | + : sticky_edges(false) |
164 | + , pimpl(new Impl(this)) |
165 | +{ |
166 | +} |
167 | + |
168 | +EdgeBarrierController::~EdgeBarrierController() |
169 | +{ |
170 | + |
171 | +} |
172 | + |
173 | +void EdgeBarrierController::Subscribe(EdgeBarrierSubscriber* subscriber, int monitor) |
174 | +{ |
175 | + if (pimpl->subscribers_.size() <= (size_t)monitor) |
176 | + pimpl->subscribers_.resize(monitor + 1); |
177 | + pimpl->subscribers_[monitor] = subscriber; |
178 | + |
179 | + pimpl->SetupBarriers(UScreen::GetDefault()->GetMonitors()); |
180 | +} |
181 | + |
182 | +void EdgeBarrierController::Unsubscribe(EdgeBarrierSubscriber* subscriber, int monitor) |
183 | +{ |
184 | + if (pimpl->subscribers_.size() < (size_t)monitor || pimpl->subscribers_[monitor] != subscriber) |
185 | + return; |
186 | + pimpl->subscribers_[monitor] = nullptr; |
187 | + |
188 | + pimpl->SetupBarriers(UScreen::GetDefault()->GetMonitors()); |
189 | +} |
190 | + |
191 | + |
192 | +} |
193 | +} |
194 | |
195 | === added file 'plugins/unityshell/src/EdgeBarrierController.h' |
196 | --- plugins/unityshell/src/EdgeBarrierController.h 1970-01-01 00:00:00 +0000 |
197 | +++ plugins/unityshell/src/EdgeBarrierController.h 2012-04-04 23:48:21 +0000 |
198 | @@ -0,0 +1,57 @@ |
199 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
200 | +/* |
201 | + * Copyright (C) 2012 Canonical Ltd |
202 | + * |
203 | + * This program is free software: you can redistribute it and/or modify |
204 | + * it under the terms of the GNU General Public License version 3 as |
205 | + * published by the Free Software Foundation. |
206 | + * |
207 | + * This program is distributed in the hope that it will be useful, |
208 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
209 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
210 | + * GNU General Public License for more details. |
211 | + * |
212 | + * You should have received a copy of the GNU General Public License |
213 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
214 | + * |
215 | + * Authored by: Jason Smith <jason.smith@canonical.com> |
216 | + */ |
217 | + |
218 | +#ifndef UNITY_EDGEBARRIERCONTROLLER_H |
219 | +#define UNITY_EDGEBARRIERCONTROLLER_H |
220 | + |
221 | +#include "PointerBarrier.h" |
222 | +#include "LauncherOptions.h" |
223 | + |
224 | +namespace unity { |
225 | +namespace ui { |
226 | + |
227 | +class EdgeBarrierSubscriber |
228 | +{ |
229 | +public: |
230 | + virtual bool HandleBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event) { return false; }; |
231 | +}; |
232 | + |
233 | +class EdgeBarrierController : public sigc::trackable |
234 | +{ |
235 | +public: |
236 | + typedef std::shared_ptr<EdgeBarrierController> Ptr; |
237 | + |
238 | + EdgeBarrierController(); |
239 | + ~EdgeBarrierController(); |
240 | + |
241 | + nux::Property<bool> sticky_edges; |
242 | + nux::Property<launcher::Options::Ptr> options; |
243 | + |
244 | + void Subscribe(EdgeBarrierSubscriber* subscriber, int monitor); |
245 | + void Unsubscribe(EdgeBarrierSubscriber* subscriber, int monitor); |
246 | + |
247 | +private: |
248 | + struct Impl; |
249 | + Impl* pimpl; |
250 | +}; |
251 | + |
252 | +} |
253 | +} |
254 | + |
255 | +#endif |
256 | |
257 | === modified file 'plugins/unityshell/src/Launcher.cpp' |
258 | --- plugins/unityshell/src/Launcher.cpp 2012-04-04 21:30:56 +0000 |
259 | +++ plugins/unityshell/src/Launcher.cpp 2012-04-04 23:48:21 +0000 |
260 | @@ -74,7 +74,6 @@ |
261 | namespace unity |
262 | { |
263 | using ui::RenderArg; |
264 | -using ui::PointerBarrierWrapper; |
265 | using ui::Decaymulator; |
266 | |
267 | namespace launcher |
268 | @@ -294,11 +293,6 @@ |
269 | launcher_sheen_ = cache.FindTexture("dash_sheen", 0, 0, cb); |
270 | launcher_pressure_effect_ = cache.FindTexture("launcher_pressure_effect", 0, 0, cb); |
271 | |
272 | - _pointer_barrier = PointerBarrierWrapper::Ptr(new PointerBarrierWrapper()); |
273 | - _pointer_barrier->barrier_event.connect(sigc::mem_fun(this, &Launcher::OnPointerBarrierEvent)); |
274 | - |
275 | - decaymulator_ = Decaymulator::Ptr(new Decaymulator()); |
276 | - |
277 | options.changed.connect (sigc::mem_fun (this, &Launcher::OnOptionsChanged)); |
278 | } |
279 | |
280 | @@ -1598,30 +1592,12 @@ |
281 | void Launcher::ConfigureBarrier() |
282 | { |
283 | nux::Geometry geo = GetAbsoluteGeometry(); |
284 | - _pointer_barrier->DestroyBarrier(); |
285 | - |
286 | - if (options()->edge_resist || geo.x == 0) |
287 | - { |
288 | - unity::panel::Style &panel_style = panel::Style::Instance(); |
289 | - |
290 | - _pointer_barrier->x1 = geo.x; |
291 | - _pointer_barrier->x2 = geo.x; |
292 | - _pointer_barrier->y1 = geo.y - panel_style.panel_height; |
293 | - _pointer_barrier->y2 = geo.y + geo.height; |
294 | - |
295 | - float decay_responsiveness_mult = ((options()->edge_responsiveness() - 1) * .3f) + 1; |
296 | - float reveal_responsiveness_mult = ((options()->edge_responsiveness() - 1) * .025f) + 1; |
297 | - float overcome_responsiveness_mult = ((options()->edge_responsiveness() - 1) * 1.0f) + 1; |
298 | - decaymulator_->rate_of_decay = options()->edge_decay_rate() * decay_responsiveness_mult; |
299 | - _edge_overcome_pressure = options()->edge_overcome_pressure() * overcome_responsiveness_mult; |
300 | - |
301 | - _pointer_barrier->threshold = options()->edge_stop_velocity(); |
302 | - _pointer_barrier->max_velocity_multiplier = options()->edge_responsiveness(); |
303 | - _pointer_barrier->ConstructBarrier(); |
304 | - |
305 | - _hide_machine->reveal_pressure = options()->edge_reveal_pressure() * reveal_responsiveness_mult; |
306 | - _hide_machine->edge_decay_rate = options()->edge_decay_rate() * decay_responsiveness_mult; |
307 | - } |
308 | + |
309 | + float decay_responsiveness_mult = ((options()->edge_responsiveness() - 1) * .3f) + 1; |
310 | + float reveal_responsiveness_mult = ((options()->edge_responsiveness() - 1) * .025f) + 1; |
311 | + |
312 | + _hide_machine->reveal_pressure = options()->edge_reveal_pressure() * reveal_responsiveness_mult; |
313 | + _hide_machine->edge_decay_rate = options()->edge_decay_rate() * decay_responsiveness_mult; |
314 | } |
315 | |
316 | void Launcher::SetHideMode(LauncherHideMode hidemode) |
317 | @@ -2416,7 +2392,7 @@ |
318 | EnsureAnimation(); |
319 | } |
320 | |
321 | -void Launcher::OnPointerBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event) |
322 | +bool Launcher::HandleBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event) |
323 | { |
324 | nux::Geometry abs_geo = GetAbsoluteGeometry(); |
325 | |
326 | @@ -2450,19 +2426,11 @@ |
327 | } |
328 | } |
329 | |
330 | - if (apply_to_reveal) |
331 | - { |
332 | - _hide_machine->AddRevealPressure(event->velocity); |
333 | - decaymulator_->value = 0; |
334 | - } |
335 | - else if (abs_geo.x > 0) |
336 | - { |
337 | - decaymulator_->value = decaymulator_->value + event->velocity; |
338 | - if (decaymulator_->value > _edge_overcome_pressure) |
339 | - { |
340 | - _pointer_barrier->ReleaseBarrier(event->event_id); |
341 | - } |
342 | - } |
343 | + if (!apply_to_reveal) |
344 | + return false; |
345 | + |
346 | + _hide_machine->AddRevealPressure(event->velocity); |
347 | + return true; |
348 | } |
349 | |
350 | bool Launcher::IsInKeyNavMode() const |
351 | |
352 | === modified file 'plugins/unityshell/src/Launcher.h' |
353 | --- plugins/unityshell/src/Launcher.h 2012-03-30 04:00:05 +0000 |
354 | +++ plugins/unityshell/src/Launcher.h 2012-04-04 23:48:21 +0000 |
355 | @@ -33,6 +33,7 @@ |
356 | #include "BackgroundEffectHelper.h" |
357 | #include "DNDCollectionWindow.h" |
358 | #include "DndData.h" |
359 | +#include "EdgeBarrierController.h" |
360 | #include "GeisAdapter.h" |
361 | #include "Introspectable.h" |
362 | #include "LauncherOptions.h" |
363 | @@ -50,7 +51,7 @@ |
364 | class AbstractLauncherIcon; |
365 | class LauncherModel; |
366 | |
367 | -class Launcher : public unity::debug::Introspectable, public nux::View |
368 | +class Launcher : public unity::debug::Introspectable, public nux::View, public ui::EdgeBarrierSubscriber |
369 | { |
370 | NUX_DECLARE_OBJECT_TYPE(Launcher, nux::View); |
371 | public: |
372 | @@ -187,7 +188,7 @@ |
373 | void OnDragUpdate(GeisAdapter::GeisDragData* data); |
374 | void OnDragFinish(GeisAdapter::GeisDragData* data); |
375 | |
376 | - void OnPointerBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event); |
377 | + bool HandleBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event); |
378 | |
379 | void OnPluginStateChanged(); |
380 | |
381 | @@ -342,9 +343,6 @@ |
382 | |
383 | nux::ObjectPtr<nux::IOpenGLBaseTexture> _offscreen_drag_texture; |
384 | |
385 | - ui::PointerBarrierWrapper::Ptr _pointer_barrier; |
386 | - ui::Decaymulator::Ptr decaymulator_; |
387 | - |
388 | int _space_between_icons; |
389 | int _icon_size; |
390 | int _icon_image_size; |
391 | |
392 | === modified file 'plugins/unityshell/src/LauncherController.cpp' |
393 | --- plugins/unityshell/src/LauncherController.cpp 2012-04-03 01:58:52 +0000 |
394 | +++ plugins/unityshell/src/LauncherController.cpp 2012-04-04 23:48:21 +0000 |
395 | @@ -32,6 +32,7 @@ |
396 | #include "DesktopLauncherIcon.h" |
397 | #include "DeviceLauncherIcon.h" |
398 | #include "DeviceLauncherSection.h" |
399 | +#include "EdgeBarrierController.h" |
400 | #include "FavoriteStore.h" |
401 | #include "HudLauncherIcon.h" |
402 | #include "Launcher.h" |
403 | @@ -173,6 +174,8 @@ |
404 | |
405 | int launcher_key_press_time_; |
406 | |
407 | + ui::EdgeBarrierController::Ptr edge_barriers_; |
408 | + |
409 | LauncherList launchers; |
410 | |
411 | sigc::connection on_expoicon_activate_connection_; |
412 | @@ -188,7 +191,10 @@ |
413 | , sort_priority_(0) |
414 | , show_desktop_icon_(false) |
415 | , display_(display) |
416 | + , edge_barriers_(new ui::EdgeBarrierController()) |
417 | { |
418 | + edge_barriers_->options = parent_->options(); |
419 | + |
420 | UScreen* uscreen = UScreen::GetDefault(); |
421 | auto monitors = uscreen->GetMonitors(); |
422 | int primary = uscreen->GetPrimaryMonitor(); |
423 | @@ -331,10 +337,16 @@ |
424 | { |
425 | parent_->RemoveChild(launcher.GetPointer()); |
426 | launcher->GetParent()->UnReference(); |
427 | + edge_barriers_->Unsubscribe(launcher.GetPointer(), launcher->monitor); |
428 | } |
429 | } |
430 | |
431 | launchers.resize(num_launchers); |
432 | + |
433 | + for (size_t i = 0; i < launchers.size(); ++i) |
434 | + { |
435 | + edge_barriers_->Subscribe(launchers[i].GetPointer(), launchers[i]->monitor); |
436 | + } |
437 | } |
438 | |
439 | void Controller::Impl::OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors) |
440 | |
441 | === modified file 'plugins/unityshell/src/PointerBarrier.cpp' |
442 | --- plugins/unityshell/src/PointerBarrier.cpp 2012-03-27 20:47:58 +0000 |
443 | +++ plugins/unityshell/src/PointerBarrier.cpp 2012-04-04 23:48:21 +0000 |
444 | @@ -37,6 +37,7 @@ |
445 | |
446 | PointerBarrierWrapper::PointerBarrierWrapper() |
447 | { |
448 | + direction = BOTH; |
449 | last_event_ = 0; |
450 | last_y_ = 0; |
451 | last_x_ = 0; |
452 | @@ -72,7 +73,7 @@ |
453 | DefaultRootWindow(dpy), |
454 | x1, y1, |
455 | x2, y2, |
456 | - 0, |
457 | + (int) direction, |
458 | threshold, |
459 | 0, |
460 | NULL); |
461 | |
462 | === modified file 'plugins/unityshell/src/PointerBarrier.h' |
463 | --- plugins/unityshell/src/PointerBarrier.h 2012-02-07 07:42:12 +0000 |
464 | +++ plugins/unityshell/src/PointerBarrier.h 2012-04-04 23:48:21 +0000 |
465 | @@ -41,6 +41,15 @@ |
466 | int event_id; |
467 | }; |
468 | |
469 | + |
470 | +// values picked to match Xfixes values |
471 | +enum BarrierDirection |
472 | +{ |
473 | + BOTH = 0, |
474 | + LEFT = 1, |
475 | + RIGHT = 4, |
476 | +}; |
477 | + |
478 | class PointerBarrierWrapper |
479 | { |
480 | public: |
481 | @@ -59,6 +68,10 @@ |
482 | |
483 | nux::Property<float> max_velocity_multiplier; |
484 | |
485 | + nux::Property<int> index; |
486 | + |
487 | + nux::Property<BarrierDirection> direction; |
488 | + |
489 | PointerBarrierWrapper(); |
490 | ~PointerBarrierWrapper(); |
491 | |
492 | |
493 | === modified file 'tests/autopilot/autopilot/tests/test_launcher.py' |
494 | --- tests/autopilot/autopilot/tests/test_launcher.py 2012-04-04 21:33:39 +0000 |
495 | +++ tests/autopilot/autopilot/tests/test_launcher.py 2012-04-04 23:48:21 +0000 |
496 | @@ -635,3 +635,109 @@ |
497 | launcher_instance.mouse_reveal_launcher() |
498 | self.assertThat(launcher_instance.is_showing(), Equals(False)) |
499 | self.mouse.release(1) |
500 | + |
501 | +class LauncherCaptureTests(AutopilotTestCase): |
502 | + """Test the launchers ability to capture/not capture the mouse.""" |
503 | + |
504 | + screen_geo = ScreenGeometry() |
505 | + |
506 | + def setHideMode(self, mode): |
507 | + launcher = self.launcher.get_launcher_for_monitor(0) |
508 | + for counter in range(10): |
509 | + sleep(1) |
510 | + if launcher.hidemode == mode: |
511 | + break |
512 | + self.assertThat(launcher.hidemode, Equals(mode), |
513 | + "Launcher did not enter revealed mode.") |
514 | + |
515 | + def leftMostMonitor(self): |
516 | + x1, y1, width, height = self.screen_geo.get_monitor_geometry(0) |
517 | + x2, y2, width, height = self.screen_geo.get_monitor_geometry(1) |
518 | + |
519 | + if x1 < x2: |
520 | + return 0 |
521 | + return 1 |
522 | + |
523 | + def rightMostMonitor(self): |
524 | + return 1 - self.leftMostMonitor() |
525 | + |
526 | + def setUp(self): |
527 | + super(LauncherCaptureTests, self).setUp() |
528 | + self.set_unity_option('launcher_capture_mouse', True) |
529 | + self.set_unity_option('launcher_hide_mode', 0) |
530 | + self.set_unity_option('num_launchers', 0) |
531 | + self.setHideMode(0) |
532 | + |
533 | + def test_launcher_captures_while_sticky_and_revealed(self): |
534 | + """Tests that the launcher captures the mouse when moving between monitors |
535 | + while revealed. |
536 | + """ |
537 | + if self.screen_geo.get_num_monitors() <= 1: |
538 | + self.skipTest("Cannot run this test with a single monitor configured.") |
539 | + |
540 | + x, y, width, height = self.screen_geo.get_monitor_geometry(self.rightMostMonitor()) |
541 | + self.mouse.move(x + width / 2, y + height / 2, False) |
542 | + self.mouse.move(x - width / 2, y + height / 2, True, 5, .002) |
543 | + |
544 | + x_fin, y_fin = self.mouse.position() |
545 | + # The launcher should have held the mouse a little bit |
546 | + self.assertThat(x_fin, GreaterThan(x - width / 2)) |
547 | + |
548 | + def test_launcher_not_capture_while_not_sticky_and_revealed(self): |
549 | + """Tests that the launcher doesn't captures the mouse when moving between monitors |
550 | + while revealed and stick is off. |
551 | + """ |
552 | + if self.screen_geo.get_num_monitors() <= 1: |
553 | + self.skipTest("Cannot run this test with a single monitor configured.") |
554 | + |
555 | + self.set_unity_option('launcher_capture_mouse', False) |
556 | + |
557 | + x, y, width, height = self.screen_geo.get_monitor_geometry(self.rightMostMonitor()) |
558 | + self.mouse.move(x + width / 2, y + height / 2, False) |
559 | + self.mouse.move(x - width / 2, y + height / 2, True, 5, .002) |
560 | + |
561 | + x_fin, y_fin = self.mouse.position() |
562 | + # The launcher should have held the mouse a little bit |
563 | + self.assertThat(x_fin, Equals(x - width / 2)) |
564 | + |
565 | + def test_launcher_not_capture_while_not_sticky_and_hidden_moving_right(self): |
566 | + """Tests that the launcher doesn't capture the mouse when moving between monitors |
567 | + while hidden and sticky is off. |
568 | + """ |
569 | + if self.screen_geo.get_num_monitors() <= 1: |
570 | + self.skipTest("Cannot run this test with a single monitor configured.") |
571 | + |
572 | + self.set_unity_option('launcher_hide_mode', 1) |
573 | + self.set_unity_option('launcher_capture_mouse', False) |
574 | + |
575 | + self.setHideMode(1) |
576 | + |
577 | + x, y, width, height = self.screen_geo.get_monitor_geometry(self.leftMostMonitor()) |
578 | + self.mouse.move(x + width / 2, y + height / 2, False) |
579 | + sleep(1.5) |
580 | + self.mouse.move(x + width * 1.5, y + height / 2, True, 5, .002) |
581 | + |
582 | + x_fin, y_fin = self.mouse.position() |
583 | + # The launcher should have held the mouse a little bit |
584 | + self.assertThat(x_fin, Equals(x + width * 1.5)) |
585 | + |
586 | + def test_launcher_capture_while_sticky_and_hidden_moving_right(self): |
587 | + """Tests that the launcher captures the mouse when moving between monitors |
588 | + while hidden. |
589 | + """ |
590 | + if self.screen_geo.get_num_monitors() <= 1: |
591 | + self.skipTest("Cannot run this test with a single monitor configured.") |
592 | + |
593 | + self.set_unity_option('launcher_hide_mode', 1) |
594 | + |
595 | + self.setHideMode(1) |
596 | + |
597 | + x, y, width, height = self.screen_geo.get_monitor_geometry(self.leftMostMonitor()) |
598 | + self.mouse.move(x + width / 2, y + height / 2, False) |
599 | + sleep(1.5) |
600 | + self.mouse.move(x + width * 1.5, y + height / 2, True, 5, .002) |
601 | + |
602 | + x_fin, y_fin = self.mouse.position() |
603 | + # The launcher should have held the mouse a little bit |
604 | + self.assertThat(x_fin, LessThan(x + width * 1.5)) |
605 | + |
606 | \ No newline at end of file |
Hi,
ResizeBarrierList should pass it's std::vector by const ref:
void ResizeBarrierLi st(std: :vector< nux::Geometry> const& layout);
same with SetupBarriers:
void SetupBarriers( std::vector< nux::Geometry> const& layout);
Should probably fix this, just to bzr / lp don't complain:
194 \ No newline at end of file
...and definitely fix this one:
257 \ No newline at end of file
Is a lack of newline character at the end of header files can cause real problems.
Pro tip - this:
edge_barriers_(new ui::EdgeBarrier Controller( ))
Is better written as this:
edge_barriers_ (std::make_ shared< ui::EdgeBarrier Controller> ())
std::make_shared returns a std::shared_ptr<T> constructed with the arguments you pass it, but it does it in only one memory allocation. Using "edge_barriers_(new ui::EdgeBarrier Controller( ))" requires at least two. Also, I believe that make_shared is exception safe, whereas the other method may throw if you cannot allocate an object (TBH though, if you get into that situation you're pretty screwed anyway). I don't mind if you choose to ignore this - it's something that I've started doing.
471 +enum BarrierDirection
472 +{
473 + BOTH = 0,
474 + LEFT = 1,
475 + RIGHT = 4,
476 +};
0, 1, 4? If you want this to be a bitmask, shouldn't RIGHT = 2?
500 +from autopilot. emulators. X11 import Mouse
512 + mouse = Mouse()
You don't need these two lines - all Autopilot test classes have access to 'self.mouse' already.
509 +class LauncherCapture Tests(Scenariod LauncherTests) :
I don't think you want to derive from ScenariodLaunch erTests - deriving from this class ensures that your tests get called several times with different sets of launcher options. It seems to me that your tests specify the options under which they'll work already? If that is in fact the case, just derive from AutopilotTestCase instead.
530 + if self.screen_ geo.get_ num_monitors( ) <= 1:
531 + return
Instead of returning, please do this:
self.skipTest( "Cannot run this test with a single monitor configured.")
... obviously this applies to all the tests.
539 + self.assertThat (x_fin, NotEquals(x - width / 2))
Try not to do negative assertions - it's too easy to have the test pass when it shouldn't. Should the mouse value be less than, or greater than x_fin? Use GreaterThan / LessThen matchers instead (you may need to import them).
This code:
565 + self.set_ unity_option( 'launcher_ hide_mode' , 1) (launcher. hidemode, Equals(1),
567 +
568 + launcher = self.get_launcher()
569 + for counter in range(10):
570 + sleep(1)
571 + if launcher.hidemode == 1:
572 + break
573 + self.assertThat
574 + "Launcher did not enter hidden mode.")
Should go in a method, so you can call it as often as you want from the setUp method and from within your tests.
Looking good though (apart from the issues above).
Cheers,
609 + self.assertThat (x_fin, NotEquals(x + width * 1.5))
Same thing as before with the negative assertions. Better to use Equals, or GreatherThan or LessTHan to test what you really mean.