~alan-griffiths/miral/proof-of-concept-resize

« back to all changes in this revision

Viewing changes to test/window_placement_client_api.cpp

merge lp:~alan-griffiths/miral/better-resize-in-titlebar-wmp

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2016 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License version 3,
 
6
 * as 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 General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authored by: Alan Griffiths <alan@octopull.co.uk>
 
17
 */
 
18
 
 
19
#include <mir/version.h>
 
20
 
 
21
#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
 
22
#include <mir_toolkit/events/surface_placement.h>
 
23
#endif
 
24
 
 
25
#include <miral/toolkit/surface_spec.h>
 
26
#include <miral/toolkit/surface.h>
 
27
 
 
28
#include <mir/test/signal.h>
 
29
#include "test_server.h"
 
30
 
 
31
#include <gtest/gtest.h>
 
32
#include <gmock/gmock.h>
 
33
 
 
34
using namespace std::literals::chrono_literals;
 
35
 
 
36
using namespace testing;
 
37
namespace mt = mir::test;
 
38
namespace mtf = mir_test_framework;
 
39
 
 
40
using namespace miral::toolkit;
 
41
 
 
42
namespace
 
43
{
 
44
struct WindowPlacementClientAPI : miral::TestServer
 
45
{
 
46
    void SetUp() override
 
47
    {
 
48
        miral::TestServer::SetUp();
 
49
 
 
50
        char const* const test_name = __PRETTY_FUNCTION__;
 
51
 
 
52
        connection = connect_client(test_name);
 
53
        auto spec = SurfaceSpec::for_normal_surface(connection, 400, 400, mir_pixel_format_argb_8888)
 
54
            .set_name(test_name);
 
55
 
 
56
        parent = spec.create_surface();
 
57
    }
 
58
 
 
59
    void TearDown() override
 
60
    {
 
61
        child.reset();
 
62
        parent.reset();
 
63
        connection.reset();
 
64
 
 
65
        miral::TestServer::TearDown();
 
66
    }
 
67
 
 
68
    Connection connection;
 
69
    Surface parent;
 
70
    Surface child;
 
71
};
 
72
}
 
73
 
 
74
#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
 
75
 
 
76
namespace
 
77
{
 
78
struct CheckPlacement
 
79
{
 
80
    CheckPlacement(int left, int top, unsigned int width, unsigned int height) :
 
81
        expected{left, top, width, height} {}
 
82
 
 
83
    void check(MirSurfacePlacementEvent const* placement_event)
 
84
    {
 
85
        EXPECT_THAT(mir_surface_placement_get_relative_position(placement_event).top, Eq(expected.top));
 
86
        EXPECT_THAT(mir_surface_placement_get_relative_position(placement_event).left, Eq(expected.left));
 
87
        EXPECT_THAT(mir_surface_placement_get_relative_position(placement_event).height, Eq(expected.height));
 
88
        EXPECT_THAT(mir_surface_placement_get_relative_position(placement_event).width, Eq(expected.width));
 
89
 
 
90
        received.raise();
 
91
    }
 
92
 
 
93
    static void callback(MirSurface* /*surface*/, MirEvent const* event, void* context)
 
94
    {
 
95
        if (mir_event_get_type(event) == mir_event_type_surface_placement)
 
96
        {
 
97
            auto const placement_event = mir_event_get_surface_placement_event(event);
 
98
            static_cast<CheckPlacement*>(context)->check(placement_event);
 
99
        }
 
100
    }
 
101
 
 
102
    ~CheckPlacement()
 
103
    {
 
104
        EXPECT_TRUE(received.wait_for(400ms));
 
105
    }
 
106
 
 
107
private:
 
108
    MirRectangle const expected;
 
109
    mt::Signal received;
 
110
};
 
111
}
 
112
 
 
113
// It would be nice to verify creation and movement placement notifications in separate tests,
 
114
// However, to avoid a racy test, we need to detect both anyway. This seems like a good trade-off.
 
115
TEST_F(WindowPlacementClientAPI, given_menu_placements_away_from_edges_when_notified_result_is_as_requested)
 
116
{
 
117
    char const* const test_name = __PRETTY_FUNCTION__;
 
118
    int const dx = 30;
 
119
    int const dy = 40;
 
120
 
 
121
    // initial placement
 
122
    {
 
123
        MirRectangle aux_rect{10, 20, 3, 4};
 
124
        CheckPlacement expected{aux_rect.left+(int)aux_rect.width, aux_rect.top, dx, dy};
 
125
 
 
126
        auto const spec = SurfaceSpec::
 
127
            for_menu(connection, dx, dy, mir_pixel_format_argb_8888, parent, &aux_rect, mir_edge_attachment_any)
 
128
            .set_event_handler(&CheckPlacement::callback, &expected)
 
129
            .set_name(test_name);
 
130
 
 
131
        child = spec.create_surface();
 
132
    }
 
133
 
 
134
    // subsequent movement
 
135
    {
 
136
        MirRectangle aux_rect{50, 60, 5, 7};
 
137
        CheckPlacement expected{aux_rect.left-dx, aux_rect.top, dx, dy};
 
138
 
 
139
        auto const spec = SurfaceSpec::for_changes(connection)
 
140
            .set_event_handler(&CheckPlacement::callback, &expected)
 
141
            .set_placement(&aux_rect, mir_placement_gravity_northwest, mir_placement_gravity_northeast, mir_placement_hints_flip_x, 0, 0);
 
142
 
 
143
        spec.apply_to(child);
 
144
    }
 
145
}
 
146
#endif