diff --git a/ui/base/x/x11_window.cc b/ui/base/x/x11_window.cc index 1bb97da344812..9cba7d4e3a7ec 100644 --- a/ui/base/x/x11_window.cc +++ b/ui/base/x/x11_window.cc @@ -88,6 +88,25 @@ bool SyncSetCounter(XDisplay* display, XID counter, int64_t value) { return XSyncSetCounter(display, counter, sync_value) == x11::True; } +// 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 XWindow::Configuration::Configuration() @@ -632,7 +651,37 @@ void XWindow::ReleasePointerGrab() { has_pointer_grab_ = false; } -void XWindow::StackAtTop() { +void XWindow::StackXWindowAbove(::Window window) { + DCHECK(window != x11::None); + + // Find all parent windows up to the root. + std::vector<::Window> window_below_parents = + GetParentsList(xdisplay_, window); + 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 XWindow::StackXWindowAtTop() { XRaiseWindow(xdisplay_, xwindow_); } diff --git a/ui/base/x/x11_window.h b/ui/base/x/x11_window.h index 9db97d2f52145..96d79b85e4b03 100644 --- a/ui/base/x/x11_window.h +++ b/ui/base/x/x11_window.h @@ -102,7 +102,8 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow { bool IsActive() const; void GrabPointer(); void ReleasePointerGrab(); - void StackAtTop(); + void StackXWindowAbove(::Window window); + void StackXWindowAtTop(); bool IsTargetedBy(const XEvent& xev) const; void WmMoveResize(int hittest, const gfx::Point& location) const; void ProcessEvent(XEvent* xev); diff --git a/ui/platform_window/platform_window.cc b/ui/platform_window/platform_window.cc index e42f8ce524d6c..b586913c1ee8f 100644 --- a/ui/platform_window/platform_window.cc +++ b/ui/platform_window/platform_window.cc @@ -16,4 +16,8 @@ ZOrderLevel PlatformWindow::GetZOrderLevel() const { return ZOrderLevel::kNormal; } +void PlatformWindow::StackAbove(gfx::AcceleratedWidget widget) {} + +void PlatformWindow::StackAtTop() {} + } // namespace ui diff --git a/ui/platform_window/platform_window.h b/ui/platform_window/platform_window.h index a5ca9927f5be7..4d98e364e0d68 100644 --- a/ui/platform_window/platform_window.h +++ b/ui/platform_window/platform_window.h @@ -11,6 +11,7 @@ #include "ui/base/class_property.h" #include "ui/base/cursor/cursor.h" #include "ui/base/ui_base_types.h" +#include "ui/gfx/native_widget_types.h" #include "ui/platform_window/platform_window_delegate.h" namespace gfx { @@ -82,6 +83,10 @@ class PlatformWindow : public PropertyHandler { // implementation always returns ZOrderLevel::kNormal value. virtual void SetZOrderLevel(ZOrderLevel order); virtual ZOrderLevel GetZOrderLevel() const; + + // Asks the PlatformWindow to stack itself on top of |widget|. + virtual void StackAbove(gfx::AcceleratedWidget widget); + virtual void StackAtTop(); }; } // namespace ui diff --git a/ui/platform_window/win/win_window.cc b/ui/platform_window/win/win_window.cc index 94810b5b4fe72..45b02f0f97efb 100644 --- a/ui/platform_window/win/win_window.cc +++ b/ui/platform_window/win/win_window.cc @@ -158,6 +158,14 @@ ZOrderLevel WinWindow::GetZOrderLevel() const { return ZOrderLevel::kNormal; } +void WinWindow::StackAbove(gfx::AcceleratedWidget widget) { + NOTIMPLEMENTED_LOG_ONCE(); +} + +void WinWindow::StackAtTop() { + NOTIMPLEMENTED_LOG_ONCE(); +} + LRESULT WinWindow::OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) { MSG msg = {hwnd(), message, diff --git a/ui/platform_window/win/win_window.h b/ui/platform_window/win/win_window.h index e83464a2c0035..b78e346307808 100644 --- a/ui/platform_window/win/win_window.h +++ b/ui/platform_window/win/win_window.h @@ -52,6 +52,8 @@ class WIN_WINDOW_EXPORT WinWindow : public PlatformWindow, gfx::Rect GetRestoredBoundsInPixels() const override; void SetZOrderLevel(ZOrderLevel order) override; ZOrderLevel GetZOrderLevel() const override; + void StackAbove(gfx::AcceleratedWidget widget) override; + void StackAtTop() override; CR_BEGIN_MSG_MAP_EX(WinWindow) CR_MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange) diff --git a/ui/platform_window/x11/x11_window.cc b/ui/platform_window/x11/x11_window.cc index 3620a87fe1378..46dbd5fa3f2a1 100644 --- a/ui/platform_window/x11/x11_window.cc +++ b/ui/platform_window/x11/x11_window.cc @@ -238,6 +238,14 @@ ZOrderLevel X11Window::GetZOrderLevel() const { : ui::ZOrderLevel::kNormal; } +void X11Window::StackAbove(gfx::AcceleratedWidget widget) { + XWindow::StackXWindowAbove(static_cast<::Window>(widget)); +} + +void X11Window::StackAtTop() { + XWindow::StackXWindowAtTop(); +} + bool X11Window::CanDispatchEvent(const PlatformEvent& xev) { #if defined(USE_X11) return XWindow::IsTargetedBy(*xev); diff --git a/ui/platform_window/x11/x11_window.h b/ui/platform_window/x11/x11_window.h index 739b87391e52e..f2189b3695ebd 100644 --- a/ui/platform_window/x11/x11_window.h +++ b/ui/platform_window/x11/x11_window.h @@ -71,6 +71,8 @@ class X11_WINDOW_EXPORT X11Window : public PlatformWindow, gfx::Rect GetRestoredBoundsInPixels() const override; void SetZOrderLevel(ZOrderLevel order) override; ZOrderLevel GetZOrderLevel() const override; + void StackAbove(gfx::AcceleratedWidget widget) override; + void StackAtTop() override; protected: PlatformWindowDelegateLinux* platform_window_delegate() const { diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc index f6e9cfd7c9b39..8a9a6fae6306b 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc @@ -290,11 +290,14 @@ void DesktopWindowTreeHostPlatform::SetSize(const gfx::Size& size) { } void DesktopWindowTreeHostPlatform::StackAbove(aura::Window* window) { - NOTIMPLEMENTED_LOG_ONCE(); + if (!window || !window->GetRootWindow()) + return; + + platform_window()->StackAbove(window->GetHost()->GetAcceleratedWidget()); } void DesktopWindowTreeHostPlatform::StackAtTop() { - NOTIMPLEMENTED_LOG_ONCE(); + platform_window()->StackAtTop(); } void DesktopWindowTreeHostPlatform::CenterWindow(const gfx::Size& size) { 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 f209d8bed7dc5..51742bba84a5d 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 @@ -81,25 +81,6 @@ DEFINE_UI_CLASS_PROPERTY_KEY(DesktopWindowTreeHostX11*, namespace { -// 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; -} - class SwapWithNewSizeObserverHelper : public ui::CompositorObserver { public: using HelperCallback = base::RepeatingCallback<void(const gfx::Size&)>; @@ -319,44 +300,6 @@ void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { } } -void DesktopWindowTreeHostX11::StackAbove(aura::Window* window) { - XDisplay* display = GetXWindow()->display(); - ::Window xwindow = GetXWindow()->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(display, window_below); - std::vector<::Window> window_above_parents = - GetParentsList(display, 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(display, windows, 2) == 0) { - // Now stack them properly. - std::swap(windows[0], windows[1]); - XRestackWindows(display, windows, 2); - } - } - } -} - -void DesktopWindowTreeHostX11::StackAtTop() { - GetXWindow()->StackAtTop(); -} - void DesktopWindowTreeHostX11::GetWindowPlacement( gfx::Rect* bounds, ui::WindowShowState* show_state) const { diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h index 87702baa1f044..a3a015af02044 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h @@ -102,8 +102,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 : public DesktopWindowTreeHostLinux, const gfx::Rect& restore_bounds) override; bool IsVisible() const override; void SetSize(const gfx::Size& requested_size) override; - void StackAbove(aura::Window* window) override; - void StackAtTop() override; void GetWindowPlacement(gfx::Rect* bounds, ui::WindowShowState* show_state) const override; gfx::Rect GetRestoredBounds() const override;