Chromium Code Reviews| Index: ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc |
| diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc |
| index 4a8f64cf47c459156b59e1f75e802b312897b433..a8215cb17f4930655e84f437feb7138692edf2ad 100644 |
| --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc |
| +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc |
| @@ -128,6 +128,25 @@ const char* kAtomsToCache[] = { |
| const char kX11WindowRolePopup[] = "popup"; |
| const char kX11WindowRoleBubble[] = "bubble"; |
| +// Returns the whole path from |window| to the root. |
| +std::vector<::Window> GetParentsList(XDisplay* xdisplay, ::Window window) { |
| + ::Window parent_win, root_win; |
| + Window* child_windows; |
| + unsigned int num_child_windows; |
| + std::vector<::Window> result; |
| + |
| + while (window) { |
| + result.push_back(window); |
| + if (!XQueryTree(xdisplay, window, |
| + &root_win, &parent_win, &child_windows, &num_child_windows)) |
|
Elliot Glaysher
2015/06/05 22:03:01
Doing a whole query tree here seems a bit unfortun
vasilii
2015/06/08 09:14:37
I don't see another function to get a parent.
|
| + break; |
| + if (child_windows) |
| + XFree(child_windows); |
| + window = parent_win; |
| + } |
| + return result; |
| +} |
| + |
| } // namespace |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -415,6 +434,37 @@ void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { |
| } |
| } |
| +void DesktopWindowTreeHostX11::StackAbove(aura::Window* window) { |
| + if (window && window->GetRootWindow()) { |
| + ::Window window_below = window->GetHost()->GetAcceleratedWidget(); |
| + // Find all parent windows up to the root. |
| + std::vector<::Window> window_below_parents = |
| + GetParentsList(xdisplay_, window_below); |
| + std::vector<::Window> window_above_parents = |
| + GetParentsList(xdisplay_, xwindow_); |
| + |
| + // Find their common ancestor. |
| + auto it_below_window = window_below_parents.rbegin(); |
| + auto it_above_window = window_above_parents.rbegin(); |
| + for (; it_below_window != window_below_parents.rend() && |
| + it_above_window != window_above_parents.rend() && |
| + *it_below_window == *it_above_window; |
| + ++it_below_window, ++it_above_window) { |
| + } |
| + |
| + if (it_below_window != window_below_parents.rend() && |
| + it_above_window != window_above_parents.rend()) { |
| + // First stack |xwindow_| below so Z-order of |window| stays the same. |
| + ::Window windows[] = {*it_below_window, *it_above_window}; |
| + if (XRestackWindows(xdisplay_, windows, 2) == 0) { |
| + // Now stack them properly. |
| + std::swap(windows[0], windows[1]); |
| + XRestackWindows(xdisplay_, windows, 2); |
| + } |
| + } |
| + } |
| +} |
| + |
| void DesktopWindowTreeHostX11::StackAtTop() { |
| XRaiseWindow(xdisplay_, xwindow_); |
| } |