Merge lp:~alan-griffiths/miral/fix-1717061 into lp:miral

Proposed by Alan Griffiths
Status: Merged
Approved by: Alan Griffiths
Approved revision: 580
Merged at revision: 580
Proposed branch: lp:~alan-griffiths/miral/fix-1717061
Merge into: lp:miral
Diff against target: 350 lines (+174/-39)
7 files modified
miral/CMakeLists.txt (+1/-0)
miral/set_window_management_policy.cpp (+16/-16)
miral/window_info.cpp (+49/-15)
miral/window_info_defaults.h (+36/-0)
miral/window_management_trace.cpp (+10/-8)
test/CMakeLists.txt (+1/-0)
test/window_info.cpp (+61/-0)
To merge this branch: bzr merge lp:~alan-griffiths/miral/fix-1717061
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Approve
Gerry Boland (community) Approve
Brandon Schaefer (community) Approve
Review via email: mp+330832@code.launchpad.net

Commit message

Define default window settings in one place and clamp the actual values to avoid ldiv0. (LP: #1717061)

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

+unsigned clamp_dim(unsigned dim)
+{
+ return std::min<unsigned long>(std::numeric_limits<long>::max(), dim);
+}

There's a mix of types here: unsigned int, unsigned long and signed long, which is causing me problems understanding. I know sizeof(unsigned int) <= sizeof(long), which implies to me that

dim <= std::numeric_limits<unsigned>::max()
    <= std::numeric_limits<long>::max()

so the min() will always choose "dim". So I don't understand what it is clamping to.

+// For our convenience when doing calculations we clamp the dimensions of the aspect ratio
+// so they will fit into a long without overflow.
What "long"? AspectRatio is a pair of unsigned ints.

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

> +unsigned clamp_dim(unsigned dim)
> +{
> + return std::min<unsigned long>(std::numeric_limits<long>::max(), dim);
> +}
>
> There's a mix of types here: unsigned int, unsigned long and signed long,
> which is causing me problems understanding. I know sizeof(unsigned int) <=
> sizeof(long), which implies to me that
>
> dim <= std::numeric_limits<unsigned>::max()
> <= std::numeric_limits<long>::max()

when, as Brandon encountered on armhf, long and int are the same size.

     std::numeric_limits<long>::max() <= std::numeric_limits<unsigned>::max()

> so the min() will always choose "dim". So I don't understand what it is
> clamping to.

In the above case it is clamping to std::numeric_limits<long>::max()

> +// For our convenience when doing calculations we clamp the dimensions of the
> aspect ratio
> +// so they will fit into a long without overflow.
> What "long"? AspectRatio is a pair of unsigned ints.

If std::numeric_limits<long>::max() <= dim <= std::numeric_limits<unsigned>::max() then dim doesn't fit in a long.

Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Yeah this seems a bit more robust then what I was doing in my branch.

I was just figuring since sizeof(long) >= sizeof(int) we could just cheat and assign the aspect to int::max() vs unsigned::max() but you do end up losing a byte there if really wanted on amd64 machines.

Though wont it all be going through the values that are depended in the RPC? Should we at some point look at moving to proper int sizes (u)int8/16/32/64 to know we wont have changing int values depending on the architecture.

Also that test is sort of ... different then this overflow issue but still nice to test. Wasnt sure if we actually had more checking higher up the stack when we come from the RPC.

LGTM

review: Approve
Revision history for this message
Gerry Boland (gerboland) wrote :

lgtm

review: Approve
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Autolanding.
More details in the following jenkins job:
https://mir-jenkins.ubuntu.com/job/miral-autolanding/44/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-miral/125/console
    None: https://mir-jenkins.ubuntu.com/job/generic-land-mp/1554/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5252
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/5240
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/5240
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/5240
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=artful/129
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=artful/129/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=xenial/129
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=xenial/129/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=zesty/129
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=zesty/129/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=i386,release=artful/129
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=i386,release=artful/129/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=i386,release=xenial/129
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=i386,release=xenial/129/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=i386,release=zesty/129/console

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Autolanding.
More details in the following jenkins job:
https://mir-jenkins.ubuntu.com/job/miral-autolanding/45/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-miral/126/console
    None: https://mir-jenkins.ubuntu.com/job/generic-land-mp/1558/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/5260
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=artful/5248
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/5248
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/5248
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=artful/130
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=artful/130/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=xenial/130
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=xenial/130/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=zesty/130
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=amd64,release=zesty/130/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=i386,release=artful/130
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=i386,release=artful/130/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=i386,release=xenial/130
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=i386,release=xenial/130/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-miral/arch=i386,release=zesty/130/console

review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'miral/CMakeLists.txt'
2--- miral/CMakeLists.txt 2017-07-26 10:44:19 +0000
3+++ miral/CMakeLists.txt 2017-09-15 13:33:35 +0000
4@@ -64,6 +64,7 @@
5 ${miral_include}/mir/client/connection.h
6 ${miral_include}/mir/client/display_config.h
7 ${miral_include}/mir/client/window.h
8+ window_info_defaults.h
9 )
10
11 target_include_directories(mirclientcpp
12
13=== modified file 'miral/set_window_management_policy.cpp'
14--- miral/set_window_management_policy.cpp 2017-08-10 16:59:22 +0000
15+++ miral/set_window_management_policy.cpp 2017-09-15 13:33:35 +0000
16@@ -32,22 +32,6 @@
17 char const* const trace_option = "window-management-trace";
18 }
19
20-MIRAL_FAKE_OLD_SYMBOL(
21- _ZN5miral24SetWindowManagmentPolicyC1ERKSt8functionIFSt10unique_ptrINS_22WindowManagementPolicyESt14default_deleteIS3_EERKNS_18WindowManagerToolsEEE,
22- _ZN5miral25SetWindowManagementPolicyC1ERKSt8functionIFSt10unique_ptrINS_22WindowManagementPolicyESt14default_deleteIS3_EERKNS_18WindowManagerToolsEEE)
23-
24-MIRAL_FAKE_OLD_SYMBOL(
25- _ZNK5miral24SetWindowManagmentPolicyclERN3mir6ServerE,
26- _ZNK5miral25SetWindowManagementPolicyclERN3mir6ServerE)
27-
28-MIRAL_FAKE_OLD_SYMBOL(
29- _ZN5miral24SetWindowManagmentPolicyD1Ev,
30- _ZN5miral25SetWindowManagementPolicyD1Ev)
31-
32-MIRAL_FAKE_OLD_SYMBOL(
33- _ZN5miral24SetWindowManagmentPolicyD2Ev,
34- _ZN5miral25SetWindowManagementPolicyD2Ev)
35-
36 miral::SetWindowManagementPolicy::SetWindowManagementPolicy(WindowManagementPolicyBuilder const& builder) :
37 builder{builder}
38 {
39@@ -89,3 +73,19 @@
40 builder);
41 });
42 }
43+
44+MIRAL_FAKE_OLD_SYMBOL(
45+ _ZN5miral24SetWindowManagmentPolicyC1ERKSt8functionIFSt10unique_ptrINS_22WindowManagementPolicyESt14default_deleteIS3_EERKNS_18WindowManagerToolsEEE,
46+ _ZN5miral25SetWindowManagementPolicyC1ERKSt8functionIFSt10unique_ptrINS_22WindowManagementPolicyESt14default_deleteIS3_EERKNS_18WindowManagerToolsEEE)
47+
48+MIRAL_FAKE_OLD_SYMBOL(
49+ _ZNK5miral24SetWindowManagmentPolicyclERN3mir6ServerE,
50+ _ZNK5miral25SetWindowManagementPolicyclERN3mir6ServerE)
51+
52+MIRAL_FAKE_OLD_SYMBOL(
53+ _ZN5miral24SetWindowManagmentPolicyD1Ev,
54+ _ZN5miral25SetWindowManagementPolicyD1Ev)
55+
56+MIRAL_FAKE_OLD_SYMBOL(
57+ _ZN5miral24SetWindowManagmentPolicyD2Ev,
58+ _ZN5miral25SetWindowManagementPolicyD2Ev)
59
60=== modified file 'miral/window_info.cpp'
61--- miral/window_info.cpp 2017-08-10 16:59:22 +0000
62+++ miral/window_info.cpp 2017-09-15 13:33:35 +0000
63@@ -17,6 +17,7 @@
64 */
65
66 #include "miral/window_info.h"
67+#include "window_info_defaults.h"
68
69 #include "both_versions.h"
70
71@@ -35,7 +36,40 @@
72 {
73 return optional_value.is_set() ? optional_value.value() : default_;
74 }
75-}
76+
77+unsigned clamp_dim(unsigned dim)
78+{
79+ return std::min<unsigned long>(std::numeric_limits<long>::max(), dim);
80+}
81+
82+// For our convenience when doing calculations we clamp the dimensions of the aspect ratio
83+// so they will fit into a long without overflow.
84+miral::WindowInfo::AspectRatio clamp(miral::WindowInfo::AspectRatio const& source)
85+{
86+ return {clamp_dim(source.width), clamp_dim(source.height)};
87+}
88+
89+miral::Width clamp(miral::Width const& source)
90+{
91+ return std::min(miral::default_max_width, std::max(miral::default_min_width, source));
92+}
93+
94+miral::Height clamp(miral::Height const& source)
95+{
96+ return std::min(miral::default_max_height, std::max(miral::default_min_height, source));
97+}
98+}
99+
100+miral::Width const miral::default_min_width{0};
101+miral::Height const miral::default_min_height{0};
102+miral::Width const miral::default_max_width{std::numeric_limits<int>::max()};
103+miral::Height const miral::default_max_height{std::numeric_limits<int>::max()};
104+miral::DeltaX const miral::default_width_inc{1};
105+miral::DeltaY const miral::default_height_inc{1};
106+miral::WindowInfo::AspectRatio const miral::default_min_aspect_ratio{
107+ clamp(WindowInfo::AspectRatio{0U, std::numeric_limits<unsigned>::max()})};
108+miral::WindowInfo::AspectRatio const miral::default_max_aspect_ratio{
109+ clamp(WindowInfo::AspectRatio{std::numeric_limits<unsigned>::max(), 0U})};
110
111 struct miral::WindowInfo::Self
112 {
113@@ -71,16 +105,16 @@
114 type{optional_value_or_default(params.type(), mir_window_type_normal)},
115 state{optional_value_or_default(params.state(), mir_window_state_restored)},
116 restore_rect{params.top_left().value(), params.size().value()},
117- min_width{optional_value_or_default(params.min_width())},
118- min_height{optional_value_or_default(params.min_height())},
119- max_width{optional_value_or_default(params.max_width(), Width{std::numeric_limits<int>::max()})},
120- max_height{optional_value_or_default(params.max_height(), Height{std::numeric_limits<int>::max()})},
121+ min_width{optional_value_or_default(params.min_width(), miral::default_min_width)},
122+ min_height{optional_value_or_default(params.min_height(), miral::default_min_height)},
123+ max_width{optional_value_or_default(params.max_width(), miral::default_max_width)},
124+ max_height{optional_value_or_default(params.max_height(), miral::default_max_height)},
125 preferred_orientation{optional_value_or_default(params.preferred_orientation(), mir_orientation_mode_any)},
126 confine_pointer(optional_value_or_default(params.confine_pointer(), mir_pointer_unconfined)),
127- width_inc{optional_value_or_default(params.width_inc(), DeltaX{1})},
128- height_inc{optional_value_or_default(params.height_inc(), DeltaY{1})},
129- min_aspect(optional_value_or_default(params.min_aspect(), AspectRatio{0U, std::numeric_limits<unsigned>::max()})),
130- max_aspect(optional_value_or_default(params.max_aspect(), AspectRatio{std::numeric_limits<unsigned>::max(), 0U})),
131+ width_inc{optional_value_or_default(params.width_inc(), default_width_inc)},
132+ height_inc{optional_value_or_default(params.height_inc(), default_height_inc)},
133+ min_aspect(optional_value_or_default(params.min_aspect(), default_min_aspect_ratio)),
134+ max_aspect(optional_value_or_default(params.max_aspect(), default_max_aspect_ratio)),
135 shell_chrome(optional_value_or_default(params.shell_chrome(), mir_shell_chrome_normal))
136 {
137 if (params.output_id().is_set())
138@@ -450,7 +484,7 @@
139
140 void miral::WindowInfo::min_width(mir::geometry::Width min_width)
141 {
142- self->min_width = min_width;
143+ self->min_width = clamp(min_width);
144 }
145
146 auto miral::WindowInfo::min_height() const -> mir::geometry::Height
147@@ -460,7 +494,7 @@
148
149 void miral::WindowInfo::min_height(mir::geometry::Height min_height)
150 {
151- self->min_height = min_height;
152+ self->min_height = clamp(min_height);
153 }
154
155 auto miral::WindowInfo::max_width() const -> mir::geometry::Width
156@@ -470,7 +504,7 @@
157
158 void miral::WindowInfo::max_width(mir::geometry::Width max_width)
159 {
160- self->max_width = max_width;
161+ self->max_width = clamp(max_width);
162 }
163
164 auto miral::WindowInfo::max_height() const -> mir::geometry::Height
165@@ -480,7 +514,7 @@
166
167 void miral::WindowInfo::max_height(mir::geometry::Height max_height)
168 {
169- self->max_height = max_height;
170+ self->max_height = clamp(max_height);
171 }
172
173 auto miral::WindowInfo::userdata() const -> std::shared_ptr<void>
174@@ -520,7 +554,7 @@
175
176 void miral::WindowInfo::min_aspect(AspectRatio min_aspect)
177 {
178- self->min_aspect = min_aspect;
179+ self->min_aspect = clamp(min_aspect);
180 }
181
182 auto miral::WindowInfo::max_aspect() const -> AspectRatio
183@@ -530,7 +564,7 @@
184
185 void miral::WindowInfo::max_aspect(AspectRatio max_aspect)
186 {
187- self->max_aspect = max_aspect;
188+ self->max_aspect = clamp(max_aspect);
189 }
190
191 bool miral::WindowInfo::has_output_id() const
192
193=== added file 'miral/window_info_defaults.h'
194--- miral/window_info_defaults.h 1970-01-01 00:00:00 +0000
195+++ miral/window_info_defaults.h 2017-09-15 13:33:35 +0000
196@@ -0,0 +1,36 @@
197+/*
198+ * Copyright © 2017 Canonical Ltd.
199+ *
200+ * This program is free software: you can redistribute it and/or modify it
201+ * under the terms of the GNU General Public License version 2 or 3,
202+ * as published by the Free Software Foundation.
203+ *
204+ * This program is distributed in the hope that it will be useful,
205+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
206+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
207+ * GNU General Public License for more details.
208+ *
209+ * You should have received a copy of the GNU General Public License
210+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
211+ *
212+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
213+ */
214+
215+#ifndef MIR_WINDOW_INFO_DEFAULTS_H
216+#define MIR_WINDOW_INFO_DEFAULTS_H
217+
218+#include "miral/window_info.h"
219+
220+namespace miral
221+{
222+Width extern const default_min_width;
223+Height extern const default_min_height;
224+Width extern const default_max_width;
225+Height extern const default_max_height;
226+DeltaX extern const default_width_inc;
227+DeltaY extern const default_height_inc;
228+WindowInfo::AspectRatio extern const default_min_aspect_ratio;
229+WindowInfo::AspectRatio extern const default_max_aspect_ratio;
230+}
231+
232+#endif //MIR_WINDOW_INFO_DEFAULTS_H
233
234=== modified file 'miral/window_management_trace.cpp'
235--- miral/window_management_trace.cpp 2017-08-10 16:59:22 +0000
236+++ miral/window_management_trace.cpp 2017-09-15 13:33:35 +0000
237@@ -17,6 +17,7 @@
238 */
239
240 #include "window_management_trace.h"
241+#include "window_info_defaults.h"
242
243 #include <miral/application_info.h>
244 #include <miral/window_info.h>
245@@ -133,18 +134,19 @@
246 APPEND(name);
247 APPEND(type);
248 APPEND(state);
249+ bout.append("size", info.window().size());
250 if (info.state() != mir_window_state_restored) APPEND(restore_rect);
251 if (std::shared_ptr<mir::scene::Surface> parent = info.parent())
252 bout.append("parent", parent->name());
253 bout.append("children", dump_of(info.children()));
254- if (info.min_width() != Width{0}) APPEND(min_width);
255- if (info.min_height() != Height{0}) APPEND(min_height);
256- if (info.max_width() != Width{std::numeric_limits<int>::max()}) APPEND(max_width);
257- if (info.max_height() != Height{std::numeric_limits<int>::max()}) APPEND(max_height);
258- if (info.width_inc() != DeltaX{1}) APPEND(width_inc);
259- if (info.height_inc() != DeltaY{1}) APPEND(height_inc);
260- if (info.min_aspect() != miral::WindowInfo::AspectRatio{0U, std::numeric_limits<unsigned>::max()}) APPEND(min_aspect);
261- if (info.max_aspect() != miral::WindowInfo::AspectRatio{std::numeric_limits<unsigned>::max(), 0U}) APPEND(max_aspect);
262+ if (info.min_width() != miral::default_min_width) APPEND(min_width);
263+ if (info.min_height() != miral::default_min_height) APPEND(min_height);
264+ if (info.max_width() != miral::default_max_width) APPEND(max_width);
265+ if (info.max_height() != miral::default_max_height) APPEND(max_height);
266+ if (info.width_inc() != miral::default_width_inc) APPEND(width_inc);
267+ if (info.height_inc() != miral::default_height_inc) APPEND(height_inc);
268+ if (info.min_aspect() != miral::default_min_aspect_ratio) APPEND(min_aspect);
269+ if (info.max_aspect() != miral::default_max_aspect_ratio) APPEND(max_aspect);
270 APPEND(preferred_orientation);
271 APPEND(confine_pointer);
272
273
274=== modified file 'test/CMakeLists.txt'
275--- test/CMakeLists.txt 2017-04-11 11:17:34 +0000
276+++ test/CMakeLists.txt 2017-09-15 13:33:35 +0000
277@@ -55,6 +55,7 @@
278 window_id.cpp
279 runner.cpp
280 select_active_window.cpp
281+ window_info.cpp
282 window_placement.cpp
283 window_placement_anchors_to_parent.cpp
284 window_placement_client_api.cpp
285
286=== added file 'test/window_info.cpp'
287--- test/window_info.cpp 1970-01-01 00:00:00 +0000
288+++ test/window_info.cpp 2017-09-15 13:33:35 +0000
289@@ -0,0 +1,61 @@
290+/*
291+ * Copyright © 2017 Canonical Ltd.
292+ *
293+ * This program is free software: you can redistribute it and/or modify it
294+ * under the terms of the GNU General Public License version 2 or 3 as
295+ * published by the Free Software Foundation.
296+ *
297+ * This program is distributed in the hope that it will be useful,
298+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
299+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
300+ * GNU General Public License for more details.
301+ *
302+ * You should have received a copy of the GNU General Public License
303+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
304+ *
305+ * Authored by: Brandon Schaefer <brandon.schaefer@canonical.com>
306+ */
307+
308+#include <miral/window_info.h>
309+
310+#include "mir_test_framework/process.h"
311+
312+#include <gtest/gtest.h>
313+#include <gmock/gmock.h>
314+
315+using namespace miral;
316+namespace mtf = mir_test_framework;
317+
318+namespace
319+{
320+static int a_successful_exit_function()
321+{
322+ return EXIT_SUCCESS;
323+}
324+}
325+
326+// Test for crash http://paste.ubuntu.com/25523431/
327+TEST(WindowInfo, negative_window_size_does_not_divide_by_zero)
328+{
329+ auto p = mtf::fork_and_run_in_a_different_process(
330+ [] {
331+ Window window;
332+ WindowSpecification params;
333+
334+ Point p{0, 0};
335+ Size s{-300, -300};
336+
337+ params.name() = "";
338+ params.top_left() = p;
339+ params.size() = s;
340+
341+ WindowInfo info(window, params);
342+
343+ info.min_width(s.width);
344+ info.min_height(s.height);
345+
346+ info.constrain_resize(p, s);
347+ }, a_successful_exit_function);
348+
349+ EXPECT_TRUE(p->wait_for_termination().succeeded());
350+}

Subscribers

People subscribed via source and target branches