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