Compare commits
6 commits
a408fe0f29
...
dbb923c299
Author | SHA1 | Date | |
---|---|---|---|
dbb923c299 | |||
4b7253ce3a | |||
cef1cd5472 | |||
f672b897a7 | |||
f8bd1e5120 | |||
87f03a8996 |
12 changed files with 124 additions and 16 deletions
|
@ -118,6 +118,7 @@ PanelWindow {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: palette.active.window
|
color: palette.active.window
|
||||||
border.color: root.failed ? "#b53030" : palette.active.accent
|
border.color: root.failed ? "#b53030" : palette.active.accent
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
radius: 10
|
radius: 10
|
||||||
margin: 10
|
margin: 10
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
|
@ -555,23 +556,88 @@ WlBufferQSGTexture* WlDmaBuffer::createQsgTexture(QQuickWindow* window) const {
|
||||||
|
|
||||||
auto* display = qEglContext->display();
|
auto* display = qEglContext->display();
|
||||||
|
|
||||||
|
// Ref https://github.com/hyprwm/hyprlock/blob/da1d076d849fc0f298c1d287bddd04802bf7d0f9/src/renderer/Screencopy.cpp#L194
|
||||||
|
struct AttribNameSet {
|
||||||
|
EGLAttrib fd;
|
||||||
|
EGLAttrib offset;
|
||||||
|
EGLAttrib pitch;
|
||||||
|
EGLAttrib modlo;
|
||||||
|
EGLAttrib modhi;
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto attribNames = std::array<AttribNameSet, 4> {
|
||||||
|
AttribNameSet {
|
||||||
|
.fd = EGL_DMA_BUF_PLANE0_FD_EXT,
|
||||||
|
.offset = EGL_DMA_BUF_PLANE0_OFFSET_EXT,
|
||||||
|
.pitch = EGL_DMA_BUF_PLANE0_PITCH_EXT,
|
||||||
|
.modlo = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
|
||||||
|
.modhi = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT
|
||||||
|
},
|
||||||
|
AttribNameSet {
|
||||||
|
.fd = EGL_DMA_BUF_PLANE1_FD_EXT,
|
||||||
|
.offset = EGL_DMA_BUF_PLANE1_OFFSET_EXT,
|
||||||
|
.pitch = EGL_DMA_BUF_PLANE1_PITCH_EXT,
|
||||||
|
.modlo = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
|
||||||
|
.modhi = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT
|
||||||
|
},
|
||||||
|
AttribNameSet {
|
||||||
|
.fd = EGL_DMA_BUF_PLANE2_FD_EXT,
|
||||||
|
.offset = EGL_DMA_BUF_PLANE2_OFFSET_EXT,
|
||||||
|
.pitch = EGL_DMA_BUF_PLANE2_PITCH_EXT,
|
||||||
|
.modlo = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT,
|
||||||
|
.modhi = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT
|
||||||
|
},
|
||||||
|
AttribNameSet {
|
||||||
|
.fd = EGL_DMA_BUF_PLANE3_FD_EXT,
|
||||||
|
.offset = EGL_DMA_BUF_PLANE3_OFFSET_EXT,
|
||||||
|
.pitch = EGL_DMA_BUF_PLANE3_PITCH_EXT,
|
||||||
|
.modlo = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT,
|
||||||
|
.modhi = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
auto attribs = std::array<EGLAttrib, 6 * 2 + 1> {
|
auto attribs = std::vector<EGLAttrib> {
|
||||||
EGL_WIDTH, this->width,
|
EGL_WIDTH, this->width,
|
||||||
EGL_HEIGHT, this->height,
|
EGL_HEIGHT, this->height,
|
||||||
EGL_LINUX_DRM_FOURCC_EXT, this->format,
|
EGL_LINUX_DRM_FOURCC_EXT, this->format,
|
||||||
EGL_DMA_BUF_PLANE0_FD_EXT, this->planes[0].fd, // NOLINT
|
|
||||||
EGL_DMA_BUF_PLANE0_OFFSET_EXT, this->planes[0].offset, // NOLINT
|
|
||||||
EGL_DMA_BUF_PLANE0_PITCH_EXT, this->planes[0].stride, // NOLINT
|
|
||||||
EGL_NONE
|
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
if (this->planeCount > 4) {
|
||||||
|
qFatal(logDmabuf) << "Could not create EGL attrib array with more than 4 planes. Count:"
|
||||||
|
<< this->planeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = 0; i != this->planeCount; i++) {
|
||||||
|
const auto& names = attribNames[i];
|
||||||
|
const auto& plane = this->planes[i]; // NOLINT
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
attribs.insert(attribs.end(), {
|
||||||
|
names.fd, plane.fd,
|
||||||
|
names.offset, plane.offset,
|
||||||
|
names.pitch, plane.stride,
|
||||||
|
});
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
if (this->modifier != DRM_FORMAT_MOD_INVALID) {
|
||||||
|
attribs.insert(attribs.end(), {
|
||||||
|
names.modlo, static_cast<EGLAttrib>(this->modifier & 0xFFFFFFFF),
|
||||||
|
names.modhi, static_cast<EGLAttrib>(this->modifier >> 32),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
attribs.emplace_back(EGL_NONE);
|
||||||
|
|
||||||
auto* eglImage =
|
auto* eglImage =
|
||||||
eglCreateImage(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
|
eglCreateImage(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
|
||||||
|
|
||||||
if (eglImage == EGL_NO_IMAGE) {
|
if (eglImage == EGL_NO_IMAGE) {
|
||||||
qFatal() << "failed to make egl image" << eglGetError();
|
qFatal() << "Failed to create egl image" << eglGetError();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,10 @@ LayerSurface::LayerSurface(LayerShellIntegration* shell, QtWaylandClient::QWayla
|
||||||
this->bridge->surface = this;
|
this->bridge->surface = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerSurface::~LayerSurface() { this->destroy(); }
|
LayerSurface::~LayerSurface() {
|
||||||
|
delete this->bridge;
|
||||||
|
this->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
void LayerSurface::zwlr_layer_surface_v1_configure(quint32 serial, quint32 width, quint32 height) {
|
void LayerSurface::zwlr_layer_surface_v1_configure(quint32 serial, quint32 width, quint32 height) {
|
||||||
this->ack_configure(serial);
|
this->ack_configure(serial);
|
||||||
|
|
|
@ -34,7 +34,8 @@ ProxiedWindow* WlrLayershell::retrieveWindow(QObject* oldInstance) {
|
||||||
auto* window = old == nullptr ? nullptr : old->disownWindow();
|
auto* window = old == nullptr ? nullptr : old->disownWindow();
|
||||||
|
|
||||||
if (window != nullptr) {
|
if (window != nullptr) {
|
||||||
this->bridge = LayerSurfaceBridge::init(window, this->computeState());
|
this->connectBridge(LayerSurfaceBridge::init(window, this->computeState()));
|
||||||
|
|
||||||
if (this->bridge) {
|
if (this->bridge) {
|
||||||
return window;
|
return window;
|
||||||
} else {
|
} else {
|
||||||
|
@ -48,7 +49,7 @@ ProxiedWindow* WlrLayershell::retrieveWindow(QObject* oldInstance) {
|
||||||
ProxiedWindow* WlrLayershell::createQQuickWindow() {
|
ProxiedWindow* WlrLayershell::createQQuickWindow() {
|
||||||
auto* window = this->ProxyWindowBase::createQQuickWindow();
|
auto* window = this->ProxyWindowBase::createQQuickWindow();
|
||||||
|
|
||||||
this->bridge = LayerSurfaceBridge::init(window, this->computeState());
|
this->connectBridge(LayerSurfaceBridge::init(window, this->computeState()));
|
||||||
if (!this->bridge) {
|
if (!this->bridge) {
|
||||||
qWarning() << "Could not attach Layershell extension to new QQuickWindow. Layer will not "
|
qWarning() << "Could not attach Layershell extension to new QQuickWindow. Layer will not "
|
||||||
"behave correctly.";
|
"behave correctly.";
|
||||||
|
@ -72,6 +73,32 @@ void WlrLayershell::connectWindow() {
|
||||||
this->updateAutoExclusion();
|
this->updateAutoExclusion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProxiedWindow* WlrLayershell::disownWindow(bool keepItemOwnership) {
|
||||||
|
auto* window = this->ProxyWindowBase::disownWindow(keepItemOwnership);
|
||||||
|
|
||||||
|
if (this->bridge) {
|
||||||
|
this->connectBridge(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WlrLayershell::connectBridge(LayerSurfaceBridge* bridge) {
|
||||||
|
if (this->bridge) {
|
||||||
|
QObject::disconnect(this->bridge, nullptr, this, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->bridge = bridge;
|
||||||
|
|
||||||
|
if (bridge) {
|
||||||
|
QObject::connect(this->bridge, &QObject::destroyed, this, &WlrLayershell::onBridgeDestroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WlrLayershell::onBridgeDestroyed() {
|
||||||
|
this->bridge = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool WlrLayershell::deleteOnInvisible() const {
|
bool WlrLayershell::deleteOnInvisible() const {
|
||||||
// Qt windows behave weirdly when geometry is modified and setVisible(false)
|
// Qt windows behave weirdly when geometry is modified and setVisible(false)
|
||||||
// is subsequently called in the same frame.
|
// is subsequently called in the same frame.
|
||||||
|
|
|
@ -122,6 +122,7 @@ public:
|
||||||
ProxiedWindow* retrieveWindow(QObject* oldInstance) override;
|
ProxiedWindow* retrieveWindow(QObject* oldInstance) override;
|
||||||
ProxiedWindow* createQQuickWindow() override;
|
ProxiedWindow* createQQuickWindow() override;
|
||||||
void connectWindow() override;
|
void connectWindow() override;
|
||||||
|
ProxiedWindow* disownWindow(bool keepItemOwnership = false) override;
|
||||||
[[nodiscard]] bool deleteOnInvisible() const override;
|
[[nodiscard]] bool deleteOnInvisible() const override;
|
||||||
|
|
||||||
void onPolished() override;
|
void onPolished() override;
|
||||||
|
@ -175,10 +176,12 @@ signals:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateAutoExclusion();
|
void updateAutoExclusion();
|
||||||
|
void onBridgeDestroyed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] LayerSurfaceState computeState() const;
|
[[nodiscard]] LayerSurfaceState computeState() const;
|
||||||
|
|
||||||
|
void connectBridge(LayerSurfaceBridge* bridge);
|
||||||
void onStateChanged();
|
void onStateChanged();
|
||||||
|
|
||||||
bool compositorPicksScreen = true;
|
bool compositorPicksScreen = true;
|
||||||
|
|
|
@ -77,7 +77,7 @@ Item {
|
||||||
anchors.fill: root
|
anchors.fill: root
|
||||||
fragmentShader: `qrc:/Quickshell/Widgets/shaders/cliprect${root.contentUnderBorder ? "-ub" : ""}.frag.qsb`
|
fragmentShader: `qrc:/Quickshell/Widgets/shaders/cliprect${root.contentUnderBorder ? "-ub" : ""}.frag.qsb`
|
||||||
property Rectangle rect: rectangle
|
property Rectangle rect: rectangle
|
||||||
property color backgroundColor
|
property color backgroundColor: "white"
|
||||||
property color borderColor: root.border.color
|
property color borderColor: root.border.color
|
||||||
|
|
||||||
property ShaderEffectSource content: ShaderEffectSource {
|
property ShaderEffectSource content: ShaderEffectSource {
|
||||||
|
|
|
@ -39,7 +39,7 @@ ClippingRectangle {
|
||||||
/// Defaults to @@margin, and may be reset by assigning `undefined`.
|
/// Defaults to @@margin, and may be reset by assigning `undefined`.
|
||||||
property /*real*/alias rightMargin: manager.rightMargin
|
property /*real*/alias rightMargin: manager.rightMargin
|
||||||
/// Determines if child item should be resized larger than its implicit size if
|
/// Determines if child item should be resized larger than its implicit size if
|
||||||
/// the parent is resized larger than its implicit size. Defaults to false.
|
/// the parent is resized larger than its implicit size. Defaults to true.
|
||||||
property /*bool*/alias resizeChild: manager.resizeChild
|
property /*bool*/alias resizeChild: manager.resizeChild
|
||||||
/// Overrides the implicit width of the wrapper.
|
/// Overrides the implicit width of the wrapper.
|
||||||
///
|
///
|
||||||
|
|
|
@ -53,7 +53,7 @@ Item {
|
||||||
/// Defaults to @@margin, and may be reset by assigning `undefined`.
|
/// Defaults to @@margin, and may be reset by assigning `undefined`.
|
||||||
property /*real*/alias rightMargin: manager.rightMargin
|
property /*real*/alias rightMargin: manager.rightMargin
|
||||||
/// Determines if child item should be resized larger than its implicit size if
|
/// Determines if child item should be resized larger than its implicit size if
|
||||||
/// the parent is resized larger than its implicit size. Defaults to false.
|
/// the parent is resized larger than its implicit size. Defaults to true.
|
||||||
property /*bool*/alias resizeChild: manager.resizeChild
|
property /*bool*/alias resizeChild: manager.resizeChild
|
||||||
/// Overrides the implicit width of the wrapper.
|
/// Overrides the implicit width of the wrapper.
|
||||||
///
|
///
|
||||||
|
|
|
@ -41,7 +41,7 @@ MouseArea {
|
||||||
/// Defaults to @@margin, and may be reset by assigning `undefined`.
|
/// Defaults to @@margin, and may be reset by assigning `undefined`.
|
||||||
property /*real*/alias rightMargin: manager.rightMargin
|
property /*real*/alias rightMargin: manager.rightMargin
|
||||||
/// Determines if child item should be resized larger than its implicit size if
|
/// Determines if child item should be resized larger than its implicit size if
|
||||||
/// the parent is resized larger than its implicit size. Defaults to false.
|
/// the parent is resized larger than its implicit size. Defaults to true.
|
||||||
property /*bool*/alias resizeChild: manager.resizeChild
|
property /*bool*/alias resizeChild: manager.resizeChild
|
||||||
/// Overrides the implicit width of the wrapper.
|
/// Overrides the implicit width of the wrapper.
|
||||||
///
|
///
|
||||||
|
|
|
@ -43,7 +43,7 @@ Rectangle {
|
||||||
/// Defaults to @@margin, and may be reset by assigning `undefined`.
|
/// Defaults to @@margin, and may be reset by assigning `undefined`.
|
||||||
property /*real*/alias rightMargin: manager.rightMargin
|
property /*real*/alias rightMargin: manager.rightMargin
|
||||||
/// Determines if child item should be resized larger than its implicit size if
|
/// Determines if child item should be resized larger than its implicit size if
|
||||||
/// the parent is resized larger than its implicit size. Defaults to false.
|
/// the parent is resized larger than its implicit size. Defaults to true.
|
||||||
property /*bool*/alias resizeChild: manager.resizeChild
|
property /*bool*/alias resizeChild: manager.resizeChild
|
||||||
/// Overrides the implicit width of the wrapper.
|
/// Overrides the implicit width of the wrapper.
|
||||||
///
|
///
|
||||||
|
@ -58,6 +58,12 @@ Rectangle {
|
||||||
/// See @@WrapperManager.child for details.
|
/// See @@WrapperManager.child for details.
|
||||||
property alias child: manager.child
|
property alias child: manager.child
|
||||||
|
|
||||||
|
// Reading the border property implicitly sets border width to 1.
|
||||||
|
// Setting it to 0 here means the user will also have to set border.width
|
||||||
|
// even if they just want 1, but it prevents adding unexpected padding
|
||||||
|
// and works around QTBUG-137166 otherwise.
|
||||||
|
border.width: 0
|
||||||
|
|
||||||
MarginWrapperManager {
|
MarginWrapperManager {
|
||||||
id: manager
|
id: manager
|
||||||
extraMargin: (root.contentInsideBorder ? root.border.width : 0) + root.extraMargin
|
extraMargin: (root.contentInsideBorder ? root.border.width : 0) + root.extraMargin
|
||||||
|
|
|
@ -90,6 +90,8 @@ void MarginWrapperManager::componentComplete() {
|
||||||
if (this->mWrapper) {
|
if (this->mWrapper) {
|
||||||
this->bWrapperWidth.setBinding([this] { return this->mWrapper->bindableWidth().value(); });
|
this->bWrapperWidth.setBinding([this] { return this->mWrapper->bindableWidth().value(); });
|
||||||
this->bWrapperHeight.setBinding([this] { return this->mWrapper->bindableHeight().value(); });
|
this->bWrapperHeight.setBinding([this] { return this->mWrapper->bindableHeight().value(); });
|
||||||
|
this->setWrapperImplicitWidth();
|
||||||
|
this->setWrapperImplicitHeight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ class MarginWrapperManager: public WrapperManager {
|
||||||
/// Defaults to @@margin, and may be reset by assigning `undefined`.
|
/// Defaults to @@margin, and may be reset by assigning `undefined`.
|
||||||
Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin RESET resetRightMargin NOTIFY rightMarginChanged FINAL);
|
Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin RESET resetRightMargin NOTIFY rightMarginChanged FINAL);
|
||||||
/// Determines if child item should be resized larger than its implicit size if
|
/// Determines if child item should be resized larger than its implicit size if
|
||||||
/// the parent is resized larger than its implicit size. Defaults to false.
|
/// the parent is resized larger than its implicit size. Defaults to true.
|
||||||
Q_PROPERTY(bool resizeChild READ default WRITE default BINDABLE bindableResizeChild NOTIFY resizeChildChanged FINAL);
|
Q_PROPERTY(bool resizeChild READ default WRITE default BINDABLE bindableResizeChild NOTIFY resizeChildChanged FINAL);
|
||||||
/// Overrides the implicit width of the wrapper.
|
/// Overrides the implicit width of the wrapper.
|
||||||
///
|
///
|
||||||
|
@ -170,7 +170,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// clang-format off
|
// clang-format off
|
||||||
Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, bool, bResizeChild);
|
Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(MarginWrapperManager, bool, bResizeChild, true);
|
||||||
Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bMargin, &MarginWrapperManager::marginChanged);
|
Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bMargin, &MarginWrapperManager::marginChanged);
|
||||||
Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bExtraMargin, &MarginWrapperManager::baseMarginChanged);
|
Q_OBJECT_BINDABLE_PROPERTY(MarginWrapperManager, qreal, bExtraMargin, &MarginWrapperManager::baseMarginChanged);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue