Commit ae0a09ce authored by Tom Anderson's avatar Tom Anderson Committed by Commit Bot

[XProto] Remove usage of Xlib in ui::XWindow

BUG=1066670
R=nickdiego,sky
CC=msisov

Change-Id: I23f36fd0fc3ac2522fdbd3de6b7b670e11352ca2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2252574
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: default avatarNick Yamane <nickdiego@igalia.com>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781162}
parent b5cdd644
......@@ -452,7 +452,8 @@ class GpuDataManagerVisualProxy : public GpuDataManagerObserver {
if (!ui::XVisualManager::GetInstance()->OnGPUInfoChanged(
gpu_info.software_rendering ||
!gpu_data_manager_->GpuAccessAllowed(nullptr),
gpu_extra_info.system_visual, gpu_extra_info.rgba_visual)) {
static_cast<x11::VisualId>(gpu_extra_info.system_visual),
static_cast<x11::VisualId>(gpu_extra_info.rgba_visual))) {
// The GPU process sent back bad visuals, which should never happen.
auto* gpu_process_host =
GpuProcessHost::Get(GPU_PROCESS_KIND_SANDBOXED, false);
......
......@@ -25,11 +25,11 @@ void GetPlatformExtraDisplayAttribs(EGLenum platform_type,
// ANGLE_NULL doesn't use the visual, and may run without X11 where we can't
// get it anyway.
if (platform_type != EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE) {
Visual* visual;
ui::XVisualManager::GetInstance()->ChooseVisualForWindow(
true, &visual, nullptr, nullptr, nullptr);
x11::VisualId visual_id;
ui::XVisualManager::GetInstance()->ChooseVisualForWindow(true, &visual_id,
nullptr, nullptr);
attributes->push_back(EGL_X11_VISUAL_ID_ANGLE);
attributes->push_back(static_cast<EGLAttrib>(XVisualIDFromVisual(visual)));
attributes->push_back(static_cast<EGLAttrib>(visual_id));
}
}
......@@ -38,8 +38,10 @@ void ChoosePlatformCustomAlphaAndBufferSize(EGLint* alpha_size,
// If we're using ANGLE_NULL, we may not have a display, in which case we
// can't use XVisualManager.
if (gl::GLSurfaceEGL::GetNativeDisplay() != EGL_DEFAULT_DISPLAY) {
ui::XVisualManager::GetInstance()->ChooseVisualForWindow(
true, nullptr, buffer_size, nullptr, nullptr);
uint8_t depth;
ui::XVisualManager::GetInstance()->ChooseVisualForWindow(true, nullptr,
&depth, nullptr);
*buffer_size = depth;
*alpha_size = *buffer_size == 32 ? 8 : 0;
}
}
......
This diff is collapsed.
......@@ -40,6 +40,79 @@ class SkBitmap;
namespace ui {
enum WmState : uint32_t {
WM_STATE_WITHDRAWN = 0,
WM_STATE_NORMAL = 1,
WM_STATE_ICONIC = 3,
};
enum SizeHintsFlags : int32_t {
SIZE_HINT_US_POSITION = 1 << 0,
SIZE_HINT_US_SIZE = 1 << 1,
SIZE_HINT_P_POSITION = 1 << 2,
SIZE_HINT_P_SIZE = 1 << 3,
SIZE_HINT_P_MIN_SIZE = 1 << 4,
SIZE_HINT_P_MAX_SIZE = 1 << 5,
SIZE_HINT_P_RESIZE_INC = 1 << 6,
SIZE_HINT_P_ASPECT = 1 << 7,
SIZE_HINT_BASE_SIZE = 1 << 8,
SIZE_HINT_P_WIN_GRAVITY = 1 << 9,
};
struct SizeHints {
// User specified flags
int32_t flags;
// User-specified position
int32_t x, y;
// User-specified size
int32_t width, height;
// Program-specified minimum size
int32_t min_width, min_height;
// Program-specified maximum size
int32_t max_width, max_height;
// Program-specified resize increments
int32_t width_inc, height_inc;
// Program-specified minimum aspect ratios
int32_t min_aspect_num, min_aspect_den;
// Program-specified maximum aspect ratios
int32_t max_aspect_num, max_aspect_den;
// Program-specified base size
int32_t base_width, base_height;
// Program-specified window gravity
uint32_t win_gravity;
};
enum WmHintsFlags : uint32_t {
WM_HINT_INPUT = 1L << 0,
WM_HINT_STATE = 1L << 1,
WM_HINT_ICON_PIXMAP = 1L << 2,
WM_HINT_ICON_WINDOW = 1L << 3,
WM_HINT_ICON_POSITION = 1L << 4,
WM_HINT_ICON_MASK = 1L << 5,
WM_HINT_WINDOW_GROUP = 1L << 6,
// 1L << 7 doesn't have any defined meaning
WM_HINT_X_URGENCY = 1L << 8
};
struct WmHints {
// Marks which fields in this structure are defined
int32_t flags;
// Does this application rely on the window manager to get keyboard input?
uint32_t input;
// See below
int32_t initial_state;
// Pixmap to be used as icon
xcb_pixmap_t icon_pixmap;
// Window to be used as icon
xcb_window_t icon_window;
// Initial position of icon
int32_t icon_x, icon_y;
// Icon mask bitmap
xcb_pixmap_t icon_mask;
// Identifier of related window group
xcb_window_t window_group;
};
// These functions use the default display and this /must/ be called from
// the UI thread. Thus, they don't support multiple displays.
......@@ -114,6 +187,30 @@ void SetProperty(x11::Window window,
COMPONENT_EXPORT(UI_BASE_X)
void DeleteProperty(x11::Window window, x11::Atom name);
COMPONENT_EXPORT(UI_BASE_X)
bool GetWmNormalHints(x11::Window window, SizeHints* hints);
COMPONENT_EXPORT(UI_BASE_X)
void SetWmNormalHints(x11::Window window, const SizeHints& hints);
COMPONENT_EXPORT(UI_BASE_X)
bool GetWmHints(x11::Window window, WmHints* hints);
COMPONENT_EXPORT(UI_BASE_X)
void SetWmHints(x11::Window window, const WmHints& hints);
COMPONENT_EXPORT(UI_BASE_X)
void WithdrawWindow(x11::Window window);
COMPONENT_EXPORT(UI_BASE_X)
void RaiseWindow(x11::Window window);
COMPONENT_EXPORT(UI_BASE_X)
void LowerWindow(x11::Window window);
COMPONENT_EXPORT(UI_BASE_X)
void DefineCursor(x11::Window window, x11::Cursor cursor);
// These functions cache their results ---------------------------------
// Returns true if the system supports XINPUT2.
......@@ -274,16 +371,14 @@ void SetStringProperty(x11::Window window,
// Sets the WM_CLASS attribute for a given X11 window.
COMPONENT_EXPORT(UI_BASE_X)
void SetWindowClassHint(XDisplay* display,
void SetWindowClassHint(x11::Connection* connection,
x11::Window window,
const std::string& res_name,
const std::string& res_class);
// Sets the WM_WINDOW_ROLE attribute for a given X11 window.
COMPONENT_EXPORT(UI_BASE_X)
void SetWindowRole(XDisplay* display,
x11::Window window,
const std::string& role);
void SetWindowRole(x11::Window window, const std::string& role);
// Sends a message to the x11 window manager, enabling or disabling the
// states |state1| and |state2|.
......@@ -299,7 +394,7 @@ void SetWMSpecState(x11::Window window,
// |direction| indicates whether this is a move or resize event, and if it is a
// resize event, which edges of the window the size grip applies to.
COMPONENT_EXPORT(UI_BASE_X)
void DoWMMoveResize(XDisplay* display,
void DoWMMoveResize(x11::Connection* connection,
x11::Window root_window,
x11::Window window,
const gfx::Point& location_px,
......
......@@ -55,18 +55,14 @@ class COMPONENT_EXPORT(UI_BASE_X) XVisualManager {
public:
static XVisualManager* GetInstance();
// Picks the best argb or opaque visual given |want_argb_visual|. If the
// default visual is returned, |colormap| is set to CopyFromParent.
// Picks the best argb or opaque visual given |want_argb_visual|.
void ChooseVisualForWindow(bool want_argb_visual,
Visual** visual,
int* depth,
Colormap* colormap,
x11::VisualId* visual_id,
uint8_t* depth,
bool* visual_has_alpha);
bool GetVisualInfo(VisualID visual_id,
Visual** visual,
int* depth,
Colormap* colormap,
bool GetVisualInfo(x11::VisualId visual_id,
uint8_t* depth,
bool* visual_has_alpha);
// Called by GpuDataManagerImplPrivate when GPUInfo becomes available. It is
......@@ -74,8 +70,8 @@ class COMPONENT_EXPORT(UI_BASE_X) XVisualManager {
// because we don't want to load GL in the browser process. Returns false iff
// |default_visual_id| or |transparent_visual_id| are invalid.
bool OnGPUInfoChanged(bool software_rendering,
VisualID default_visual_id,
VisualID transparent_visual_id);
x11::VisualId default_visual_id,
x11::VisualId transparent_visual_id);
// Are all of the system requirements met for using transparent visuals?
bool ArgbVisualAvailable() const;
......@@ -87,40 +83,34 @@ class COMPONENT_EXPORT(UI_BASE_X) XVisualManager {
class XVisualData {
public:
explicit XVisualData(XVisualInfo visual_info);
XVisualData(uint8_t depth, const x11::VisualType* info);
~XVisualData();
Colormap GetColormap();
const XVisualInfo visual_info;
private:
Colormap colormap_;
uint8_t depth = 0;
const x11::VisualType* info = nullptr;
};
XVisualManager();
bool GetVisualInfoImpl(VisualID visual_id,
Visual** visual,
int* depth,
Colormap* colormap,
bool GetVisualInfoImpl(x11::VisualId visual_id,
uint8_t* depth,
bool* visual_has_alpha);
mutable base::Lock lock_;
std::unordered_map<VisualID, std::unique_ptr<XVisualData>> visuals_;
std::unordered_map<x11::VisualId, std::unique_ptr<XVisualData>> visuals_;
XDisplay* display_;
x11::Connection* const connection_;
VisualID default_visual_id_;
x11::VisualId default_visual_id_{};
// The system visual is usually the same as the default visual, but
// may not be in general.
VisualID system_visual_id_;
VisualID transparent_visual_id_;
x11::VisualId system_visual_id_{};
x11::VisualId transparent_visual_id_{};
bool using_software_rendering_;
bool have_gpu_argb_visual_;
bool using_software_rendering_ = false;
bool have_gpu_argb_visual_ = false;
DISALLOW_COPY_AND_ASSIGN(XVisualManager);
};
......
This diff is collapsed.
......@@ -8,6 +8,7 @@
#include <array>
#include <memory>
#include <string>
#include <vector>
#include "base/cancelable_callback.h"
#include "base/component_export.h"
......@@ -20,8 +21,11 @@
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_f.h"
#include "ui/gfx/x/event.h"
#include "ui/gfx/x/sync.h"
#include "ui/gfx/x/x11.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/gfx/x/xfixes.h"
#include "ui/gfx/x/xproto.h"
class SkPath;
......@@ -164,12 +168,14 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow {
bool has_alpha() const { return visual_has_alpha_; }
base::Optional<int> workspace() const { return workspace_; }
XDisplay* display() const { return xdisplay_; }
x11::Connection* connection() const { return connection_; }
x11::Window window() const { return xwindow_; }
x11::Window root_window() const { return x_root_window_; }
::Region shape() const { return window_shape_.get(); }
XID update_counter() const { return update_counter_; }
XID extended_update_counter() const { return extended_update_counter_; }
std::vector<x11::Rectangle>* shape() const { return window_shape_.get(); }
x11::Sync::Counter update_counter() const { return update_counter_; }
x11::Sync::Counter extended_update_counter() const {
return extended_update_counter_;
}
::Cursor last_cursor() const { return last_cursor_; }
protected:
......@@ -179,14 +185,16 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow {
private:
// Called on an XFocusInEvent, XFocusOutEvent, XIFocusInEvent, or an
// XIFocusOutEvent.
void OnFocusEvent(bool focus_in, int mode, int detail);
void OnFocusEvent(bool focus_in,
x11::NotifyMode mode,
x11::NotifyDetail detail);
// Called on an XEnterWindowEvent, XLeaveWindowEvent, XIEnterEvent, or an
// XILeaveEvent.
void OnCrossingEvent(bool enter,
bool focus_in_window_or_ancestor,
int mode,
int detail);
x11::NotifyMode mode,
x11::NotifyDetail detail);
// Called when |xwindow_|'s _NET_WM_STATE property is updated.
void OnWMStateUpdated();
......@@ -194,7 +202,7 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow {
// Called when |xwindow_|'s _NET_FRAME_EXTENTS property is updated.
void OnFrameExtentsUpdated();
void OnConfigureEvent(x11::Event* xev);
void OnConfigureEvent(const x11::ConfigureNotifyEvent& event);
void OnWorkspaceUpdated();
......@@ -224,7 +232,7 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow {
void UnconfineCursor();
void UpdateWindowRegion(XRegion* xregion);
void UpdateWindowRegion(std::unique_ptr<std::vector<x11::Rectangle>> region);
void NotifyBoundsChanged(const gfx::Rect& new_bounds_in_px);
......@@ -250,7 +258,7 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow {
SkPath* window_mask) = 0;
// The display and the native X window hosting the root window.
XDisplay* xdisplay_ = nullptr;
x11::Connection* const connection_;
x11::Window xwindow_ = x11::Window::None;
x11::Window x_root_window_ = x11::Window::None;
......@@ -277,7 +285,7 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow {
// The bounds of |xwindow_|.
gfx::Rect bounds_in_pixels_;
VisualID visual_id_ = 0;
x11::VisualId visual_id_{};
// Whether we used an ARGB visual for our window.
bool visual_has_alpha_ = false;
......@@ -326,8 +334,8 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow {
// Used for synchronizing between |xwindow_| and desktop compositor during
// resizing.
XID update_counter_ = x11::None;
XID extended_update_counter_ = x11::None;
x11::Sync::Counter update_counter_{};
x11::Sync::Counter extended_update_counter_{};
// Whenever the bounds are set, we keep the previous set of bounds around so
// we can have a better chance of getting the real
......@@ -354,8 +362,7 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow {
gfx::Size max_size_in_pixels_;
// The window shape if the window is non-rectangular.
gfx::XScopedPtr<XRegion, gfx::XObjectDeleter<XRegion, int, XDestroyRegion>>
window_shape_;
std::unique_ptr<std::vector<x11::Rectangle>> window_shape_;
// Whether |window_shape_| was set via SetShape().
bool custom_window_shape_ = false;
......@@ -378,7 +385,7 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow {
// Keep track of barriers to confine cursor.
bool has_pointer_barriers_ = false;
std::array<XID, 4> pointer_barriers_;
std::array<x11::XFixes::Barrier, 4> pointer_barriers_;
::Cursor last_cursor_ = x11::None;
};
......
......@@ -63,7 +63,7 @@ Connection::Connection() : XProto(this), display_(OpenNewXDisplay()) {
setup_ = Read<Setup>(
reinterpret_cast<const uint8_t*>(xcb_get_setup(XcbConnection())));
default_screen_ = &setup_.roots[DefaultScreen(display_)];
default_screen_ = &setup_.roots[DefaultScreenId()];
default_root_depth_ = &*std::find_if(
default_screen_->allowed_depths.begin(),
default_screen_->allowed_depths.end(), [&](const Depth& depth) {
......@@ -115,6 +115,13 @@ bool Connection::HasNextResponse() const {
requests_.front().sequence) >= 0;
}
int Connection::DefaultScreenId() const {
// This is not part of the setup data as the server has no concept of a
// default screen. Instead, it's part of the display name. Eg in
// "localhost:0.0", the screen ID is the second "0".
return DefaultScreen(display_);
}
bool Connection::Ready() const {
return display_ && !xcb_connection_has_error(XGetXCBConnection(display_));
}
......
......@@ -46,11 +46,14 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
const Setup& setup() const { return setup_; }
const Screen& default_screen() const { return *default_screen_; }
x11::Window default_root() const { return default_screen().root; }
const Depth& default_root_depth() const { return *default_root_depth_; }
const VisualType& default_root_visual() const {
return *default_root_visual_;
}
int DefaultScreenId() const;
template <typename T>
T GenerateId() {
return static_cast<T>(xcb_generate_id(XcbConnection()));
......
......@@ -231,6 +231,7 @@ READ_SPECIAL = set([
WRITE_SPECIAL = set([
('xcb', 'ClientMessage'),
('xcb', 'UnmapNotify'),
])
......@@ -858,6 +859,7 @@ class GenXproto(FileWriter):
for opcode, opname in sorted(items):
self.undef(opname)
self.write('%s = %s,' % (opname, opcode))
self.write('bool send_event{};')
self.declare_fields(event.fields)
self.write()
......@@ -1493,6 +1495,7 @@ class GenReadEvent(FileWriter):
if len(event.opcodes) > 1:
self.write('{0} = static_cast<decltype({0})>({1});'.format(
'event_->opcode', opcode))
self.write('event_->send_event = send_event;')
self.write('event->event_ = event_;')
self.write('return;')
self.write()
......@@ -1514,6 +1517,7 @@ class GenReadEvent(FileWriter):
self.write(cast % ('ev', 'xcb_generic_event_t'))
self.write(cast % ('ge', 'xcb_ge_generic_event_t'))
self.write('auto evtype = ev->response_type & ~kSendEventMask;')
self.write('bool send_event = ev->response_type & kSendEventMask;')
self.write()
for name, event, proto in self.events:
self.gen_event(name, event, proto)
......
......@@ -12,8 +12,9 @@
namespace gfx {
Region CreateRegionFromSkRegion(const SkRegion& region) {
Region result = XCreateRegion();
std::unique_ptr<std::vector<x11::Rectangle>> CreateRegionFromSkRegion(
const SkRegion& region) {
auto result = std::make_unique<std::vector<x11::Rectangle>>();
for (SkRegion::Iterator i(region); !i.done(); i.next()) {
XRectangle rect;
......@@ -21,23 +22,23 @@ Region CreateRegionFromSkRegion(const SkRegion& region) {
rect.y = i.rect().y();
rect.width = i.rect().width();
rect.height = i.rect().height();
XUnionRectWithRegion(&rect, result, result);
result->push_back({
.x = i.rect().x(),
.y = i.rect().y(),
.width = i.rect().width(),
.height = i.rect().height(),
});
}
return result;
}
Region CreateRegionFromSkPath(const SkPath& path) {
int point_count = path.getPoints(nullptr, 0);
std::unique_ptr<SkPoint[]> points(new SkPoint[point_count]);
path.getPoints(points.get(), point_count);
std::unique_ptr<XPoint[]> x11_points(new XPoint[point_count]);
for (int i = 0; i < point_count; ++i) {
x11_points[i].x = SkScalarRoundToInt(points[i].fX);
x11_points[i].y = SkScalarRoundToInt(points[i].fY);
}
return XPolygonRegion(x11_points.get(), point_count, EvenOddRule);
std::unique_ptr<std::vector<x11::Rectangle>> CreateRegionFromSkPath(
const SkPath& path) {
SkRegion clip{path.getBounds().roundOut()};
SkRegion region;
region.setPath(path, clip);
return CreateRegionFromSkRegion(region);
}
} // namespace gfx
......@@ -6,7 +6,7 @@
#define UI_GFX_X_X11_PATH_H_
#include "ui/gfx/gfx_export.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/gfx/x/xproto.h"
class SkPath;
class SkRegion;
......@@ -15,11 +15,13 @@ namespace gfx {
// Creates a new XRegion given |region|. The caller is responsible for
// destroying the returned region.
GFX_EXPORT XRegion* CreateRegionFromSkRegion(const SkRegion& region);
GFX_EXPORT std::unique_ptr<std::vector<x11::Rectangle>>
CreateRegionFromSkRegion(const SkRegion& region);
// Creates a new XRegion given |path|. The caller is responsible for destroying
// the returned region.
GFX_EXPORT XRegion* CreateRegionFromSkPath(const SkPath& path);
GFX_EXPORT std::unique_ptr<std::vector<x11::Rectangle>> CreateRegionFromSkPath(
const SkPath& path);
} // namespace gfx
......
......@@ -144,6 +144,10 @@ class Future : public FutureBase {
OnResponseImpl(base::BindOnce(wrapper, std::move(callback)));
}
void IgnoreError() {
OnResponse(base::BindOnce([](Response<Reply>) {}));
}
private:
template <typename R>
friend Future<R> SendRequest(Connection*, std::vector<uint8_t>*);
......@@ -179,6 +183,11 @@ inline void Future<void>::OnResponse(Callback callback) {
OnResponseImpl(base::BindOnce(wrapper, std::move(callback)));
}
template <>
inline void Future<void>::IgnoreError() {
OnResponse(base::BindOnce([](Response<void>) {}));
}
} // namespace x11
#endif // UI_GFX_X_XPROTO_TYPES_H_
......@@ -163,8 +163,8 @@ void X11Window::Initialize(PlatformWindowInitProperties properties) {
#if defined(USE_OZONE)
SetWmDragHandler(this, this);
drag_drop_client_ =
std::make_unique<XDragDropClient>(this, display(), window());
drag_drop_client_ = std::make_unique<XDragDropClient>(
this, connection()->display(), window());
#endif
}
......
......@@ -40,7 +40,7 @@ namespace {
bool InitializeVisuals() {
#if defined(USE_X11)
bool has_compositing_manager = false;
int depth = 0;
uint8_t depth = 0;
bool using_argb_visual;
if (depth > 0)
......@@ -50,7 +50,7 @@ bool InitializeVisuals() {
std::unique_ptr<base::Environment> env(base::Environment::Create());
has_compositing_manager = env->HasVar("_CHROMIUM_INSIDE_XVFB");
ui::XVisualManager::GetInstance()->ChooseVisualForWindow(
has_compositing_manager, nullptr, &depth, nullptr, &using_argb_visual);
has_compositing_manager, nullptr, &depth, &using_argb_visual);
if (using_argb_visual)
EXPECT_EQ(32, depth);
......
......@@ -91,8 +91,8 @@ void DesktopWindowTreeHostX11::Init(const Widget::InitParams& params) {
std::unique_ptr<aura::client::DragDropClient>
DesktopWindowTreeHostX11::CreateDragDropClient(
DesktopNativeCursorManager* cursor_manager) {
drag_drop_client_ = new DesktopDragDropClientAuraX11(window(), cursor_manager,
GetXWindow()->display(),
drag_drop_client_ = new DesktopDragDropClientAuraX11(
window(), cursor_manager, GetXWindow()->connection()->display(),
GetXWindow()->window());
drag_drop_client_->Init();
return base::WrapUnique(drag_drop_client_);
......
......@@ -18,7 +18,9 @@
#include "ui/base/x/x11_util.h"
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/event.h"
#include "ui/gfx/x/shape.h"
#include "ui/gfx/x/x11.h"
#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/gfx/x/x11_path.h"
......@@ -296,10 +298,14 @@ TEST_F(X11TopmostWindowFinderTest, NonRectangular) {
skregion2.op(SkIRect::MakeXYWH(0, 10, 10, 90), SkRegion::kUnion_Op);
skregion2.op(SkIRect::MakeXYWH(10, 0, 90, 100), SkRegion::kUnion_Op);
x11::Window window2 = CreateAndShowXWindow(gfx::Rect(300, 100, 100, 100));
gfx::XScopedPtr<REGION, gfx::XObjectDeleter<REGION, int, XDestroyRegion>>
region2(gfx::CreateRegionFromSkRegion(skregion2));
XShapeCombineRegion(xdisplay(), static_cast<uint32_t>(window2), ShapeBounding,
0, 0, region2.get(), false);
auto region2 = gfx::CreateRegionFromSkRegion(skregion2);
x11::Connection::Get()->shape().Rectangles({
.operation = x11::Shape::So::Set,
.destination_kind = x11::Shape::Sk::Bounding,
.ordering = x11::ClipOrdering::YXBanded,
.destination_window = window2,
.rectangles = *region2,
});
x11::Window windows[] = {window1, window2};
StackingClientListWaiter stack_waiter(windows, base::size(windows));
stack_waiter.Wait();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment