Move Window::{opaqueRegion,shapeRegion} to X11Window

This commit is contained in:
Vlad Zahorodnii 2023-03-29 11:04:22 +03:00
parent 46d0c04f91
commit fa8bd5c0d9
4 changed files with 62 additions and 78 deletions

View file

@ -78,8 +78,6 @@ Window::Window()
{ {
connect(this, &Window::bufferGeometryChanged, this, &Window::inputTransformationChanged); connect(this, &Window::bufferGeometryChanged, this, &Window::inputTransformationChanged);
connect(this, &Window::geometryShapeChanged, this, &Window::discardShapeRegion);
connect(this, &Window::interactiveMoveResizeStarted, this, &Window::moveResizedChanged); connect(this, &Window::interactiveMoveResizeStarted, this, &Window::moveResizedChanged);
connect(this, &Window::interactiveMoveResizeFinished, this, &Window::moveResizedChanged); connect(this, &Window::interactiveMoveResizeFinished, this, &Window::moveResizedChanged);
@ -392,59 +390,6 @@ bool Window::wantsShadowToBeRendered() const
return !isFullScreen() && maximizeMode() != MaximizeFull; return !isFullScreen() && maximizeMode() != MaximizeFull;
} }
void Window::getWmOpaqueRegion()
{
if (!info) {
return;
}
const auto rects = info->opaqueRegion();
QRegion new_opaque_region;
for (const auto &r : rects) {
new_opaque_region |= Xcb::fromXNative(QRect(r.pos.x, r.pos.y, r.size.width, r.size.height)).toRect();
}
opaque_region = new_opaque_region;
}
QVector<QRectF> Window::shapeRegion() const
{
if (m_shapeRegionIsValid) {
return m_shapeRegion;
}
const QRectF bufferGeometry = this->bufferGeometry();
if (is_shape) {
auto cookie = xcb_shape_get_rectangles_unchecked(kwinApp()->x11Connection(), frameId(), XCB_SHAPE_SK_BOUNDING);
UniqueCPtr<xcb_shape_get_rectangles_reply_t> reply(xcb_shape_get_rectangles_reply(kwinApp()->x11Connection(), cookie, nullptr));
if (reply) {
m_shapeRegion.clear();
const xcb_rectangle_t *rects = xcb_shape_get_rectangles_rectangles(reply.get());
const int rectCount = xcb_shape_get_rectangles_rectangles_length(reply.get());
for (int i = 0; i < rectCount; ++i) {
QRectF region = Xcb::fromXNative(QRect(rects[i].x, rects[i].y, rects[i].width, rects[i].height)).toAlignedRect();
// make sure the shape is sane (X is async, maybe even XShape is broken)
region = region.intersected(QRectF(QPointF(0, 0), bufferGeometry.size()));
m_shapeRegion += region;
}
} else {
m_shapeRegion.clear();
}
} else {
m_shapeRegion = {QRectF(0, 0, bufferGeometry.width(), bufferGeometry.height())};
}
m_shapeRegionIsValid = true;
return m_shapeRegion;
}
void Window::discardShapeRegion()
{
m_shapeRegionIsValid = false;
m_shapeRegion.clear();
}
bool Window::isClient() const bool Window::isClient() const
{ {
return false; return false;

View file

@ -714,14 +714,6 @@ public:
*/ */
bool wantsShadowToBeRendered() const; bool wantsShadowToBeRendered() const;
/**
* This method returns the area that the Window window reports to be opaque.
* It is supposed to only provide valuable information if hasAlpha is @c true .
* @see hasAlpha
*/
const QRegion &opaqueRegion() const;
QVector<QRectF> shapeRegion() const;
bool skipsCloseAnimation() const; bool skipsCloseAnimation() const;
void setSkipCloseAnimation(bool set); void setSkipCloseAnimation(bool set);
@ -1489,13 +1481,6 @@ protected:
void getWmClientLeader(); void getWmClientLeader();
void getWmClientMachine(); void getWmClientMachine();
/**
* This function fetches the opaque region from this Window.
* Will only be called on corresponding property changes and for initialization.
*/
void getWmOpaqueRegion();
void discardShapeRegion();
virtual std::unique_ptr<WindowItem> createItem(Scene *scene) = 0; virtual std::unique_ptr<WindowItem> createItem(Scene *scene) = 0;
void getResourceClass(); void getResourceClass();
@ -1821,9 +1806,6 @@ private:
QString resource_class; QString resource_class;
ClientMachine *m_clientMachine; ClientMachine *m_clientMachine;
xcb_window_t m_wmClientLeader; xcb_window_t m_wmClientLeader;
QRegion opaque_region;
mutable QVector<QRectF> m_shapeRegion;
mutable bool m_shapeRegionIsValid = false;
bool m_skipCloseAnimation; bool m_skipCloseAnimation;
QPointer<KWaylandServer::SurfaceInterface> m_surface; QPointer<KWaylandServer::SurfaceInterface> m_surface;
// when adding new data members, check also copyToDeleted() // when adding new data members, check also copyToDeleted()
@ -2125,11 +2107,6 @@ inline bool Window::isInternal() const
return false; return false;
} }
inline const QRegion &Window::opaqueRegion() const
{
return opaque_region;
}
inline EffectWindowImpl *Window::effectWindow() inline EffectWindowImpl *Window::effectWindow()
{ {
return m_effectWindow.get(); return m_effectWindow.get();

View file

@ -326,6 +326,7 @@ X11Window::X11Window()
connect(clientMachine(), &ClientMachine::localhostChanged, this, &X11Window::updateCaption); connect(clientMachine(), &ClientMachine::localhostChanged, this, &X11Window::updateCaption);
connect(options, &Options::configChanged, this, &X11Window::updateMouseGrab); connect(options, &Options::configChanged, this, &X11Window::updateMouseGrab);
connect(options, &Options::condensedTitleChanged, this, &X11Window::updateCaption); connect(options, &Options::condensedTitleChanged, this, &X11Window::updateCaption);
connect(this, &Window::geometryShapeChanged, this, &X11Window::discardShapeRegion);
if (kwinApp()->operationMode() == Application::OperationModeX11) { if (kwinApp()->operationMode() == Application::OperationModeX11) {
connect(this, &X11Window::moveResizeCursorChanged, this, [this](CursorShape cursor) { connect(this, &X11Window::moveResizeCursorChanged, this, [this](CursorShape cursor) {
@ -5046,4 +5047,53 @@ void X11Window::checkOutput()
setOutput(workspace()->outputAt(frameGeometry().center())); setOutput(workspace()->outputAt(frameGeometry().center()));
} }
void X11Window::getWmOpaqueRegion()
{
const auto rects = info->opaqueRegion();
QRegion new_opaque_region;
for (const auto &r : rects) {
new_opaque_region |= Xcb::fromXNative(QRect(r.pos.x, r.pos.y, r.size.width, r.size.height)).toRect();
}
opaque_region = new_opaque_region;
}
QVector<QRectF> X11Window::shapeRegion() const
{
if (m_shapeRegionIsValid) {
return m_shapeRegion;
}
const QRectF bufferGeometry = this->bufferGeometry();
if (is_shape) {
auto cookie = xcb_shape_get_rectangles_unchecked(kwinApp()->x11Connection(), frameId(), XCB_SHAPE_SK_BOUNDING);
UniqueCPtr<xcb_shape_get_rectangles_reply_t> reply(xcb_shape_get_rectangles_reply(kwinApp()->x11Connection(), cookie, nullptr));
if (reply) {
m_shapeRegion.clear();
const xcb_rectangle_t *rects = xcb_shape_get_rectangles_rectangles(reply.get());
const int rectCount = xcb_shape_get_rectangles_rectangles_length(reply.get());
for (int i = 0; i < rectCount; ++i) {
QRectF region = Xcb::fromXNative(QRect(rects[i].x, rects[i].y, rects[i].width, rects[i].height)).toAlignedRect();
// make sure the shape is sane (X is async, maybe even XShape is broken)
region = region.intersected(QRectF(QPointF(0, 0), bufferGeometry.size()));
m_shapeRegion += region;
}
} else {
m_shapeRegion.clear();
}
} else {
m_shapeRegion = {QRectF(0, 0, bufferGeometry.width(), bufferGeometry.height())};
}
m_shapeRegionIsValid = true;
return m_shapeRegion;
}
void X11Window::discardShapeRegion()
{
m_shapeRegionIsValid = false;
m_shapeRegion.clear();
}
} // namespace } // namespace

View file

@ -93,6 +93,8 @@ public:
xcb_visualid_t visual() const; xcb_visualid_t visual() const;
int depth() const; int depth() const;
bool hasAlpha() const; bool hasAlpha() const;
QRegion opaqueRegion() const;
QVector<QRectF> shapeRegion() const;
QMatrix4x4 inputTransformation() const override; QMatrix4x4 inputTransformation() const override;
@ -359,6 +361,8 @@ private:
void getWmNormalHints(); void getWmNormalHints();
void getMotifHints(); void getMotifHints();
void getIcons(); void getIcons();
void getWmOpaqueRegion();
void discardShapeRegion();
void fetchName(); void fetchName();
void fetchIconicName(); void fetchIconicName();
QString readName() const; QString readName() const;
@ -483,6 +487,9 @@ private:
int sm_stacking_order; int sm_stacking_order;
xcb_visualid_t m_visual = XCB_NONE; xcb_visualid_t m_visual = XCB_NONE;
int bit_depth = 24; int bit_depth = 24;
QRegion opaque_region;
mutable QVector<QRectF> m_shapeRegion;
mutable bool m_shapeRegionIsValid = false;
friend struct ResetupRulesProcedure; friend struct ResetupRulesProcedure;
friend bool performTransiencyCheck(); friend bool performTransiencyCheck();
@ -530,6 +537,11 @@ inline bool X11Window::hasAlpha() const
return depth() == 32; return depth() == 32;
} }
inline QRegion X11Window::opaqueRegion() const
{
return opaque_region;
}
inline xcb_window_t X11Window::wrapperId() const inline xcb_window_t X11Window::wrapperId() const
{ {
return m_wrapper; return m_wrapper;