Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(587)

Side by Side Diff: ui/base/x/x11_window_cache_unittest.cc

Issue 2199063003: Linux: Add xcb FD to glib event loop (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Refactor Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/base/x/x11_window_cache.h"
6
7 #include "base/macros.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/gfx/x/x11_types.h"
10
11 #include <X11/Xlib.h>
12 #include <X11/Xatom.h>
13
14 namespace ui {
15
16 class XWindowCacheTest : public testing::Test {
17 public:
18 XWindowCacheTest()
19 : display_(gfx::GetXDisplay()),
20 root_(DefaultRootWindow(display_)),
21 testing_atom_(XInternAtom(display_, "CHROMIUM_TESTING_ATOM", False)) {}
22 ~XWindowCacheTest() override {}
23
24 protected:
25 void SetUp() override { XSynchronize(display_, True); }
26
27 void TearDown() override { XSynchronize(display_, False); }
28
29 void EnsureMemoryReclaimed(XWindowCache* cache) {
30 cache->Synchronize();
31 EXPECT_TRUE(cache->windows_.empty());
32 EXPECT_TRUE(cache->requests_.empty());
33 }
34
35 XID CreateWindow(XID parent) {
36 XSetWindowAttributes swa;
37 swa.override_redirect = True;
38 return XCreateWindow(display_, parent, 0, 0, 1, 1, 0, CopyFromParent,
39 InputOutput, CopyFromParent, CWOverrideRedirect, &swa);
40 }
41
42 void SetProperty8(XID window, XID property, uint8_t value) {
43 XChangeProperty(display_, window, property, XA_CARDINAL, 8, PropModeReplace,
44 &value, 1);
45 }
46
47 template <typename T>
48 void VerifyStackingOrder(const XWindowCache::Window* window,
49 const T& container) {
50 EXPECT_TRUE(window);
51 EXPECT_EQ(window->children.size(), container.size());
52 auto it = window->children.begin();
53 for (XID id : container)
54 EXPECT_EQ(id, (*it++)->id);
55 }
56
57 XDisplay* display_;
58 XID root_;
59 XAtom testing_atom_;
60
61 private:
62 DISALLOW_COPY_AND_ASSIGN(XWindowCacheTest);
63 };
64
65 TEST_F(XWindowCacheTest, BasicTest) {
66 XID parent_xid = CreateWindow(root_);
67 XID child1_xid = CreateWindow(parent_xid);
68 XID child2_xid = CreateWindow(parent_xid);
69
70 XWindowCache cache(display_, parent_xid);
71 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
72 auto parent_window = cache.GetWindow(parent_xid);
73 EXPECT_TRUE(parent_window);
74 EXPECT_EQ(parent_window->children.size(), 2U);
75 auto it = parent_window->children.begin();
76 EXPECT_EQ((*it++)->id, child2_xid);
77 EXPECT_EQ((*it++)->id, child1_xid);
78
79 XDestroyWindow(display_, parent_xid);
80 EnsureMemoryReclaimed(&cache);
81 }
82
83 TEST_F(XWindowCacheTest, NestingTest) {
84 XID parent_xid = CreateWindow(root_);
85 XID child_xid = CreateWindow(parent_xid);
86 XID nested_child_xid = CreateWindow(child_xid);
87 SetProperty8(nested_child_xid, testing_atom_, 0x42);
88
89 XWindowCache cache(display_, parent_xid);
90 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
91
92 auto parent_window = cache.GetWindow(parent_xid);
93 EXPECT_TRUE(parent_window);
94 EXPECT_EQ(parent_window->children.size(), 1U);
95 EXPECT_EQ(parent_window->properties.size(), 0U);
96
97 auto child_window = parent_window->children.front();
98 EXPECT_TRUE(child_window);
99 EXPECT_EQ(child_window->children.size(), 1U);
100 EXPECT_EQ(child_window->properties.size(), 0U);
101
102 auto nested_child_window = child_window->children.front();
103 EXPECT_TRUE(nested_child_window);
104 EXPECT_EQ(nested_child_window->children.size(), 0U);
105 EXPECT_EQ(nested_child_window->properties.size(), 1U);
106
107 auto prop = nested_child_window->GetProperty(testing_atom_);
108 EXPECT_TRUE(prop);
109 EXPECT_TRUE(prop->cached_property);
110 EXPECT_EQ(prop->type, XA_CARDINAL);
111 EXPECT_EQ(prop->data_format, 8);
112 EXPECT_EQ(prop->data_length, 1);
113 EXPECT_EQ(prop->data.bits_8[0], 0x42);
114
115 XDestroyWindow(display_, parent_xid);
116 EnsureMemoryReclaimed(&cache);
117 }
118
119 TEST_F(XWindowCacheTest, CreateNotifyAndDestroyNotifyTest) {
120 XID parent_xid = CreateWindow(root_);
121
122 XWindowCache cache(display_, parent_xid);
123 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
124
125 XID child1_xid = CreateWindow(parent_xid);
126 XID child2_xid = CreateWindow(parent_xid);
127
128 EXPECT_TRUE(cache.Synchronize());
129 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
130
131 auto parent_window = cache.GetWindow(parent_xid);
132 EXPECT_TRUE(parent_window);
133 EXPECT_EQ(parent_window->children.size(), 2U);
134 auto it = parent_window->children.begin();
135 EXPECT_EQ((*it++)->id, child2_xid);
136 EXPECT_EQ((*it++)->id, child1_xid);
137
138 XDestroyWindow(display_, child1_xid);
139 XDestroyWindow(display_, child2_xid);
140
141 EXPECT_TRUE(cache.Synchronize());
142 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
143
144 parent_window = cache.GetWindow(parent_xid);
145 EXPECT_TRUE(parent_window);
146 EXPECT_EQ(parent_window->children.size(), 0U);
147
148 XDestroyWindow(display_, parent_xid);
149 EnsureMemoryReclaimed(&cache);
150 }
151
152 TEST_F(XWindowCacheTest, PropertyNotifyTest) {
153 XID window_xid = CreateWindow(root_);
154 SetProperty8(window_xid, testing_atom_, 0x42);
155
156 XWindowCache cache(display_, window_xid);
157 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
158
159 auto window = cache.GetWindow(window_xid);
160 EXPECT_TRUE(window);
161 EXPECT_EQ(window->children.size(), 0U);
162 EXPECT_EQ(window->properties.size(), 1U);
163
164 auto prop = window->GetProperty(testing_atom_);
165 EXPECT_TRUE(prop);
166 EXPECT_TRUE(prop->cached_property);
167 EXPECT_EQ(prop->type, XA_CARDINAL);
168 EXPECT_EQ(prop->data_format, 8);
169 EXPECT_EQ(prop->data_length, 1);
170 EXPECT_EQ(prop->data.bits_8[0], 0x42);
171
172 SetProperty8(window_xid, testing_atom_, 0x24);
173 EXPECT_TRUE(cache.Synchronize());
174 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
175
176 prop = window->GetProperty(testing_atom_);
177 EXPECT_TRUE(prop);
178 EXPECT_TRUE(prop->cached_property);
179 EXPECT_EQ(prop->type, XA_CARDINAL);
180 EXPECT_EQ(prop->data_format, 8);
181 EXPECT_EQ(prop->data_length, 1);
182 EXPECT_EQ(prop->data.bits_8[0], 0x24);
183
184 XDestroyWindow(display_, window_xid);
185 EnsureMemoryReclaimed(&cache);
186 }
187
188 TEST_F(XWindowCacheTest, MapNotifyUnmapNotifyTest) {
189 XID window_xid = CreateWindow(root_);
190
191 XWindowCache cache(display_, window_xid);
192 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
193
194 auto window = cache.GetWindow(window_xid);
195 EXPECT_TRUE(window);
196 EXPECT_TRUE(window->cached_attributes);
197 EXPECT_FALSE(window->is_mapped);
198
199 XMapWindow(display_, window_xid);
200 EXPECT_TRUE(cache.Synchronize());
201 EXPECT_TRUE(window->is_mapped);
202
203 XUnmapWindow(display_, window_xid);
204 EXPECT_TRUE(cache.Synchronize());
205 EXPECT_FALSE(window->is_mapped);
206
207 XDestroyWindow(display_, window_xid);
208 EnsureMemoryReclaimed(&cache);
209 }
210
211 TEST_F(XWindowCacheTest, CirculateNotifyTest) {
212 XID parent_xid = CreateWindow(root_);
213
214 std::list<XID> children_xids;
215 for (int i = 0; i < 10; i++) {
216 XID child = CreateWindow(parent_xid);
217 children_xids.push_front(child);
218 XMapWindow(display_, child);
219 }
220
221 XWindowCache cache(display_, parent_xid);
222 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
223 VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
224
225 XID child;
226 XCirculateSubwindowsUp(display_, parent_xid);
227 child = children_xids.back();
228 children_xids.pop_back();
229 children_xids.push_front(child);
230 EXPECT_TRUE(cache.Synchronize());
231 VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
232
233 XCirculateSubwindowsDown(display_, parent_xid);
234 child = children_xids.front();
235 children_xids.pop_front();
236 children_xids.push_back(child);
237 EXPECT_TRUE(cache.Synchronize());
238 VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
239
240 XDestroyWindow(display_, parent_xid);
241 EnsureMemoryReclaimed(&cache);
242 }
243
244 TEST_F(XWindowCacheTest, ConfigureNotifyTest) {
245 XID window_xid = CreateWindow(root_);
246
247 XWindowCache cache(display_, window_xid);
248 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
249 auto window = cache.GetWindow(window_xid);
250 EXPECT_TRUE(window);
251 EXPECT_TRUE(window->cached_attributes);
252 EXPECT_TRUE(window->cached_geometry);
253
254 EXPECT_EQ(window->x, 0);
255 EXPECT_EQ(window->y, 0);
256 XMoveWindow(display_, window_xid, 1, 1);
257 EXPECT_TRUE(cache.Synchronize());
258 EXPECT_EQ(window->x, 1);
259 EXPECT_EQ(window->y, 1);
260
261 EXPECT_EQ(window->width, 1U);
262 EXPECT_EQ(window->height, 1U);
263 XResizeWindow(display_, window_xid, 2, 2);
264 EXPECT_TRUE(cache.Synchronize());
265 EXPECT_EQ(window->width, 2U);
266 EXPECT_EQ(window->height, 2U);
267
268 EXPECT_EQ(window->border_width, 0U);
269 XSetWindowBorderWidth(display_, window_xid, 1);
270 EXPECT_TRUE(cache.Synchronize());
271 EXPECT_EQ(window->border_width, 1U);
272
273 XDestroyWindow(display_, window_xid);
274 EnsureMemoryReclaimed(&cache);
275 }
276
277 TEST_F(XWindowCacheTest, StackingOrderTest) {
278 XID parent_xid = CreateWindow(root_);
279
280 std::vector<XID> children_xids;
281 for (int i = 0; i < 10; i++) {
282 XID child = CreateWindow(parent_xid);
283 children_xids.push_back(child);
284 XMapWindow(display_, child);
285 }
286 std::reverse(children_xids.begin(), children_xids.end());
287
288 XWindowCache cache(display_, parent_xid);
289 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
290 VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
291
292 // XRaiseWindow
293 // Raise window 5
294 XID child = children_xids[5];
295 XRaiseWindow(display_, child);
296 children_xids.erase(children_xids.begin() + 5);
297 children_xids.insert(children_xids.begin(), child);
298 EXPECT_TRUE(cache.Synchronize());
299 VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
300
301 // XLowerWindow
302 // Lower window 5
303 child = children_xids[5];
304 XLowerWindow(display_, child);
305 children_xids.erase(children_xids.begin() + 5);
306 children_xids.insert(children_xids.end(), child);
307 EXPECT_TRUE(cache.Synchronize());
308 VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
309
310 // XRestackWindows
311 // Stack window 2 below window 6
312 XID restack_windows[2] = {children_xids[6], children_xids[2]};
313 child = children_xids[2];
314 children_xids.erase(children_xids.begin() + 2);
315 children_xids.insert(children_xids.begin() + 6, child);
316 XRestackWindows(display_, restack_windows, 2);
317 EXPECT_TRUE(cache.Synchronize());
318 VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
319
320 // XConfigureWindow
321 // Stack window 2 below window 6
322 XWindowChanges changes;
323 child = children_xids[2];
324 changes.sibling = children_xids[6];
325 changes.stack_mode = Below;
326 children_xids.erase(children_xids.begin() + 2);
327 children_xids.insert(children_xids.begin() + 6, child);
328 XConfigureWindow(display_, child, CWSibling | CWStackMode, &changes);
329 EXPECT_TRUE(cache.Synchronize());
330 VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
331
332 XDestroyWindow(display_, parent_xid);
333 EnsureMemoryReclaimed(&cache);
334 }
335
336 TEST_F(XWindowCacheTest, GravityNotifyTest) {
337 XID parent_xid = CreateWindow(root_);
338 XID child_xid = CreateWindow(parent_xid);
339
340 XSetWindowAttributes swa;
341 swa.bit_gravity = ForgetGravity;
342 swa.win_gravity = NorthEastGravity;
343 XChangeWindowAttributes(display_, child_xid, CWBitGravity | CWWinGravity,
344 &swa);
345
346 XResizeWindow(display_, parent_xid, 100, 100);
347 XResizeWindow(display_, child_xid, 25, 25);
348 XMoveWindow(display_, child_xid, 75, 0);
349
350 XWindowCache cache(display_, parent_xid);
351 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
352
353 auto parent = cache.GetWindow(parent_xid);
354 EXPECT_TRUE(parent);
355 EXPECT_EQ(parent->x, 0);
356 EXPECT_EQ(parent->y, 0);
357 EXPECT_EQ(parent->width, 100U);
358 EXPECT_EQ(parent->height, 100U);
359 auto child = cache.GetWindow(child_xid);
360 EXPECT_TRUE(child);
361 EXPECT_EQ(child->x, 75);
362 EXPECT_EQ(child->y, 0);
363
364 XResizeWindow(display_, parent_xid, 50, 50);
365 EXPECT_TRUE(cache.Synchronize());
366
367 EXPECT_EQ(child->x, 25);
368 EXPECT_EQ(child->y, 0);
369
370 XDestroyWindow(display_, parent_xid);
371 EnsureMemoryReclaimed(&cache);
372 }
373
374 TEST_F(XWindowCacheTest, ReparentNotifyTest) {
375 // Start with this tree:
376 //
377 // child1 -- grandchild
378 // /
379 // parent
380 // \
381 // child2
382 XID parent_xid = CreateWindow(root_);
383 XID child1_xid = CreateWindow(parent_xid);
384 XID child2_xid = CreateWindow(parent_xid);
385 XID grandchild_xid = CreateWindow(child1_xid);
386
387 XWindowCache cache(display_, parent_xid);
388 EXPECT_TRUE(cache.BlockUntilTreeIsCached());
389 auto parent = cache.GetWindow(parent_xid);
390 auto child1 = cache.GetWindow(child1_xid);
391 auto child2 = cache.GetWindow(child2_xid);
392 auto grandchild = cache.GetWindow(grandchild_xid);
393
394 EXPECT_TRUE(parent);
395 EXPECT_TRUE(child1);
396 EXPECT_TRUE(child2);
397 EXPECT_TRUE(grandchild);
398 EXPECT_EQ(parent->children.size(), 2U);
399 EXPECT_EQ(child1->children.size(), 1U);
400 EXPECT_EQ(child2->children.size(), 0U);
401 EXPECT_EQ(grandchild->children.size(), 0U);
402 EXPECT_EQ(child1->children.front(), grandchild);
403 EXPECT_EQ(grandchild->parent, child1);
404
405 // Reparent grandchild so the tree now looks like this:
406 //
407 // child1
408 // /
409 // parent
410 // \
411 // child2 -- grandchild
412 XReparentWindow(display_, grandchild_xid, child2_xid, 0, 0);
413 EXPECT_TRUE(cache.Synchronize());
414
415 EXPECT_EQ(parent->children.size(), 2U);
416 EXPECT_EQ(child1->children.size(), 0U);
417 EXPECT_EQ(child2->children.size(), 1U);
418 EXPECT_EQ(grandchild->children.size(), 0U);
419 EXPECT_EQ(child2->children.front(), grandchild);
420 EXPECT_EQ(grandchild->parent, child2);
421
422 XDestroyWindow(display_, parent_xid);
423 EnsureMemoryReclaimed(&cache);
424 }
425
426 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/x/x11_window_cache_event_source.cc ('k') | ui/events/platform/x11/x11_event_source_glib.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698