| 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))
|
| + 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_);
|
| }
|
|
|