Index: ui/views/widget/desktop_aura/x11_topmost_window_finder_unittest.cc |
diff --git a/ui/views/widget/desktop_aura/x11_topmost_window_finder_unittest.cc b/ui/views/widget/desktop_aura/x11_topmost_window_finder_unittest.cc |
deleted file mode 100644 |
index 7c719640abb511c4c6d7036eb4ce93cb89b5cc7d..0000000000000000000000000000000000000000 |
--- a/ui/views/widget/desktop_aura/x11_topmost_window_finder_unittest.cc |
+++ /dev/null |
@@ -1,393 +0,0 @@ |
-// Copyright 2014 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/views/widget/desktop_aura/x11_topmost_window_finder.h" |
- |
-#include <algorithm> |
-#include <vector> |
-#include <X11/extensions/shape.h> |
-#include <X11/Xlib.h> |
-#include <X11/Xregion.h> |
- |
-// Get rid of X11 macros which conflict with gtest. |
-#undef Bool |
-#undef None |
- |
-#include "base/memory/scoped_ptr.h" |
-#include "third_party/skia/include/core/SkRect.h" |
-#include "third_party/skia/include/core/SkRegion.h" |
-#include "ui/aura/window.h" |
-#include "ui/aura/window_tree_host.h" |
-#include "ui/events/platform/x11/x11_event_source.h" |
-#include "ui/gfx/path.h" |
-#include "ui/gfx/path_x11.h" |
-#include "ui/gfx/x/x11_atom_cache.h" |
-#include "ui/views/test/views_test_base.h" |
-#include "ui/views/test/x11_property_change_waiter.h" |
-#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" |
-#include "ui/views/widget/desktop_aura/x11_desktop_handler.h" |
-#include "ui/views/widget/widget.h" |
- |
-namespace views { |
- |
-namespace { |
- |
-// Waits till |window| is minimized. |
-class MinimizeWaiter : public X11PropertyChangeWaiter { |
- public: |
- explicit MinimizeWaiter(XID window) |
- : X11PropertyChangeWaiter(window, "_NET_WM_STATE") { |
- const char* kAtomsToCache[] = { "_NET_WM_STATE_HIDDEN", NULL }; |
- atom_cache_.reset(new ui::X11AtomCache(gfx::GetXDisplay(), kAtomsToCache)); |
- } |
- |
- virtual ~MinimizeWaiter() { |
- } |
- |
- private: |
- // X11PropertyChangeWaiter: |
- virtual bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) OVERRIDE { |
- std::vector<Atom> wm_states; |
- if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &wm_states)) { |
- std::vector<Atom>::iterator it = std::find( |
- wm_states.begin(), |
- wm_states.end(), |
- atom_cache_->GetAtom("_NET_WM_STATE_HIDDEN")); |
- return it == wm_states.end(); |
- } |
- return true; |
- } |
- |
- scoped_ptr<ui::X11AtomCache> atom_cache_; |
- |
- DISALLOW_COPY_AND_ASSIGN(MinimizeWaiter); |
-}; |
- |
-// Waits till |_NET_CLIENT_LIST_STACKING| is updated to include |
-// |expected_windows|. |
-class StackingClientListWaiter : public X11PropertyChangeWaiter { |
- public: |
- StackingClientListWaiter(XID* expected_windows, size_t count) |
- : X11PropertyChangeWaiter(ui::GetX11RootWindow(), |
- "_NET_CLIENT_LIST_STACKING"), |
- expected_windows_(expected_windows, expected_windows + count) { |
- } |
- |
- virtual ~StackingClientListWaiter() { |
- } |
- |
- // X11PropertyChangeWaiter: |
- virtual void Wait() OVERRIDE { |
- // StackingClientListWaiter may be created after |
- // _NET_CLIENT_LIST_STACKING already contains |expected_windows|. |
- if (!ShouldKeepOnWaiting(NULL)) |
- return; |
- |
- X11PropertyChangeWaiter::Wait(); |
- } |
- |
- private: |
- // X11PropertyChangeWaiter: |
- virtual bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) OVERRIDE { |
- std::vector<XID> stack; |
- ui::GetXWindowStack(ui::GetX11RootWindow(), &stack); |
- for (size_t i = 0; i < expected_windows_.size(); ++i) { |
- std::vector<XID>::iterator it = std::find( |
- stack.begin(), stack.end(), expected_windows_[i]); |
- if (it == stack.end()) |
- return true; |
- } |
- return false; |
- } |
- |
- std::vector<XID> expected_windows_; |
- |
- DISALLOW_COPY_AND_ASSIGN(StackingClientListWaiter); |
-}; |
- |
-} // namespace |
- |
-class X11TopmostWindowFinderTest : public ViewsTestBase { |
- public: |
- X11TopmostWindowFinderTest() { |
- } |
- |
- virtual ~X11TopmostWindowFinderTest() { |
- } |
- |
- // Creates and shows a Widget with |bounds|. The caller takes ownership of |
- // the returned widget. |
- scoped_ptr<Widget> CreateAndShowWidget(const gfx::Rect& bounds) { |
- scoped_ptr<Widget> toplevel(new Widget); |
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); |
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
- params.native_widget = new DesktopNativeWidgetAura(toplevel.get()); |
- params.bounds = bounds; |
- params.remove_standard_frame = true; |
- toplevel->Init(params); |
- toplevel->Show(); |
- return toplevel.Pass(); |
- } |
- |
- // Creates and shows an X window with |bounds|. |
- XID CreateAndShowXWindow(const gfx::Rect& bounds) { |
- XID root = DefaultRootWindow(xdisplay()); |
- XID xid = XCreateSimpleWindow(xdisplay(), |
- root, |
- 0, 0, 1, 1, |
- 0, // border_width |
- 0, // border |
- 0); // background |
- |
- ui::SetUseOSWindowFrame(xid, false); |
- ShowAndSetXWindowBounds(xid, bounds); |
- return xid; |
- } |
- |
- // Shows |xid| and sets its bounds. |
- void ShowAndSetXWindowBounds(XID xid, const gfx::Rect& bounds) { |
- XMapWindow(xdisplay(), xid); |
- |
- XWindowChanges changes = {0}; |
- changes.x = bounds.x(); |
- changes.y = bounds.y(); |
- changes.width = bounds.width(); |
- changes.height = bounds.height(); |
- XConfigureWindow(xdisplay(), |
- xid, |
- CWX | CWY | CWWidth | CWHeight, |
- &changes); |
- } |
- |
- Display* xdisplay() { |
- return gfx::GetXDisplay(); |
- } |
- |
- // Returns the topmost X window at the passed in screen position. |
- XID FindTopmostXWindowAt(int screen_x, int screen_y) { |
- X11TopmostWindowFinder finder; |
- return finder.FindWindowAt(gfx::Point(screen_x, screen_y)); |
- } |
- |
- // Returns the topmost aura::Window at the passed in screen position. Returns |
- // NULL if the topmost window does not have an associated aura::Window. |
- aura::Window* FindTopmostLocalProcessWindowAt(int screen_x, int screen_y) { |
- X11TopmostWindowFinder finder; |
- return finder.FindLocalProcessWindowAt(gfx::Point(screen_x, screen_y), |
- std::set<aura::Window*>()); |
- } |
- |
- // Returns the topmost aura::Window at the passed in screen position ignoring |
- // |ignore_window|. Returns NULL if the topmost window does not have an |
- // associated aura::Window. |
- aura::Window* FindTopmostLocalProcessWindowWithIgnore( |
- int screen_x, |
- int screen_y, |
- aura::Window* ignore_window) { |
- std::set<aura::Window*> ignore; |
- ignore.insert(ignore_window); |
- X11TopmostWindowFinder finder; |
- return finder.FindLocalProcessWindowAt(gfx::Point(screen_x, screen_y), |
- ignore); |
- } |
- |
- // ViewsTestBase: |
- virtual void SetUp() OVERRIDE { |
- ViewsTestBase::SetUp(); |
- |
- // Make X11 synchronous for our display connection. This does not force the |
- // window manager to behave synchronously. |
- XSynchronize(xdisplay(), True); |
- |
- // Ensure that the X11DesktopHandler exists. The X11DesktopHandler is |
- // necessary to properly track menu windows. |
- X11DesktopHandler::get(); |
- } |
- |
- virtual void TearDown() OVERRIDE { |
- XSynchronize(xdisplay(), False); |
- ViewsTestBase::TearDown(); |
- } |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(X11TopmostWindowFinderTest); |
-}; |
- |
-// Flaky on Linux. http://crbug.com/388241 |
-TEST_F(X11TopmostWindowFinderTest, DISABLED_Basic) { |
- // Avoid positioning test windows at 0x0 because window managers often have a |
- // panel/launcher along one of the screen edges and do not allow windows to |
- // position themselves to overlap the panel/launcher. |
- scoped_ptr<Widget> widget1( |
- CreateAndShowWidget(gfx::Rect(100, 100, 200, 100))); |
- aura::Window* window1 = widget1->GetNativeWindow(); |
- XID xid1 = window1->GetHost()->GetAcceleratedWidget(); |
- |
- XID xid2 = CreateAndShowXWindow(gfx::Rect(200, 100, 100, 200)); |
- |
- scoped_ptr<Widget> widget3( |
- CreateAndShowWidget(gfx::Rect(100, 190, 200, 110))); |
- aura::Window* window3 = widget3->GetNativeWindow(); |
- XID xid3 = window3->GetHost()->GetAcceleratedWidget(); |
- |
- XID xids[] = { xid1, xid2, xid3 }; |
- StackingClientListWaiter waiter(xids, arraysize(xids)); |
- waiter.Wait(); |
- ui::X11EventSource::GetInstance()->DispatchXEvents(); |
- |
- EXPECT_EQ(xid1, FindTopmostXWindowAt(150, 150)); |
- EXPECT_EQ(window1, FindTopmostLocalProcessWindowAt(150, 150)); |
- |
- EXPECT_EQ(xid2, FindTopmostXWindowAt(250, 150)); |
- EXPECT_EQ(NULL, FindTopmostLocalProcessWindowAt(250, 150)); |
- |
- EXPECT_EQ(xid3, FindTopmostXWindowAt(250, 250)); |
- EXPECT_EQ(window3, FindTopmostLocalProcessWindowAt(250, 250)); |
- |
- EXPECT_EQ(xid3, FindTopmostXWindowAt(150, 250)); |
- EXPECT_EQ(window3, FindTopmostLocalProcessWindowAt(150, 250)); |
- |
- EXPECT_EQ(xid3, FindTopmostXWindowAt(150, 195)); |
- EXPECT_EQ(window3, FindTopmostLocalProcessWindowAt(150, 195)); |
- |
- EXPECT_NE(xid1, FindTopmostXWindowAt(1000, 1000)); |
- EXPECT_NE(xid2, FindTopmostXWindowAt(1000, 1000)); |
- EXPECT_NE(xid3, FindTopmostXWindowAt(1000, 1000)); |
- EXPECT_EQ(NULL, FindTopmostLocalProcessWindowAt(1000, 1000)); |
- |
- EXPECT_EQ(window1, |
- FindTopmostLocalProcessWindowWithIgnore(150, 150, window3)); |
- EXPECT_EQ(NULL, |
- FindTopmostLocalProcessWindowWithIgnore(250, 250, window3)); |
- EXPECT_EQ(NULL, |
- FindTopmostLocalProcessWindowWithIgnore(150, 250, window3)); |
- EXPECT_EQ(window1, |
- FindTopmostLocalProcessWindowWithIgnore(150, 195, window3)); |
- |
- XDestroyWindow(xdisplay(), xid2); |
-} |
- |
-// Test that the minimized state is properly handled. |
-// Flaky on Linux. http://crbug.com/388241 |
-TEST_F(X11TopmostWindowFinderTest, DISABLED_Minimized) { |
- scoped_ptr<Widget> widget1( |
- CreateAndShowWidget(gfx::Rect(100, 100, 100, 100))); |
- aura::Window* window1 = widget1->GetNativeWindow(); |
- XID xid1 = window1->GetHost()->GetAcceleratedWidget(); |
- XID xid2 = CreateAndShowXWindow(gfx::Rect(300, 100, 100, 100)); |
- |
- XID xids[] = { xid1, xid2 }; |
- StackingClientListWaiter stack_waiter(xids, arraysize(xids)); |
- stack_waiter.Wait(); |
- ui::X11EventSource::GetInstance()->DispatchXEvents(); |
- |
- EXPECT_EQ(xid1, FindTopmostXWindowAt(150, 150)); |
- { |
- MinimizeWaiter minimize_waiter(xid1); |
- XIconifyWindow(xdisplay(), xid1, 0); |
- minimize_waiter.Wait(); |
- } |
- EXPECT_NE(xid1, FindTopmostXWindowAt(150, 150)); |
- EXPECT_NE(xid2, FindTopmostXWindowAt(150, 150)); |
- |
- // Repeat test for an X window which does not belong to a views::Widget |
- // because the code path is different. |
- EXPECT_EQ(xid2, FindTopmostXWindowAt(350, 150)); |
- { |
- MinimizeWaiter minimize_waiter(xid2); |
- XIconifyWindow(xdisplay(), xid2, 0); |
- minimize_waiter.Wait(); |
- } |
- EXPECT_NE(xid1, FindTopmostXWindowAt(350, 150)); |
- EXPECT_NE(xid2, FindTopmostXWindowAt(350, 150)); |
- |
- XDestroyWindow(xdisplay(), xid2); |
-} |
- |
-// Test that non-rectangular windows are properly handled. |
-// Flaky on Linux. http://crbug.com/388241 |
-TEST_F(X11TopmostWindowFinderTest, DISABLED_NonRectangular) { |
- if (!ui::IsShapeExtensionAvailable()) |
- return; |
- |
- scoped_ptr<Widget> widget1( |
- CreateAndShowWidget(gfx::Rect(100, 100, 100, 100))); |
- XID xid1 = widget1->GetNativeWindow()->GetHost()->GetAcceleratedWidget(); |
- SkRegion* skregion1 = new SkRegion; |
- skregion1->op(SkIRect::MakeXYWH(0, 10, 10, 90), SkRegion::kUnion_Op); |
- skregion1->op(SkIRect::MakeXYWH(10, 0, 90, 100), SkRegion::kUnion_Op); |
- // Widget takes ownership of |skregion1|. |
- widget1->SetShape(skregion1); |
- |
- SkRegion skregion2; |
- skregion2.op(SkIRect::MakeXYWH(0, 10, 10, 90), SkRegion::kUnion_Op); |
- skregion2.op(SkIRect::MakeXYWH(10, 0, 90, 100), SkRegion::kUnion_Op); |
- XID xid2 = CreateAndShowXWindow(gfx::Rect(300, 100, 100, 100)); |
- REGION* region2 = gfx::CreateRegionFromSkRegion(skregion2); |
- XShapeCombineRegion(xdisplay(), xid2, ShapeBounding, 0, 0, region2, |
- false); |
- XDestroyRegion(region2); |
- |
- XID xids[] = { xid1, xid2 }; |
- StackingClientListWaiter stack_waiter(xids, arraysize(xids)); |
- stack_waiter.Wait(); |
- ui::X11EventSource::GetInstance()->DispatchXEvents(); |
- |
- EXPECT_EQ(xid1, FindTopmostXWindowAt(105, 120)); |
- EXPECT_NE(xid1, FindTopmostXWindowAt(105, 105)); |
- EXPECT_NE(xid2, FindTopmostXWindowAt(105, 105)); |
- |
- // Repeat test for an X window which does not belong to a views::Widget |
- // because the code path is different. |
- EXPECT_EQ(xid2, FindTopmostXWindowAt(305, 120)); |
- EXPECT_NE(xid1, FindTopmostXWindowAt(305, 105)); |
- EXPECT_NE(xid2, FindTopmostXWindowAt(305, 105)); |
- |
- XDestroyWindow(xdisplay(), xid2); |
-} |
- |
-// Test that the TopmostWindowFinder finds windows which belong to menus |
-// (which may or may not belong to Chrome). |
-// Flaky on Linux. http://crbug.com/388241 |
-TEST_F(X11TopmostWindowFinderTest, DISABLED_Menu) { |
- XID xid = CreateAndShowXWindow(gfx::Rect(100, 100, 100, 100)); |
- |
- XID root = DefaultRootWindow(xdisplay()); |
- XSetWindowAttributes swa; |
- swa.override_redirect = True; |
- XID menu_xid = XCreateWindow(xdisplay(), |
- root, |
- 0, 0, 1, 1, |
- 0, // border width |
- CopyFromParent, // depth |
- InputOutput, |
- CopyFromParent, // visual |
- CWOverrideRedirect, |
- &swa); |
- { |
- const char* kAtomsToCache[] = { "_NET_WM_WINDOW_TYPE_MENU", NULL }; |
- ui::X11AtomCache atom_cache(gfx::GetXDisplay(), kAtomsToCache); |
- ui::SetAtomProperty(menu_xid, |
- "_NET_WM_WINDOW_TYPE", |
- "ATOM", |
- atom_cache.GetAtom("_NET_WM_WINDOW_TYPE_MENU")); |
- } |
- ui::SetUseOSWindowFrame(menu_xid, false); |
- ShowAndSetXWindowBounds(menu_xid, gfx::Rect(140, 110, 100, 100)); |
- ui::X11EventSource::GetInstance()->DispatchXEvents(); |
- |
- // |menu_xid| is never added to _NET_CLIENT_LIST_STACKING. |
- XID xids[] = { xid }; |
- StackingClientListWaiter stack_waiter(xids, arraysize(xids)); |
- stack_waiter.Wait(); |
- |
- EXPECT_EQ(xid, FindTopmostXWindowAt(110, 110)); |
- EXPECT_EQ(menu_xid, FindTopmostXWindowAt(150, 120)); |
- EXPECT_EQ(menu_xid, FindTopmostXWindowAt(210, 120)); |
- |
- XDestroyWindow(xdisplay(), xid); |
- XDestroyWindow(xdisplay(), menu_xid); |
-} |
- |
-} // namespace views |