diff --git a/src/window.cpp b/src/window.cpp index 1af9fd8e9e..f42e2ff3cf 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -78,8 +78,6 @@ Window::Window() { connect(this, &Window::bufferGeometryChanged, this, &Window::inputTransformationChanged); - connect(this, &Window::geometryShapeChanged, this, &Window::discardShapeRegion); - connect(this, &Window::interactiveMoveResizeStarted, this, &Window::moveResizedChanged); connect(this, &Window::interactiveMoveResizeFinished, this, &Window::moveResizedChanged); @@ -392,59 +390,6 @@ bool Window::wantsShadowToBeRendered() const 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 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 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 { return false; diff --git a/src/window.h b/src/window.h index 78c23bb6c7..81d928c404 100644 --- a/src/window.h +++ b/src/window.h @@ -714,14 +714,6 @@ public: */ 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 shapeRegion() const; - bool skipsCloseAnimation() const; void setSkipCloseAnimation(bool set); @@ -1489,13 +1481,6 @@ protected: void getWmClientLeader(); 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 createItem(Scene *scene) = 0; void getResourceClass(); @@ -1821,9 +1806,6 @@ private: QString resource_class; ClientMachine *m_clientMachine; xcb_window_t m_wmClientLeader; - QRegion opaque_region; - mutable QVector m_shapeRegion; - mutable bool m_shapeRegionIsValid = false; bool m_skipCloseAnimation; QPointer m_surface; // when adding new data members, check also copyToDeleted() @@ -2125,11 +2107,6 @@ inline bool Window::isInternal() const return false; } -inline const QRegion &Window::opaqueRegion() const -{ - return opaque_region; -} - inline EffectWindowImpl *Window::effectWindow() { return m_effectWindow.get(); diff --git a/src/x11window.cpp b/src/x11window.cpp index de7c449d99..7040f5f288 100644 --- a/src/x11window.cpp +++ b/src/x11window.cpp @@ -326,6 +326,7 @@ X11Window::X11Window() connect(clientMachine(), &ClientMachine::localhostChanged, this, &X11Window::updateCaption); connect(options, &Options::configChanged, this, &X11Window::updateMouseGrab); connect(options, &Options::condensedTitleChanged, this, &X11Window::updateCaption); + connect(this, &Window::geometryShapeChanged, this, &X11Window::discardShapeRegion); if (kwinApp()->operationMode() == Application::OperationModeX11) { connect(this, &X11Window::moveResizeCursorChanged, this, [this](CursorShape cursor) { @@ -5046,4 +5047,53 @@ void X11Window::checkOutput() 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 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 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 diff --git a/src/x11window.h b/src/x11window.h index 68b7f6f5f7..7f6df77e92 100644 --- a/src/x11window.h +++ b/src/x11window.h @@ -93,6 +93,8 @@ public: xcb_visualid_t visual() const; int depth() const; bool hasAlpha() const; + QRegion opaqueRegion() const; + QVector shapeRegion() const; QMatrix4x4 inputTransformation() const override; @@ -359,6 +361,8 @@ private: void getWmNormalHints(); void getMotifHints(); void getIcons(); + void getWmOpaqueRegion(); + void discardShapeRegion(); void fetchName(); void fetchIconicName(); QString readName() const; @@ -483,6 +487,9 @@ private: int sm_stacking_order; xcb_visualid_t m_visual = XCB_NONE; int bit_depth = 24; + QRegion opaque_region; + mutable QVector m_shapeRegion; + mutable bool m_shapeRegionIsValid = false; friend struct ResetupRulesProcedure; friend bool performTransiencyCheck(); @@ -530,6 +537,11 @@ inline bool X11Window::hasAlpha() const return depth() == 32; } +inline QRegion X11Window::opaqueRegion() const +{ + return opaque_region; +} + inline xcb_window_t X11Window::wrapperId() const { return m_wrapper;