0

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:
Maksim Sisov
2019-09-20 11:30:53 +00:00
committed by Commit Bot
parent ceab08a5dd
commit c0e8ba67b5
11 changed files with 86 additions and 63 deletions

@ -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;