Merge lp:~alan-griffiths/mir/first-pass-of-surface-spec-modification into lp:mir
- first-pass-of-surface-spec-modification
- Merge into development-branch
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Alan Griffiths | ||||||||
Approved revision: | no longer in the source branch. | ||||||||
Merged at revision: | 2484 | ||||||||
Proposed branch: | lp:~alan-griffiths/mir/first-pass-of-surface-spec-modification | ||||||||
Merge into: | lp:mir | ||||||||
Prerequisite: | lp:~alan-griffiths/mir/some-surface-modification-infrastructure | ||||||||
Diff against target: |
397 lines (+184/-56) 9 files modified
include/client/mir_toolkit/mir_surface.h (+23/-3) src/client/mir_surface.cpp (+1/-2) src/client/mir_surface.h (+1/-3) src/client/mir_surface_api.cpp (+41/-40) src/client/symbols.map (+2/-0) src/server/shell/canonical_window_manager.cpp (+36/-5) src/server/shell/canonical_window_manager.h (+7/-0) tests/acceptance-tests/test_client_surfaces.cpp (+3/-3) tests/acceptance-tests/test_surface_modifications.cpp (+70/-0) |
||||||||
To merge this branch: | bzr merge lp:~alan-griffiths/mir/first-pass-of-surface-spec-modification | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Carr (community) | Approve | ||
Kevin DuBois (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Thomas Voß (community) | Approve | ||
Alexandros Frantzis (community) | Approve | ||
Alberto Aguirre (community) | Approve | ||
Alan Griffiths | Abstain | ||
Chris Halse Rogers | Approve | ||
Review via email: mp+255707@code.launchpad.net |
Commit message
client API, shell: start exposing the surface spec modification functionality
Description of the change
client API, shell: start exposing the surface spec modification functionality
PS Jenkins bot (ps-jenkins) wrote : | # |
Chris Halse Rogers (raof) wrote : | # |
This looks mostly sensible, but does mean that we need a separate API for introspecting the state of surfaces. IIRC the longer-term plan was to move all the surface introspection into MirSurfaceSpec accessors and deprecate things such as MirSurfaceParam
That said, now that I think of it some more, I think being able to get a SurfaceSpec from an existing surface and apply it would probably a misfeature, as the possibility for clients to accidentally override user changes would be high.
Hm. If we need to support morphing from different surface types - dialog to normal, for example - we'll need to have a mir_surface_
I'm not sure what I think about this. On the one hand, it might be nice to not have the same type for both. On the other, that's obvious duplication. I guess I lean towards the former; one type with perhaps surprising behaviour.
17 +mir_connection
Why does this take a MirConnection? It's not used for anything, and it doesn't seem likely that it'll be used for anything in the future.
Chris Halse Rogers (raof) wrote : | # |
I guess that's “needs discussion” ☺
Alan Griffiths (alan-griffiths) wrote : | # |
*Needs Discussion*
> This looks mostly sensible, but does mean that we need a separate API for
> introspecting the state of surfaces. IIRC the longer-term plan was to move all
> the surface introspection into MirSurfaceSpec accessors and deprecate things
> such as MirSurfaceParam
While I'm not strongly against it I'm not sure there is currently such a plan. The client trying to use the "existing state" with a surface specification leads to synchronization issues. Like this:
> That said, now that I think of it some more, I think being able to get a
> SurfaceSpec from an existing surface and apply it would probably a misfeature,
> as the possibility for clients to accidentally override user changes would be
> high.
~~~~
> Hm. If we need to support morphing from different surface types - dialog to
> normal, for example - we'll need to have a mir_surface_
> will be somewhat redundant with the mir_connection_
> of functions. A client would be able to mir_create_
> all the same details as mir_connection_
> pass it to mir_surface_
> an abort(), because the MirConnection isn't set.
>
> I'm not sure what I think about this. On the one hand, it might be nice to not
> have the same type for both. On the other, that's obvious duplication. I guess
> I lean towards the former; one type with perhaps surprising behaviour.
Well, while MirSurfaceSpec isn't currently polymorphic the various mir_surface_
For example, mir_surface_
Alternatively, we could just constrain the state of MirSurfaceSpec in the functions that accept it and use the various mir_connection_
> 17 +mir_connection
> Why does this take a MirConnection? It's not used for anything, and it doesn't
> seem likely that it'll be used for anything in the future.
Initially it was for consistency, but given the points you raise above we could use it to initialize MirSurfaceSpec:
Although, if we decide on that approach this function should probably be renamed mir_connection_
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2480
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Kevin DuBois (kdub) wrote : | # |
nits:
93 namespace { // Private for now. TODO: Finalize and publish later (LP: #1422522)
comment needs removal
46 +
47 +
extra whitespace
57 +MirSurfaceSpec
could we just remove this, and keep MirSurfaceSpec() = default?
Kevin DuBois (kdub) wrote : | # |
As for the API changes, I'm all for publishing some sort of surface-changing functions (with a slightly different way proposed in the rfc-branch https:/
My points here:
After I call mir_surface_
This also leads to the topic of guaranteeing that the surface is in a particular state while the client decides what to do with the surface next. Like, it seems sensible that we have to lock the surface state, and then apply all the changes at once, and then 'unlock' the surface for further server-started changes.
It also seems that just rejecting change-specs the server doesn't like will lead to a somewhat frustrating back-and-forth for the clients trying to apply the change they want and then being told for non-obvious reasons that the change that was requested was rejected.
Alan Griffiths (alan-griffiths) wrote : | # |
> nits:
> 93 namespace { // Private for now. TODO: Finalize and publish later (LP:
> #1422522)
> comment needs removal
Done
>
> 46 +
> 47 +
> extra whitespace
Done
> 57 +MirSurfaceSpec
> could we just remove this, and keep MirSurfaceSpec() = default?
We could, but there's no advantage to having it inline (and it might change as result of discussion).
Alan Griffiths (alan-griffiths) wrote : | # |
> As for the API changes, I'm all for publishing some sort of surface-changing
> functions (with a slightly different way proposed in the rfc-branch
> https:/
But isn't that now about arranging buffer streams within a surface, and not to do with modifying the surface.
> My points here:
> After I call mir_surface_
> with the surface. It makes more sense (to me at least) to query the surface,
> where MirSurfaceSpec "lives", for the existing specification of the surface.
I don't think the MirSurfaceSpec is associated with a surface. If I were to call mir_surface_
> This also leads to the topic of guaranteeing that the surface is in a
> particular state while the client decides what to do with the surface next.
> Like, it seems sensible that we have to lock the surface state, and then apply
> all the changes at once, and then 'unlock' the surface for further server-
> started changes.
Clients cannot reasonably "lock" the state of the surface - the window manager needs to respond to user input, display changes etc.
> It also seems that just rejecting change-specs the server doesn't like will
> lead to a somewhat frustrating back-and-forth for the clients trying to apply
> the change they want and then being told for non-obvious reasons that the
> change that was requested was rejected.
There is no way for a client to get a meaningful response to a change spec request. It is "fire and forget". There will likely be corresponding events from the server - but even if the request is honored in full the surface may never be in the requested state because of concurrent changes by (e.g.) the user.
Alan Griffiths (alan-griffiths) wrote : | # |
> There is no way for a client to get a meaningful response to a change spec
> request. It is "fire and forget". There will likely be corresponding events
> from the server - but even if the request is honored in full the surface may
> never be in the requested state because of concurrent changes by (e.g.) the
> user.
This was discussed to death in lp:~vanvugt/mir/wait-result/+merge/252403
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2482
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
Another thought is that we don't necessarily need mir_surface_
We could, for example, do this:
void morph_to_
{
auto const spec = mir_connection_
mir_
mir_
}
This way we avoid the complexity of managing the required parameters for the new type.
The "con" is that it is then difficult to "inherit" parameters from the existing surface.
But this is not a problem with the current MP - we can still chose several options building upon it.
Alberto Aguirre (albaguirre) wrote : | # |
I think this MP is reasonable.
I don't think a mir_surface_
I know that would require passing width/height/
In any case this MP looks ok to me.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2484
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Kevin DuBois (kdub) wrote : | # |
nits fixed, unblocking while I think more about the observations in my above comment.
Chris Halse Rogers (raof) wrote : | # |
I'm conceptually happy with this.
I was thinking that we needed a surface-
For the specific case of Kevin's MirBufferStream bypass work, the introspection API is only necessary to ease testing - clients are perfectly capable of maintaining their own stacking and positioning state.
I'm in favour of doing the mir_connection_
With that, I don't mind the useless MirConnection parameter to spec_for_changes :).
Why does mir_surface_
Alan Griffiths (alan-griffiths) wrote : | # |
*Needs Discussion*
> Why does mir_surface_
> mind it doing so, but as (extensively!) discussed, there's nothing useful a
> client can do with it.
I agree it is useless. But it is consistent with the other APIs we discussed. Is it better to be inconsistent and return void now? Or to plan on removing the wait handle in all similar APIs when we next break ABI compatibility?
Alberto Aguirre (albaguirre) wrote : | # |
I would vote for just returning void, but it's not a blocking issue.
Alan Griffiths (alan-griffiths) wrote : | # |
> I would vote for just returning void, but it's not a blocking issue.
Let's do it then
Alberto Aguirre (albaguirre) : | # |
Robert Carr (robertcarr) wrote : | # |
146 and 153
+void mir_surface_
+...set_name...
Should catch exceptions right?
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2486
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Kevin DuBois (kdub) wrote : | # |
So, I'm okay with this approach, as opposed to some sort of "lock" guarantee, as that seems to raise all sorts of questions about what a 'locked' surface might mean.
The wait handle seemed useless too, so also okay with its removal.
Chris's point that the nested stuff (or other clients) can maintain some of their own info is a good one. I'm not sure though that we explain well what changing a surface spec means... It makes sense to me to say that "when the title name is set to "X" on the MirSurfaceSpec, it will be presented as "X" when the server chooses to show a title", as opposed to saying "when the title name is set to "X" on the MirSurfaceSpec, it can be silently rejected"
needs-info:
1) Shouldn't this take a MirSurfaceSpec* instead of of a MirSurface*?
31 +void mir_surface_
2) Is it (or will it be) possible to construct a MirSurfaceSpec that's invalid? For instance, if we have a mir_surface_
Alan Griffiths (alan-griffiths) wrote : | # |
> needs-info:
> 1) Shouldn't this take a MirSurfaceSpec* instead of of a MirSurface*?
> 31 +void mir_surface_
No, this is a signature change (dropping the wait handle) to an existing method that's a "convenience wrapper" around the MirSurfaceSpec calls needed to change a surface title. (C.f. lp:~vanvugt/mir/rename-api/+merge/252864/comments/628924.)
> 2) Is it (or will it be) possible to construct a MirSurfaceSpec that's
> invalid? For instance, if we have a mir_surface_
> y), and someone tries to morph a tooltip to a tooltip that spans multiple
> monitors that seems to violate the meaning of the types in the spec document.
> It might make sense to indicate to the client that its request was "flat-out
> rejected forever", instead of "accepted as something that the server will try
> to apply when appropriate".
That's a poor example of a MirSurfaceSpec that's invalid: How is that any different from the existing scenario of a "someone" requesting a tooltip that spans multiple monitors without a modification? The server knows what monitors are attached at the time it processes the request (and what "shell space" exists on the monitors) and sizes the surface accordingly.
A better example would be creating a MirSurfaceSpec for changes and then calling mir_surface_
Alan Griffiths (alan-griffiths) wrote : | # |
> 146 and 153
> +void mir_surface_
> +...set_name...
>
> Should catch exceptions right?
Fixed
Alexandros Frantzis (afrantzis) wrote : | # |
Looks sensible.
31 +void mir_surface_
Now that we have a way to perform the same task with a more general mechanism, I am not convinced that we should keep mir_surface_
Thomas Voß (thomas-voss) wrote : | # |
LGTM, two remarks inline, though.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2488
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) : | # |
Kevin DuBois (kdub) wrote : | # |
@Alan, I see now that its just a convenience wrapper, so okay with the signature.
resolved the second point on IRC, my assumption that there were invalid change MirSurfaceSpecs isn't part of the intended model.
okay by me, and can port base the rfc branch I have up on this one
Preview Diff
1 | === modified file 'include/client/mir_toolkit/mir_surface.h' |
2 | --- include/client/mir_toolkit/mir_surface.h 2015-04-09 06:20:31 +0000 |
3 | +++ include/client/mir_toolkit/mir_surface.h 2015-04-14 08:39:35 +0000 |
4 | @@ -168,6 +168,18 @@ |
5 | MirPixelFormat format); |
6 | |
7 | /** |
8 | + * Create a surface specification for updating a surface. |
9 | + * |
10 | + * This can be applied to one or more target surfaces using |
11 | + * mir_surface_apply_spec(...). |
12 | + * |
13 | + * \param [in] connection a valid mir connection |
14 | + * |
15 | + */ |
16 | +MirSurfaceSpec* |
17 | +mir_connection_create_spec_for_changes(MirConnection* connection); |
18 | + |
19 | +/** |
20 | * Create a surface from a given specification |
21 | * |
22 | * |
23 | @@ -577,9 +589,17 @@ |
24 | * Change the title (name) of a surface. |
25 | * \param [in] surface The surface to rename |
26 | * \param [in] name The new name |
27 | - * \returns When the change has completed |
28 | - */ |
29 | -MirWaitHandle* mir_surface_set_title(MirSurface* surf, char const* name); |
30 | + */ |
31 | +void mir_surface_set_title(MirSurface* surface, char const* name); |
32 | + |
33 | +/** |
34 | + * Request changes to the specification of a surface. The server will decide |
35 | + * whether and how the request can be honoured. |
36 | + * |
37 | + * \param [in] surface The surface to rename |
38 | + * \param [in] spec Spec with the requested changes applied |
39 | + */ |
40 | +void mir_surface_apply_spec(MirSurface* surface, MirSurfaceSpec* spec); |
41 | |
42 | #ifdef __cplusplus |
43 | } |
44 | |
45 | === modified file 'src/client/mir_surface.cpp' |
46 | --- src/client/mir_surface.cpp 2015-04-13 12:07:15 +0000 |
47 | +++ src/client/mir_surface.cpp 2015-04-14 08:39:35 +0000 |
48 | @@ -74,9 +74,8 @@ |
49 | } |
50 | } |
51 | |
52 | -MirSurfaceSpec::MirSurfaceSpec(MirSurface* preexisting) |
53 | +MirSurfaceSpec::MirSurfaceSpec() |
54 | { |
55 | - self = preexisting; |
56 | } |
57 | |
58 | mir::protobuf::SurfaceParameters MirSurfaceSpec::serialize() const |
59 | |
60 | === modified file 'src/client/mir_surface.h' |
61 | --- src/client/mir_surface.h 2015-04-09 14:29:02 +0000 |
62 | +++ src/client/mir_surface.h 2015-04-14 08:39:35 +0000 |
63 | @@ -61,10 +61,9 @@ |
64 | |
65 | struct MirSurfaceSpec |
66 | { |
67 | - MirSurfaceSpec() = default; |
68 | + MirSurfaceSpec(); |
69 | MirSurfaceSpec(MirConnection* connection, int width, int height, MirPixelFormat format); |
70 | MirSurfaceSpec(MirConnection* connection, MirSurfaceParameters const& params); |
71 | - MirSurfaceSpec(MirSurface* preexisting); |
72 | |
73 | mir::protobuf::SurfaceParameters serialize() const; |
74 | |
75 | @@ -84,7 +83,6 @@ |
76 | mir::optional_value<MirSurfaceState> state; |
77 | mir::optional_value<MirOrientationMode> pref_orientation; |
78 | |
79 | - mir::optional_value<MirSurface*> self; |
80 | mir::optional_value<MirSurface*> parent; |
81 | mir::optional_value<MirRectangle> aux_rect; |
82 | mir::optional_value<MirEdgeAttachment> edge_attachment; |
83 | |
84 | === modified file 'src/client/mir_surface_api.cpp' |
85 | --- src/client/mir_surface_api.cpp 2015-04-10 16:50:12 +0000 |
86 | +++ src/client/mir_surface_api.cpp 2015-04-14 08:39:35 +0000 |
87 | @@ -583,44 +583,45 @@ |
88 | return nullptr; |
89 | } |
90 | |
91 | -namespace { // Private for now. TODO: Finalize and publish later (LP: #1422522) |
92 | - |
93 | -MirSurfaceSpec* mir_surface_begin_changes(MirSurface* surf) |
94 | -{ |
95 | - mir::require(mir_surface_is_valid(surf)); |
96 | - |
97 | - MirSurfaceSpec* spec = nullptr; |
98 | - try |
99 | - { |
100 | - spec = new MirSurfaceSpec(surf); |
101 | - } |
102 | - catch (std::exception const& ex) |
103 | - { |
104 | - MIR_LOG_UNCAUGHT_EXCEPTION(ex); |
105 | - } |
106 | - |
107 | - return spec; |
108 | -} |
109 | - |
110 | -MirWaitHandle* mir_surface_spec_commit_changes(MirSurfaceSpec* spec) |
111 | -{ |
112 | - if (!spec->self.is_set()) |
113 | - return nullptr; |
114 | - |
115 | - auto surface = spec->self.value(); |
116 | - return surface->modify(*spec); |
117 | -} |
118 | - |
119 | -} // Private namespace. TODO: finalize morphing API and publish. |
120 | - |
121 | -MirWaitHandle* mir_surface_set_title(MirSurface* surf, char const* name) |
122 | -{ |
123 | - MirWaitHandle* result = nullptr; |
124 | - if (auto spec = mir_surface_begin_changes(surf)) |
125 | - { |
126 | - mir_surface_spec_set_name(spec, name); |
127 | - result = mir_surface_spec_commit_changes(spec); |
128 | - mir_surface_spec_release(spec); |
129 | - } |
130 | - return result; |
131 | +namespace |
132 | +{ |
133 | +MirSurfaceSpec* create_spec_for_changes() |
134 | +try |
135 | +{ |
136 | + return new MirSurfaceSpec{}; |
137 | +} |
138 | +catch (std::exception const& ex) |
139 | +{ |
140 | + MIR_LOG_UNCAUGHT_EXCEPTION(ex); |
141 | + std::abort(); // If we just failed to allocate a MirSurfaceSpec returning isn't safe |
142 | +} |
143 | +} |
144 | + |
145 | +MirSurfaceSpec* mir_connection_create_spec_for_changes(MirConnection* connection) |
146 | +{ |
147 | + mir::require(mir_connection_is_valid(connection)); |
148 | + |
149 | + return create_spec_for_changes(); |
150 | +} |
151 | + |
152 | +void mir_surface_apply_spec(MirSurface* surface, MirSurfaceSpec* spec) |
153 | +try |
154 | +{ |
155 | + mir::require(mir_surface_is_valid(surface)); |
156 | + mir::require(spec); |
157 | + |
158 | + surface->modify(*spec); |
159 | +} |
160 | +catch (std::exception const& ex) |
161 | +{ |
162 | + MIR_LOG_UNCAUGHT_EXCEPTION(ex); |
163 | + // Keep calm and carry on |
164 | +} |
165 | + |
166 | +void mir_surface_set_title(MirSurface* surface, char const* name) |
167 | +{ |
168 | + auto const spec = create_spec_for_changes(); |
169 | + mir_surface_spec_set_name(spec, name); |
170 | + mir_surface_apply_spec(surface, spec); |
171 | + mir_surface_spec_release(spec); |
172 | } |
173 | |
174 | === modified file 'src/client/symbols.map' |
175 | --- src/client/symbols.map 2015-04-09 06:20:31 +0000 |
176 | +++ src/client/symbols.map 2015-04-14 08:39:35 +0000 |
177 | @@ -113,6 +113,8 @@ |
178 | |
179 | MIR_CLIENT_8.4 { # New in Mir 0.13 |
180 | global: |
181 | + mir_connection_create_spec_for_changes; |
182 | + mir_surface_apply_spec; |
183 | mir_surface_set_event_handler; |
184 | mir_surface_set_title; |
185 | mir_default_cursor_name; |
186 | |
187 | === modified file 'src/server/shell/canonical_window_manager.cpp' |
188 | --- src/server/shell/canonical_window_manager.cpp 2015-04-09 06:20:31 +0000 |
189 | +++ src/server/shell/canonical_window_manager.cpp 2015-04-14 08:39:35 +0000 |
190 | @@ -248,6 +248,26 @@ |
191 | { |
192 | if (modifications.name.is_set()) |
193 | surface->rename(modifications.name.value()); |
194 | + |
195 | + if (modifications.width.is_set() || modifications.height.is_set()) |
196 | + { |
197 | + // TODO similar logic is needed in example window management policies |
198 | + auto new_size = surface->size(); |
199 | + |
200 | + if (modifications.width.is_set()) |
201 | + new_size.width = modifications.width.value(); |
202 | + |
203 | + if (modifications.height.is_set()) |
204 | + new_size.height = modifications.height.value(); |
205 | + |
206 | + constrained_resize( |
207 | + surface, |
208 | + surface->top_left(), |
209 | + new_size, |
210 | + false, |
211 | + false, |
212 | + display_area); |
213 | + } |
214 | } |
215 | |
216 | void msh::CanonicalWindowManagerPolicy::handle_delete_surface(std::shared_ptr<ms::Session> const& session, std::weak_ptr<ms::Surface> const& surface) |
217 | @@ -577,6 +597,17 @@ |
218 | |
219 | Point new_pos = top_left + left_resize*delta.dx + top_resize*delta.dy; |
220 | |
221 | + return constrained_resize(surface, new_pos, new_size, left_resize, top_resize, bounds); |
222 | +} |
223 | + |
224 | +bool msh::CanonicalWindowManagerPolicy::constrained_resize( |
225 | + std::shared_ptr<ms::Surface> const& surface, |
226 | + Point new_pos, |
227 | + Size new_size, |
228 | + bool const left_resize, |
229 | + bool const top_resize, |
230 | + Rectangle const& bounds) |
231 | +{ |
232 | if (left_resize) |
233 | { |
234 | if (new_pos.x < bounds.top_left.x) |
235 | @@ -615,15 +646,15 @@ |
236 | // "A vertically maximised surface is anchored to the top and bottom of |
237 | // the available workspace and can have any width." |
238 | case mir_surface_state_vertmaximized: |
239 | - new_pos.y = old_pos.top_left.y; |
240 | - new_size.height = old_pos.size.height; |
241 | + new_pos.y = surface->top_left().y; |
242 | + new_size.height = surface->size().height; |
243 | break; |
244 | |
245 | // "A horizontally maximised surface is anchored to the left and right of |
246 | // the available workspace and can have any height" |
247 | case mir_surface_state_horizmaximized: |
248 | - new_pos.x = old_pos.top_left.x; |
249 | - new_size.width = old_pos.size.width; |
250 | + new_pos.x = surface->top_left().x; |
251 | + new_size.width = surface->size().width; |
252 | break; |
253 | |
254 | // "A maximised surface is anchored to the top, bottom, left and right of the |
255 | @@ -639,7 +670,7 @@ |
256 | // TODO It is rather simplistic to move a tree WRT the top_left of the root |
257 | // TODO when resizing. But for more sophistication we would need to encode |
258 | // TODO some sensible layout rules. |
259 | - move_tree(surface, new_pos-top_left); |
260 | + move_tree(surface, new_pos-surface->top_left()); |
261 | |
262 | return true; |
263 | } |
264 | |
265 | === modified file 'src/server/shell/canonical_window_manager.h' |
266 | --- src/server/shell/canonical_window_manager.h 2015-04-09 06:20:31 +0000 |
267 | +++ src/server/shell/canonical_window_manager.h 2015-04-14 08:39:35 +0000 |
268 | @@ -119,6 +119,13 @@ |
269 | bool drag(std::shared_ptr<scene::Surface> surface, geometry::Point to, geometry::Point from, geometry::Rectangle bounds); |
270 | void move_tree(std::shared_ptr<scene::Surface> const& root, geometry::Displacement movement) const; |
271 | void raise_tree(std::shared_ptr<scene::Surface> const& root) const; |
272 | + bool constrained_resize( |
273 | + std::shared_ptr<scene::Surface> const& surface, |
274 | + geometry::Point new_pos, |
275 | + geometry::Size new_size, |
276 | + const bool left_resize, |
277 | + const bool top_resize, |
278 | + geometry::Rectangle const& bounds); |
279 | |
280 | Tools* const tools; |
281 | std::shared_ptr<DisplayLayout> const display_layout; |
282 | |
283 | === modified file 'tests/acceptance-tests/test_client_surfaces.cpp' |
284 | --- tests/acceptance-tests/test_client_surfaces.cpp 2015-04-09 06:20:31 +0000 |
285 | +++ tests/acceptance-tests/test_client_surfaces.cpp 2015-04-14 08:39:35 +0000 |
286 | @@ -314,9 +314,9 @@ |
287 | * |
288 | * At least verify the rename completes without blocking... |
289 | */ |
290 | - mir_wait_for_one(mir_surface_set_title(surf, "New Name")); |
291 | - mir_wait_for_one(mir_surface_set_title(surf, "")); |
292 | - mir_wait_for_one(mir_surface_set_title(surf, "Alice")); |
293 | + mir_surface_set_title(surf, "New Name"); |
294 | + mir_surface_set_title(surf, ""); |
295 | + mir_surface_set_title(surf, "Alice"); |
296 | |
297 | mir_surface_release_sync(surf); |
298 | } |
299 | |
300 | === modified file 'tests/acceptance-tests/test_surface_modifications.cpp' |
301 | --- tests/acceptance-tests/test_surface_modifications.cpp 2015-04-02 12:57:34 +0000 |
302 | +++ tests/acceptance-tests/test_surface_modifications.cpp 2015-04-14 08:39:35 +0000 |
303 | @@ -31,6 +31,7 @@ |
304 | namespace msh = mir::shell; |
305 | namespace mt = mir::test; |
306 | |
307 | +using namespace mir::geometry; |
308 | using namespace testing; |
309 | |
310 | namespace |
311 | @@ -39,6 +40,7 @@ |
312 | { |
313 | public: |
314 | MOCK_METHOD1(renamed, void(char const*)); |
315 | + MOCK_METHOD1(resized_to, void(Size const& size)); |
316 | }; |
317 | |
318 | struct StubShell : msh::ShellWrapper |
319 | @@ -80,6 +82,17 @@ |
320 | |
321 | MockSurfaceObserver surface_observer; |
322 | }; |
323 | + |
324 | +MATCHER_P(WidthEq, value, "") |
325 | +{ |
326 | + return Width(value) == arg.width; |
327 | +} |
328 | + |
329 | +MATCHER_P(HeightEq, value, "") |
330 | +{ |
331 | + return Height(value) == arg.height; |
332 | +} |
333 | + |
334 | } |
335 | |
336 | TEST_F(SurfaceModifications, rename_is_notified) |
337 | @@ -90,3 +103,60 @@ |
338 | |
339 | mir_surface_set_title(surface, new_title); |
340 | } |
341 | + |
342 | +TEST_F(SurfaceModifications, surface_spec_name_is_notified) |
343 | +{ |
344 | + auto const new_title = __PRETTY_FUNCTION__; |
345 | + |
346 | + EXPECT_CALL(surface_observer, renamed(StrEq(new_title))); |
347 | + |
348 | + auto const spec = mir_connection_create_spec_for_changes(connection); |
349 | + |
350 | + mir_surface_spec_set_name(spec, new_title); |
351 | + mir_surface_apply_spec(surface, spec); |
352 | + mir_surface_spec_release(spec); |
353 | +} |
354 | + |
355 | +TEST_F(SurfaceModifications, surface_spec_resize_is_notified) |
356 | +{ |
357 | + auto const new_width = 5; |
358 | + auto const new_height = 7; |
359 | + |
360 | + EXPECT_CALL(surface_observer, resized_to(Size{new_width, new_height})); |
361 | + |
362 | + auto const spec = mir_connection_create_spec_for_changes(connection); |
363 | + |
364 | + mir_surface_spec_set_width(spec, new_width); |
365 | + mir_surface_spec_set_height(spec, new_height); |
366 | + |
367 | + mir_surface_apply_spec(surface, spec); |
368 | + mir_surface_spec_release(spec); |
369 | +} |
370 | + |
371 | +TEST_F(SurfaceModifications, surface_spec_change_width_is_notified) |
372 | +{ |
373 | + auto const new_width = 11; |
374 | + |
375 | + EXPECT_CALL(surface_observer, resized_to(WidthEq(new_width))); |
376 | + |
377 | + auto const spec = mir_connection_create_spec_for_changes(connection); |
378 | + |
379 | + mir_surface_spec_set_width(spec, new_width); |
380 | + |
381 | + mir_surface_apply_spec(surface, spec); |
382 | + mir_surface_spec_release(spec); |
383 | +} |
384 | + |
385 | +TEST_F(SurfaceModifications, surface_spec_change_height_is_notified) |
386 | +{ |
387 | + auto const new_height = 13; |
388 | + |
389 | + EXPECT_CALL(surface_observer, resized_to(HeightEq(new_height))); |
390 | + |
391 | + auto const spec = mir_connection_create_spec_for_changes(connection); |
392 | + |
393 | + mir_surface_spec_set_height(spec, new_height); |
394 | + |
395 | + mir_surface_apply_spec(surface, spec); |
396 | + mir_surface_spec_release(spec); |
397 | +} |
PASSED: Continuous integration, rev:2478 jenkins. qa.ubuntu. com/job/ mir-ci/ 3488/ jenkins. qa.ubuntu. com/job/ mir-android- vivid-i386- build/2008 jenkins. qa.ubuntu. com/job/ mir-clang- vivid-amd64- build/2007 jenkins. qa.ubuntu. com/job/ mir-mediumtests -vivid- touch/1958 jenkins. qa.ubuntu. com/job/ mir-vivid- amd64-ci/ 1485 jenkins. qa.ubuntu. com/job/ mir-vivid- amd64-ci/ 1485/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- vivid-armhf/ 1958 jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- vivid-armhf/ 1958/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-mediumtests -runner- mako/4894 s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 19520
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mir- ci/3488/ rebuild
http://