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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/base/x/x11_window_cache_unittest.cc
diff --git a/ui/base/x/x11_window_cache_unittest.cc b/ui/base/x/x11_window_cache_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..446302592f27889317c1e006902ad37dc96cb5e3
--- /dev/null
+++ b/ui/base/x/x11_window_cache_unittest.cc
@@ -0,0 +1,426 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/base/x/x11_window_cache.h"
+
+#include "base/macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/x/x11_types.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+namespace ui {
+
+class XWindowCacheTest : public testing::Test {
+ public:
+ XWindowCacheTest()
+ : display_(gfx::GetXDisplay()),
+ root_(DefaultRootWindow(display_)),
+ testing_atom_(XInternAtom(display_, "CHROMIUM_TESTING_ATOM", False)) {}
+ ~XWindowCacheTest() override {}
+
+ protected:
+ void SetUp() override { XSynchronize(display_, True); }
+
+ void TearDown() override { XSynchronize(display_, False); }
+
+ void EnsureMemoryReclaimed(XWindowCache* cache) {
+ cache->Synchronize();
+ EXPECT_TRUE(cache->windows_.empty());
+ EXPECT_TRUE(cache->requests_.empty());
+ }
+
+ XID CreateWindow(XID parent) {
+ XSetWindowAttributes swa;
+ swa.override_redirect = True;
+ return XCreateWindow(display_, parent, 0, 0, 1, 1, 0, CopyFromParent,
+ InputOutput, CopyFromParent, CWOverrideRedirect, &swa);
+ }
+
+ void SetProperty8(XID window, XID property, uint8_t value) {
+ XChangeProperty(display_, window, property, XA_CARDINAL, 8, PropModeReplace,
+ &value, 1);
+ }
+
+ template <typename T>
+ void VerifyStackingOrder(const XWindowCache::Window* window,
+ const T& container) {
+ EXPECT_TRUE(window);
+ EXPECT_EQ(window->children.size(), container.size());
+ auto it = window->children.begin();
+ for (XID id : container)
+ EXPECT_EQ(id, (*it++)->id);
+ }
+
+ XDisplay* display_;
+ XID root_;
+ XAtom testing_atom_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(XWindowCacheTest);
+};
+
+TEST_F(XWindowCacheTest, BasicTest) {
+ XID parent_xid = CreateWindow(root_);
+ XID child1_xid = CreateWindow(parent_xid);
+ XID child2_xid = CreateWindow(parent_xid);
+
+ XWindowCache cache(display_, parent_xid);
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+ auto parent_window = cache.GetWindow(parent_xid);
+ EXPECT_TRUE(parent_window);
+ EXPECT_EQ(parent_window->children.size(), 2U);
+ auto it = parent_window->children.begin();
+ EXPECT_EQ((*it++)->id, child2_xid);
+ EXPECT_EQ((*it++)->id, child1_xid);
+
+ XDestroyWindow(display_, parent_xid);
+ EnsureMemoryReclaimed(&cache);
+}
+
+TEST_F(XWindowCacheTest, NestingTest) {
+ XID parent_xid = CreateWindow(root_);
+ XID child_xid = CreateWindow(parent_xid);
+ XID nested_child_xid = CreateWindow(child_xid);
+ SetProperty8(nested_child_xid, testing_atom_, 0x42);
+
+ XWindowCache cache(display_, parent_xid);
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+
+ auto parent_window = cache.GetWindow(parent_xid);
+ EXPECT_TRUE(parent_window);
+ EXPECT_EQ(parent_window->children.size(), 1U);
+ EXPECT_EQ(parent_window->properties.size(), 0U);
+
+ auto child_window = parent_window->children.front();
+ EXPECT_TRUE(child_window);
+ EXPECT_EQ(child_window->children.size(), 1U);
+ EXPECT_EQ(child_window->properties.size(), 0U);
+
+ auto nested_child_window = child_window->children.front();
+ EXPECT_TRUE(nested_child_window);
+ EXPECT_EQ(nested_child_window->children.size(), 0U);
+ EXPECT_EQ(nested_child_window->properties.size(), 1U);
+
+ auto prop = nested_child_window->GetProperty(testing_atom_);
+ EXPECT_TRUE(prop);
+ EXPECT_TRUE(prop->cached_property);
+ EXPECT_EQ(prop->type, XA_CARDINAL);
+ EXPECT_EQ(prop->data_format, 8);
+ EXPECT_EQ(prop->data_length, 1);
+ EXPECT_EQ(prop->data.bits_8[0], 0x42);
+
+ XDestroyWindow(display_, parent_xid);
+ EnsureMemoryReclaimed(&cache);
+}
+
+TEST_F(XWindowCacheTest, CreateNotifyAndDestroyNotifyTest) {
+ XID parent_xid = CreateWindow(root_);
+
+ XWindowCache cache(display_, parent_xid);
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+
+ XID child1_xid = CreateWindow(parent_xid);
+ XID child2_xid = CreateWindow(parent_xid);
+
+ EXPECT_TRUE(cache.Synchronize());
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+
+ auto parent_window = cache.GetWindow(parent_xid);
+ EXPECT_TRUE(parent_window);
+ EXPECT_EQ(parent_window->children.size(), 2U);
+ auto it = parent_window->children.begin();
+ EXPECT_EQ((*it++)->id, child2_xid);
+ EXPECT_EQ((*it++)->id, child1_xid);
+
+ XDestroyWindow(display_, child1_xid);
+ XDestroyWindow(display_, child2_xid);
+
+ EXPECT_TRUE(cache.Synchronize());
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+
+ parent_window = cache.GetWindow(parent_xid);
+ EXPECT_TRUE(parent_window);
+ EXPECT_EQ(parent_window->children.size(), 0U);
+
+ XDestroyWindow(display_, parent_xid);
+ EnsureMemoryReclaimed(&cache);
+}
+
+TEST_F(XWindowCacheTest, PropertyNotifyTest) {
+ XID window_xid = CreateWindow(root_);
+ SetProperty8(window_xid, testing_atom_, 0x42);
+
+ XWindowCache cache(display_, window_xid);
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+
+ auto window = cache.GetWindow(window_xid);
+ EXPECT_TRUE(window);
+ EXPECT_EQ(window->children.size(), 0U);
+ EXPECT_EQ(window->properties.size(), 1U);
+
+ auto prop = window->GetProperty(testing_atom_);
+ EXPECT_TRUE(prop);
+ EXPECT_TRUE(prop->cached_property);
+ EXPECT_EQ(prop->type, XA_CARDINAL);
+ EXPECT_EQ(prop->data_format, 8);
+ EXPECT_EQ(prop->data_length, 1);
+ EXPECT_EQ(prop->data.bits_8[0], 0x42);
+
+ SetProperty8(window_xid, testing_atom_, 0x24);
+ EXPECT_TRUE(cache.Synchronize());
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+
+ prop = window->GetProperty(testing_atom_);
+ EXPECT_TRUE(prop);
+ EXPECT_TRUE(prop->cached_property);
+ EXPECT_EQ(prop->type, XA_CARDINAL);
+ EXPECT_EQ(prop->data_format, 8);
+ EXPECT_EQ(prop->data_length, 1);
+ EXPECT_EQ(prop->data.bits_8[0], 0x24);
+
+ XDestroyWindow(display_, window_xid);
+ EnsureMemoryReclaimed(&cache);
+}
+
+TEST_F(XWindowCacheTest, MapNotifyUnmapNotifyTest) {
+ XID window_xid = CreateWindow(root_);
+
+ XWindowCache cache(display_, window_xid);
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+
+ auto window = cache.GetWindow(window_xid);
+ EXPECT_TRUE(window);
+ EXPECT_TRUE(window->cached_attributes);
+ EXPECT_FALSE(window->is_mapped);
+
+ XMapWindow(display_, window_xid);
+ EXPECT_TRUE(cache.Synchronize());
+ EXPECT_TRUE(window->is_mapped);
+
+ XUnmapWindow(display_, window_xid);
+ EXPECT_TRUE(cache.Synchronize());
+ EXPECT_FALSE(window->is_mapped);
+
+ XDestroyWindow(display_, window_xid);
+ EnsureMemoryReclaimed(&cache);
+}
+
+TEST_F(XWindowCacheTest, CirculateNotifyTest) {
+ XID parent_xid = CreateWindow(root_);
+
+ std::list<XID> children_xids;
+ for (int i = 0; i < 10; i++) {
+ XID child = CreateWindow(parent_xid);
+ children_xids.push_front(child);
+ XMapWindow(display_, child);
+ }
+
+ XWindowCache cache(display_, parent_xid);
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+ VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
+
+ XID child;
+ XCirculateSubwindowsUp(display_, parent_xid);
+ child = children_xids.back();
+ children_xids.pop_back();
+ children_xids.push_front(child);
+ EXPECT_TRUE(cache.Synchronize());
+ VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
+
+ XCirculateSubwindowsDown(display_, parent_xid);
+ child = children_xids.front();
+ children_xids.pop_front();
+ children_xids.push_back(child);
+ EXPECT_TRUE(cache.Synchronize());
+ VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
+
+ XDestroyWindow(display_, parent_xid);
+ EnsureMemoryReclaimed(&cache);
+}
+
+TEST_F(XWindowCacheTest, ConfigureNotifyTest) {
+ XID window_xid = CreateWindow(root_);
+
+ XWindowCache cache(display_, window_xid);
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+ auto window = cache.GetWindow(window_xid);
+ EXPECT_TRUE(window);
+ EXPECT_TRUE(window->cached_attributes);
+ EXPECT_TRUE(window->cached_geometry);
+
+ EXPECT_EQ(window->x, 0);
+ EXPECT_EQ(window->y, 0);
+ XMoveWindow(display_, window_xid, 1, 1);
+ EXPECT_TRUE(cache.Synchronize());
+ EXPECT_EQ(window->x, 1);
+ EXPECT_EQ(window->y, 1);
+
+ EXPECT_EQ(window->width, 1U);
+ EXPECT_EQ(window->height, 1U);
+ XResizeWindow(display_, window_xid, 2, 2);
+ EXPECT_TRUE(cache.Synchronize());
+ EXPECT_EQ(window->width, 2U);
+ EXPECT_EQ(window->height, 2U);
+
+ EXPECT_EQ(window->border_width, 0U);
+ XSetWindowBorderWidth(display_, window_xid, 1);
+ EXPECT_TRUE(cache.Synchronize());
+ EXPECT_EQ(window->border_width, 1U);
+
+ XDestroyWindow(display_, window_xid);
+ EnsureMemoryReclaimed(&cache);
+}
+
+TEST_F(XWindowCacheTest, StackingOrderTest) {
+ XID parent_xid = CreateWindow(root_);
+
+ std::vector<XID> children_xids;
+ for (int i = 0; i < 10; i++) {
+ XID child = CreateWindow(parent_xid);
+ children_xids.push_back(child);
+ XMapWindow(display_, child);
+ }
+ std::reverse(children_xids.begin(), children_xids.end());
+
+ XWindowCache cache(display_, parent_xid);
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+ VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
+
+ // XRaiseWindow
+ // Raise window 5
+ XID child = children_xids[5];
+ XRaiseWindow(display_, child);
+ children_xids.erase(children_xids.begin() + 5);
+ children_xids.insert(children_xids.begin(), child);
+ EXPECT_TRUE(cache.Synchronize());
+ VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
+
+ // XLowerWindow
+ // Lower window 5
+ child = children_xids[5];
+ XLowerWindow(display_, child);
+ children_xids.erase(children_xids.begin() + 5);
+ children_xids.insert(children_xids.end(), child);
+ EXPECT_TRUE(cache.Synchronize());
+ VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
+
+ // XRestackWindows
+ // Stack window 2 below window 6
+ XID restack_windows[2] = {children_xids[6], children_xids[2]};
+ child = children_xids[2];
+ children_xids.erase(children_xids.begin() + 2);
+ children_xids.insert(children_xids.begin() + 6, child);
+ XRestackWindows(display_, restack_windows, 2);
+ EXPECT_TRUE(cache.Synchronize());
+ VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
+
+ // XConfigureWindow
+ // Stack window 2 below window 6
+ XWindowChanges changes;
+ child = children_xids[2];
+ changes.sibling = children_xids[6];
+ changes.stack_mode = Below;
+ children_xids.erase(children_xids.begin() + 2);
+ children_xids.insert(children_xids.begin() + 6, child);
+ XConfigureWindow(display_, child, CWSibling | CWStackMode, &changes);
+ EXPECT_TRUE(cache.Synchronize());
+ VerifyStackingOrder(cache.GetWindow(parent_xid), children_xids);
+
+ XDestroyWindow(display_, parent_xid);
+ EnsureMemoryReclaimed(&cache);
+}
+
+TEST_F(XWindowCacheTest, GravityNotifyTest) {
+ XID parent_xid = CreateWindow(root_);
+ XID child_xid = CreateWindow(parent_xid);
+
+ XSetWindowAttributes swa;
+ swa.bit_gravity = ForgetGravity;
+ swa.win_gravity = NorthEastGravity;
+ XChangeWindowAttributes(display_, child_xid, CWBitGravity | CWWinGravity,
+ &swa);
+
+ XResizeWindow(display_, parent_xid, 100, 100);
+ XResizeWindow(display_, child_xid, 25, 25);
+ XMoveWindow(display_, child_xid, 75, 0);
+
+ XWindowCache cache(display_, parent_xid);
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+
+ auto parent = cache.GetWindow(parent_xid);
+ EXPECT_TRUE(parent);
+ EXPECT_EQ(parent->x, 0);
+ EXPECT_EQ(parent->y, 0);
+ EXPECT_EQ(parent->width, 100U);
+ EXPECT_EQ(parent->height, 100U);
+ auto child = cache.GetWindow(child_xid);
+ EXPECT_TRUE(child);
+ EXPECT_EQ(child->x, 75);
+ EXPECT_EQ(child->y, 0);
+
+ XResizeWindow(display_, parent_xid, 50, 50);
+ EXPECT_TRUE(cache.Synchronize());
+
+ EXPECT_EQ(child->x, 25);
+ EXPECT_EQ(child->y, 0);
+
+ XDestroyWindow(display_, parent_xid);
+ EnsureMemoryReclaimed(&cache);
+}
+
+TEST_F(XWindowCacheTest, ReparentNotifyTest) {
+ // Start with this tree:
+ //
+ // child1 -- grandchild
+ // /
+ // parent
+ // \
+ // child2
+ XID parent_xid = CreateWindow(root_);
+ XID child1_xid = CreateWindow(parent_xid);
+ XID child2_xid = CreateWindow(parent_xid);
+ XID grandchild_xid = CreateWindow(child1_xid);
+
+ XWindowCache cache(display_, parent_xid);
+ EXPECT_TRUE(cache.BlockUntilTreeIsCached());
+ auto parent = cache.GetWindow(parent_xid);
+ auto child1 = cache.GetWindow(child1_xid);
+ auto child2 = cache.GetWindow(child2_xid);
+ auto grandchild = cache.GetWindow(grandchild_xid);
+
+ EXPECT_TRUE(parent);
+ EXPECT_TRUE(child1);
+ EXPECT_TRUE(child2);
+ EXPECT_TRUE(grandchild);
+ EXPECT_EQ(parent->children.size(), 2U);
+ EXPECT_EQ(child1->children.size(), 1U);
+ EXPECT_EQ(child2->children.size(), 0U);
+ EXPECT_EQ(grandchild->children.size(), 0U);
+ EXPECT_EQ(child1->children.front(), grandchild);
+ EXPECT_EQ(grandchild->parent, child1);
+
+ // Reparent grandchild so the tree now looks like this:
+ //
+ // child1
+ // /
+ // parent
+ // \
+ // child2 -- grandchild
+ XReparentWindow(display_, grandchild_xid, child2_xid, 0, 0);
+ EXPECT_TRUE(cache.Synchronize());
+
+ EXPECT_EQ(parent->children.size(), 2U);
+ EXPECT_EQ(child1->children.size(), 0U);
+ EXPECT_EQ(child2->children.size(), 1U);
+ EXPECT_EQ(grandchild->children.size(), 0U);
+ EXPECT_EQ(child2->children.front(), grandchild);
+ EXPECT_EQ(grandchild->parent, child2);
+
+ XDestroyWindow(display_, parent_xid);
+ EnsureMemoryReclaimed(&cache);
+}
+
+} // namespace ui
« 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