Mir

Merge lp:~albaguirre/mir/add-menu-api into lp:mir

Proposed by Alberto Aguirre
Status: Merged
Approved by: Chris Halse Rogers
Approved revision: no longer in the source branch.
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
Reviewer Review Type Date Requested Status
Chris Halse Rogers Approve
PS Jenkins bot (community) continuous-integration Approve
Alan Griffiths Approve
Robert Carr (community) Approve
Daniel van Vugt Abstain
Cemil Azizoglu (community) Approve
Review via email: mp+244632@code.launchpad.net

Commit message

Add API to specify client menu surfaces (LP: #1324101)

Description of the change

Add API to specify client menu surfaces

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

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:
   include/client/mir_toolkit/mir_surface.h

We don't impose this standard on our own internal code, but the public stuff needs to be more consumable.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
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_create_spec_for_surface_type.

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/maximized/min), position (x,y relative to parent), decoration style (client or server decorations), min/max width/height, window title...

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.

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

https://lists.ubuntu.com/archives/mir-devel/2014-November/000961.html has been brought to my attention. I won't resurrect the argument, but it is pity the main voice of dissent was missing from that meeting.

The API design does makes sense, but I'm glad I'm not maintaining such an API. Objection withdrawn

Revision history for this message
Robert Carr (robertcarr) wrote :

lgtm

review: Approve
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Looks good.

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

53 + if (!mir_surface_is_valid(parent)) abort();
54 + if (!rect) abort();

I think we need mir::require(mir_surface_is_valid(parent)) or MIR_REQUIRE(mir_surface_is_valid(parent)) (or similar)

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

> 53 + if (!mir_surface_is_valid(parent)) abort();
> 54 + if (!rect) abort();
>
> I think we need mir::require(mir_surface_is_valid(parent)) or
> MIR_REQUIRE(mir_surface_is_valid(parent)) (or similar)

Done.

Revision history for this message
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/client/mir_toolkit/mir_surface.h
>
> 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.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
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_create_spec_for_menu_surface(connection, width, height, parent, adjacency_rect, format)?

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) :
review: Abstain
Revision history for this message
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 :(

Revision history for this message
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_create_spec_for_menu_surface(connection, width, height, parent,
> adjacency_rect, format)?

I don't understand what adjacency rect is supposed to represent, could you elaborate?

Revision history for this message
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 |
| |
+----------------+

---------------------- Screen edge ------------------

Revision history for this message
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/left-edge rather than top-edge/bottom-edge.

Revision history for this message
Robert Carr (robertcarr) wrote :

Seems like Chris is correct...

review: Needs Fixing
Revision history for this message
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_create_spec_for_menu_surface(connection, width, height, format, parent, attachment_rect, preferred_edge_direction)

Revision history for this message
Robert Carr (robertcarr) wrote :

This is strange but I would expect the c'tor arguments to be ordered otherwise:
create_spec_for_menu_surface(connection, parent, rect, direction, width, height, format)

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...on...in...due....or...other"

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.

Revision history for this message
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.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

Tests have some
+ ASSERT_TRUE(mir_surface_is_valid(menu));
this would be better with mir_test/validity_matchers.h and:
+ ASSERT_THAT(menu, IsValid())
(this gets you a helpful message when the assertion fails

What are the semantics of mir_edge_attachment_none? I don't think that value makes sense?

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_attachment_none mean?” Everything else is nice-to-have.

review: Needs Fixing
Revision history for this message
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.

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

> This is strange but I would expect the c'tor arguments to be ordered
> otherwise:
> create_spec_for_menu_surface(connection, parent, rect, direction, width,
> 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_create_spec_for_normal_surface

> 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.

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

358 + ASSERT_TRUE(spec != nullptr);

Could be ASSERT_THAT(spec, NotNull());

review: Approve
Revision history for this message
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->create_surface(params) instead of session mediator itself, which is now possible since optional_values are used in SurfaceCreationParameters

Revision history for this message
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->create_surface(params) instead of session mediator itself, which is
> now possible since optional_values are used in SurfaceCreationParameters

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.

Revision history for this message
Robert Carr (robertcarr) wrote :

>> I think that should be the responsibility of the implementation of session->create_surface(params) >> instead of session mediator itself, which is now possible since optional_values are used in
>> SurfaceCreationParameters

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 :)

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

> Tests have some
> + ASSERT_TRUE(mir_surface_is_valid(menu));
> this would be better with mir_test/validity_matchers.h and:
> + ASSERT_THAT(menu, IsValid())
> (this gets you a helpful message when the assertion fails
>
>
Done.

> What are the semantics of mir_edge_attachment_none? I don't think that value
> makes sense?
Changed the name to any - meaning both horizonal and vertical edge attachment is ok.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

Um, now mir_edge_attachment_any != mir_edge_attachment_horizontal | mir_edge_attachment_vertical, but means the same thing :(.

I think it should either be removed, or specified as equal to mir_edge_attachment_horizontal | mir_edge_attachment_vertical. I lean slightly towards the latter.

@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_attachment_any. It's possible we want to name the surface type differently. ☺

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.

review: Needs Fixing
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
Alberto Aguirre (albaguirre) wrote :

> Um, now mir_edge_attachment_any != mir_edge_attachment_horizontal |
> mir_edge_attachment_vertical, but means the same thing :(.
>
> I think it should either be removed, or specified as equal to
> mir_edge_attachment_horizontal | mir_edge_attachment_vertical. I lean slightly
> 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.

Revision history for this message
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.

Revision history for this message
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 SurfaceCreationParameters into NormalSurfaceCreationParameters, MenuSurfaceCreationParameters, etc and explicitly asking the shell to create a normal, menu, etc surface.

Could you update the mir_connection_create_spec_for_menu_surface doc with a big INPUT SEMANTICS TBD warning so we don't forget to update it?

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'client-ABI-sha1sums'
--- client-ABI-sha1sums 2015-01-06 03:29:48 +0000
+++ client-ABI-sha1sums 2015-01-13 16:38:19 +0000
@@ -6,11 +6,11 @@
6d739af6e64db6b314a727b5fb00be662b98ccd57 include/client/mir_toolkit/mir_platform_message.h6d739af6e64db6b314a727b5fb00be662b98ccd57 include/client/mir_toolkit/mir_platform_message.h
79d50df5a141ca03ee8a79f7e844ed4b8b3b7d5d3 include/client/mir_toolkit/mir_prompt_session.h79d50df5a141ca03ee8a79f7e844ed4b8b3b7d5d3 include/client/mir_toolkit/mir_prompt_session.h
821d07e655e85eeec8a3523e1c6f9c2252176ec01 include/client/mir_toolkit/mir_screencast.h821d07e655e85eeec8a3523e1c6f9c2252176ec01 include/client/mir_toolkit/mir_screencast.h
982a2a3d219747a778284811ba0c01e0fdf167b30 include/client/mir_toolkit/mir_surface.h98ea06d0a56ef400ae7813312fd4edb8114a4632a include/client/mir_toolkit/mir_surface.h
10b141c4d79802ad626d969249c0004744e5c2a525 include/client/mir_toolkit/mir_wait.h10b141c4d79802ad626d969249c0004744e5c2a525 include/client/mir_toolkit/mir_wait.h
116f7b4ecc22afba923806ed2bd7d8244be90b0cfd include/client/mir_toolkit/version.h116f7b4ecc22afba923806ed2bd7d8244be90b0cfd include/client/mir_toolkit/version.h
123350dac884d6006753de2a955bc7a05663cd9449 include/common/mir_toolkit/client_types.h123350dac884d6006753de2a955bc7a05663cd9449 include/common/mir_toolkit/client_types.h
13c7c708734715a6d1b6fb2652584adb912071a518 include/common/mir_toolkit/common.h1320086d47f8747ba34f8d2c4aba75503adb347247 include/common/mir_toolkit/common.h
14fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h14fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h
15f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h15f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h
162507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h162507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h
1717
=== modified file 'common-ABI-sha1sums'
--- common-ABI-sha1sums 2015-01-06 03:29:48 +0000
+++ common-ABI-sha1sums 2015-01-13 16:38:19 +0000
@@ -17,7 +17,7 @@
1731b9c24e2ce7194aeea6694e81c160354033d28a include/common/mir/optional_value.h1731b9c24e2ce7194aeea6694e81c160354033d28a include/common/mir/optional_value.h
189ae8473df05dd9e048a73797f01a2f34f7447554 include/common/mir/time/types.h189ae8473df05dd9e048a73797f01a2f34f7447554 include/common/mir/time/types.h
193350dac884d6006753de2a955bc7a05663cd9449 include/common/mir_toolkit/client_types.h193350dac884d6006753de2a955bc7a05663cd9449 include/common/mir_toolkit/client_types.h
20c7c708734715a6d1b6fb2652584adb912071a518 include/common/mir_toolkit/common.h2020086d47f8747ba34f8d2c4aba75503adb347247 include/common/mir_toolkit/common.h
21fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h21fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h
22f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h22f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h
232507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h232507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h
2424
=== modified file 'include/client/mir_toolkit/mir_surface.h'
--- include/client/mir_toolkit/mir_surface.h 2014-12-12 14:51:33 +0000
+++ include/client/mir_toolkit/mir_surface.h 2015-01-13 16:38:19 +0000
@@ -51,6 +51,40 @@
51 MirPixelFormat format);51 MirPixelFormat format);
5252
53/**53/**
54 * Create a surface specification for a menu surface.
55 *
56 * Positioning of the surface is specified with respect to the parent surface
57 * via an adjacency rectangle. The server will attempt to choose an edge of the
58 * adjacency rectangle on which to place the surface taking in to account
59 * screen-edge proximity or similar constraints. In addition, the server can use
60 * the edge affinity hint to consider only horizontal or only vertical adjacency
61 * edges in the given rectangle.
62 *
63 * \param [in] connection Connection the surface will be created on
64 * \param [in] width Requested width. The server is not guaranteed to
65 * return a surface of this width.
66 * \param [in] height Requested height. The server is not guaranteed to
67 * return a surface of this height.
68 * \param [in] format Pixel format for the surface.
69 * \param [in] parent A valid parent surface for this menu.
70 * \param [in] rect The adjacency rectangle. The server is not
71 * guaranteed to create a surface at the requested
72 * location.
73 * \param [in] edge The preferred edge direction to attach to. Use
74 * mir_edge_attachment_any for no preference.
75 * \return A handle that can be passed to mir_surface_create()
76 * to complete construction.
77 */
78MirSurfaceSpec*
79mir_connection_create_spec_for_menu_surface(MirConnection* connection,
80 int width,
81 int height,
82 MirPixelFormat format,
83 MirSurface* parent,
84 MirRectangle* rect,
85 MirEdgeAttachment edge);
86
87/**
54 * Create a surface from a given specification88 * Create a surface from a given specification
55 *89 *
56 *90 *
5791
=== modified file 'include/common/mir_toolkit/common.h'
--- include/common/mir_toolkit/common.h 2014-12-19 02:31:34 +0000
+++ include/common/mir_toolkit/common.h 2015-01-13 16:38:19 +0000
@@ -159,6 +159,13 @@
159 mir_orientation_mode_landscape_any159 mir_orientation_mode_landscape_any
160} MirOrientationMode;160} MirOrientationMode;
161161
162typedef enum MirEdgeAttachment
163{
164 mir_edge_attachment_vertical = 1 << 0,
165 mir_edge_attachment_horizontal = 1 << 1,
166 mir_edge_attachment_any = mir_edge_attachment_vertical |
167 mir_edge_attachment_horizontal
168} MirEdgeAttachment;
162/**@}*/169/**@}*/
163170
164#endif171#endif
165172
=== modified file 'include/server/mir/scene/surface_creation_parameters.h'
--- include/server/mir/scene/surface_creation_parameters.h 2014-12-19 04:40:45 +0000
+++ include/server/mir/scene/surface_creation_parameters.h 2015-01-13 16:38:19 +0000
@@ -67,6 +67,10 @@
6767
68 SurfaceCreationParameters& with_parent_id(frontend::SurfaceId const& id);68 SurfaceCreationParameters& with_parent_id(frontend::SurfaceId const& id);
6969
70 SurfaceCreationParameters& with_attachment_rect(geometry::Rectangle const& rect);
71
72 SurfaceCreationParameters& with_edge_attachment(MirEdgeAttachment edge);
73
70 std::string name;74 std::string name;
71 geometry::Size size;75 geometry::Size size;
72 geometry::Point top_left;76 geometry::Point top_left;
@@ -80,6 +84,8 @@
80 mir::optional_value<MirSurfaceType> type;84 mir::optional_value<MirSurfaceType> type;
81 mir::optional_value<MirOrientationMode> preferred_orientation;85 mir::optional_value<MirOrientationMode> preferred_orientation;
82 mir::optional_value<frontend::SurfaceId> parent_id;86 mir::optional_value<frontend::SurfaceId> parent_id;
87 mir::optional_value<geometry::Rectangle> attachment_rect;
88 mir::optional_value<MirEdgeAttachment> edge_attachment;
83};89};
8490
85bool operator==(const SurfaceCreationParameters& lhs, const SurfaceCreationParameters& rhs);91bool operator==(const SurfaceCreationParameters& lhs, const SurfaceCreationParameters& rhs);
8692
=== modified file 'platform-ABI-sha1sums'
--- platform-ABI-sha1sums 2015-01-08 03:16:37 +0000
+++ platform-ABI-sha1sums 2015-01-13 16:38:19 +0000
@@ -17,7 +17,7 @@
1731b9c24e2ce7194aeea6694e81c160354033d28a include/common/mir/optional_value.h1731b9c24e2ce7194aeea6694e81c160354033d28a include/common/mir/optional_value.h
189ae8473df05dd9e048a73797f01a2f34f7447554 include/common/mir/time/types.h189ae8473df05dd9e048a73797f01a2f34f7447554 include/common/mir/time/types.h
193350dac884d6006753de2a955bc7a05663cd9449 include/common/mir_toolkit/client_types.h193350dac884d6006753de2a955bc7a05663cd9449 include/common/mir_toolkit/client_types.h
20c7c708734715a6d1b6fb2652584adb912071a518 include/common/mir_toolkit/common.h2020086d47f8747ba34f8d2c4aba75503adb347247 include/common/mir_toolkit/common.h
21fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h21fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h
22f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h22f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h
232507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h232507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h
2424
=== modified file 'server-ABI-sha1sums'
--- server-ABI-sha1sums 2015-01-08 03:16:37 +0000
+++ server-ABI-sha1sums 2015-01-13 16:38:19 +0000
@@ -17,7 +17,7 @@
1731b9c24e2ce7194aeea6694e81c160354033d28a include/common/mir/optional_value.h1731b9c24e2ce7194aeea6694e81c160354033d28a include/common/mir/optional_value.h
189ae8473df05dd9e048a73797f01a2f34f7447554 include/common/mir/time/types.h189ae8473df05dd9e048a73797f01a2f34f7447554 include/common/mir/time/types.h
193350dac884d6006753de2a955bc7a05663cd9449 include/common/mir_toolkit/client_types.h193350dac884d6006753de2a955bc7a05663cd9449 include/common/mir_toolkit/client_types.h
20c7c708734715a6d1b6fb2652584adb912071a518 include/common/mir_toolkit/common.h2020086d47f8747ba34f8d2c4aba75503adb347247 include/common/mir_toolkit/common.h
21fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h21fce4c1a9e0d037244f7e9e96ea2d8eaab4fc404c include/common/mir_toolkit/cursors.h
22f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h22f4d39e9893ce6308bddd83a49b90f0051f565323 include/common/mir_toolkit/event.h
232507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h232507f2929415aa423f9551d3c595c439fe1c6efd include/common/mir_toolkit/events/event_deprecated.h
@@ -96,7 +96,7 @@
965bab4dc0a6488b8b9d47e958c6bab94f1dcf2c57 include/server/mir/scene/surface_buffer_access.h965bab4dc0a6488b8b9d47e958c6bab94f1dcf2c57 include/server/mir/scene/surface_buffer_access.h
97bbc9e2e2bb71634cd6f1c5c0430093e10e74fa23 include/server/mir/scene/surface_configurator.h97bbc9e2e2bb71634cd6f1c5c0430093e10e74fa23 include/server/mir/scene/surface_configurator.h
98e5e4dd7bcaf186810043fa0f05be42d7e49b0843 include/server/mir/scene/surface_coordinator.h98e5e4dd7bcaf186810043fa0f05be42d7e49b0843 include/server/mir/scene/surface_coordinator.h
996d669f4235c2237fb35578671405db882b6aafba include/server/mir/scene/surface_creation_parameters.h998e3636b736700d72520709c8a61f5e85d9231d4c include/server/mir/scene/surface_creation_parameters.h
1007da48dbedb4430ce322a50ef8f4e93ce08bdf147 include/server/mir/scene/surface.h1007da48dbedb4430ce322a50ef8f4e93ce08bdf147 include/server/mir/scene/surface.h
101587e22d751656ce2d9536afdf5659276ff9bbc46 include/server/mir/scene/surface_observer.h101587e22d751656ce2d9536afdf5659276ff9bbc46 include/server/mir/scene/surface_observer.h
1027ef3e99901168cda296d74d05a979f47bf9c3ff1 include/server/mir/server_action_queue.h1027ef3e99901168cda296d74d05a979f47bf9c3ff1 include/server/mir/server_action_queue.h
103103
=== modified file 'src/client/mir_surface.cpp'
--- src/client/mir_surface.cpp 2014-12-19 04:37:16 +0000
+++ src/client/mir_surface.cpp 2015-01-13 16:38:19 +0000
@@ -89,6 +89,14 @@
89 SERIALIZE_OPTION_IF_SET(pref_orientation, message);89 SERIALIZE_OPTION_IF_SET(pref_orientation, message);
90 if (parent.is_set() && parent.value() != nullptr)90 if (parent.is_set() && parent.value() != nullptr)
91 message.set_parent_id(parent.value()->id());91 message.set_parent_id(parent.value()->id());
92 if (attachment_rect.is_set())
93 {
94 message.mutable_attachment_rect()->set_left(attachment_rect.value().left);
95 message.mutable_attachment_rect()->set_top(attachment_rect.value().top);
96 message.mutable_attachment_rect()->set_width(attachment_rect.value().width);
97 message.mutable_attachment_rect()->set_height(attachment_rect.value().height);
98 }
99 SERIALIZE_OPTION_IF_SET(edge_attachment, message);
92100
93 return message;101 return message;
94}102}
95103
=== modified file 'src/client/mir_surface.h'
--- src/client/mir_surface.h 2014-12-19 04:37:16 +0000
+++ src/client/mir_surface.h 2015-01-13 16:38:19 +0000
@@ -78,6 +78,8 @@
78 mir::optional_value<MirOrientationMode> pref_orientation;78 mir::optional_value<MirOrientationMode> pref_orientation;
7979
80 mir::optional_value<MirSurface*> parent;80 mir::optional_value<MirSurface*> parent;
81 mir::optional_value<MirRectangle> attachment_rect;
82 mir::optional_value<MirEdgeAttachment> edge_attachment;
81};83};
8284
83struct MirSurface : public mir::client::ClientSurface85struct MirSurface : public mir::client::ClientSurface
8486
=== modified file 'src/client/mir_surface_api.cpp'
--- src/client/mir_surface_api.cpp 2015-01-06 03:29:48 +0000
+++ src/client/mir_surface_api.cpp 2015-01-13 16:38:19 +0000
@@ -51,6 +51,25 @@
51 return new MirSurfaceSpec{connection, width, height, format};51 return new MirSurfaceSpec{connection, width, height, format};
52}52}
5353
54MirSurfaceSpec* mir_connection_create_spec_for_menu_surface(MirConnection* connection,
55 int width,
56 int height,
57 MirPixelFormat format,
58 MirSurface* parent,
59 MirRectangle* rect,
60 MirEdgeAttachment edge)
61{
62 mir::require(mir_surface_is_valid(parent));
63 mir::require(rect != nullptr);
64
65 auto spec = new MirSurfaceSpec{connection, width, height, format};
66 spec->type = mir_surface_type_menu;
67 spec->parent = parent;
68 spec->attachment_rect = *rect;
69 spec->edge_attachment = edge;
70 return spec;
71}
72
54MirSurface* mir_surface_create_sync(MirSurfaceSpec* requested_specification)73MirSurface* mir_surface_create_sync(MirSurfaceSpec* requested_specification)
55{74{
56 MirSurface* surface = nullptr;75 MirSurface* surface = nullptr;
5776
=== modified file 'src/client/symbols.map'
--- src/client/symbols.map 2014-12-12 14:51:33 +0000
+++ src/client/symbols.map 2015-01-13 16:38:19 +0000
@@ -33,4 +33,8 @@
33 mir_surface_set_preferred_orientation;33 mir_surface_set_preferred_orientation;
34 mir_surface_get_preferred_orientation;34 mir_surface_get_preferred_orientation;
35 mir_surface_spec_set_preferred_orientation;35 mir_surface_spec_set_preferred_orientation;
36} MIR_CLIENT_8.1;
37\ No newline at end of file36\ No newline at end of file
37} MIR_CLIENT_8.1;
38
39MIR_CLIENT_8.3 {
40 mir_connection_create_spec_for_menu_surface;
41} MIR_CLIENT_8.2;
38\ No newline at end of file42\ No newline at end of file
3943
=== removed file 'src/include/common/mir/require.h'
--- src/include/common/mir/require.h 2014-12-19 05:01:58 +0000
+++ src/include/common/mir/require.h 1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alberto Aguirre <alberto.aguirre@canonical.com>
17 */
18
19#ifndef MIR_REQUIRE_H_
20#define MIR_REQUIRE_H_
21
22#include <cstdlib>
23
24namespace mir
25{
26inline void require(bool const expr)
27{
28 if (!expr) std::abort();
29}
30}
31
32#endif /* MIR_REQUIRE_H_ */
330
=== modified file 'src/protobuf/mir_protobuf.proto'
--- src/protobuf/mir_protobuf.proto 2014-12-19 04:38:08 +0000
+++ src/protobuf/mir_protobuf.proto 2015-01-13 16:38:19 +0000
@@ -24,6 +24,9 @@
24 optional int32 state = 8;24 optional int32 state = 8;
25 optional int32 pref_orientation = 9;25 optional int32 pref_orientation = 9;
26 optional int32 parent_id = 10;26 optional int32 parent_id = 10;
27
28 optional Rectangle attachment_rect = 11;
29 optional int32 edge_attachment = 12;
27}30}
2831
29message SurfaceId {32message SurfaceId {
3033
=== modified file 'src/server/frontend/session_mediator.cpp'
--- src/server/frontend/session_mediator.cpp 2014-12-19 04:40:45 +0000
+++ src/server/frontend/session_mediator.cpp 2015-01-13 16:38:19 +0000
@@ -198,6 +198,17 @@
198 if (request->has_parent_id())198 if (request->has_parent_id())
199 params.with_parent_id(SurfaceId{request->parent_id()});199 params.with_parent_id(SurfaceId{request->parent_id()});
200200
201 if (request->has_attachment_rect())
202 {
203 params.with_attachment_rect(geom::Rectangle{
204 {request->attachment_rect().left(), request->attachment_rect().top()},
205 {request->attachment_rect().width(), request->attachment_rect().height()}
206 });
207 }
208
209 if (request->has_edge_attachment())
210 params.with_edge_attachment(static_cast<MirEdgeAttachment>(request->edge_attachment()));
211
201 auto const surf_id = session->create_surface(params);212 auto const surf_id = session->create_surface(params);
202213
203 auto surface = session->get_surface(surf_id);214 auto surface = session->get_surface(surf_id);
204215
=== modified file 'src/server/scene/surface_creation_parameters.cpp'
--- src/server/scene/surface_creation_parameters.cpp 2014-12-19 04:40:45 +0000
+++ src/server/scene/surface_creation_parameters.cpp 2015-01-13 16:38:19 +0000
@@ -124,6 +124,18 @@
124 return *this;124 return *this;
125}125}
126126
127ms::SurfaceCreationParameters& ms::SurfaceCreationParameters::with_attachment_rect(geometry::Rectangle const& rect)
128{
129 attachment_rect = rect;
130 return *this;
131}
132
133ms::SurfaceCreationParameters& ms::SurfaceCreationParameters::with_edge_attachment(MirEdgeAttachment edge)
134{
135 edge_attachment = edge;
136 return *this;
137}
138
127bool ms::operator==(139bool ms::operator==(
128 const SurfaceCreationParameters& lhs,140 const SurfaceCreationParameters& lhs,
129 const ms::SurfaceCreationParameters& rhs)141 const ms::SurfaceCreationParameters& rhs)
130142
=== modified file 'tests/acceptance-tests/test_client_surfaces.cpp'
--- tests/acceptance-tests/test_client_surfaces.cpp 2014-12-17 15:20:40 +0000
+++ tests/acceptance-tests/test_client_surfaces.cpp 2015-01-13 16:38:19 +0000
@@ -21,6 +21,7 @@
2121
22#include "mir_test_framework/connected_client_headless_server.h"22#include "mir_test_framework/connected_client_headless_server.h"
23#include "mir_test_framework/any_surface.h"23#include "mir_test_framework/any_surface.h"
24#include "mir_test/validity_matchers.h"
2425
25#include <gmock/gmock.h>26#include <gmock/gmock.h>
26#include <gtest/gtest.h>27#include <gtest/gtest.h>
@@ -190,7 +191,7 @@
190TEST_P(WithOrientation, have_requested_preferred_orientation)191TEST_P(WithOrientation, have_requested_preferred_orientation)
191{192{
192 auto spec = mir_connection_create_spec_for_normal_surface(connection, 1, 1, mir_pixel_format_abgr_8888);193 auto spec = mir_connection_create_spec_for_normal_surface(connection, 1, 1, mir_pixel_format_abgr_8888);
193 ASSERT_TRUE(spec != nullptr);194 ASSERT_THAT(spec, NotNull());
194195
195 MirOrientationMode mode{GetParam()};196 MirOrientationMode mode{GetParam()};
196 mir_surface_spec_set_preferred_orientation(spec, mode);197 mir_surface_spec_set_preferred_orientation(spec, mode);
@@ -198,7 +199,7 @@
198 auto surface = mir_surface_create_sync(spec);199 auto surface = mir_surface_create_sync(spec);
199 mir_surface_spec_release(spec);200 mir_surface_spec_release(spec);
200201
201 ASSERT_TRUE(mir_surface_is_valid(surface));202 ASSERT_THAT(surface, IsValid());
202 EXPECT_EQ(mir_surface_get_preferred_orientation(surface), mode);203 EXPECT_EQ(mir_surface_get_preferred_orientation(surface), mode);
203204
204 mir_surface_release_sync(surface);205 mir_surface_release_sync(surface);
@@ -211,3 +212,22 @@
211 mir_orientation_mode_portrait_any, mir_orientation_mode_landscape_any,212 mir_orientation_mode_portrait_any, mir_orientation_mode_landscape_any,
212 mir_orientation_mode_any));213 mir_orientation_mode_any));
213214
215TEST_F(ClientSurfaces, can_be_menus)
216{
217 auto parent = mtf::make_any_surface(connection);
218 MirRectangle attachment_rect{100, 200, 100, 100};
219
220 auto spec = mir_connection_create_spec_for_menu_surface(connection, 640, 480,
221 mir_pixel_format_abgr_8888, parent, &attachment_rect, mir_edge_attachment_vertical);
222 ASSERT_THAT(spec, NotNull());
223
224 auto menu = mir_surface_create_sync(spec);
225 mir_surface_spec_release(spec);
226
227 ASSERT_THAT(menu, IsValid());
228 EXPECT_EQ(mir_surface_get_type(menu), mir_surface_type_menu);
229
230 mir_surface_release_sync(parent);
231 mir_surface_release_sync(menu);
232}
233
214234
=== modified file 'tests/integration-tests/client/test_mirsurface.cpp'
--- tests/integration-tests/client/test_mirsurface.cpp 2014-12-19 04:42:39 +0000
+++ tests/integration-tests/client/test_mirsurface.cpp 2015-01-13 16:38:19 +0000
@@ -19,6 +19,7 @@
19#include "mir_test_framework/connected_client_headless_server.h"19#include "mir_test_framework/connected_client_headless_server.h"
20#include "mir_test_doubles/stub_scene_surface.h"20#include "mir_test_doubles/stub_scene_surface.h"
21#include "mir_test/fake_shared.h"21#include "mir_test/fake_shared.h"
22#include "mir_test/validity_matchers.h"
2223
23#include "mir/scene/surface.h"24#include "mir/scene/surface.h"
24#include "mir/scene/surface_creation_parameters.h"25#include "mir/scene/surface_creation_parameters.h"
@@ -73,6 +74,31 @@
73 parent_field_matches(arg, spec->parent);74 parent_field_matches(arg, spec->parent);
74}75}
7576
77MATCHER(IsAMenu, "")
78{
79 return arg.type == mir_surface_type_menu;
80}
81
82MATCHER_P(HasParent, parent, "")
83{
84 return arg.parent_id.is_set() && arg.parent_id.value().as_value() == parent->id();
85}
86
87MATCHER_P(MatchesAttachment, rect, "")
88{
89 return arg.attachment_rect.is_set() &&
90 arg.attachment_rect.value().top_left.x.as_int() == rect.left &&
91 arg.attachment_rect.value().top_left.y.as_int() == rect.top &&
92 arg.attachment_rect.value().size.width.as_uint32_t() == rect.width &&
93 arg.attachment_rect.value().size.height.as_uint32_t() == rect.height;
94}
95
96MATCHER_P(MatchesEdge, edge, "")
97{
98 return arg.edge_attachment.is_set() &&
99 arg.edge_attachment.value() == edge;
100}
101
76}102}
77103
78struct ClientMirSurface : mtf::ConnectedClientHeadlessServer104struct ClientMirSurface : mtf::ConnectedClientHeadlessServer
@@ -103,9 +129,9 @@
103 spec.pref_orientation = mir_orientation_mode_landscape;129 spec.pref_orientation = mir_orientation_mode_landscape;
104 }130 }
105131
106 std::unique_ptr<MirSurface, std::function<void(MirSurface*)>> create_surface()132 std::unique_ptr<MirSurface, std::function<void(MirSurface*)>> create_surface(MirSurfaceSpec* spec)
107 {133 {
108 return {mir_surface_create_sync(&spec), [](MirSurface *surf){mir_surface_release_sync(surf);}};134 return {mir_surface_create_sync(spec), [](MirSurface *surf){mir_surface_release_sync(surf);}};
109 }135 }
110136
111 MirSurfaceSpec spec{nullptr, 640, 480, mir_pixel_format_abgr_8888};137 MirSurfaceSpec spec{nullptr, 640, 480, mir_pixel_format_abgr_8888};
@@ -118,10 +144,10 @@
118{144{
119 EXPECT_CALL(*mock_surface_coordinator, add_surface(AllOf(MatchesRequired(&spec), MatchesOptional(&spec)),_));145 EXPECT_CALL(*mock_surface_coordinator, add_surface(AllOf(MatchesRequired(&spec), MatchesOptional(&spec)),_));
120146
121 auto surf = create_surface();147 auto surf = create_surface(&spec);
122148
123 // A valid surface is needed to be specified as a parent149 // A valid surface is needed to be specified as a parent
124 ASSERT_TRUE(mir_surface_is_valid(surf.get()));150 ASSERT_THAT(surf.get(), IsValid());
125 spec.parent = surf.get();151 spec.parent = surf.get();
126152
127 // The second time around we don't care if the surface gets created,153 // The second time around we don't care if the surface gets created,
@@ -130,5 +156,29 @@
130 spec.output_id = arbitrary_output_id;156 spec.output_id = arbitrary_output_id;
131157
132 EXPECT_CALL(*mock_surface_coordinator, add_surface(MatchesOptional(&spec),_));158 EXPECT_CALL(*mock_surface_coordinator, add_surface(MatchesOptional(&spec),_));
133 create_surface();159 create_surface(&spec);
160}
161
162TEST_F(ClientMirSurface, as_menu_sends_correct_params)
163{
164 EXPECT_CALL(*mock_surface_coordinator, add_surface(_,_));
165 auto parent = create_surface(&spec);
166 ASSERT_THAT(parent.get(), IsValid());
167
168 MirRectangle attachment_rect{100, 200, 300, 400};
169 MirEdgeAttachment edge{mir_edge_attachment_horizontal};
170
171 auto spec_deleter = [](MirSurfaceSpec* spec) {mir_surface_spec_release(spec);};
172 std::unique_ptr<MirSurfaceSpec, decltype(spec_deleter)> menu_spec{
173 mir_connection_create_spec_for_menu_surface(connection, 640, 480,
174 mir_pixel_format_abgr_8888, parent.get(), &attachment_rect,
175 edge),
176 spec_deleter
177 };
178
179 ASSERT_THAT(menu_spec, NotNull());
180
181 EXPECT_CALL(*mock_surface_coordinator, add_surface(AllOf(IsAMenu(),
182 HasParent(parent.get()), MatchesAttachment(attachment_rect), MatchesEdge(edge)),_));
183 create_surface(menu_spec.get());
134}184}

Subscribers

People subscribed via source and target branches