Merge lp:~3v1n0/unity/fix-load-icon-crash-926658 into lp:unity
- fix-load-icon-crash-926658
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~3v1n0/unity/fix-load-icon-crash-926658 |
Merge into: | lp:unity |
Diff against target: |
1356 lines (+613/-180) 18 files modified
UnityCore/GLibSource.cpp (+1/-2) dash/ResultRendererTile.cpp (+26/-22) launcher/Decaymulator.h (+1/-3) launcher/EdgeBarrierController.cpp (+88/-46) launcher/EdgeBarrierController.h (+8/-7) launcher/LauncherController.cpp (+4/-5) launcher/LauncherHideMachine.cpp (+6/-8) launcher/LauncherHideMachine.h (+1/-1) launcher/LauncherHoverMachine.cpp (+1/-2) launcher/LauncherOptions.cpp (+34/-34) launcher/LauncherOptions.h (+1/-0) launcher/PointerBarrier.cpp (+30/-23) launcher/PointerBarrier.h (+17/-16) plugins/unityshell/src/unityshell.cpp (+5/-0) plugins/unityshell/unityshell.xml.in (+8/-0) tests/CMakeLists.txt (+16/-11) tests/test_edge_barrier_controller.cpp (+225/-0) tests/test_pointer_barrier.cpp (+141/-0) |
To merge this branch: | bzr merge lp:~3v1n0/unity/fix-load-icon-crash-926658 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity Team | Pending | ||
Review via email: mp+116089@code.launchpad.net |
This proposal has been superseded by a proposal from 2012-07-20.
Commit message
ResultRendererTile: fix a crash if row.renderer<
Description of the change
In ResultRendererT
The implementation of that depends on dee_model_
So, at this point, even if it would not the best solution, it's better to add a safety check to prevent crashes.
Preview Diff
1 | === modified file 'UnityCore/GLibSource.cpp' |
2 | --- UnityCore/GLibSource.cpp 2012-07-16 11:03:32 +0000 |
3 | +++ UnityCore/GLibSource.cpp 2012-07-20 23:00:30 +0000 |
4 | @@ -18,7 +18,6 @@ |
5 | */ |
6 | |
7 | #include "GLibSource.h" |
8 | -#include <boost/lexical_cast.hpp> |
9 | |
10 | namespace unity |
11 | { |
12 | @@ -225,7 +224,7 @@ |
13 | if (source_nick.empty()) |
14 | { |
15 | /* If we don't have a nick, we use the source pointer string as nick. */ |
16 | - source_nick = boost::lexical_cast<std::string>(source.get()); |
17 | + source_nick = std::to_string(reinterpret_cast<uintptr_t>(source.get())); |
18 | } |
19 | |
20 | auto old_source_it = sources_.find(source_nick); |
21 | |
22 | === modified file 'dash/ResultRendererTile.cpp' |
23 | --- dash/ResultRendererTile.cpp 2012-06-18 02:57:23 +0000 |
24 | +++ dash/ResultRendererTile.cpp 2012-07-20 23:00:30 +0000 |
25 | @@ -21,14 +21,10 @@ |
26 | */ |
27 | |
28 | |
29 | -#include <sstream> // for ostringstream |
30 | #include "ResultRendererTile.h" |
31 | |
32 | -#include <boost/algorithm/string.hpp> |
33 | - |
34 | #include <pango/pango.h> |
35 | #include <pango/pangocairo.h> |
36 | -#include <gdk/gdk.h> |
37 | #include <gtk/gtk.h> |
38 | |
39 | #include <NuxCore/Logger.h> |
40 | @@ -51,6 +47,7 @@ |
41 | namespace |
42 | { |
43 | nux::logging::Logger logger("unity.dash.results"); |
44 | +const std::string DEFAULT_GICON = ". GThemedIcon text-x-preview"; |
45 | |
46 | const int FONT_SIZE = 10; |
47 | } |
48 | @@ -230,7 +227,7 @@ |
49 | |
50 | void ResultRendererTile::Preload(Result& row) |
51 | { |
52 | - if (row.renderer<TextureContainer*>() == nullptr) |
53 | + if (!row.renderer<TextureContainer*>()) |
54 | { |
55 | row.set_renderer(new TextureContainer()); |
56 | LoadIcon(row); |
57 | @@ -240,17 +237,25 @@ |
58 | |
59 | void ResultRendererTile::Unload(Result& row) |
60 | { |
61 | - TextureContainer *container = row.renderer<TextureContainer*>(); |
62 | - delete container; |
63 | + delete row.renderer<TextureContainer*>(); |
64 | row.set_renderer<TextureContainer*>(nullptr); |
65 | } |
66 | |
67 | void ResultRendererTile::LoadIcon(Result& row) |
68 | { |
69 | + auto container = row.renderer<TextureContainer*>(); |
70 | + |
71 | + if (!container) |
72 | + { |
73 | + LOG_ERROR(logger) << "No valid container for Result " << row.name() << " with URI " |
74 | + << row.uri(); |
75 | + return; |
76 | + } |
77 | + |
78 | Style& style = Style::Instance(); |
79 | std::string const& icon_hint = row.icon_hint; |
80 | -#define DEFAULT_GICON ". GThemedIcon text-x-preview" |
81 | std::string icon_name; |
82 | + |
83 | if (G_UNLIKELY(neko)) |
84 | { |
85 | int tmp1 = style.GetTileIconSize() + (rand() % 16) - 8; |
86 | @@ -266,26 +271,25 @@ |
87 | icon_name = !icon_hint.empty() ? icon_hint : DEFAULT_GICON; |
88 | } |
89 | |
90 | - GIcon* icon = g_icon_new_for_string(icon_name.c_str(), NULL); |
91 | - TextureContainer* container = row.renderer<TextureContainer*>(); |
92 | - |
93 | - IconLoader::IconLoaderCallback slot = sigc::bind(sigc::mem_fun(this, &ResultRendererTile::IconLoaded), icon_hint, row); |
94 | - |
95 | - if (g_strrstr(icon_name.c_str(), "://")) |
96 | + auto slot = sigc::bind(sigc::mem_fun(this, &ResultRendererTile::IconLoaded), icon_hint, row); |
97 | + |
98 | + if (icon_name.find("://") != std::string::npos) |
99 | { |
100 | container->slot_handle = IconLoader::GetDefault().LoadFromURI(icon_name, style.GetTileIconSize(), slot); |
101 | } |
102 | - else if (G_IS_ICON(icon)) |
103 | - { |
104 | - container->slot_handle = IconLoader::GetDefault().LoadFromGIconString(icon_name, style.GetTileIconSize(), slot); |
105 | - } |
106 | else |
107 | { |
108 | - container->slot_handle = IconLoader::GetDefault().LoadFromIconName(icon_name, style.GetTileIconSize(), slot); |
109 | + glib::Object<GIcon> icon(g_icon_new_for_string(icon_name.c_str(), nullptr)); |
110 | + |
111 | + if (icon.IsType(G_TYPE_ICON)) |
112 | + { |
113 | + container->slot_handle = IconLoader::GetDefault().LoadFromGIconString(icon_name, style.GetTileIconSize(), slot); |
114 | + } |
115 | + else |
116 | + { |
117 | + container->slot_handle = IconLoader::GetDefault().LoadFromIconName(icon_name, style.GetTileIconSize(), slot); |
118 | + } |
119 | } |
120 | - |
121 | - if (icon != NULL) |
122 | - g_object_unref(icon); |
123 | } |
124 | |
125 | nux::BaseTexture* ResultRendererTile::CreateTextureCallback(std::string const& texid, |
126 | |
127 | === modified file 'launcher/Decaymulator.h' |
128 | --- launcher/Decaymulator.h 2012-06-18 02:57:23 +0000 |
129 | +++ launcher/Decaymulator.h 2012-07-20 23:00:30 +0000 |
130 | @@ -31,13 +31,11 @@ |
131 | class Decaymulator |
132 | { |
133 | public: |
134 | - typedef std::shared_ptr<Decaymulator> Ptr; |
135 | + Decaymulator(); |
136 | |
137 | nux::Property<int> rate_of_decay; |
138 | nux::Property<int> value; |
139 | |
140 | - Decaymulator(); |
141 | - |
142 | private: |
143 | void OnValueChanged(int value); |
144 | bool OnDecayTimeout(); |
145 | |
146 | === modified file 'launcher/EdgeBarrierController.cpp' |
147 | --- launcher/EdgeBarrierController.cpp 2012-06-28 17:21:44 +0000 |
148 | +++ launcher/EdgeBarrierController.cpp 2012-07-20 23:00:30 +0000 |
149 | @@ -20,6 +20,7 @@ |
150 | #include "EdgeBarrierController.h" |
151 | #include "Decaymulator.h" |
152 | #include "unity-shared/UScreen.h" |
153 | +#include "UnityCore/GLibSource.h" |
154 | |
155 | namespace unity { |
156 | namespace ui { |
157 | @@ -27,23 +28,38 @@ |
158 | struct EdgeBarrierController::Impl |
159 | { |
160 | Impl(EdgeBarrierController *parent); |
161 | - ~Impl(); |
162 | |
163 | void ResizeBarrierList(std::vector<nux::Geometry> const& layout); |
164 | void SetupBarriers(std::vector<nux::Geometry> const& layout); |
165 | |
166 | - void OnPointerBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event); |
167 | + void OnPointerBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event); |
168 | + void BarrierRelease(PointerBarrierWrapper* owner, int event); |
169 | + |
170 | + bool StickyEdgeSetter(bool const& new_val) |
171 | + { |
172 | + if (parent_->options() && new_val != parent_->options()->edge_resist()) |
173 | + { |
174 | + parent_->options()->edge_resist = new_val; |
175 | + return true; |
176 | + } |
177 | + return false; |
178 | + } |
179 | + |
180 | + bool StickyEdgeGetter() |
181 | + { |
182 | + return parent_->options() ? parent_->options()->edge_resist() : false; |
183 | + } |
184 | |
185 | std::vector<PointerBarrierWrapper::Ptr> barriers_; |
186 | - Decaymulator::Ptr decaymulator_; |
187 | + std::vector<EdgeBarrierSubscriber*> subscribers_; |
188 | + Decaymulator decaymulator_; |
189 | + glib::Source::UniquePtr release_timeout_; |
190 | float edge_overcome_pressure_; |
191 | EdgeBarrierController* parent_; |
192 | - std::vector<EdgeBarrierSubscriber*> subscribers_; |
193 | }; |
194 | |
195 | EdgeBarrierController::Impl::Impl(EdgeBarrierController *parent) |
196 | - : decaymulator_(Decaymulator::Ptr(new Decaymulator())) |
197 | - , edge_overcome_pressure_(0) |
198 | + : edge_overcome_pressure_(0) |
199 | , parent_(parent) |
200 | { |
201 | UScreen *uscreen = UScreen::GetDefault(); |
202 | @@ -56,9 +72,23 @@ |
203 | SetupBarriers(layout); |
204 | }); |
205 | |
206 | - parent_->sticky_edges.changed.connect([&](bool value) { |
207 | - SetupBarriers(UScreen::GetDefault()->GetMonitors()); |
208 | - }); |
209 | + parent_->sticky_edges.SetGetterFunction(sigc::mem_fun(this, &Impl::StickyEdgeGetter)); |
210 | + parent_->sticky_edges.SetSetterFunction(sigc::mem_fun(this, &Impl::StickyEdgeSetter)); |
211 | + |
212 | +/* Set this back, once lp:~3v1n0/nux/use-std-function is merged |
213 | + parent_->sticky_edges.SetGetterFunction([parent_] { |
214 | + return parent_->options() ? parent_->options()->edge_resist() : false; |
215 | + }); |
216 | + |
217 | + parent_->sticky_edges.SetSetterFunction([parent_] (bool const& new_val) { |
218 | + if (parent_->options() && new_val != parent_->options()->edge_resist()) |
219 | + { |
220 | + parent_->options()->edge_resist = new_val; |
221 | + return true; |
222 | + } |
223 | + return false; |
224 | + }); |
225 | + */ |
226 | |
227 | parent_->options.changed.connect([&](launcher::Options::Ptr options) { |
228 | options->option_changed.connect([&]() { |
229 | @@ -68,14 +98,9 @@ |
230 | }); |
231 | } |
232 | |
233 | -EdgeBarrierController::Impl::~Impl() |
234 | -{ |
235 | - |
236 | -} |
237 | - |
238 | void EdgeBarrierController::Impl::ResizeBarrierList(std::vector<nux::Geometry> const& layout) |
239 | { |
240 | - size_t num_monitors = layout.size(); |
241 | + auto num_monitors = layout.size(); |
242 | if (barriers_.size() > num_monitors) |
243 | { |
244 | barriers_.resize(num_monitors); |
245 | @@ -83,7 +108,7 @@ |
246 | |
247 | while (barriers_.size() < num_monitors) |
248 | { |
249 | - auto barrier = PointerBarrierWrapper::Ptr(new PointerBarrierWrapper()); |
250 | + auto barrier = std::make_shared<PointerBarrierWrapper>(); |
251 | barrier->barrier_event.connect(sigc::mem_fun(this, &EdgeBarrierController::Impl::OnPointerBarrierEvent)); |
252 | barriers_.push_back(barrier); |
253 | } |
254 | @@ -91,10 +116,9 @@ |
255 | |
256 | void EdgeBarrierController::Impl::SetupBarriers(std::vector<nux::Geometry> const& layout) |
257 | { |
258 | - bool edge_resist = parent_->options()->edge_resist(); |
259 | + bool edge_resist = parent_->sticky_edges(); |
260 | |
261 | - size_t size = layout.size(); |
262 | - for (size_t i = 0; i < size; i++) |
263 | + for (unsigned i = 0; i < layout.size(); i++) |
264 | { |
265 | auto barrier = barriers_[i]; |
266 | auto monitor = layout[i]; |
267 | @@ -122,68 +146,86 @@ |
268 | } |
269 | |
270 | float decay_responsiveness_mult = ((parent_->options()->edge_responsiveness() - 1) * .3f) + 1; |
271 | - decaymulator_->rate_of_decay = parent_->options()->edge_decay_rate() * decay_responsiveness_mult; |
272 | - |
273 | + decaymulator_.rate_of_decay = parent_->options()->edge_decay_rate() * decay_responsiveness_mult; |
274 | + |
275 | float overcome_responsiveness_mult = ((parent_->options()->edge_responsiveness() - 1) * 1.0f) + 1; |
276 | edge_overcome_pressure_ = parent_->options()->edge_overcome_pressure() * overcome_responsiveness_mult; |
277 | } |
278 | |
279 | -void EdgeBarrierController::Impl::OnPointerBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event) |
280 | +void EdgeBarrierController::Impl::OnPointerBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event) |
281 | { |
282 | - int monitor = owner->index; |
283 | + unsigned int monitor = owner->index; |
284 | bool process = true; |
285 | |
286 | - if ((size_t)monitor <= subscribers_.size()) |
287 | + if (monitor <= subscribers_.size()) |
288 | { |
289 | auto subscriber = subscribers_[monitor]; |
290 | + |
291 | if (subscriber && subscriber->HandleBarrierEvent(owner, event)) |
292 | process = false; |
293 | } |
294 | |
295 | - if (process && owner->x1 > 0) |
296 | - { |
297 | - decaymulator_->value = decaymulator_->value + event->velocity; |
298 | - if (decaymulator_->value > edge_overcome_pressure_ || (!parent_->options()->edge_resist() && !subscribers_[monitor])) |
299 | + if (process && owner->released) |
300 | + { |
301 | + BarrierRelease(owner, event->event_id); |
302 | + } |
303 | + else if (process && owner->x1 > 0) |
304 | + { |
305 | + decaymulator_.value = decaymulator_.value + event->velocity; |
306 | + |
307 | + if (decaymulator_.value > edge_overcome_pressure_ || (!parent_->sticky_edges() && !subscribers_[monitor])) |
308 | { |
309 | - owner->ReleaseBarrier(event->event_id); |
310 | - decaymulator_->value = 0; |
311 | + BarrierRelease(owner, event->event_id); |
312 | } |
313 | } |
314 | else |
315 | { |
316 | - decaymulator_->value = 0; |
317 | + decaymulator_.value = 0; |
318 | } |
319 | } |
320 | |
321 | +void EdgeBarrierController::Impl::BarrierRelease(PointerBarrierWrapper* owner, int event) |
322 | +{ |
323 | + owner->ReleaseBarrier(event); |
324 | + owner->released = true; |
325 | + decaymulator_.value = 0; |
326 | + |
327 | + unsigned duration = parent_->options()->edge_passed_disabled_ms; |
328 | + release_timeout_.reset(new glib::Timeout(duration, [owner] { |
329 | + owner->released = false; |
330 | + return false; |
331 | + })); |
332 | +} |
333 | + |
334 | EdgeBarrierController::EdgeBarrierController() |
335 | - : sticky_edges(false) |
336 | - , pimpl(new Impl(this)) |
337 | -{ |
338 | -} |
339 | + : pimpl(new Impl(this)) |
340 | +{} |
341 | |
342 | EdgeBarrierController::~EdgeBarrierController() |
343 | -{ |
344 | - |
345 | -} |
346 | - |
347 | -void EdgeBarrierController::Subscribe(EdgeBarrierSubscriber* subscriber, int monitor) |
348 | -{ |
349 | - if (pimpl->subscribers_.size() <= (size_t)monitor) |
350 | +{} |
351 | + |
352 | +void EdgeBarrierController::Subscribe(EdgeBarrierSubscriber* subscriber, unsigned int monitor) |
353 | +{ |
354 | + if (pimpl->subscribers_.size() <= monitor) |
355 | pimpl->subscribers_.resize(monitor + 1); |
356 | + |
357 | pimpl->subscribers_[monitor] = subscriber; |
358 | - |
359 | pimpl->SetupBarriers(UScreen::GetDefault()->GetMonitors()); |
360 | } |
361 | |
362 | -void EdgeBarrierController::Unsubscribe(EdgeBarrierSubscriber* subscriber, int monitor) |
363 | +void EdgeBarrierController::Unsubscribe(EdgeBarrierSubscriber* subscriber, unsigned int monitor) |
364 | { |
365 | - if (pimpl->subscribers_.size() < (size_t)monitor || pimpl->subscribers_[monitor] != subscriber) |
366 | + if (pimpl->subscribers_.size() < monitor || pimpl->subscribers_[monitor] != subscriber) |
367 | return; |
368 | + |
369 | pimpl->subscribers_[monitor] = nullptr; |
370 | - |
371 | pimpl->SetupBarriers(UScreen::GetDefault()->GetMonitors()); |
372 | } |
373 | |
374 | +void EdgeBarrierController::ProcessBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event) |
375 | +{ |
376 | + pimpl->OnPointerBarrierEvent(owner, event); |
377 | +} |
378 | |
379 | } |
380 | } |
381 | |
382 | === modified file 'launcher/EdgeBarrierController.h' |
383 | --- launcher/EdgeBarrierController.h 2012-05-07 19:52:54 +0000 |
384 | +++ launcher/EdgeBarrierController.h 2012-07-20 23:00:30 +0000 |
385 | @@ -29,26 +29,27 @@ |
386 | class EdgeBarrierSubscriber |
387 | { |
388 | public: |
389 | - virtual bool HandleBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event) { return false; }; |
390 | + virtual bool HandleBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event) = 0; |
391 | }; |
392 | |
393 | class EdgeBarrierController : public sigc::trackable |
394 | { |
395 | public: |
396 | - typedef std::shared_ptr<EdgeBarrierController> Ptr; |
397 | - |
398 | EdgeBarrierController(); |
399 | ~EdgeBarrierController(); |
400 | |
401 | - nux::Property<bool> sticky_edges; |
402 | + nux::RWProperty<bool> sticky_edges; |
403 | nux::Property<launcher::Options::Ptr> options; |
404 | |
405 | - void Subscribe(EdgeBarrierSubscriber* subscriber, int monitor); |
406 | - void Unsubscribe(EdgeBarrierSubscriber* subscriber, int monitor); |
407 | + void Subscribe(EdgeBarrierSubscriber* subscriber, unsigned int monitor); |
408 | + void Unsubscribe(EdgeBarrierSubscriber* subscriber, unsigned int monitor); |
409 | + |
410 | +protected: |
411 | + void ProcessBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event); |
412 | |
413 | private: |
414 | struct Impl; |
415 | - Impl* pimpl; |
416 | + std::unique_ptr<Impl> pimpl; |
417 | }; |
418 | |
419 | } |
420 | |
421 | === modified file 'launcher/LauncherController.cpp' |
422 | --- launcher/LauncherController.cpp 2012-07-18 17:51:56 +0000 |
423 | +++ launcher/LauncherController.cpp 2012-07-20 23:00:30 +0000 |
424 | @@ -194,7 +194,7 @@ |
425 | int launcher_key_press_time_; |
426 | unsigned int dbus_owner_; |
427 | |
428 | - ui::EdgeBarrierController::Ptr edge_barriers_; |
429 | + ui::EdgeBarrierController edge_barriers_; |
430 | |
431 | LauncherList launchers; |
432 | |
433 | @@ -219,10 +219,9 @@ |
434 | , device_section_(volume_monitor_) |
435 | , show_desktop_icon_(false) |
436 | , display_(display) |
437 | - , edge_barriers_(new ui::EdgeBarrierController()) |
438 | , matcher_(bamf_matcher_get_default()) |
439 | { |
440 | - edge_barriers_->options = parent_->options(); |
441 | + edge_barriers_.options = parent_->options(); |
442 | |
443 | UScreen* uscreen = UScreen::GetDefault(); |
444 | auto monitors = uscreen->GetMonitors(); |
445 | @@ -355,7 +354,7 @@ |
446 | { |
447 | parent_->RemoveChild(launcher.GetPointer()); |
448 | launcher->GetParent()->UnReference(); |
449 | - edge_barriers_->Unsubscribe(launcher.GetPointer(), launcher->monitor); |
450 | + edge_barriers_.Unsubscribe(launcher.GetPointer(), launcher->monitor); |
451 | } |
452 | } |
453 | |
454 | @@ -363,7 +362,7 @@ |
455 | |
456 | for (size_t i = 0; i < launchers.size(); ++i) |
457 | { |
458 | - edge_barriers_->Subscribe(launchers[i].GetPointer(), launchers[i]->monitor); |
459 | + edge_barriers_.Subscribe(launchers[i].GetPointer(), launchers[i]->monitor); |
460 | } |
461 | } |
462 | |
463 | |
464 | === modified file 'launcher/LauncherHideMachine.cpp' |
465 | --- launcher/LauncherHideMachine.cpp 2012-06-18 02:57:23 +0000 |
466 | +++ launcher/LauncherHideMachine.cpp 2012-07-20 23:00:30 +0000 |
467 | @@ -19,7 +19,6 @@ |
468 | |
469 | #include "LauncherHideMachine.h" |
470 | |
471 | -#include <boost/lexical_cast.hpp> |
472 | #include <NuxCore/Logger.h> |
473 | |
474 | namespace unity |
475 | @@ -35,30 +34,29 @@ |
476 | |
477 | LauncherHideMachine::LauncherHideMachine() |
478 | : reveal_progress(0) |
479 | - , decaymulator_(new ui::Decaymulator()) |
480 | , _mode(HIDE_NEVER) |
481 | , _quirks(DEFAULT) |
482 | , _should_hide(false) |
483 | , _latest_emit_should_hide(false) |
484 | { |
485 | - decaymulator_->value.changed.connect([&](int value) { reveal_progress = value / static_cast<float>(reveal_pressure); }); |
486 | + decaymulator_.value.changed.connect([&](int value) { reveal_progress = value / static_cast<float>(reveal_pressure); }); |
487 | edge_decay_rate.changed.connect(sigc::mem_fun (this, &LauncherHideMachine::OnDecayRateChanged)); |
488 | } |
489 | |
490 | void LauncherHideMachine::OnDecayRateChanged(int value) |
491 | { |
492 | - decaymulator_->rate_of_decay = value; |
493 | + decaymulator_.rate_of_decay = value; |
494 | } |
495 | |
496 | void LauncherHideMachine::AddRevealPressure(int pressure) |
497 | { |
498 | - decaymulator_->value = decaymulator_->value + pressure; |
499 | + decaymulator_.value = decaymulator_.value + pressure; |
500 | |
501 | - if (decaymulator_->value > reveal_pressure) |
502 | + if (decaymulator_.value > reveal_pressure) |
503 | { |
504 | SetQuirk(REVEAL_PRESSURE_PASS, true); |
505 | SetQuirk(MOUSE_MOVE_POST_REVEAL, true); |
506 | - decaymulator_->value = 0; |
507 | + decaymulator_.value = 0; |
508 | } |
509 | } |
510 | |
511 | @@ -240,7 +238,7 @@ |
512 | { |
513 | // Although I do wonder why we are returning a string representation |
514 | // of the enum value as an integer anyway. |
515 | - return boost::lexical_cast<std::string>(_quirks); |
516 | + return std::to_string(_quirks); |
517 | } |
518 | |
519 | } // namespace launcher |
520 | |
521 | === modified file 'launcher/LauncherHideMachine.h' |
522 | --- launcher/LauncherHideMachine.h 2012-06-18 02:57:23 +0000 |
523 | +++ launcher/LauncherHideMachine.h 2012-07-20 23:00:30 +0000 |
524 | @@ -93,7 +93,7 @@ |
525 | |
526 | void OnDecayRateChanged (int value); |
527 | |
528 | - ui::Decaymulator::Ptr decaymulator_; |
529 | + ui::Decaymulator decaymulator_; |
530 | HideMode _mode; |
531 | HideQuirk _quirks; |
532 | bool _should_hide; |
533 | |
534 | === modified file 'launcher/LauncherHoverMachine.cpp' |
535 | --- launcher/LauncherHoverMachine.cpp 2012-06-18 02:57:23 +0000 |
536 | +++ launcher/LauncherHoverMachine.cpp 2012-07-20 23:00:30 +0000 |
537 | @@ -16,7 +16,6 @@ |
538 | * |
539 | * Authored by: Didier Roche <didrocks@ubuntu.com> |
540 | */ |
541 | -#include <boost/lexical_cast.hpp> |
542 | |
543 | #include "LauncherHoverMachine.h" |
544 | |
545 | @@ -110,7 +109,7 @@ |
546 | { |
547 | // Although I do wonder why we are returning a string representation |
548 | // of the enum value as an integer anyway. |
549 | - return boost::lexical_cast<std::string>(_quirks); |
550 | + return std::to_string(_quirks); |
551 | } |
552 | |
553 | } //unity namespace |
554 | |
555 | === modified file 'launcher/LauncherOptions.cpp' |
556 | --- launcher/LauncherOptions.cpp 2012-05-07 19:52:54 +0000 |
557 | +++ launcher/LauncherOptions.cpp 2012-07-20 23:00:30 +0000 |
558 | @@ -26,42 +26,42 @@ |
559 | { |
560 | |
561 | Options::Options() |
562 | + // defaults from XML file |
563 | + : hide_mode(LAUNCHER_HIDE_NEVER) |
564 | + , launch_animation(LAUNCH_ANIMATION_PULSE) |
565 | + , urgent_animation(URGENT_ANIMATION_WIGGLE) |
566 | + , auto_hide_animation(FADE_AND_SLIDE) |
567 | + , backlight_mode(BACKLIGHT_ALWAYS_ON) |
568 | + , reveal_trigger(RevealTrigger::EDGE) |
569 | + , icon_size(48) |
570 | + , tile_size(54) |
571 | + , background_alpha(0.6667) |
572 | + , edge_decay_rate(1500) |
573 | + , edge_overcome_pressure(2000) |
574 | + , edge_stop_velocity(6500) |
575 | + , edge_reveal_pressure(2000) |
576 | + , edge_responsiveness(2.0f) |
577 | + , edge_passed_disabled_ms(1000) |
578 | + , edge_resist(true) |
579 | + , show_for_all(false) |
580 | { |
581 | - // defaults from XML file |
582 | - auto_hide_animation = FADE_AND_SLIDE; |
583 | - background_alpha = 0.6667; |
584 | - backlight_mode = BACKLIGHT_ALWAYS_ON; |
585 | - edge_decay_rate = 1500; |
586 | - edge_overcome_pressure = 2000; |
587 | - edge_responsiveness = 2.0f; |
588 | - edge_reveal_pressure = 2000; |
589 | - edge_stop_velocity = 6500; |
590 | - hide_mode = LAUNCHER_HIDE_NEVER; |
591 | - icon_size = 48; |
592 | - launch_animation = LAUNCH_ANIMATION_PULSE; |
593 | - reveal_trigger = RevealTrigger::EDGE; |
594 | - tile_size = 54; |
595 | - urgent_animation = URGENT_ANIMATION_WIGGLE; |
596 | - edge_resist = true; |
597 | - show_for_all = false; |
598 | - |
599 | - auto_hide_animation.changed.connect ([&] (AutoHideAnimation value)-> void { option_changed.emit(); }); |
600 | - background_alpha.changed.connect ([&] (float value) -> void { option_changed.emit(); }); |
601 | - backlight_mode.changed.connect ([&] (BacklightMode value) -> void { option_changed.emit(); }); |
602 | - edge_decay_rate.changed.connect ([&] (int value) -> void { option_changed.emit(); }); |
603 | - edge_overcome_pressure.changed.connect([&] (int value) -> void { option_changed.emit(); }); |
604 | - edge_responsiveness.changed.connect ([&] (float value) -> void { option_changed.emit(); }); |
605 | - edge_reveal_pressure.changed.connect ([&] (int value) -> void { option_changed.emit(); }); |
606 | - edge_stop_velocity.changed.connect ([&] (int value) -> void { option_changed.emit(); }); |
607 | - hide_mode.changed.connect ([&] (LauncherHideMode value) -> void { option_changed.emit(); }); |
608 | - icon_size.changed.connect ([&] (int value) -> void { option_changed.emit(); }); |
609 | - launch_animation.changed.connect ([&] (LaunchAnimation value) -> void { option_changed.emit(); }); |
610 | - reveal_trigger.changed.connect ([&] (RevealTrigger vallue) -> void { option_changed.emit(); }); |
611 | - tile_size.changed.connect ([&] (int value) -> void { option_changed.emit(); }); |
612 | - urgent_animation.changed.connect ([&] (UrgentAnimation value) -> void { option_changed.emit(); }); |
613 | - edge_resist.changed.connect ([&] (bool value) -> void { option_changed.emit(); }); |
614 | + auto_hide_animation.changed.connect ([this] (AutoHideAnimation value) { option_changed.emit(); }); |
615 | + background_alpha.changed.connect ([this] (float value) { option_changed.emit(); }); |
616 | + backlight_mode.changed.connect ([this] (BacklightMode value) { option_changed.emit(); }); |
617 | + edge_decay_rate.changed.connect ([this] (int value) { option_changed.emit(); }); |
618 | + edge_overcome_pressure.changed.connect ([this] (int value) { option_changed.emit(); }); |
619 | + edge_responsiveness.changed.connect ([this] (float value) { option_changed.emit(); }); |
620 | + edge_reveal_pressure.changed.connect ([this] (int value) { option_changed.emit(); }); |
621 | + edge_stop_velocity.changed.connect ([this] (int value) { option_changed.emit(); }); |
622 | + edge_passed_disabled_ms.changed.connect([this] (unsigned value) { option_changed.emit(); }); |
623 | + hide_mode.changed.connect ([this] (LauncherHideMode value) { option_changed.emit(); }); |
624 | + icon_size.changed.connect ([this] (int value) { option_changed.emit(); }); |
625 | + launch_animation.changed.connect ([this] (LaunchAnimation value) { option_changed.emit(); }); |
626 | + reveal_trigger.changed.connect ([this] (RevealTrigger vallue) { option_changed.emit(); }); |
627 | + tile_size.changed.connect ([this] (int value) { option_changed.emit(); }); |
628 | + urgent_animation.changed.connect ([this] (UrgentAnimation value) { option_changed.emit(); }); |
629 | + edge_resist.changed.connect ([this] (bool value) { option_changed.emit(); }); |
630 | } |
631 | - |
632 | |
633 | } |
634 | } |
635 | |
636 | === modified file 'launcher/LauncherOptions.h' |
637 | --- launcher/LauncherOptions.h 2012-05-07 19:52:54 +0000 |
638 | +++ launcher/LauncherOptions.h 2012-07-20 23:00:30 +0000 |
639 | @@ -97,6 +97,7 @@ |
640 | nux::Property<int> edge_stop_velocity; |
641 | nux::Property<int> edge_reveal_pressure; |
642 | nux::Property<float> edge_responsiveness; |
643 | + nux::Property<unsigned> edge_passed_disabled_ms; |
644 | nux::Property<bool> edge_resist; |
645 | nux::Property<bool> show_for_all; |
646 | |
647 | |
648 | === modified file 'launcher/PointerBarrier.cpp' |
649 | --- launcher/PointerBarrier.cpp 2012-06-18 02:57:23 +0000 |
650 | +++ launcher/PointerBarrier.cpp 2012-07-20 23:00:30 +0000 |
651 | @@ -37,12 +37,12 @@ |
652 | |
653 | PointerBarrierWrapper::PointerBarrierWrapper() |
654 | : active(false) |
655 | + , released(false) |
656 | , smoothing(75) |
657 | , max_velocity_multiplier(1.0f) |
658 | , direction(BOTH) |
659 | - , last_event_(0) |
660 | - , last_x_(0) |
661 | - , last_y_(0) |
662 | + , event_base_(0) |
663 | + , barrier(0) |
664 | , smoothing_count_(0) |
665 | , smoothing_accum_(0) |
666 | {} |
667 | @@ -59,7 +59,8 @@ |
668 | |
669 | Display *dpy = nux::GetGraphicsDisplay()->GetX11Display(); |
670 | |
671 | - XFixesQueryExtension(dpy, &event_base_, &error_base_); |
672 | + int error_base; |
673 | + XFixesQueryExtension(dpy, &event_base_, &error_base); |
674 | |
675 | int maj,min; |
676 | XFixesQueryVersion(dpy, &maj, &min); |
677 | @@ -68,7 +69,7 @@ |
678 | DefaultRootWindow(dpy), |
679 | x1, y1, |
680 | x2, y2, |
681 | - (int) direction, |
682 | + static_cast<int>(direction), |
683 | threshold, |
684 | 0, |
685 | NULL); |
686 | @@ -103,19 +104,16 @@ |
687 | |
688 | void PointerBarrierWrapper::ReleaseBarrier(int event_id) |
689 | { |
690 | - XFixesBarrierReleasePointer (nux::GetGraphicsDisplay()->GetX11Display(), barrier, event_id); |
691 | + XFixesBarrierReleasePointer(nux::GetGraphicsDisplay()->GetX11Display(), barrier, event_id); |
692 | } |
693 | |
694 | -void PointerBarrierWrapper::EmitCurrentData() |
695 | +void PointerBarrierWrapper::EmitCurrentData(int event_id, int x, int y) |
696 | { |
697 | if (smoothing_count_ <= 0) |
698 | return; |
699 | |
700 | - BarrierEvent::Ptr event (new BarrierEvent()); |
701 | - event->x = last_x_; |
702 | - event->y = last_y_; |
703 | - event->velocity = std::min<int> (600 * max_velocity_multiplier, smoothing_accum_ / smoothing_count_); |
704 | - event->event_id = last_event_; |
705 | + int velocity = std::min<int>(600 * max_velocity_multiplier, smoothing_accum_ / smoothing_count_); |
706 | + auto event = std::make_shared<BarrierEvent>(x, y, velocity, event_id); |
707 | |
708 | barrier_event.emit(this, event); |
709 | |
710 | @@ -125,31 +123,40 @@ |
711 | |
712 | bool PointerBarrierWrapper::HandleEvent(XEvent xevent) |
713 | { |
714 | - if(xevent.type - event_base_ == XFixesBarrierNotify) |
715 | + if (xevent.type - event_base_ == XFixesBarrierNotify) |
716 | { |
717 | - XFixesBarrierNotifyEvent *notify_event = (XFixesBarrierNotifyEvent *)&xevent; |
718 | + auto notify_event = reinterpret_cast<XFixesBarrierNotifyEvent*>(&xevent); |
719 | |
720 | if (notify_event->barrier == barrier && notify_event->subtype == XFixesBarrierHitNotify) |
721 | { |
722 | - last_x_ = notify_event->x; |
723 | - last_y_ = notify_event->y; |
724 | - last_event_ = notify_event->event_id; |
725 | smoothing_accum_ += notify_event->velocity; |
726 | smoothing_count_++; |
727 | |
728 | - if (!smoothing_timeout_) |
729 | - { |
730 | - auto smoothing_cb = [&] () |
731 | + if (released) |
732 | + { |
733 | + /* If the barrier is released, just emit the current event without |
734 | + * waiting, so there won't be any delay on releasing the barrier. */ |
735 | + smoothing_timeout_.reset(); |
736 | + auto event = std::make_shared<BarrierEvent>(notify_event->x, notify_event->y, |
737 | + notify_event->velocity, notify_event->event_id); |
738 | + barrier_event.emit(this, event); |
739 | + } |
740 | + else if (!smoothing_timeout_) |
741 | + { |
742 | + int x = notify_event->x; |
743 | + int y = notify_event->y; |
744 | + int event = notify_event->event_id; |
745 | + |
746 | + auto smoothing_cb = [&, event, x, y] () |
747 | { |
748 | - EmitCurrentData(); |
749 | + EmitCurrentData(event, x, y); |
750 | |
751 | smoothing_timeout_.reset(); |
752 | return false; |
753 | }; |
754 | |
755 | - smoothing_timeout_.reset(new glib::Timeout(smoothing(), smoothing_cb)); |
756 | + smoothing_timeout_.reset(new glib::Timeout(smoothing, smoothing_cb)); |
757 | } |
758 | - |
759 | } |
760 | |
761 | return notify_event->barrier == barrier; |
762 | |
763 | === modified file 'launcher/PointerBarrier.h' |
764 | --- launcher/PointerBarrier.h 2012-06-18 02:57:23 +0000 |
765 | +++ launcher/PointerBarrier.h 2012-07-20 23:00:30 +0000 |
766 | @@ -30,11 +30,14 @@ |
767 | namespace ui |
768 | { |
769 | |
770 | -class BarrierEvent |
771 | +struct BarrierEvent |
772 | { |
773 | -public: |
774 | typedef std::shared_ptr<BarrierEvent> Ptr; |
775 | |
776 | + BarrierEvent(int x_, int y_, int velocity_, int event_id_) |
777 | + : x(x_), y(y_), velocity(velocity_), event_id(event_id_) |
778 | + {} |
779 | + |
780 | int x; |
781 | int y; |
782 | int velocity; |
783 | @@ -55,6 +58,9 @@ |
784 | public: |
785 | typedef std::shared_ptr<PointerBarrierWrapper> Ptr; |
786 | |
787 | + PointerBarrierWrapper(); |
788 | + virtual ~PointerBarrierWrapper(); |
789 | + |
790 | nux::Property<int> x1; |
791 | nux::Property<int> x2; |
792 | nux::Property<int> y1; |
793 | @@ -63,6 +69,7 @@ |
794 | nux::Property<int> threshold; |
795 | |
796 | nux::Property<bool> active; |
797 | + nux::Property<bool> released; |
798 | |
799 | nux::Property<int> smoothing; |
800 | |
801 | @@ -72,28 +79,22 @@ |
802 | |
803 | nux::Property<BarrierDirection> direction; |
804 | |
805 | - PointerBarrierWrapper(); |
806 | - ~PointerBarrierWrapper(); |
807 | - |
808 | - void ConstructBarrier(); |
809 | - void DestroyBarrier(); |
810 | - void ReleaseBarrier(int event_id); |
811 | + virtual void ConstructBarrier(); |
812 | + virtual void DestroyBarrier(); |
813 | + virtual void ReleaseBarrier(int event_id); |
814 | |
815 | sigc::signal<void, PointerBarrierWrapper*, BarrierEvent::Ptr> barrier_event; |
816 | |
817 | +protected: |
818 | + void EmitCurrentData(int event_id, int x, int y); |
819 | + bool HandleEvent(XEvent event); |
820 | + |
821 | private: |
822 | - void EmitCurrentData(); |
823 | - bool HandleEvent (XEvent event); |
824 | static bool HandleEventWrapper(XEvent event, void* data); |
825 | |
826 | - int last_event_; |
827 | - int last_x_; |
828 | - int last_y_; |
829 | - |
830 | int event_base_; |
831 | - int error_base_; |
832 | PointerBarrier barrier; |
833 | - |
834 | + |
835 | int smoothing_count_; |
836 | int smoothing_accum_; |
837 | glib::Source::UniquePtr smoothing_timeout_; |
838 | |
839 | === modified file 'plugins/unityshell/src/unityshell.cpp' |
840 | --- plugins/unityshell/src/unityshell.cpp 2012-07-16 11:28:24 +0000 |
841 | +++ plugins/unityshell/src/unityshell.cpp 2012-07-20 23:00:30 +0000 |
842 | @@ -337,6 +337,7 @@ |
843 | optionSetOvercomePressureNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
844 | optionSetDecayRateNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
845 | optionSetShowMinimizedWindowsNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
846 | + optionSetEdgePassedDisabledMsNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
847 | |
848 | optionSetNumLaunchersNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
849 | optionSetLauncherCaptureMouseNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
850 | @@ -2894,9 +2895,13 @@ |
851 | break; |
852 | case UnityshellOptions::RevealPressure: |
853 | launcher_options->edge_reveal_pressure = optionGetRevealPressure() * 100; |
854 | + break; |
855 | case UnityshellOptions::EdgeResponsiveness: |
856 | launcher_options->edge_responsiveness = optionGetEdgeResponsiveness(); |
857 | break; |
858 | + case UnityshellOptions::EdgePassedDisabledMs: |
859 | + launcher_options->edge_passed_disabled_ms = optionGetEdgePassedDisabledMs(); |
860 | + break; |
861 | default: |
862 | break; |
863 | } |
864 | |
865 | === modified file 'plugins/unityshell/unityshell.xml.in' |
866 | --- plugins/unityshell/unityshell.xml.in 2012-03-23 15:30:56 +0000 |
867 | +++ plugins/unityshell/unityshell.xml.in 2012-07-20 23:00:30 +0000 |
868 | @@ -329,6 +329,14 @@ |
869 | <max>1000</max> |
870 | <precision>1</precision> |
871 | </option> |
872 | + <option name="edge_passed_disabled_ms" type="int"> |
873 | + <_short>Duration of Sticky Edge Release after Break</_short> |
874 | + <_long>Sticky edges deactivated for number of milliseconds after the user breaks the barrier</_long> |
875 | + <default>1000</default> |
876 | + <min>0</min> |
877 | + <max>5000</max> |
878 | + <precision>1</precision> |
879 | + </option> |
880 | <option name="autohide_animation" type="int"> |
881 | <_short>Hide Animation</_short> |
882 | <_long>Animation played when the launcher is showing or hiding</_long> |
883 | |
884 | === modified file 'tests/CMakeLists.txt' |
885 | --- tests/CMakeLists.txt 2012-07-18 23:54:43 +0000 |
886 | +++ tests/CMakeLists.txt 2012-07-20 23:00:30 +0000 |
887 | @@ -124,6 +124,7 @@ |
888 | |
889 | # The actual test executable (xless) - do not put anything that requires X in here |
890 | add_executable(test-gtest-xless |
891 | + test_main_xless.cpp |
892 | test_animator.cpp |
893 | test_launcher_model.cpp |
894 | test_glib_object.cpp |
895 | @@ -134,25 +135,25 @@ |
896 | test_glib_signals_utils.h |
897 | test_glib_source.cpp |
898 | test_glib_variant.cpp |
899 | + test_grabhandle.cpp |
900 | test_desktop_utilities.cpp |
901 | - ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp |
902 | + test_hud_private.cpp |
903 | test_indicator.cpp |
904 | test_indicator_appmenu.cpp |
905 | test_indicator_entry.cpp |
906 | test_indicators.cpp |
907 | + test_introspection.cpp |
908 | test_favorite_store_gsettings.cpp |
909 | test_favorite_store_private.cpp |
910 | test_home_lens.cpp |
911 | test_launcher_entry_remote.cpp |
912 | + test_pointer_barrier.cpp |
913 | test_previews.cpp |
914 | test_shortcut_model.cpp |
915 | test_shortcut_private.cpp |
916 | - test_introspection.cpp |
917 | - test_main_xless.cpp |
918 | - test_grabhandle.cpp |
919 | + test_showdesktop_handler.cpp |
920 | test_unityshell_private.cpp |
921 | - test_showdesktop_handler.cpp |
922 | - test_hud_private.cpp |
923 | + ${CMAKE_CURRENT_BINARY_DIR}/test_glib_signals_utils_marshal.cpp |
924 | ${CMAKE_SOURCE_DIR}/launcher/AbstractLauncherIcon.cpp |
925 | ${CMAKE_SOURCE_DIR}/unity-shared/Animator.cpp |
926 | ${UNITY_SRC}/DebugDBusInterface.cpp |
927 | @@ -164,6 +165,7 @@ |
928 | ${CMAKE_SOURCE_DIR}/launcher/LauncherEntryRemote.cpp |
929 | ${CMAKE_SOURCE_DIR}/launcher/MockLauncherIcon.cpp |
930 | ${CMAKE_SOURCE_DIR}/launcher/FavoriteStorePrivate.cpp |
931 | + ${CMAKE_SOURCE_DIR}/launcher/PointerBarrier.cpp |
932 | ${CMAKE_SOURCE_DIR}/shortcuts/ShortcutModel.cpp |
933 | ${CMAKE_SOURCE_DIR}/shortcuts/ShortcutHintPrivate.cpp |
934 | ${CMAKE_SOURCE_DIR}/unity-shared/Introspectable.cpp |
935 | @@ -203,23 +205,24 @@ |
936 | |
937 | # Tests that require X |
938 | add_executable(test-gtest |
939 | + test_main.cpp |
940 | test_bamflaunchericon.cpp |
941 | - test_hud_button.cpp |
942 | - test_hud_controller.cpp |
943 | test_dashview_impl.cpp |
944 | - test_texture_cache.cpp |
945 | - test_main.cpp |
946 | + test_edge_barrier_controller.cpp |
947 | test_launcher.cpp |
948 | test_device_launcher_section.cpp |
949 | test_lensview_impl.cpp |
950 | + test_hud_button.cpp |
951 | + test_hud_controller.cpp |
952 | + test_hud_view.cpp |
953 | test_icon_loader.cpp |
954 | test_im_text_entry.cpp |
955 | - test_hud_view.cpp |
956 | test_keyboard_util.cpp |
957 | test_resultviewgrid.cpp |
958 | test_single_monitor_launcher_icon.cpp |
959 | test_switcher_controller.cpp |
960 | test_switcher_model.cpp |
961 | + test_texture_cache.cpp |
962 | gmockvolume.c |
963 | ${CMAKE_SOURCE_DIR}/dash/AbstractPlacesGroup.cpp |
964 | ${CMAKE_SOURCE_DIR}/dash/DashViewPrivate.cpp |
965 | @@ -243,6 +246,7 @@ |
966 | ${CMAKE_SOURCE_DIR}/launcher/DeviceLauncherSection.cpp |
967 | ${CMAKE_SOURCE_DIR}/launcher/DevicesSettings.cpp |
968 | ${CMAKE_SOURCE_DIR}/launcher/DndData.cpp |
969 | + ${CMAKE_SOURCE_DIR}/launcher/EdgeBarrierController.cpp |
970 | ${CMAKE_SOURCE_DIR}/launcher/FavoriteStore.cpp |
971 | ${CMAKE_SOURCE_DIR}/launcher/FavoriteStoreGSettings.cpp |
972 | ${CMAKE_SOURCE_DIR}/launcher/FavoriteStorePrivate.cpp |
973 | @@ -254,6 +258,7 @@ |
974 | ${CMAKE_SOURCE_DIR}/launcher/LauncherHoverMachine.cpp |
975 | ${CMAKE_SOURCE_DIR}/launcher/LauncherIcon.cpp |
976 | ${CMAKE_SOURCE_DIR}/launcher/LauncherModel.cpp |
977 | + ${CMAKE_SOURCE_DIR}/launcher/LauncherOptions.cpp |
978 | ${CMAKE_SOURCE_DIR}/launcher/LayoutSystem.cpp |
979 | ${CMAKE_SOURCE_DIR}/launcher/MockLauncherIcon.cpp |
980 | ${CMAKE_SOURCE_DIR}/launcher/PointerBarrier.cpp |
981 | |
982 | === added file 'tests/test_edge_barrier_controller.cpp' |
983 | --- tests/test_edge_barrier_controller.cpp 1970-01-01 00:00:00 +0000 |
984 | +++ tests/test_edge_barrier_controller.cpp 2012-07-20 23:00:30 +0000 |
985 | @@ -0,0 +1,225 @@ |
986 | +/* |
987 | + * Copyright 2012 Canonical Ltd. |
988 | + * |
989 | + * This program is free software: you can redistribute it and/or modify it |
990 | + * under the terms of the GNU General Public License version 3, as published |
991 | + * by the Free Software Foundation. |
992 | + * |
993 | + * This program is distributed in the hope that it will be useful, but |
994 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
995 | + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
996 | + * PURPOSE. See the GNU General Public License for more details. |
997 | + * |
998 | + * You should have received a copy of the GNU General Public License |
999 | + * version 3 along with this program. If not, see |
1000 | + * <http://www.gnu.org/licenses/> |
1001 | + * |
1002 | + * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com> |
1003 | + * |
1004 | + */ |
1005 | + |
1006 | +#include <gmock/gmock.h> |
1007 | +#include "test_utils.h" |
1008 | + |
1009 | +#include "EdgeBarrierController.h" |
1010 | +#include "MultiMonitor.h" |
1011 | + |
1012 | +using namespace unity; |
1013 | +using namespace unity::ui; |
1014 | +using namespace testing; |
1015 | + |
1016 | +namespace |
1017 | +{ |
1018 | + |
1019 | +class MockPointerBarrier : public PointerBarrierWrapper |
1020 | +{ |
1021 | +public: |
1022 | + MockPointerBarrier(int monitor = 0, bool released_ = false) |
1023 | + { |
1024 | + index = monitor; |
1025 | + x1 = 1; |
1026 | + released = released_; |
1027 | + } |
1028 | + |
1029 | + MOCK_METHOD0(ConstructBarrier, void()); |
1030 | + MOCK_METHOD0(DestroyBarrier, void()); |
1031 | + MOCK_METHOD1(ReleaseBarrier, void(int)); |
1032 | +}; |
1033 | + |
1034 | +class MockEdgeBarrierController : public EdgeBarrierController |
1035 | +{ |
1036 | +public: |
1037 | + void ProcessBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event) |
1038 | + { |
1039 | + EdgeBarrierController::ProcessBarrierEvent(owner, event); |
1040 | + } |
1041 | +}; |
1042 | + |
1043 | +class TestBarrierSubscriber : public EdgeBarrierSubscriber |
1044 | +{ |
1045 | +public: |
1046 | + TestBarrierSubscriber(bool handles = false) |
1047 | + : handles_(handles) |
1048 | + {} |
1049 | + |
1050 | + bool HandleBarrierEvent(PointerBarrierWrapper* owner, BarrierEvent::Ptr event) |
1051 | + { |
1052 | + return handles_; |
1053 | + } |
1054 | + |
1055 | + bool handles_; |
1056 | +}; |
1057 | + |
1058 | +class TestEdgeBarrierController : public Test |
1059 | +{ |
1060 | +public: |
1061 | + virtual void SetUp() |
1062 | + { |
1063 | + bc.options = std::make_shared<launcher::Options>(); |
1064 | + bc.options()->edge_resist = true; |
1065 | + bc.options()->edge_passed_disabled_ms = 150; |
1066 | + |
1067 | + for (int i = 0; i < max_num_monitors; ++i) |
1068 | + { |
1069 | + // By default we assume that no subscriber handles the events!!! |
1070 | + bc.Subscribe(&subscribers_[i], i); |
1071 | + } |
1072 | + } |
1073 | + |
1074 | + BarrierEvent::Ptr MakeBarrierEvent(int id, bool breaker) |
1075 | + { |
1076 | + int velocity = breaker ? std::numeric_limits<int>::max() : bc.options()->edge_overcome_pressure() - 1; |
1077 | + return std::make_shared<BarrierEvent>(0, 1, velocity, id); |
1078 | + } |
1079 | + |
1080 | + TestBarrierSubscriber subscribers_[max_num_monitors]; |
1081 | + MockEdgeBarrierController bc; |
1082 | +}; |
1083 | + |
1084 | +TEST_F(TestEdgeBarrierController, Construction) |
1085 | +{ |
1086 | + EXPECT_TRUE(bc.sticky_edges); |
1087 | +} |
1088 | + |
1089 | +TEST_F(TestEdgeBarrierController, ProcessHandledEvent) |
1090 | +{ |
1091 | + int monitor = 0; |
1092 | + |
1093 | + TestBarrierSubscriber handling_subscriber(true); |
1094 | + bc.Subscribe(&handling_subscriber, monitor); |
1095 | + |
1096 | + MockPointerBarrier owner(monitor); |
1097 | + auto breaking_barrier_event = MakeBarrierEvent(0, true); |
1098 | + |
1099 | + EXPECT_CALL(owner, ReleaseBarrier(_)).Times(0); |
1100 | + bc.ProcessBarrierEvent(&owner, breaking_barrier_event); |
1101 | +} |
1102 | + |
1103 | +TEST_F(TestEdgeBarrierController, ProcessHandledEventOnReleasedBarrier) |
1104 | +{ |
1105 | + int monitor = max_num_monitors-1; |
1106 | + |
1107 | + TestBarrierSubscriber handling_subscriber(true); |
1108 | + bc.Subscribe(&handling_subscriber, monitor); |
1109 | + |
1110 | + MockPointerBarrier owner(monitor, true); |
1111 | + auto breaking_barrier_event = MakeBarrierEvent(0, true); |
1112 | + |
1113 | + EXPECT_CALL(owner, ReleaseBarrier(_)).Times(0); |
1114 | + bc.ProcessBarrierEvent(&owner, breaking_barrier_event); |
1115 | +} |
1116 | + |
1117 | +TEST_F(TestEdgeBarrierController, ProcessUnHandledEventBreakingBarrier) |
1118 | +{ |
1119 | + int monitor = 1; |
1120 | + |
1121 | + MockPointerBarrier owner(monitor); |
1122 | + int breaking_id = 12345; |
1123 | + auto breaking_barrier_event = MakeBarrierEvent(breaking_id, true); |
1124 | + |
1125 | + EXPECT_CALL(owner, ReleaseBarrier(breaking_id)); |
1126 | + bc.ProcessBarrierEvent(&owner, breaking_barrier_event); |
1127 | +} |
1128 | + |
1129 | +TEST_F(TestEdgeBarrierController, ProcessUnHandledEventNotBreakingBarrier) |
1130 | +{ |
1131 | + int monitor = 2; |
1132 | + |
1133 | + MockPointerBarrier owner(monitor); |
1134 | + int not_breaking_id = 54321; |
1135 | + auto not_breaking_barrier_event = MakeBarrierEvent(not_breaking_id, false); |
1136 | + |
1137 | + EXPECT_CALL(owner, ReleaseBarrier(not_breaking_id)).Times(0); |
1138 | + bc.ProcessBarrierEvent(&owner, not_breaking_barrier_event); |
1139 | +} |
1140 | + |
1141 | +TEST_F(TestEdgeBarrierController, ProcessUnHandledEventOnReleasedBarrier) |
1142 | +{ |
1143 | + int monitor = 2; |
1144 | + |
1145 | + MockPointerBarrier owner(monitor, true); |
1146 | + int not_breaking_id = 345678; |
1147 | + auto not_breaking_barrier_event = MakeBarrierEvent(not_breaking_id, false); |
1148 | + |
1149 | + EXPECT_CALL(owner, ReleaseBarrier(not_breaking_id)); |
1150 | + bc.ProcessBarrierEvent(&owner, not_breaking_barrier_event); |
1151 | +} |
1152 | + |
1153 | +TEST_F(TestEdgeBarrierController, BreakingEdgeTemporaryReleasesBarrier) |
1154 | +{ |
1155 | + MockPointerBarrier owner; |
1156 | + |
1157 | + EXPECT_CALL(owner, ReleaseBarrier(1)); |
1158 | + bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(1, true)); |
1159 | + ASSERT_TRUE(owner.released()); |
1160 | + |
1161 | + Utils::WaitForTimeoutMSec(bc.options()->edge_passed_disabled_ms); |
1162 | + EXPECT_FALSE(owner.released()); |
1163 | +} |
1164 | + |
1165 | +TEST_F(TestEdgeBarrierController, BreakingEdgeTemporaryReleasesBarrierForNotHandledEvents) |
1166 | +{ |
1167 | + MockPointerBarrier owner; |
1168 | + int monitor = 0; |
1169 | + subscribers_[monitor].handles_ = false; |
1170 | + |
1171 | + EXPECT_CALL(owner, ReleaseBarrier(5)); |
1172 | + bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(5, true)); |
1173 | + ASSERT_TRUE(owner.released()); |
1174 | + |
1175 | + subscribers_[monitor].handles_ = false; |
1176 | + EXPECT_CALL(owner, ReleaseBarrier(6)); |
1177 | + bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(6, false)); |
1178 | +} |
1179 | + |
1180 | +TEST_F(TestEdgeBarrierController, BreakingEdgeDontReleasesBarrierForHandledEvents) |
1181 | +{ |
1182 | + MockPointerBarrier owner; |
1183 | + int monitor = 0; |
1184 | + subscribers_[monitor].handles_ = false; |
1185 | + |
1186 | + EXPECT_CALL(owner, ReleaseBarrier(5)); |
1187 | + bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(5, true)); |
1188 | + ASSERT_TRUE(owner.released()); |
1189 | + |
1190 | + subscribers_[monitor].handles_ = true; |
1191 | + EXPECT_CALL(owner, ReleaseBarrier(_)).Times(0); |
1192 | + bc.ProcessBarrierEvent(&owner, MakeBarrierEvent(6, true)); |
1193 | +} |
1194 | + |
1195 | +TEST_F(TestEdgeBarrierController, StickyEdgePropertyProxiesLauncherOption) |
1196 | +{ |
1197 | + bc.options()->edge_resist = false; |
1198 | + EXPECT_FALSE(bc.sticky_edges()); |
1199 | + |
1200 | + bc.options()->edge_resist = true; |
1201 | + EXPECT_TRUE(bc.sticky_edges()); |
1202 | + |
1203 | + bc.sticky_edges = false; |
1204 | + EXPECT_FALSE(bc.options()->edge_resist()); |
1205 | + |
1206 | + bc.sticky_edges = true; |
1207 | + EXPECT_TRUE(bc.options()->edge_resist()); |
1208 | +} |
1209 | + |
1210 | +} |
1211 | |
1212 | === added file 'tests/test_pointer_barrier.cpp' |
1213 | --- tests/test_pointer_barrier.cpp 1970-01-01 00:00:00 +0000 |
1214 | +++ tests/test_pointer_barrier.cpp 2012-07-20 23:00:30 +0000 |
1215 | @@ -0,0 +1,141 @@ |
1216 | +/* |
1217 | + * Copyright 2012 Canonical Ltd. |
1218 | + * |
1219 | + * This program is free software: you can redistribute it and/or modify it |
1220 | + * under the terms of the GNU General Public License version 3, as published |
1221 | + * by the Free Software Foundation. |
1222 | + * |
1223 | + * This program is distributed in the hope that it will be useful, but |
1224 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1225 | + * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR |
1226 | + * PURPOSE. See the GNU General Public License for more details. |
1227 | + * |
1228 | + * You should have received a copy of the GNU General Public License |
1229 | + * version 3 along with this program. If not, see |
1230 | + * <http://www.gnu.org/licenses/> |
1231 | + * |
1232 | + * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com> |
1233 | + * |
1234 | + */ |
1235 | + |
1236 | +#include <gtest/gtest.h> |
1237 | +#include <limits> |
1238 | + |
1239 | +#include "test_utils.h" |
1240 | +#include "PointerBarrier.h" |
1241 | + |
1242 | +using namespace unity::ui; |
1243 | + |
1244 | +namespace |
1245 | +{ |
1246 | + |
1247 | +class MockPointerBarrier : public PointerBarrierWrapper |
1248 | +{ |
1249 | +public: |
1250 | + bool HandleEvent(XEvent ev) { return PointerBarrierWrapper::HandleEvent(ev); } |
1251 | +}; |
1252 | + |
1253 | +TEST(TestPointerBarrier, Construction) |
1254 | +{ |
1255 | + PointerBarrierWrapper pb; |
1256 | + |
1257 | + EXPECT_EQ(pb.active, false); |
1258 | + EXPECT_EQ(pb.released, false); |
1259 | + EXPECT_EQ(pb.smoothing, 75); |
1260 | + EXPECT_EQ(pb.max_velocity_multiplier, 1.0f); |
1261 | + EXPECT_EQ(pb.direction, BOTH); |
1262 | +} |
1263 | + |
1264 | +TEST(TestPointerBarrier, EventConstruction) |
1265 | +{ |
1266 | + BarrierEvent bev(1, 2, 3, 4); |
1267 | + EXPECT_EQ(bev.x, 1); |
1268 | + EXPECT_EQ(bev.y, 2); |
1269 | + EXPECT_EQ(bev.velocity, 3); |
1270 | + EXPECT_EQ(bev.event_id, 4); |
1271 | +} |
1272 | + |
1273 | +TEST(TestPointerBarrier, HandleInvalidEvents) |
1274 | +{ |
1275 | + MockPointerBarrier pb; |
1276 | + XFixesBarrierNotifyEvent ev; |
1277 | + auto xev = reinterpret_cast<XEvent*>(&ev); |
1278 | + |
1279 | + ev.type = XFixesBarrierNotify + 1; |
1280 | + EXPECT_FALSE(pb.HandleEvent(*xev)); |
1281 | + |
1282 | + ev.type = XFixesBarrierNotify; |
1283 | + ev.subtype = XFixesBarrierHitNotify + 1; |
1284 | + ev.barrier = 1; |
1285 | + EXPECT_FALSE(pb.HandleEvent(*xev)); |
1286 | + |
1287 | + ev.barrier = 0; |
1288 | + EXPECT_TRUE(pb.HandleEvent(*xev)); |
1289 | +} |
1290 | + |
1291 | +TEST(TestPointerBarrier, HandleHitNotifyEvents) |
1292 | +{ |
1293 | + MockPointerBarrier pb; |
1294 | + XFixesBarrierNotifyEvent ev; |
1295 | + auto xev = reinterpret_cast<XEvent*>(&ev); |
1296 | + |
1297 | + ev.type = XFixesBarrierNotify; |
1298 | + ev.subtype = XFixesBarrierHitNotify; |
1299 | + ev.barrier = 0; |
1300 | + ev.event_id = 0xdeadbeef; |
1301 | + ev.x = 555; |
1302 | + ev.y = 333; |
1303 | + ev.velocity = std::numeric_limits<int>::max(); |
1304 | + |
1305 | + bool got_event = false; |
1306 | + |
1307 | + pb.barrier_event.connect([&] (PointerBarrierWrapper* pbw, BarrierEvent::Ptr bev) { |
1308 | + got_event = true; |
1309 | + |
1310 | + EXPECT_EQ(pbw, &pb); |
1311 | + EXPECT_EQ(bev->x, ev.x); |
1312 | + EXPECT_EQ(bev->y, ev.y); |
1313 | + EXPECT_EQ(bev->velocity, 600 * pb.max_velocity_multiplier); |
1314 | + EXPECT_EQ(bev->event_id, ev.event_id); |
1315 | + }); |
1316 | + |
1317 | + EXPECT_TRUE(pb.HandleEvent(*xev)); |
1318 | + EXPECT_FALSE(got_event); |
1319 | + |
1320 | + Utils::WaitForTimeoutMSec(pb.smoothing()); |
1321 | + |
1322 | + EXPECT_TRUE(got_event); |
1323 | +} |
1324 | + |
1325 | +TEST(TestPointerBarrier, HandleHitNotifyReleasedEvents) |
1326 | +{ |
1327 | + MockPointerBarrier pb; |
1328 | + XFixesBarrierNotifyEvent ev; |
1329 | + auto xev = reinterpret_cast<XEvent*>(&ev); |
1330 | + |
1331 | + ev.type = XFixesBarrierNotify; |
1332 | + ev.subtype = XFixesBarrierHitNotify; |
1333 | + ev.barrier = 0; |
1334 | + ev.event_id = 0xabba; |
1335 | + ev.x = 3333; |
1336 | + ev.y = 5555; |
1337 | + ev.velocity = std::numeric_limits<int>::max(); |
1338 | + |
1339 | + bool got_event = false; |
1340 | + |
1341 | + pb.barrier_event.connect([&] (PointerBarrierWrapper* pbw, BarrierEvent::Ptr bev) { |
1342 | + got_event = true; |
1343 | + |
1344 | + EXPECT_EQ(pbw, &pb); |
1345 | + EXPECT_EQ(bev->x, ev.x); |
1346 | + EXPECT_EQ(bev->y, ev.y); |
1347 | + EXPECT_EQ(bev->velocity, ev.velocity); |
1348 | + EXPECT_EQ(bev->event_id, ev.event_id); |
1349 | + }); |
1350 | + |
1351 | + pb.released = true; |
1352 | + EXPECT_TRUE(pb.HandleEvent(*xev)); |
1353 | + EXPECT_TRUE(got_event); |
1354 | +} |
1355 | + |
1356 | +} |