Merge lp:~albaguirre/mir/add-menu-api into lp:mir
| Status: | Merged |
|---|---|
| Approved by: | Chris Halse Rogers on 2015-01-13 |
| Approved revision: | 2167 |
| Merged at revision: | 2219 |
| Proposed branch: | lp:~albaguirre/mir/add-menu-api |
| Merge into: | lp:mir |
| Prerequisite: | lp:~albaguirre/mir/pref-orientation-at-create-time |
| Diff against target: |
479 lines (+190/-46) 17 files modified
client-ABI-sha1sums (+2/-2) common-ABI-sha1sums (+1/-1) include/client/mir_toolkit/mir_surface.h (+34/-0) include/common/mir_toolkit/common.h (+7/-0) include/server/mir/scene/surface_creation_parameters.h (+6/-0) platform-ABI-sha1sums (+1/-1) server-ABI-sha1sums (+2/-2) src/client/mir_surface.cpp (+8/-0) src/client/mir_surface.h (+2/-0) src/client/mir_surface_api.cpp (+19/-0) src/client/symbols.map (+5/-1) src/include/common/mir/require.h (+0/-32) src/protobuf/mir_protobuf.proto (+3/-0) src/server/frontend/session_mediator.cpp (+11/-0) src/server/scene/surface_creation_parameters.cpp (+12/-0) tests/acceptance-tests/test_client_surfaces.cpp (+22/-2) tests/integration-tests/client/test_mirsurface.cpp (+55/-5) |
| To merge this branch: | bzr merge lp:~albaguirre/mir/add-menu-api |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Chris Halse Rogers | Approve on 2015-01-13 | ||
| PS Jenkins bot | continuous-integration | Approve on 2015-01-13 | |
| Alan Griffiths | Approve on 2015-01-12 | ||
| Robert Carr (community) | Approve on 2015-01-09 | ||
| Daniel van Vugt | 2014-12-12 | Abstain on 2014-12-18 | |
| Cemil Azizoglu (community) | Approve on 2014-12-15 | ||
|
Review via email:
|
|||
Commit Message
Add API to specify client menu surfaces (LP: #1324101)
Description of the Change
Add API to specify client menu surfaces
| PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2150
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
| Gerry Boland (gerboland) wrote : | # |
Weighing in as an external perspective, I must agree with Daniel. Having a method for each surface type will result in a huge number of methods. Plus if/when we change surface type names, we'll be carrying around the old names for some time.
We have an enum with surface types already. Why can't that be passed as a parameter to a mir_connection_
Also why pass parent, rect & format as arguments? Why not just ask for a surface type, be returned a MirSurfaceSpec, which then we can set parent,rect,format upon (if possible)
I ask because I expect we'll later want to specify extra properties when creating a surface, things like surface state (fullscreen/
So as opposed to adding more parameters to that function to set properties of MirSurfaceSpec, instead allow those properties to be set once we've got a MirSurfaceSpec.
| Gerry Boland (gerboland) wrote : | # |
https:/
The API design does makes sense, but I'm glad I'm not maintaining such an API. Objection withdrawn
| Alan Griffiths (alan-griffiths) wrote : | # |
53 + if (!mir_surface_
54 + if (!rect) abort();
I think we need mir::require(
| Alberto Aguirre (albaguirre) wrote : | # |
> 53 + if (!mir_surface_
> 54 + if (!rect) abort();
>
> I think we need mir::require(
> MIR_REQUIRE(
Done.
| Alberto Aguirre (albaguirre) wrote : | # |
> (1) Headers containing documentation that will be read by users as such should
> be wrapped within 80 columns so they display in users' terminals correctly:
> include/
>
> We don't impose this standard on our own internal code, but the public stuff
> needs to be more consumable.
Fixed - but we'll need to address the rest of the file as well.
| PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2153
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://
| Chris Halse Rogers (raof) wrote : | # |
I think we need to guarantee a bit more semantics to the client for this. Specifically, I think we want to guarantee a rectangle that the surface will share an edge with.
If you check out how GTK currently handles menus (for example, try GTK_MODULES= gnome-calculator) the mode menu pops up so that one of its edges is against the “mode” label. It would seem that this API is insufficiently expressive to support that?
Even if we don't want to guarantee that - maybe phone shells want to ignore that? - I think we need to support that.
Maybe the API needs to be something like:
mir_connection_
| Daniel van Vugt (vanvugt) wrote : | # |
Yes, this is the shell-specific semantics being baked into the client API I was warning about a while back :(
| Alberto Aguirre (albaguirre) wrote : | # |
> I think we need to guarantee a bit more semantics to the client for this.
> Specifically, I think we want to guarantee a rectangle that the surface will
> share an edge with.
>
> If you check out how GTK currently handles menus (for example, try
> GTK_MODULES= gnome-calculator) the mode menu pops up so that one of its edges
> is against the “mode” label. It would seem that this API is insufficiently
> expressive to support that?
>
> Even if we don't want to guarantee that - maybe phone shells want to ignore
> that? - I think we need to support that.
>
> Maybe the API needs to be something like:
> mir_connection_
> adjacency_rect, format)?
I don't understand what adjacency rect is supposed to represent, could you elaborate?
| Chris Halse Rogers (raof) wrote : | # |
Normal case:
+----------------+
| |
| Adjacency Rect |
| |
+----------------+
+------
| |
| |
| |
| |
| Valid menu placement |
| |
| |
| |
| |
+------
When the placing the menu there would make it partially offscreen, we have:
+------
| |
| |
| |
| Valid menu placement |
| |
| |
+------
+----------------+
| |
| Adjacency Rect |
| |
+----------------+
-------
| Chris Halse Rogers (raof) wrote : | # |
Boo. Launchpad messes up the ASCII art.
The adjacency rect is a rectangle that the menu shares an edge (and most commonly a corner) with.
Think of how menus are presented at the moment - there's a box around the text label, and the menu's top-left corner normally matches with the bottom-left corner of the label-box.
However, if this placement would leave the menu partially off-screen then the menu is displayed so that its bottom left-corner matches the top-left corner of the label-box.
If *that* would result in the menu being partially off-screen, then the menu is displayed so that it's bottom *edge* matches the top edge of the label-box.
Hm. Observing the behaviour, we also need an edge-affinity - context menus do right-edge/
| Alberto Aguirre (albaguirre) wrote : | # |
@Chris,
I see so adjacency rectangle is about the client hinting the four preferred corners.
On edge affinity - maybe:
enum EdgeDirection
{
none,
vertical,
horizontal
};
So the api would be something like
mir_connection_
| Robert Carr (robertcarr) wrote : | # |
This is strange but I would expect the c'tor arguments to be ordered otherwise:
create_
Feel free to ignore that :p
>>
>> + * \param [in] rect A rectangle that specifies four edges this surface
>> 49 + * can attach to depending on placement constraints in
>> 50 + * the server due to screen size or other requirements.
>> 51 + * The server is not guaranteed to create a surface at
>> 52 + * the requested location
"four edges this surface can attach to depending.
I think this might be hard to read if you don't know you are looking for a definition of an adjacency rectangle.
Maybe we can clarify it by introducing the adjacency term e.g. in the top level comment:
/**
39 + * Create a surface specification for a menu surface.
* Positioning of the surface may be specified with respect to the parent surface via an
* rectangle. The server will attempt to choose an edge of the adjacency rectangle on \
* which to place the surface (taking in to account screen-edge proximity
* and similar constraints)
Then:
>> + * \param [in] rect The adjacency rectangle.
| Robert Carr (robertcarr) wrote : | # |
I kind of think that SessionMediator should throw if for example adjacency rect is set and parent is not set. Maybe we already had this discussion and you convinced me otherwise though? Having trouble remembering but have some vague notion.
Any looks good please consider introducing the adjacency terminology though.
| PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2160
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://
| Chris Halse Rogers (raof) wrote : | # |
Tests have some
+ ASSERT_
this would be better with mir_test/
+ ASSERT_THAT(menu, IsValid())
(this gets you a helpful message when the assertion fails
What are the semantics of mir_edge_
I agree with Robert; having an adjacency rect set but not a parent or edge_attachment should throw from SessionMediator. As long as our client library isn't buggy it will never send such a message, but it's cheap and useful to check.
Hm. That actually suggests a MessageValidator type interface, dispatching based on surface_type. Probably not for this MP, though.
I also like Robert's rewording of the documentation comment (although I'd replace ‘may be specified’ with ‘is specified’).
I'm only blocking on “what does mir_edge_
| Daniel van Vugt (vanvugt) wrote : | # |
Attached bug 1324101. Note however that bug needs a solution for tooltips too. So if this lands, please keep the bug marked In Progress.
- 2161. By Alberto Aguirre on 2015-01-12
-
From none to any
- 2162. By Alberto Aguirre on 2015-01-12
-
update documentation
- 2163. By Alberto Aguirre on 2015-01-12
-
Use validity matchers
- 2164. By Alberto Aguirre on 2015-01-12
-
merge lp:mir
| Alberto Aguirre (albaguirre) wrote : | # |
> This is strange but I would expect the c'tor arguments to be ordered
> otherwise:
> create_
> height, format)
>
> Feel free to ignore that :p
>
I don't feel strongly one way or the other, but I thought I would make it consistent with mir_connection_
> I think this might be hard to read if you don't know you are looking for a
> definition of an adjacency rectangle.
>
> Maybe we can clarify it by introducing the adjacency term e.g. in the top
> level comment
Done.
| Alan Griffiths (alan-griffiths) wrote : | # |
358 + ASSERT_TRUE(spec != nullptr);
Could be ASSERT_THAT(spec, NotNull());
| Alberto Aguirre (albaguirre) wrote : | # |
> I kind of think that SessionMediator should throw if for example adjacency
> rect is set and parent is not set. Maybe we already had this discussion and
> you convinced me otherwise though? Having trouble remembering but have some
> vague notion.
>
I think that should be the responsibility of the implementation of session-
| Alan Griffiths (alan-griffiths) wrote : | # |
> > I kind of think that SessionMediator should throw if for example adjacency
> > rect is set and parent is not set. Maybe we already had this discussion and
> > you convinced me otherwise though? Having trouble remembering but have some
> > vague notion.
> >
> I think that should be the responsibility of the implementation of
> session-
> now possible since optional_values are used in SurfaceCreation
I agree it shouldn't be down to the frontend (i.e. SessionMediator) to impose window management rules like this.
I know it is before the time of many current team members but we originally envisaged an MVC arrangement where changes to the model (like creating a surface) would be routed through a controller (like a window manager) that is part of the shell and not go directly to the model (in this case the session).
Were we in that hypothetical world then the window manager would validate this policy.
- 2165. By Alberto Aguirre on 2015-01-12
-
Use ASSERT_THAT
| Robert Carr (robertcarr) wrote : | # |
>> I think that should be the responsibility of the implementation of session-
>> SurfaceCreation
Ah right :).
I guess I am still not 100% convinced, because I think of this as a sort of "protocol validation condition" which I view the session mediator as responsible for. Still...not particularly concerned :)
| Alberto Aguirre (albaguirre) wrote : | # |
> Tests have some
> + ASSERT_
> this would be better with mir_test/
> + ASSERT_THAT(menu, IsValid())
> (this gets you a helpful message when the assertion fails
>
>
Done.
> What are the semantics of mir_edge_
> makes sense?
Changed the name to any - meaning both horizonal and vertical edge attachment is ok.
| PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2165
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 2166. By Alberto Aguirre on 2015-01-12
-
update sha1sums
| Chris Halse Rogers (raof) wrote : | # |
Um, now mir_edge_
I think it should either be removed, or specified as equal to mir_edge_
@Alan:
> I know it is before the time of many current team members but we originally envisaged an MVC arrangement
> where changes to the model (like creating a surface) would be routed through a controller
> (like a window manager) that is part of the shell and not go directly to the model (in this case the session).
>
> Were we in that hypothetical world then the window manager would validate this policy.
Hm. Whereas I think this would be a part of the contract with the window manager - “when we ask you to create a window, we guarantee that it'll have all the mandatory information”. The client library needs to specify what the mandatory information is, because that's the only place where we can specify client semantics.
> Attached bug 1324101. Note however that bug needs a solution for tooltips too. So if this lands,
> please keep the bug marked In Progress.
This actually *is* a solution for tooltips - with a small adjacency rectangle and mir_edge_
But that reminds me - we need to specify the input semantics of these surfaces. Something like “the new surface has input focus, and will not lose input focus while it is alive and the topmost menu surface. Any tap¹ outside the bounds of the surface will result in the surface being immediately closed and receive a mir_surface_closed event. (Without that event being otherwise delivered?)”
We also need to specify what happens with stacked menus - something like “While a menu is alive, any request to create a menu surface that does *not* specify the existing menu as its parent will fail.”
It might be sensible to require the parent of a new menu to have focus, or the request fail?
¹: This needs to be better defined.
| PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2166
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://
- 2167. By Alberto Aguirre on 2015-01-13
-
Change mir_edge_
attachment_ any to be bitmask combination
| PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2167
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://
| Alberto Aguirre (albaguirre) wrote : | # |
> Um, now mir_edge_
> mir_edge_
>
> I think it should either be removed, or specified as equal to
> mir_edge_
> towards the latter.
>
Fixed.
> @Alan:
> > I know it is before the time of many current team members but we originally
> envisaged an MVC arrangement
> > where changes to the model (like creating a surface) would be routed through
> a controller
> > (like a window manager) that is part of the shell and not go directly to the
> model (in this case the session).
> >
> > Were we in that hypothetical world then the window manager would validate
> this policy.
>
> Hm. Whereas I think this would be a part of the contract with the window
> manager - “when we ask you to create a window, we guarantee that it'll have
> all the mandatory information”. The client library needs to specify what the
> mandatory information is, because that's the only place where we can specify
> client semantics.
Sure, but we are talking about malformed requests, which need to be validated by something. That something for me is not the frontend as that would couple knowledge of window management semantics (The implementation of the window management policy is the one that knows what combination of arguments are correct for a surface type for example).
> But that reminds me - we need to specify the input semantics of these
> surfaces. Something like “the new surface has input focus, and will not lose
> input focus while it is alive and the topmost menu surface. Any tap¹ outside
> the bounds of the surface will result in the surface being immediately closed
> and receive a mir_surface_closed event. (Without that event being otherwise
> delivered?)”
>
> We also need to specify what happens with stacked menus - something like
> “While a menu is alive, any request to create a menu surface that does *not*
> specify the existing menu as its parent will fail.”
>
> It might be sensible to require the parent of a new menu to have focus, or the
> request fail?
>
> ¹: This needs to be better defined.
Yes we need the details on focusing semantics, but I think that goes in hand with the window management story on the server side, i.e. outside of the scope of this particular MP.
| Chris Halse Rogers (raof) wrote : | # |
On Wed, Jan 14, 2015 at 9:27 AM, Alberto Aguirre
<email address hidden> wrote:
>> @Alan:
>> > I know it is before the time of many current team members but we
>> originally
>> envisaged an MVC arrangement
>> > where changes to the model (like creating a surface) would be
>> routed through
>> a controller
>> > (like a window manager) that is part of the shell and not go
>> directly to the
>> model (in this case the session).
>> >
>> > Were we in that hypothetical world then the window manager would
>> validate
>> this policy.
>>
>> Hm. Whereas I think this would be a part of the contract with the
>> window
>> manager - “when we ask you to create a window, we guarantee that
>> it'll have
>> all the mandatory information”. The client library needs to
>> specify what the
>> mandatory information is, because that's the only place where we
>> can specify
>> client semantics.
>
> Sure, but we are talking about malformed requests, which need to be
> validated by something. That something for me is not the frontend as
> that would couple knowledge of window management semantics (The
> implementation of the window management policy is the one that knows
> what combination of arguments are correct for a surface type for
> example).
We're (by necessity - there's no where else to put it) encoding window
management semantics into the client library and protocol. The client
library already knows what properties are mandatory for a given surface
type - we encode them in the surface_spec constructor.
The shell's window management policy may (but almost always
*shouldn't*) impose additional constraints.
I think that malformed requests are exactly the sort of thing the
protocol layer should be filtering out. Surface creation isn't a
hot-path, so a defence-in-depth, validate whatever you can at this
stage and let the next stage validate some more, is reasonable.
Note that this doesn't necessarily mean validation is baked into
SessionManager - we could have a separate MessageValidator interface
SessionManager delegates to, or (possibly a better idea) we could
specialise the SurfaceCreate protocol message for each surface type so
it's not possible to represent an invalid request.
That's not necessarily in-scope for this MP, though.
| Chris Halse Rogers (raof) wrote : | # |
Looks acceptable to me.
Ideally I'd like to have <parent, adjacency_rect, edge_affinity> be a single optional tuple, but (a) I'm not sure that we have consensus for that, and (b) that'd probably be better handled by splitting SurfaceCreation
Could you update the mir_connection_

As already discussed, I don't think it's a good idea to make make creation functions type-specific. The result is we'll have exponentially more API functions this way, and higher coupling to type-specific semantics. But I lost that argument and so will abstain... although there is a cosmetic issue that needs fixing:
(1) Headers containing documentation that will be read by users as such should be wrapped within 80 columns so they display in users' terminals correctly: client/ mir_toolkit/ mir_surface. h
include/
We don't impose this standard on our own internal code, but the public stuff needs to be more consumable.