Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / views / widget / desktop_aura / x11_topmost_window_finder.cc
blobd5dbd55f38c0914e2dc350bc2590bd995d31ad89
1 // Copyright 2014 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.
5 #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
7 #include <X11/Xutil.h>
9 #include "ui/aura/client/screen_position_client.h"
10 #include "ui/aura/window.h"
11 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
13 namespace views {
15 X11TopmostWindowFinder::X11TopmostWindowFinder() : toplevel_(None) {
18 X11TopmostWindowFinder::~X11TopmostWindowFinder() {
21 aura::Window* X11TopmostWindowFinder::FindLocalProcessWindowAt(
22 const gfx::Point& screen_loc_in_pixels,
23 const std::set<aura::Window*>& ignore) {
24 screen_loc_in_pixels_ = screen_loc_in_pixels;
25 ignore_ = ignore;
27 std::vector<aura::Window*> local_process_windows =
28 DesktopWindowTreeHostX11::GetAllOpenWindows();
29 bool found_local_process_window = false;
30 for (size_t i = 0; i < local_process_windows.size(); ++i) {
31 if (ShouldStopIteratingAtLocalProcessWindow(local_process_windows[i])) {
32 found_local_process_window = true;
33 break;
36 if (!found_local_process_window)
37 return NULL;
39 ui::EnumerateTopLevelWindows(this);
40 return DesktopWindowTreeHostX11::GetContentWindowForXID(toplevel_);
43 XID X11TopmostWindowFinder::FindWindowAt(
44 const gfx::Point& screen_loc_in_pixels) {
45 screen_loc_in_pixels_ = screen_loc_in_pixels;
46 ui::EnumerateTopLevelWindows(this);
47 return toplevel_;
50 bool X11TopmostWindowFinder::ShouldStopIterating(XID xid) {
51 if (!ui::IsWindowVisible(xid))
52 return false;
54 aura::Window* window =
55 views::DesktopWindowTreeHostX11::GetContentWindowForXID(xid);
56 if (window) {
57 if (ShouldStopIteratingAtLocalProcessWindow(window)) {
58 toplevel_ = xid;
59 return true;
61 return false;
64 if (ui::WindowContainsPoint(xid, screen_loc_in_pixels_)) {
65 toplevel_ = xid;
66 return true;
68 return false;
71 bool X11TopmostWindowFinder::ShouldStopIteratingAtLocalProcessWindow(
72 aura::Window* window) {
73 if (ignore_.find(window) != ignore_.end())
74 return false;
76 // Currently |window|->IsVisible() always returns true.
77 // TODO(pkotwicz): Fix this. crbug.com/353038
78 if (!window->IsVisible())
79 return false;
81 DesktopWindowTreeHostX11* host =
82 DesktopWindowTreeHostX11::GetHostForXID(
83 window->GetHost()->GetAcceleratedWidget());
84 if (!host->GetX11RootWindowOuterBounds().Contains(screen_loc_in_pixels_))
85 return false;
87 ::Region shape = host->GetWindowShape();
88 if (!shape)
89 return true;
91 aura::client::ScreenPositionClient* screen_position_client =
92 aura::client::GetScreenPositionClient(window->GetRootWindow());
93 gfx::Point window_loc(screen_loc_in_pixels_);
94 screen_position_client->ConvertPointFromScreen(window, &window_loc);
95 return XPointInRegion(shape, window_loc.x(), window_loc.y()) == True;
98 } // namespace views