Mir

Merge lp:~vanvugt/mir/move into lp:~mir-team/mir/trunk

Proposed by Daniel van Vugt
Status: Superseded
Proposed branch: lp:~vanvugt/mir/move
Merge into: lp:~mir-team/mir/trunk
Diff against target: 456 lines (+163/-41)
12 files modified
examples/demo-shell/CMakeLists.txt (+1/-1)
examples/demo-shell/demo_shell.cpp (+7/-6)
examples/demo-shell/window_manager.cpp (+45/-4)
examples/demo-shell/window_manager.h (+13/-8)
include/server/mir/shell/session_manager.h (+1/-0)
include/server/mir/shell/surface.h (+2/-0)
include/shared/mir/geometry/dimensions.h (+24/-20)
src/server/shell/session_manager.cpp (+5/-0)
src/server/shell/surface.cpp (+12/-0)
src/server/surfaces/surface.cpp (+2/-2)
tests/unit-tests/geometry/test-dimensions.cpp (+44/-0)
tests/unit-tests/geometry/test-displacement.cpp (+7/-0)
To merge this branch: bzr merge lp:~vanvugt/mir/move
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Alan Griffiths Approve
Robert Ancell Approve
Review via email: mp+162487@code.launchpad.net

This proposal has been superseded by a proposal from 2013-06-11.

Commit message

demo-shell: Add support for moving windows/surfaces via Alt+drag.

Only the "default" surface of the focussed app is moved. In future we
should move whichever surface is hit by the pointer.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I don't like the name "WindowManager" either. But the good alternative is to name it Shell and merge yet more classes into that. So leaving it for now.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

166 + void set_session_manager(std::shared_ptr<shell::SessionManager> const& sm);

I don't think we should be making this public - if it needs to be public in DemoServerConfiguration, then that can achieve the same effect with a "using" directive in the Demo code.

The MP as a whole introduces behavior it may be better not to expose to users. Vis: "Don't move things left or up. Surfaces will vanish if they are placed left of or above the screen."

review: Abstain
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> 166 + void set_session_manager(std::shared_ptr<shell::SessionManager>
> const& sm);
>
> I don't think we should be making this public - if it needs to be public in
> DemoServerConfiguration, then that can achieve the same effect with a "using"
> directive in the Demo code.

I meant, of course,

195 + virtual std::shared_ptr<shell::SessionManager> the_session_manager();

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Oops!

review: Abstain
Revision history for this message
kevin gunn (kgunn72) wrote :

moving to WIP as this has been sitting (altho daniel's been out)

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Resubmitted. I've fixed the vanishing surfaces problem. Not really sure what Alan wanted re: "set_session_manager".

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

220 - typedef uint32_t ValueType;
221 + typedef int ValueType;

(and related uint_32 -> int changes)

While these changes fix the problem mentioned here, I imagine that there was a reason for choosing uint32_t, and that this change could have unintended consequences. Has this been checked?

review: Needs Information
Revision history for this message
Robert Ancell (robert-ancell) wrote :

Approve as long as racarr doesn't indicate a problem with the uint32_t -> int change.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I just noticed bug 1188451 as a result of playing with movement...

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

> 220 - typedef uint32_t ValueType;
> 221 + typedef int ValueType;
>
> (and related uint_32 -> int changes)
>
> While these changes fix the problem mentioned here, I imagine that there was a
> reason for choosing uint32_t, and that this change could have unintended
> consequences. Has this been checked?

Alan,

Yes it's been checked to some extent:
1. No test case failures.
2. No visible regressions when running mir binaries.

Furthermore, you have theoretical peace of mind:
1. All the +,-,==,!= operators are unaffected by sign. They produce the same result regardless of the signedness of the operands.
2. Only the >,<,>=,<= might be affected in theory. But you'd have to be unlucky to use them in a way that they are affected and all testing so far has shown no change in behaviour.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

No point in discussing any longer

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Did I do that?...
The following tests FAILED:
  72 - memcheck(unit-tests.ProtobufCommunicator.*) (Failed)
Errors while running CTest
make[2]: *** [test] Error 8

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/demo-shell/CMakeLists.txt'
2--- examples/demo-shell/CMakeLists.txt 2013-05-22 14:21:16 +0000
3+++ examples/demo-shell/CMakeLists.txt 2013-06-10 06:32:24 +0000
4@@ -1,7 +1,7 @@
5 add_executable(mir_demo_server_shell
6 demo_shell.cpp
7 fullscreen_placement_strategy.cpp
8- application_switcher.cpp
9+ window_manager.cpp
10 )
11
12 target_link_libraries(mir_demo_server_shell
13
14=== modified file 'examples/demo-shell/demo_shell.cpp'
15--- examples/demo-shell/demo_shell.cpp 2013-04-29 17:39:12 +0000
16+++ examples/demo-shell/demo_shell.cpp 2013-06-10 06:32:24 +0000
17@@ -18,7 +18,7 @@
18
19 /// \example demo_shell.cpp A simple mir shell
20
21-#include "application_switcher.h"
22+#include "window_manager.h"
23 #include "fullscreen_placement_strategy.h"
24
25 #include "mir/run_mir.h"
26@@ -76,14 +76,15 @@
27 int main(int argc, char const* argv[])
28 try
29 {
30- auto app_switcher = std::make_shared<me::ApplicationSwitcher>();
31- me::DemoServerConfiguration config(argc, argv, {app_switcher});
32-
33- mir::run_mir(config, [&config, &app_switcher](mir::DisplayServer&)
34+ auto wm = std::make_shared<me::WindowManager>();
35+ me::DemoServerConfiguration config(argc, argv, {wm});
36+
37+ mir::run_mir(config, [&config, &wm](mir::DisplayServer&)
38 {
39 // We use this strange two stage initialization to avoid a circular dependency between the EventFilters
40 // and the SessionStore
41- app_switcher->set_focus_controller(config.the_focus_controller());
42+ wm->set_focus_controller(config.the_focus_controller());
43+ wm->set_session_manager(config.the_session_manager());
44 });
45 return 0;
46 }
47
48=== renamed file 'examples/demo-shell/application_switcher.cpp' => 'examples/demo-shell/window_manager.cpp'
49--- examples/demo-shell/application_switcher.cpp 2013-06-06 10:03:12 +0000
50+++ examples/demo-shell/window_manager.cpp 2013-06-10 06:32:24 +0000
51@@ -16,9 +16,12 @@
52 * Authored by: Robert Carr <robert.carr@canonical.com>
53 */
54
55-#include "application_switcher.h"
56+#include "window_manager.h"
57
58 #include "mir/shell/focus_controller.h"
59+#include "mir/shell/session_manager.h"
60+#include "mir/shell/session.h"
61+#include "mir/shell/surface.h"
62
63 #include <linux/input.h>
64
65@@ -27,16 +30,22 @@
66 namespace me = mir::examples;
67 namespace msh = mir::shell;
68
69-me::ApplicationSwitcher::ApplicationSwitcher()
70+me::WindowManager::WindowManager()
71 {
72 }
73
74-void me::ApplicationSwitcher::set_focus_controller(std::shared_ptr<msh::FocusController> const& controller)
75+void me::WindowManager::set_focus_controller(std::shared_ptr<msh::FocusController> const& controller)
76 {
77 focus_controller = controller;
78 }
79
80-bool me::ApplicationSwitcher::handle(MirEvent const& event)
81+void me::WindowManager::set_session_manager(
82+ std::shared_ptr<msh::SessionManager> const& sm)
83+{
84+ session_manager = sm;
85+}
86+
87+bool me::WindowManager::handle(MirEvent const& event)
88 {
89 assert(focus_controller);
90
91@@ -48,5 +57,37 @@
92 focus_controller->focus_next();
93 return true;
94 }
95+ else if (event.type == mir_event_type_motion &&
96+ session_manager)
97+ {
98+ std::shared_ptr<msh::Session> app =
99+ session_manager->focussed_application().lock();
100+
101+ if (app)
102+ {
103+ // FIXME: We need to be able to select individual surfaces in
104+ // future and not just the "default" one.
105+ std::shared_ptr<msh::Surface> surf = app->default_surface();
106+
107+ if (surf &&
108+ event.motion.modifiers & mir_key_modifier_alt)
109+ {
110+ geometry::Point cursor{
111+ geometry::X{event.motion.pointer_coordinates[0].x},
112+ geometry::Y{event.motion.pointer_coordinates[0].y}};
113+
114+ if (event.motion.button_state == 0)
115+ {
116+ relative_click = cursor - surf->top_left();
117+ }
118+ else if (event.motion.button_state & mir_motion_button_primary)
119+ {
120+ geometry::Point abs = cursor - relative_click;
121+ surf->move_to(abs);
122+ return true;
123+ }
124+ }
125+ }
126+ }
127 return false;
128 }
129
130=== renamed file 'examples/demo-shell/application_switcher.h' => 'examples/demo-shell/window_manager.h'
131--- examples/demo-shell/application_switcher.h 2013-06-06 10:03:12 +0000
132+++ examples/demo-shell/window_manager.h 2013-06-10 06:32:24 +0000
133@@ -16,10 +16,11 @@
134 * Authored by: Robert Carr <robert.carr@canonical.com>
135 */
136
137-#ifndef MIR_EXAMPLES_APPLICATION_SWITCHER_H_
138-#define MIR_EXAMPLES_APPLICATION_SWITCHER_H_
139+#ifndef MIR_EXAMPLES_WINDOW_MANAGER_H_
140+#define MIR_EXAMPLES_WINDOW_MANAGER_H_
141
142 #include "mir/input/event_filter.h"
143+#include "mir/geometry/displacement.h"
144
145 #include <memory>
146
147@@ -28,29 +29,33 @@
148 namespace shell
149 {
150 class FocusController;
151+class SessionManager;
152 }
153 namespace examples
154 {
155
156-class ApplicationSwitcher : public input::EventFilter
157+class WindowManager : public input::EventFilter
158 {
159 public:
160- ApplicationSwitcher();
161- ~ApplicationSwitcher() = default;
162+ WindowManager();
163+ ~WindowManager() = default;
164
165 void set_focus_controller(std::shared_ptr<shell::FocusController> const& focus_controller);
166+ void set_session_manager(std::shared_ptr<shell::SessionManager> const& sm);
167
168 bool handle(MirEvent const& event) override;
169
170 protected:
171- ApplicationSwitcher(const ApplicationSwitcher&) = delete;
172- ApplicationSwitcher& operator=(const ApplicationSwitcher&) = delete;
173+ WindowManager(const WindowManager&) = delete;
174+ WindowManager& operator=(const WindowManager&) = delete;
175
176 private:
177 std::shared_ptr<shell::FocusController> focus_controller;
178+ std::shared_ptr<shell::SessionManager> session_manager;
179+ geometry::Displacement relative_click; // Click location in window space
180 };
181
182 }
183 } // namespace mir
184
185-#endif // MIR_EXAMPLES_APPLICATION_SWITCHER_H_
186+#endif // MIR_EXAMPLES_WINDOW_MANAGER_H_
187
188=== modified file 'include/server/mir/shell/session_manager.h'
189--- include/server/mir/shell/session_manager.h 2013-05-28 14:34:35 +0000
190+++ include/server/mir/shell/session_manager.h 2013-06-10 06:32:24 +0000
191@@ -59,6 +59,7 @@
192 SurfaceCreationParameters const& params);
193
194 void focus_next();
195+ std::weak_ptr<Session> focussed_application() const;
196
197 protected:
198 SessionManager(const SessionManager&) = delete;
199
200=== modified file 'include/server/mir/shell/surface.h'
201--- include/server/mir/shell/surface.h 2013-05-28 15:44:18 +0000
202+++ include/server/mir/shell/surface.h 2013-06-10 06:32:24 +0000
203@@ -66,6 +66,8 @@
204
205 virtual std::string name() const;
206
207+ virtual void move_to(geometry::Point const& top_left);
208+
209 virtual geometry::Size size() const;
210 virtual geometry::Point top_left() const;
211
212
213=== modified file 'include/shared/mir/geometry/dimensions.h'
214--- include/shared/mir/geometry/dimensions.h 2013-04-24 05:22:20 +0000
215+++ include/shared/mir/geometry/dimensions.h 2013-06-10 06:32:24 +0000
216@@ -38,13 +38,17 @@
217 class IntWrapper
218 {
219 public:
220- typedef uint32_t ValueType;
221+ typedef int ValueType;
222
223 IntWrapper() : value(0) {}
224 template<typename AnyInteger>
225 explicit IntWrapper(AnyInteger value) : value(static_cast<ValueType>(value)) {}
226
227- uint32_t as_uint32_t() const
228+ uint32_t as_uint32_t() const // TODO: Deprecate this later
229+ {
230+ return (uint32_t)value;
231+ }
232+ int as_int() const
233 {
234 return value;
235 }
236@@ -60,44 +64,44 @@
237 template<DimensionTag Tag>
238 std::ostream& operator<<(std::ostream& out, IntWrapper<Tag> const& value)
239 {
240- out << value.as_uint32_t();
241+ out << value.as_int();
242 return out;
243 }
244
245 template<DimensionTag Tag>
246 inline bool operator == (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)
247 {
248- return lhs.as_uint32_t() == rhs.as_uint32_t();
249+ return lhs.as_int() == rhs.as_int();
250 }
251
252 template<DimensionTag Tag>
253 inline bool operator != (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)
254 {
255- return lhs.as_uint32_t() != rhs.as_uint32_t();
256+ return lhs.as_int() != rhs.as_int();
257 }
258
259 template<DimensionTag Tag>
260 inline bool operator <= (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)
261 {
262- return lhs.as_uint32_t() <= rhs.as_uint32_t();
263+ return lhs.as_int() <= rhs.as_int();
264 }
265
266 template<DimensionTag Tag>
267 inline bool operator >= (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)
268 {
269- return lhs.as_uint32_t() >= rhs.as_uint32_t();
270+ return lhs.as_int() >= rhs.as_int();
271 }
272
273 template<DimensionTag Tag>
274 inline bool operator < (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)
275 {
276- return lhs.as_uint32_t() < rhs.as_uint32_t();
277+ return lhs.as_int() < rhs.as_int();
278 }
279
280 template<DimensionTag Tag>
281 inline bool operator > (IntWrapper<Tag> const& lhs, IntWrapper<Tag> const& rhs)
282 {
283- return lhs.as_uint32_t() > rhs.as_uint32_t();
284+ return lhs.as_int() > rhs.as_int();
285 }
286 } // namespace detail
287
288@@ -111,23 +115,23 @@
289 typedef detail::IntWrapper<detail::dy> DeltaY;
290
291 // Adding deltas is fine
292-inline DeltaX operator+(DeltaX lhs, DeltaX rhs) { return DeltaX(lhs.as_uint32_t() + rhs.as_uint32_t()); }
293-inline DeltaY operator+(DeltaY lhs, DeltaY rhs) { return DeltaY(lhs.as_uint32_t() + rhs.as_uint32_t()); }
294-inline DeltaX operator-(DeltaX lhs, DeltaX rhs) { return DeltaX(lhs.as_uint32_t() - rhs.as_uint32_t()); }
295-inline DeltaY operator-(DeltaY lhs, DeltaY rhs) { return DeltaY(lhs.as_uint32_t() - rhs.as_uint32_t()); }
296+inline DeltaX operator+(DeltaX lhs, DeltaX rhs) { return DeltaX(lhs.as_int() + rhs.as_int()); }
297+inline DeltaY operator+(DeltaY lhs, DeltaY rhs) { return DeltaY(lhs.as_int() + rhs.as_int()); }
298+inline DeltaX operator-(DeltaX lhs, DeltaX rhs) { return DeltaX(lhs.as_int() - rhs.as_int()); }
299+inline DeltaY operator-(DeltaY lhs, DeltaY rhs) { return DeltaY(lhs.as_int() - rhs.as_int()); }
300
301 // Adding deltas to co-ordinates is fine
302-inline X operator+(X lhs, DeltaX rhs) { return X(lhs.as_uint32_t() + rhs.as_uint32_t()); }
303-inline Y operator+(Y lhs, DeltaY rhs) { return Y(lhs.as_uint32_t() + rhs.as_uint32_t()); }
304-inline X operator-(X lhs, DeltaX rhs) { return X(lhs.as_uint32_t() - rhs.as_uint32_t()); }
305-inline Y operator-(Y lhs, DeltaY rhs) { return Y(lhs.as_uint32_t() - rhs.as_uint32_t()); }
306+inline X operator+(X lhs, DeltaX rhs) { return X(lhs.as_int() + rhs.as_int()); }
307+inline Y operator+(Y lhs, DeltaY rhs) { return Y(lhs.as_int() + rhs.as_int()); }
308+inline X operator-(X lhs, DeltaX rhs) { return X(lhs.as_int() - rhs.as_int()); }
309+inline Y operator-(Y lhs, DeltaY rhs) { return Y(lhs.as_int() - rhs.as_int()); }
310
311 // Subtracting coordinates is fine
312-inline DeltaX operator-(X lhs, X rhs) { return DeltaX(lhs.as_uint32_t() - rhs.as_uint32_t()); }
313-inline DeltaY operator-(Y lhs, Y rhs) { return DeltaY(lhs.as_uint32_t() - rhs.as_uint32_t()); }
314+inline DeltaX operator-(X lhs, X rhs) { return DeltaX(lhs.as_int() - rhs.as_int()); }
315+inline DeltaY operator-(Y lhs, Y rhs) { return DeltaY(lhs.as_int() - rhs.as_int()); }
316
317 template<typename Target, typename Source>
318-inline Target dim_cast(Source s) { return Target(s.as_uint32_t()); }
319+inline Target dim_cast(Source s) { return Target(s.as_int()); }
320 }
321 }
322
323
324=== modified file 'src/server/shell/session_manager.cpp'
325--- src/server/shell/session_manager.cpp 2013-05-28 14:34:35 +0000
326+++ src/server/shell/session_manager.cpp 2013-06-10 06:32:24 +0000
327@@ -128,6 +128,11 @@
328 set_focus_to_locked(lock, focus);
329 }
330
331+std::weak_ptr<msh::Session> msh::SessionManager::focussed_application() const
332+{
333+ return focus_application;
334+}
335+
336 mf::SurfaceId msh::SessionManager::create_surface_for(std::shared_ptr<mf::Session> const& session,
337 msh::SurfaceCreationParameters const& params)
338 {
339
340=== modified file 'src/server/shell/surface.cpp'
341--- src/server/shell/surface.cpp 2013-05-28 15:44:18 +0000
342+++ src/server/shell/surface.cpp 2013-06-10 06:32:24 +0000
343@@ -109,6 +109,18 @@
344 }
345 }
346
347+void msh::Surface::move_to(geometry::Point const& p)
348+{
349+ if (auto const& s = surface.lock())
350+ {
351+ s->move_to(p);
352+ }
353+ else
354+ {
355+ BOOST_THROW_EXCEPTION(std::runtime_error("Invalid surface"));
356+ }
357+}
358+
359 mir::geometry::Point msh::Surface::top_left() const
360 {
361 if (auto const& s = surface.lock())
362
363=== modified file 'src/server/surfaces/surface.cpp'
364--- src/server/surfaces/surface.cpp 2013-05-22 17:36:47 +0000
365+++ src/server/surfaces/surface.cpp 2013-06-10 06:32:24 +0000
366@@ -113,8 +113,8 @@
367 {
368 const geom::Size sz = size();
369
370- const glm::vec3 top_left_vec{top_left_point.x.as_uint32_t(),
371- top_left_point.y.as_uint32_t(),
372+ const glm::vec3 top_left_vec{top_left_point.x.as_int(),
373+ top_left_point.y.as_int(),
374 0.0f};
375 const glm::vec3 size_vec{sz.width.as_uint32_t(),
376 sz.height.as_uint32_t(),
377
378=== modified file 'tests/unit-tests/geometry/test-dimensions.cpp'
379--- tests/unit-tests/geometry/test-dimensions.cpp 2012-09-18 09:44:45 +0000
380+++ tests/unit-tests/geometry/test-dimensions.cpp 2013-06-10 06:32:24 +0000
381@@ -89,3 +89,47 @@
382 EXPECT_EQ(dx1, dim_cast<DeltaX>(w1));
383 EXPECT_NE(dx1, dim_cast<DeltaX>(X()));
384 }
385+
386+TEST(geometry, signed_dimensions)
387+{
388+ using namespace geom;
389+
390+ X const x0{0};
391+ X const x2{2};
392+ X const xn5{-5};
393+ Y const y0{0};
394+ Y const y3{3};
395+ Y const yn6{-6};
396+ Y const yn7{-7};
397+
398+ // Compare against zero to catch regressions of signed->unsigned that
399+ // wouldn't be caught using as_*int()...
400+ EXPECT_GT(x0, xn5);
401+ EXPECT_GT(y0, yn7);
402+
403+ EXPECT_LT(xn5, x0);
404+ EXPECT_LT(xn5, x2);
405+ EXPECT_LT(yn7, yn6);
406+ EXPECT_LT(yn7, y0);
407+ EXPECT_LT(yn7, y3);
408+
409+ EXPECT_LE(xn5, x0);
410+ EXPECT_LE(xn5, x2);
411+ EXPECT_LE(yn7, yn6);
412+ EXPECT_LE(yn7, y0);
413+ EXPECT_LE(yn7, y3);
414+ EXPECT_LE(yn7, yn7);
415+
416+ EXPECT_GT(x0, xn5);
417+ EXPECT_GT(x2, xn5);
418+ EXPECT_GT(yn6, yn7);
419+ EXPECT_GT(y0, yn7);
420+ EXPECT_GT(y3, yn7);
421+
422+ EXPECT_GE(x0, xn5);
423+ EXPECT_GE(x2, xn5);
424+ EXPECT_GE(yn6, yn7);
425+ EXPECT_GE(y0, yn7);
426+ EXPECT_GE(y3, yn7);
427+ EXPECT_GE(yn7, yn7);
428+}
429
430=== modified file 'tests/unit-tests/geometry/test-displacement.cpp'
431--- tests/unit-tests/geometry/test-displacement.cpp 2013-03-21 03:32:59 +0000
432+++ tests/unit-tests/geometry/test-displacement.cpp 2013-06-10 06:32:24 +0000
433@@ -62,16 +62,23 @@
434 Point const x2y4{X{2}, Y{4}};
435 Point const x3y9{X{3}, Y{9}};
436 Displacement const dx2dy4{DeltaX{2}, DeltaY{4}};
437+ Displacement const dx7dy11{DeltaX{7}, DeltaY{11}};
438
439 Point const expected_pd_add{X{5}, Y{13}};
440 Point const expected_pd_sub{X{1}, Y{5}};
441+ Point const expected_pd_sub2{X{-4}, Y{-2}};
442 Displacement const expected_pp_sub{DeltaX{1}, DeltaY{5}};
443+ Displacement const expected_pp_sub2{DeltaX{-1}, DeltaY{-5}};
444
445 Point const pd_add = x3y9 + dx2dy4;
446 Point const pd_sub = x3y9 - dx2dy4;
447+ Point const pd_sub2 = x3y9 - dx7dy11;
448 Displacement const pp_sub = x3y9 - x2y4;
449+ Displacement const pp_sub2 = x2y4 - x3y9;
450
451 EXPECT_EQ(expected_pd_add, pd_add);
452 EXPECT_EQ(expected_pd_sub, pd_sub);
453+ EXPECT_EQ(expected_pd_sub2, pd_sub2);
454 EXPECT_EQ(expected_pp_sub, pp_sub);
455+ EXPECT_EQ(expected_pp_sub2, pp_sub2);
456 }

Subscribers

People subscribed via source and target branches