X11 and Ozone: Add StackAtTop and StackAbove to PlatformWindow.
This CL is just a code move and does not bring any functionality changes. It's responsibility of PlatformWindows to do restacking now. The API is optional and default implementation is provided. Bug: 990756 Change-Id: Ife24422206ca3aee2ee23e4d5276bc7eba6bb551 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1813348 Commit-Queue: Maksim Sisov <msisov@igalia.com> Reviewed-by: Scott Violet <sky@chromium.org> Reviewed-by: Thomas Anderson <thomasanderson@chromium.org> Cr-Commit-Position: refs/heads/master@{#698442}
This commit is contained in:
@ -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_);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -16,4 +16,8 @@ ZOrderLevel PlatformWindow::GetZOrderLevel() const {
|
||||
return ZOrderLevel::kNormal;
|
||||
}
|
||||
|
||||
void PlatformWindow::StackAbove(gfx::AcceleratedWidget widget) {}
|
||||
|
||||
void PlatformWindow::StackAtTop() {}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user