23
23
#include <gtest/gtest.h>
26
using namespace testing;
27
using namespace mir::geometry;
28
using namespace mir::compositor;
29
using namespace mir::test::doubles;
26
namespace mg=mir::graphics;
27
namespace geom=mir::geometry;
28
namespace mc=mir::compositor;
29
namespace mtd=mir::test::doubles;
31
struct BypassFilterTest : public Test
31
struct BypassMatchTest : public testing::Test
35
monitor_rect[0].top_left = {0, 0};
36
monitor_rect[0].size = {1920, 1200};
37
EXPECT_CALL(display_buffer[0], view_area())
38
.WillRepeatedly(Return(monitor_rect[0]));
40
monitor_rect[1].top_left = {1920, 0};
41
monitor_rect[1].size = {1920, 1200};
42
EXPECT_CALL(display_buffer[1], view_area())
43
.WillRepeatedly(Return(monitor_rect[1]));
46
Rectangle monitor_rect[2];
47
MockDisplayBuffer display_buffer[2];
33
geom::Rectangle const primary_monitor{{0, 0},{1920, 1200}};
34
geom::Rectangle const secondary_monitor{{1920, 0},{1920, 1200}};
50
TEST_F(BypassFilterTest, nothing_matches_nothing)
52
BypassFilter filter(display_buffer[0]);
55
EXPECT_FALSE(filter.fullscreen_on_top());
56
EXPECT_FALSE(match.topmost_fullscreen());
59
TEST_F(BypassFilterTest, small_window_not_bypassed)
61
BypassFilter filter(display_buffer[0]);
63
FakeRenderable win(12, 34, 56, 78);
65
EXPECT_FALSE(filter(win));
66
EXPECT_FALSE(filter.fullscreen_on_top());
69
TEST_F(BypassFilterTest, single_fullscreen_window_bypassed)
71
BypassFilter filter(display_buffer[0]);
73
FakeRenderable win(0, 0, 1920, 1200);
75
EXPECT_TRUE(filter(win));
76
EXPECT_TRUE(filter.fullscreen_on_top());
79
TEST_F(BypassFilterTest, translucent_fullscreen_window_not_bypassed)
81
BypassFilter filter(display_buffer[0]);
83
FakeRenderable win(0, 0, 1920, 1200, 0.5f);
85
EXPECT_FALSE(filter(win));
86
EXPECT_FALSE(filter.fullscreen_on_top());
89
TEST_F(BypassFilterTest, hidden_fullscreen_window_not_bypassed)
91
BypassFilter filter(display_buffer[0]);
93
FakeRenderable win(0, 0, 1920, 1200, 1.0f, true, false);
95
EXPECT_FALSE(filter(win));
96
EXPECT_FALSE(filter.fullscreen_on_top());
99
TEST_F(BypassFilterTest, unposted_fullscreen_window_not_bypassed)
101
BypassFilter filter(display_buffer[0]);
103
FakeRenderable win(0, 0, 1920, 1200, 1.0f, true, true, false);
105
EXPECT_FALSE(filter(win));
106
EXPECT_FALSE(filter.fullscreen_on_top());
109
TEST_F(BypassFilterTest, shaped_fullscreen_window_not_bypassed)
111
BypassFilter filter(display_buffer[0]);
113
FakeRenderable win(0, 0, 1920, 1200, 1.0f, false);
115
EXPECT_FALSE(filter(win));
116
EXPECT_FALSE(filter.fullscreen_on_top());
119
TEST_F(BypassFilterTest, offset_fullscreen_window_not_bypassed)
121
BypassFilter filter(display_buffer[0]);
123
FakeRenderable win(10, 50, 1920, 1200);
125
EXPECT_FALSE(filter(win));
126
EXPECT_FALSE(filter.fullscreen_on_top());
129
TEST_F(BypassFilterTest, obscured_fullscreen_window_not_bypassed)
131
BypassFilter filter(display_buffer[0]);
133
FakeRenderable fs(0, 0, 1920, 1200);
134
FakeRenderable small(20, 30, 40, 50);
136
EXPECT_TRUE(filter(fs));
137
EXPECT_FALSE(filter(small));
138
EXPECT_FALSE(filter.fullscreen_on_top());
141
TEST_F(BypassFilterTest, translucently_obscured_fullscreen_window_not_bypassed)
37
TEST_F(BypassMatchTest, nothing_matches_nothing)
39
mg::RenderableList empty_list{};
40
mc::BypassMatch matcher(primary_monitor);
42
EXPECT_EQ(empty_list.rend(), std::find_if(empty_list.rbegin(), empty_list.rend(), matcher));
45
TEST_F(BypassMatchTest, small_window_not_bypassed)
47
mc::BypassMatch matcher(primary_monitor);
48
mg::RenderableList list{
49
std::make_shared<mtd::FakeRenderable>(12, 34, 56, 78)
52
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
55
TEST_F(BypassMatchTest, single_fullscreen_window_bypassed)
57
auto window = std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200);
58
mc::BypassMatch matcher(primary_monitor);
59
mg::RenderableList list{window};
61
auto it = std::find_if(list.rbegin(), list.rend(), matcher);
62
EXPECT_NE(list.rend(), it);
63
EXPECT_EQ(window, *it);
66
TEST_F(BypassMatchTest, translucent_fullscreen_window_not_bypassed)
68
mc::BypassMatch matcher(primary_monitor);
69
mg::RenderableList list{
70
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 0.5f)
73
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
76
TEST_F(BypassMatchTest, hidden_fullscreen_window_not_bypassed)
78
mc::BypassMatch matcher(primary_monitor);
79
mg::RenderableList list{
80
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 1.0f, true, false)
83
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
86
TEST_F(BypassMatchTest, unposted_fullscreen_window_not_bypassed)
88
mc::BypassMatch matcher(primary_monitor);
89
mg::RenderableList list{
90
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 1.0f, true, true, false)
93
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
96
TEST_F(BypassMatchTest, shaped_fullscreen_window_not_bypassed)
98
mc::BypassMatch matcher(primary_monitor);
100
mg::RenderableList list{
101
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 1.0f, false)
104
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
107
TEST_F(BypassMatchTest, offset_fullscreen_window_not_bypassed)
109
mc::BypassMatch matcher(primary_monitor);
111
mg::RenderableList list{
112
std::make_shared<mtd::FakeRenderable>(10, 50, 1920, 1200)
115
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
118
TEST_F(BypassMatchTest, obscured_fullscreen_window_not_bypassed)
120
mc::BypassMatch matcher(primary_monitor);
122
mg::RenderableList list{
123
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200),
124
std::make_shared<mtd::FakeRenderable>(20, 30, 40, 50)
127
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
130
TEST_F(BypassMatchTest, translucently_obscured_fullscreen_window_not_bypassed)
142
131
{ // Regression test for LP: #1266385
143
BypassFilter filter(display_buffer[0]);
145
FakeRenderable fs(0, 0, 1920, 1200);
146
FakeRenderable small(20, 30, 40, 50, 0.5f);
148
EXPECT_TRUE(filter(fs));
149
EXPECT_FALSE(filter(small));
150
EXPECT_FALSE(filter.fullscreen_on_top());
153
TEST_F(BypassFilterTest, unobscured_fullscreen_window_bypassed)
155
BypassFilter filter(display_buffer[0]);
157
FakeRenderable fs(0, 0, 1920, 1200);
158
FakeRenderable small(20, 30, 40, 50);
160
EXPECT_FALSE(filter(small));
161
EXPECT_TRUE(filter(fs));
162
EXPECT_TRUE(filter.fullscreen_on_top());
165
TEST_F(BypassFilterTest, unobscured_fullscreen_alpha_window_not_bypassed)
167
BypassFilter filter(display_buffer[0]);
169
FakeRenderable fs(0, 0, 1920, 1200, 0.9f);
170
FakeRenderable small(20, 30, 40, 50);
172
EXPECT_FALSE(filter(small));
173
EXPECT_FALSE(filter(fs));
174
EXPECT_FALSE(filter.fullscreen_on_top());
177
TEST_F(BypassFilterTest, many_fullscreen_windows_only_bypass_top)
179
BypassFilter filter(display_buffer[0]);
181
FakeRenderable a(0, 0, 1920, 1200);
182
EXPECT_TRUE(filter(a));
183
EXPECT_TRUE(filter.fullscreen_on_top());
185
FakeRenderable b(1, 2, 3, 4);
186
EXPECT_FALSE(filter(b));
187
EXPECT_FALSE(filter.fullscreen_on_top());
189
FakeRenderable c(0, 0, 1920, 1200);
190
EXPECT_TRUE(filter(c));
191
EXPECT_TRUE(filter.fullscreen_on_top());
193
FakeRenderable d(5, 6, 7, 8);
194
EXPECT_FALSE(filter(d));
195
EXPECT_FALSE(filter.fullscreen_on_top());
197
FakeRenderable e(0, 0, 1920, 1200);
198
EXPECT_TRUE(filter(e));
199
EXPECT_TRUE(filter.fullscreen_on_top());
201
FakeRenderable f(9, 10, 11, 12);
202
EXPECT_FALSE(filter(f));
203
EXPECT_FALSE(filter.fullscreen_on_top());
205
FakeRenderable g(0, 0, 1920, 1200);
206
EXPECT_TRUE(filter(g));
207
EXPECT_TRUE(filter.fullscreen_on_top());
210
TEST_F(BypassFilterTest, many_fullscreen_windows_only_bypass_top_rectangular)
212
BypassFilter filter(display_buffer[0]);
214
FakeRenderable a(0, 0, 1920, 1200, 1.0f, false);
215
EXPECT_FALSE(filter(a));
216
EXPECT_FALSE(filter.fullscreen_on_top());
218
FakeRenderable b(1, 2, 3, 4);
219
EXPECT_FALSE(filter(b));
220
EXPECT_FALSE(filter.fullscreen_on_top());
222
FakeRenderable c(0, 0, 1920, 1200);
223
EXPECT_TRUE(filter(c));
224
EXPECT_TRUE(filter.fullscreen_on_top());
226
FakeRenderable d(5, 6, 7, 8);
227
EXPECT_FALSE(filter(d));
228
EXPECT_FALSE(filter.fullscreen_on_top());
230
FakeRenderable e(0, 0, 1920, 1200, 1.0f, true);
231
EXPECT_TRUE(filter(e));
232
EXPECT_TRUE(filter.fullscreen_on_top());
234
FakeRenderable f(9, 10, 11, 12);
235
EXPECT_FALSE(filter(f));
236
EXPECT_FALSE(filter.fullscreen_on_top());
238
FakeRenderable g(0, 0, 1920, 1200, 0.5f, false);
239
EXPECT_FALSE(filter(g));
240
EXPECT_FALSE(filter.fullscreen_on_top());
243
TEST_F(BypassFilterTest, many_fullscreen_windows_only_bypass_top_visible_posted)
245
BypassFilter filter(display_buffer[0]);
247
FakeRenderable a(0, 0, 1920, 1200, 1.0f, false);
248
EXPECT_FALSE(filter(a));
249
EXPECT_FALSE(filter.fullscreen_on_top());
251
FakeRenderable b(1, 2, 3, 4);
252
EXPECT_FALSE(filter(b));
253
EXPECT_FALSE(filter.fullscreen_on_top());
255
FakeRenderable c(0, 0, 1920, 1200);
256
EXPECT_TRUE(filter(c));
257
EXPECT_TRUE(filter.fullscreen_on_top());
259
FakeRenderable d(5, 6, 7, 8);
260
EXPECT_FALSE(filter(d));
261
EXPECT_FALSE(filter.fullscreen_on_top());
263
FakeRenderable e(0, 0, 1920, 1200, 1.0f, true, false, true);
264
EXPECT_FALSE(filter(e));
265
EXPECT_FALSE(filter.fullscreen_on_top());
267
FakeRenderable f(0, 0, 1920, 1200, 1.0f, true, true, false);
268
EXPECT_FALSE(filter(f));
269
EXPECT_FALSE(filter.fullscreen_on_top());
271
FakeRenderable g(9, 10, 11, 12);
272
EXPECT_FALSE(filter(g));
273
EXPECT_FALSE(filter.fullscreen_on_top());
275
FakeRenderable h(0, 0, 1920, 1200, 1.0f, true, true, true);
276
EXPECT_TRUE(filter(h));
277
EXPECT_TRUE(filter.fullscreen_on_top());
280
TEST_F(BypassFilterTest, multimonitor_one_bypassed)
282
BypassFilter left(display_buffer[0]);
283
BypassFilter right(display_buffer[1]);
285
FakeRenderable fs(1920, 0, 1920, 1200);
286
FakeRenderable small(20, 30, 40, 50);
288
EXPECT_FALSE(left(small));
289
EXPECT_FALSE(left.fullscreen_on_top());
290
EXPECT_FALSE(left(fs));
291
EXPECT_FALSE(left.fullscreen_on_top());
293
EXPECT_FALSE(right(small));
294
EXPECT_FALSE(right.fullscreen_on_top());
295
EXPECT_TRUE(right(fs));
296
EXPECT_TRUE(right.fullscreen_on_top());
297
EXPECT_FALSE(right(small));
298
EXPECT_TRUE(right.fullscreen_on_top());
301
TEST_F(BypassFilterTest, dual_bypass)
303
BypassFilter left_filter(display_buffer[0]);
304
BypassFilter right_filter(display_buffer[1]);
306
FakeRenderable left_win(0, 0, 1920, 1200);
307
FakeRenderable right_win(1920, 0, 1920, 1200);
309
EXPECT_TRUE(left_filter(left_win));
310
EXPECT_TRUE(left_filter.fullscreen_on_top());
311
EXPECT_FALSE(left_filter(right_win));
312
EXPECT_TRUE(left_filter.fullscreen_on_top());
314
EXPECT_FALSE(right_filter(left_win));
315
EXPECT_FALSE(right_filter.fullscreen_on_top());
316
EXPECT_TRUE(right_filter(right_win));
317
EXPECT_TRUE(right_filter.fullscreen_on_top());
320
TEST_F(BypassFilterTest, multimonitor_oversized_no_bypass)
322
BypassFilter left_filter(display_buffer[0]);
323
BypassFilter right_filter(display_buffer[1]);
325
FakeRenderable big_win(0, 0, 3840, 1200);
327
EXPECT_FALSE(left_filter(big_win));
328
EXPECT_FALSE(left_filter.fullscreen_on_top());
330
EXPECT_FALSE(right_filter(big_win));
331
EXPECT_FALSE(right_filter.fullscreen_on_top());
334
TEST(BypassMatchTest, defaults_to_null)
338
EXPECT_EQ(nullptr, match.topmost_fullscreen());
341
TEST(BypassMatchTest, returns_one)
344
FakeRenderable win(1, 2, 3, 4);
346
EXPECT_EQ(nullptr, match.topmost_fullscreen());
348
EXPECT_EQ(&win, match.topmost_fullscreen());
351
TEST(BypassMatchTest, returns_latest)
354
FakeRenderable a(1, 2, 3, 4), b(5, 6, 7, 8), c(9, 10, 11, 12);
356
EXPECT_EQ(nullptr, match.topmost_fullscreen());
358
EXPECT_EQ(&a, match.topmost_fullscreen());
360
EXPECT_EQ(&b, match.topmost_fullscreen());
362
EXPECT_EQ(&c, match.topmost_fullscreen());
363
EXPECT_EQ(&c, match.topmost_fullscreen());
364
EXPECT_EQ(&c, match.topmost_fullscreen());
132
mc::BypassMatch matcher(primary_monitor);
134
mg::RenderableList list{
135
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200),
136
std::make_shared<mtd::FakeRenderable>(20, 30, 40, 50, 0.5f)
139
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
142
TEST_F(BypassMatchTest, unobscured_fullscreen_window_bypassed)
144
mc::BypassMatch matcher(primary_monitor);
146
auto bypassed = std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200);
147
mg::RenderableList list{
148
std::make_shared<mtd::FakeRenderable>(20, 30, 40, 50),
152
auto it = std::find_if(list.rbegin(), list.rend(), matcher);
153
EXPECT_NE(list.rend(), it);
154
EXPECT_EQ(bypassed, *it);
157
TEST_F(BypassMatchTest, unobscured_fullscreen_alpha_window_not_bypassed)
159
mc::BypassMatch matcher(primary_monitor);
161
mg::RenderableList list{
162
std::make_shared<mtd::FakeRenderable>(20, 30, 40, 50),
163
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 0.9f)
166
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
169
TEST_F(BypassMatchTest, many_fullscreen_windows_only_bypass_top)
171
mc::BypassMatch matcher(primary_monitor);
173
auto bypassed = std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200);
174
auto fullscreen_not_bypassed = std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200);
175
mg::RenderableList list{
176
fullscreen_not_bypassed,
177
std::make_shared<mtd::FakeRenderable>(9, 10, 11, 12),
178
fullscreen_not_bypassed,
179
std::make_shared<mtd::FakeRenderable>(5, 6, 7, 8),
180
fullscreen_not_bypassed,
181
std::make_shared<mtd::FakeRenderable>(1, 2, 3, 4),
185
auto it = std::find_if(list.rbegin(), list.rend(), matcher);
186
EXPECT_NE(list.rend(), it);
187
EXPECT_EQ(bypassed, *it);
190
TEST_F(BypassMatchTest, many_fullscreen_windows_only_bypass_top_rectangular)
192
mc::BypassMatch matcher(primary_monitor);
194
auto bypassed = std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200);
195
mg::RenderableList list{
196
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 0.5f, false),
197
std::make_shared<mtd::FakeRenderable>(9, 10, 11, 12),
198
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 1.0f, true),
199
std::make_shared<mtd::FakeRenderable>(5, 6, 7, 8),
200
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200),
201
std::make_shared<mtd::FakeRenderable>(1, 2, 3, 4),
202
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 1.0f, false),
206
auto it = std::find_if(list.rbegin(), list.rend(), matcher);
207
EXPECT_NE(list.rend(), it);
208
EXPECT_EQ(bypassed, *it);
211
TEST_F(BypassMatchTest, nonrectangular_not_bypassable)
213
mc::BypassMatch matcher(primary_monitor);
215
auto bypassed = std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200);
216
auto fullscreen_not_bypassed = std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200);
217
mg::RenderableList list{
218
std::make_shared<mtd::FakeRenderable>(1, 2, 3, 4),
219
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 1.0f, false)
222
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
225
TEST_F(BypassMatchTest, nonvisible_not_bypassble)
227
mc::BypassMatch matcher(primary_monitor);
228
mg::RenderableList list{
229
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 1.0f, true, false, true)
232
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
235
TEST_F(BypassMatchTest, offscreen_not_bypassable)
237
mc::BypassMatch matcher(primary_monitor);
238
mg::RenderableList list{
239
std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200, 1.0f, true, true, false)
241
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), matcher));
244
TEST_F(BypassMatchTest, multimonitor_one_bypassed)
246
mc::BypassMatch primary_matcher(primary_monitor);
247
mc::BypassMatch secondary_matcher(secondary_monitor);
249
auto bypassed = std::make_shared<mtd::FakeRenderable>(1920, 0, 1920, 1200);
250
mg::RenderableList list{
251
std::make_shared<mtd::FakeRenderable>(20, 30, 40, 50),
255
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), primary_matcher));
257
auto it = std::find_if(list.rbegin(), list.rend(), secondary_matcher);
258
EXPECT_NE(list.rend(), it);
259
EXPECT_EQ(bypassed, *it);
262
TEST_F(BypassMatchTest, dual_bypass)
264
mc::BypassMatch primary_matcher(primary_monitor);
265
mc::BypassMatch secondary_matcher(secondary_monitor);
267
auto primary_bypassed = std::make_shared<mtd::FakeRenderable>(0, 0, 1920, 1200);
268
auto secondary_bypassed = std::make_shared<mtd::FakeRenderable>(1920, 0, 1920, 1200);
269
mg::RenderableList list{
274
auto it = std::find_if(list.rbegin(), list.rend(), primary_matcher);
275
EXPECT_NE(list.rend(), it);
276
EXPECT_EQ(primary_bypassed, *it);
278
it = std::find_if(list.rbegin(), list.rend(), secondary_matcher);
279
EXPECT_NE(list.rend(), it);
280
EXPECT_EQ(secondary_bypassed, *it);
283
TEST_F(BypassMatchTest, multimonitor_oversized_no_bypass)
285
mc::BypassMatch primary_matcher(primary_monitor);
286
mc::BypassMatch secondary_matcher(secondary_monitor);
288
mg::RenderableList list{
289
std::make_shared<mtd::FakeRenderable>(0, 0, 3840, 1200)
292
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), primary_matcher));
293
EXPECT_EQ(list.rend(), std::find_if(list.rbegin(), list.rend(), secondary_matcher));