forked from quickshell/quickshell
		
	hyprland/surface: add visibleMask
This commit is contained in:
		
							parent
							
								
									cdaff2967f
								
							
						
					
					
						commit
						b289bfa504
					
				
					 6 changed files with 230 additions and 36 deletions
				
			
		| 
						 | 
				
			
			@ -34,7 +34,7 @@
 | 
			
		|||
    This protocol exposes hyprland-specific wl_surface properties.
 | 
			
		||||
  </description>
 | 
			
		||||
 | 
			
		||||
  <interface name="hyprland_surface_manager_v1" version="1">
 | 
			
		||||
  <interface name="hyprland_surface_manager_v1" version="2">
 | 
			
		||||
    <description summary="manager for hyprland surface objects">
 | 
			
		||||
      This interface allows a client to create hyprland surface objects.
 | 
			
		||||
    </description>
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +63,7 @@
 | 
			
		|||
    </enum>
 | 
			
		||||
  </interface>
 | 
			
		||||
 | 
			
		||||
  <interface name="hyprland_surface_v1" version="1">
 | 
			
		||||
  <interface name="hyprland_surface_v1" version="2">
 | 
			
		||||
    <description summary="hyprland-specific wl_surface properties">
 | 
			
		||||
      This interface allows access to hyprland-specific properties of a wl_surface.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -96,5 +96,31 @@
 | 
			
		|||
      <entry name="no_surface" value="0" summary="wl_surface was destroyed"/>
 | 
			
		||||
      <entry name="out_of_range" value="1" summary="given opacity was not in the range 0.0 - 1.0 (inclusive)"/>
 | 
			
		||||
    </enum>
 | 
			
		||||
 | 
			
		||||
    <request name="set_visible_region" since="2">
 | 
			
		||||
      <description summary="set the visible region of the surface">
 | 
			
		||||
        This request sets the region of the surface that contains visible content.
 | 
			
		||||
        Visible content refers to content that has an alpha value greater than zero.
 | 
			
		||||
 | 
			
		||||
        The visible region is an optimization hint for the compositor that lets it
 | 
			
		||||
        avoid drawing parts of the surface that are not visible. Setting a visible region
 | 
			
		||||
        that does not contain all content in the surface may result in missing content
 | 
			
		||||
        not being drawn.
 | 
			
		||||
 | 
			
		||||
        The visible region is specified in buffer-local coordinates.
 | 
			
		||||
 | 
			
		||||
        The compositor ignores the parts of the visible region that fall outside of the surface.
 | 
			
		||||
        When all parts of the region fall outside of the buffer geometry, the compositor may
 | 
			
		||||
        avoid rendering the surface entirely.
 | 
			
		||||
 | 
			
		||||
        The initial value for the visible region is empty. Setting the
 | 
			
		||||
        visible region has copy semantics, and the wl_region object can be destroyed immediately.
 | 
			
		||||
        A NULL wl_region causes the visible region to be set to empty.
 | 
			
		||||
 | 
			
		||||
        Does not take effect until wl_surface.commit is called.
 | 
			
		||||
      </description>
 | 
			
		||||
 | 
			
		||||
      <arg name="region" type="object" interface="wl_region" allow-null="true"/>
 | 
			
		||||
    </request>
 | 
			
		||||
  </interface>
 | 
			
		||||
</protocol>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,13 +7,13 @@
 | 
			
		|||
 | 
			
		||||
namespace qs::hyprland::surface::impl {
 | 
			
		||||
 | 
			
		||||
HyprlandSurfaceManager::HyprlandSurfaceManager(): QWaylandClientExtensionTemplate(1) {
 | 
			
		||||
HyprlandSurfaceManager::HyprlandSurfaceManager(): QWaylandClientExtensionTemplate(2) {
 | 
			
		||||
	this->initialize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HyprlandSurface*
 | 
			
		||||
HyprlandSurfaceManager::createHyprlandExtension(QtWaylandClient::QWaylandWindow* surface) {
 | 
			
		||||
	return new HyprlandSurface(this->get_hyprland_surface(surface->surface()));
 | 
			
		||||
	return new HyprlandSurface(this->get_hyprland_surface(surface->surface()), surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HyprlandSurfaceManager* HyprlandSurfaceManager::instance() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,17 +1,20 @@
 | 
			
		|||
#include "qml.hpp"
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#include <private/qhighdpiscaling_p.h>
 | 
			
		||||
#include <private/qwaylandwindow_p.h>
 | 
			
		||||
#include <qlogging.h>
 | 
			
		||||
#include <qobject.h>
 | 
			
		||||
#include <qqmlinfo.h>
 | 
			
		||||
#include <qregion.h>
 | 
			
		||||
#include <qtmetamacros.h>
 | 
			
		||||
#include <qtypes.h>
 | 
			
		||||
#include <qvariant.h>
 | 
			
		||||
#include <qwindow.h>
 | 
			
		||||
 | 
			
		||||
#include "../../../core/region.hpp"
 | 
			
		||||
#include "../../../window/proxywindow.hpp"
 | 
			
		||||
#include "../../../window/windowinterface.hpp"
 | 
			
		||||
#include "../../util.hpp"
 | 
			
		||||
#include "manager.hpp"
 | 
			
		||||
#include "surface.hpp"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +43,15 @@ HyprlandWindow::HyprlandWindow(ProxyWindowBase* window): QObject(nullptr), proxy
 | 
			
		|||
	    &HyprlandWindow::onWindowConnected
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	QObject::connect(window, &ProxyWindowBase::polished, this, &HyprlandWindow::onWindowPolished);
 | 
			
		||||
 | 
			
		||||
	QObject::connect(
 | 
			
		||||
	    window,
 | 
			
		||||
	    &ProxyWindowBase::devicePixelRatioChanged,
 | 
			
		||||
	    this,
 | 
			
		||||
	    &HyprlandWindow::updateVisibleMask
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	QObject::connect(window, &QObject::destroyed, this, &HyprlandWindow::onProxyWindowDestroyed);
 | 
			
		||||
 | 
			
		||||
	if (window->backingWindow()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,14 +72,76 @@ void HyprlandWindow::setOpacity(qreal opacity) {
 | 
			
		|||
 | 
			
		||||
	this->mOpacity = opacity;
 | 
			
		||||
 | 
			
		||||
	if (this->surface) {
 | 
			
		||||
		this->surface->setOpacity(opacity);
 | 
			
		||||
		qs::wayland::util::scheduleCommit(this->proxyWindow);
 | 
			
		||||
	if (this->surface && this->proxyWindow) {
 | 
			
		||||
		this->pendingPolish.opacity = true;
 | 
			
		||||
		this->proxyWindow->schedulePolish();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	emit this->opacityChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PendingRegion* HyprlandWindow::visibleMask() const { return this->mVisibleMask; }
 | 
			
		||||
 | 
			
		||||
void HyprlandWindow::setVisibleMask(PendingRegion* mask) {
 | 
			
		||||
	if (mask == this->mVisibleMask) return;
 | 
			
		||||
 | 
			
		||||
	if (this->mVisibleMask) {
 | 
			
		||||
		QObject::disconnect(this->mVisibleMask, nullptr, this, nullptr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this->mVisibleMask = mask;
 | 
			
		||||
 | 
			
		||||
	if (mask) {
 | 
			
		||||
		QObject::connect(mask, &QObject::destroyed, this, &HyprlandWindow::onVisibleMaskDestroyed);
 | 
			
		||||
		QObject::connect(mask, &PendingRegion::changed, this, &HyprlandWindow::updateVisibleMask);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this->updateVisibleMask();
 | 
			
		||||
	emit this->visibleMaskChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HyprlandWindow::onVisibleMaskDestroyed() {
 | 
			
		||||
	this->mVisibleMask = nullptr;
 | 
			
		||||
	this->updateVisibleMask();
 | 
			
		||||
	emit this->visibleMaskChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HyprlandWindow::updateVisibleMask() {
 | 
			
		||||
	if (!this->surface || !this->proxyWindow) return;
 | 
			
		||||
 | 
			
		||||
	this->pendingPolish.visibleMask = true;
 | 
			
		||||
	this->proxyWindow->schedulePolish();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HyprlandWindow::onWindowPolished() {
 | 
			
		||||
	if (!this->surface) return;
 | 
			
		||||
 | 
			
		||||
	if (this->pendingPolish.opacity) {
 | 
			
		||||
		this->surface->setOpacity(this->mOpacity);
 | 
			
		||||
		this->pendingPolish.opacity = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (this->pendingPolish.visibleMask) {
 | 
			
		||||
		QRegion mask;
 | 
			
		||||
		if (this->mVisibleMask != nullptr) {
 | 
			
		||||
			mask =
 | 
			
		||||
			    this->mVisibleMask->applyTo(QRect(0, 0, this->mWindow->width(), this->mWindow->height()));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		auto dpr = this->proxyWindow->devicePixelRatio();
 | 
			
		||||
		if (dpr != 1.0) {
 | 
			
		||||
			mask = QHighDpi::scale(mask, dpr);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (mask.isEmpty() && this->mVisibleMask) {
 | 
			
		||||
			mask = QRect(-1, -1, 1, 1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this->surface->setVisibleRegion(mask);
 | 
			
		||||
		this->pendingPolish.visibleMask = false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HyprlandWindow::onWindowConnected() {
 | 
			
		||||
	this->mWindow = this->proxyWindow->backingWindow();
 | 
			
		||||
	// disconnected by destructor
 | 
			
		||||
| 
						 | 
				
			
			@ -86,33 +160,46 @@ void HyprlandWindow::onWindowVisibleChanged() {
 | 
			
		|||
		if (!this->mWindow->handle()) {
 | 
			
		||||
			this->mWindow->create();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		this->mWaylandWindow = dynamic_cast<QWaylandWindow*>(this->mWindow->handle());
 | 
			
		||||
	auto* window = dynamic_cast<QWaylandWindow*>(this->mWindow->handle());
 | 
			
		||||
	if (window == this->mWaylandWindow) return;
 | 
			
		||||
 | 
			
		||||
		if (this->mWaylandWindow) {
 | 
			
		||||
			// disconnected by destructor
 | 
			
		||||
	if (this->mWaylandWindow) {
 | 
			
		||||
		QObject::disconnect(this->mWaylandWindow, nullptr, this, nullptr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
			QObject::connect(
 | 
			
		||||
			    this->mWaylandWindow,
 | 
			
		||||
			    &QWaylandWindow::surfaceCreated,
 | 
			
		||||
			    this,
 | 
			
		||||
			    &HyprlandWindow::onWaylandSurfaceCreated
 | 
			
		||||
			);
 | 
			
		||||
	this->mWaylandWindow = window;
 | 
			
		||||
	if (!window) return;
 | 
			
		||||
 | 
			
		||||
			QObject::connect(
 | 
			
		||||
			    this->mWaylandWindow,
 | 
			
		||||
			    &QWaylandWindow::surfaceDestroyed,
 | 
			
		||||
			    this,
 | 
			
		||||
			    &HyprlandWindow::onWaylandSurfaceDestroyed
 | 
			
		||||
			);
 | 
			
		||||
	QObject::connect(
 | 
			
		||||
	    this->mWaylandWindow,
 | 
			
		||||
	    &QObject::destroyed,
 | 
			
		||||
	    this,
 | 
			
		||||
	    &HyprlandWindow::onWaylandWindowDestroyed
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
			if (this->mWaylandWindow->surface()) {
 | 
			
		||||
				this->onWaylandSurfaceCreated();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	QObject::connect(
 | 
			
		||||
	    this->mWaylandWindow,
 | 
			
		||||
	    &QWaylandWindow::surfaceCreated,
 | 
			
		||||
	    this,
 | 
			
		||||
	    &HyprlandWindow::onWaylandSurfaceCreated
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	QObject::connect(
 | 
			
		||||
	    this->mWaylandWindow,
 | 
			
		||||
	    &QWaylandWindow::surfaceDestroyed,
 | 
			
		||||
	    this,
 | 
			
		||||
	    &HyprlandWindow::onWaylandSurfaceDestroyed
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	if (this->mWaylandWindow->surface()) {
 | 
			
		||||
		this->onWaylandSurfaceCreated();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HyprlandWindow::onWaylandWindowDestroyed() { this->mWaylandWindow = nullptr; }
 | 
			
		||||
 | 
			
		||||
void HyprlandWindow::onWaylandSurfaceCreated() {
 | 
			
		||||
	auto* manager = impl::HyprlandSurfaceManager::instance();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -122,12 +209,26 @@ void HyprlandWindow::onWaylandSurfaceCreated() {
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	auto* ext = manager->createHyprlandExtension(this->mWaylandWindow);
 | 
			
		||||
	this->surface = std::unique_ptr<impl::HyprlandSurface>(ext);
 | 
			
		||||
	auto v = this->mWaylandWindow->property("hyprland_window_ext");
 | 
			
		||||
	if (v.canConvert<HyprlandWindow*>()) {
 | 
			
		||||
		auto* windowExt = v.value<HyprlandWindow*>();
 | 
			
		||||
		if (windowExt != this && windowExt->surface) {
 | 
			
		||||
			this->surface.swap(windowExt->surface);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (this->mOpacity != 1.0) {
 | 
			
		||||
		this->surface->setOpacity(this->mOpacity);
 | 
			
		||||
		qs::wayland::util::scheduleCommit(this->proxyWindow);
 | 
			
		||||
	if (!this->surface) {
 | 
			
		||||
		auto* ext = manager->createHyprlandExtension(this->mWaylandWindow);
 | 
			
		||||
		this->surface = std::unique_ptr<impl::HyprlandSurface>(ext);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this->mWaylandWindow->setProperty("hyprland_window_ext", QVariant::fromValue(this));
 | 
			
		||||
 | 
			
		||||
	this->pendingPolish.opacity = this->mOpacity != 1.0;
 | 
			
		||||
	this->pendingPolish.visibleMask = this->mVisibleMask;
 | 
			
		||||
 | 
			
		||||
	if (this->pendingPolish.opacity || this->pendingPolish.visibleMask) {
 | 
			
		||||
		this->proxyWindow->schedulePolish();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,8 +245,9 @@ void HyprlandWindow::onProxyWindowDestroyed() {
 | 
			
		|||
	// Deleting it when the proxy window is deleted will cause a full opacity frame between the destruction of the
 | 
			
		||||
	// hyprland_surface_v1 and wl_surface objects.
 | 
			
		||||
 | 
			
		||||
	this->proxyWindow = nullptr;
 | 
			
		||||
 | 
			
		||||
	if (this->surface == nullptr) {
 | 
			
		||||
		this->proxyWindow = nullptr;
 | 
			
		||||
		this->deleteLater();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@
 | 
			
		|||
#include <qtypes.h>
 | 
			
		||||
#include <qwindow.h>
 | 
			
		||||
 | 
			
		||||
#include "../../../core/region.hpp"
 | 
			
		||||
#include "../../../window/proxywindow.hpp"
 | 
			
		||||
#include "surface.hpp"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,11 +32,18 @@ namespace qs::hyprland::surface {
 | 
			
		|||
/// [hyprland-surface-v1]: https://github.com/hyprwm/hyprland-protocols/blob/main/protocols/hyprland-surface-v1.xml
 | 
			
		||||
class HyprlandWindow: public QObject {
 | 
			
		||||
	Q_OBJECT;
 | 
			
		||||
	// clang-format off
 | 
			
		||||
	/// A multiplier for the window's overall opacity, ranging from 1.0 to 0.0. Overall opacity includes the opacity of
 | 
			
		||||
	/// both the window content *and* visual effects such as blur that apply to it.
 | 
			
		||||
	///
 | 
			
		||||
	/// Default: 1.0
 | 
			
		||||
	Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged);
 | 
			
		||||
	/// A hint to the compositor that only certain regions of the surface should be rendered.
 | 
			
		||||
	/// This can be used to avoid rendering large empty regions of a window which can increase
 | 
			
		||||
	/// performance, especially if the window is blurred. The mask should include all pixels
 | 
			
		||||
	/// of the window that do not have an alpha value of 0.
 | 
			
		||||
	Q_PROPERTY(PendingRegion* visibleMask READ visibleMask WRITE setVisibleMask NOTIFY visibleMaskChanged);
 | 
			
		||||
	// clang-format on
 | 
			
		||||
	QML_ELEMENT;
 | 
			
		||||
	QML_UNCREATABLE("HyprlandWindow can only be used as an attached object.");
 | 
			
		||||
	QML_ATTACHED(HyprlandWindow);
 | 
			
		||||
| 
						 | 
				
			
			@ -48,17 +56,25 @@ public:
 | 
			
		|||
	[[nodiscard]] qreal opacity() const;
 | 
			
		||||
	void setOpacity(qreal opacity);
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] PendingRegion* visibleMask() const;
 | 
			
		||||
	virtual void setVisibleMask(PendingRegion* mask);
 | 
			
		||||
 | 
			
		||||
	static HyprlandWindow* qmlAttachedProperties(QObject* object);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
	void opacityChanged();
 | 
			
		||||
	void visibleMaskChanged();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
	void onWindowConnected();
 | 
			
		||||
	void onWindowVisibleChanged();
 | 
			
		||||
	void onWaylandWindowDestroyed();
 | 
			
		||||
	void onWaylandSurfaceCreated();
 | 
			
		||||
	void onWaylandSurfaceDestroyed();
 | 
			
		||||
	void onProxyWindowDestroyed();
 | 
			
		||||
	void onVisibleMaskDestroyed();
 | 
			
		||||
	void onWindowPolished();
 | 
			
		||||
	void updateVisibleMask();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void disconnectWaylandWindow();
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +83,13 @@ private:
 | 
			
		|||
	QWindow* mWindow = nullptr;
 | 
			
		||||
	QtWaylandClient::QWaylandWindow* mWaylandWindow = nullptr;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		bool opacity : 1 = false;
 | 
			
		||||
		bool visibleMask : 1 = false;
 | 
			
		||||
	} pendingPolish;
 | 
			
		||||
 | 
			
		||||
	qreal mOpacity = 1.0;
 | 
			
		||||
	PendingRegion* mVisibleMask = nullptr;
 | 
			
		||||
	std::unique_ptr<impl::HyprlandSurface> surface;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,19 +1,53 @@
 | 
			
		|||
#include "surface.hpp"
 | 
			
		||||
#include <cmath>
 | 
			
		||||
 | 
			
		||||
#include <private/qwaylanddisplay_p.h>
 | 
			
		||||
#include <private/qwaylandintegration_p.h>
 | 
			
		||||
#include <qlogging.h>
 | 
			
		||||
#include <qregion.h>
 | 
			
		||||
#include <qtypes.h>
 | 
			
		||||
#include <qwayland-hyprland-surface-v1.h>
 | 
			
		||||
#include <wayland-client-protocol.h>
 | 
			
		||||
#include <wayland-hyprland-surface-v1-client-protocol.h>
 | 
			
		||||
#include <wayland-util.h>
 | 
			
		||||
 | 
			
		||||
namespace qs::hyprland::surface::impl {
 | 
			
		||||
 | 
			
		||||
HyprlandSurface::HyprlandSurface(::hyprland_surface_v1* surface)
 | 
			
		||||
    : QtWayland::hyprland_surface_v1(surface) {}
 | 
			
		||||
HyprlandSurface::HyprlandSurface(
 | 
			
		||||
    ::hyprland_surface_v1* surface,
 | 
			
		||||
    QtWaylandClient::QWaylandWindow* backer
 | 
			
		||||
)
 | 
			
		||||
    : QtWayland::hyprland_surface_v1(surface)
 | 
			
		||||
    , backer(backer)
 | 
			
		||||
    , backerSurface(backer->surface()) {}
 | 
			
		||||
 | 
			
		||||
HyprlandSurface::~HyprlandSurface() { this->destroy(); }
 | 
			
		||||
 | 
			
		||||
bool HyprlandSurface::surfaceEq(wl_surface* surface) const {
 | 
			
		||||
	return surface == this->backerSurface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HyprlandSurface::setOpacity(qreal opacity) {
 | 
			
		||||
	this->set_opacity(wl_fixed_from_double(opacity));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HyprlandSurface::setVisibleRegion(const QRegion& region) {
 | 
			
		||||
	if (this->version() < HYPRLAND_SURFACE_V1_SET_VISIBLE_REGION_SINCE_VERSION) {
 | 
			
		||||
		qWarning() << "Cannot set hyprland surface visible region: compositor does not support "
 | 
			
		||||
		              "hyprland_surface_v1.set_visible_region";
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (region.isEmpty()) {
 | 
			
		||||
		this->set_visible_region(nullptr);
 | 
			
		||||
	} else {
 | 
			
		||||
		static const auto* waylandIntegration = QtWaylandClient::QWaylandIntegration::instance();
 | 
			
		||||
		auto* display = waylandIntegration->display();
 | 
			
		||||
 | 
			
		||||
		auto* wlRegion = display->createRegion(region);
 | 
			
		||||
		this->set_visible_region(wlRegion);
 | 
			
		||||
		wl_region_destroy(wlRegion); // NOLINT(misc-include-cleaner)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace qs::hyprland::surface::impl
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,21 +1,31 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <private/qwaylandwindow_p.h>
 | 
			
		||||
#include <qobject.h>
 | 
			
		||||
#include <qregion.h>
 | 
			
		||||
#include <qtclasshelpermacros.h>
 | 
			
		||||
#include <qtmetamacros.h>
 | 
			
		||||
#include <qtypes.h>
 | 
			
		||||
#include <qwayland-hyprland-surface-v1.h>
 | 
			
		||||
#include <wayland-client-protocol.h>
 | 
			
		||||
#include <wayland-hyprland-surface-v1-client-protocol.h>
 | 
			
		||||
 | 
			
		||||
namespace qs::hyprland::surface::impl {
 | 
			
		||||
 | 
			
		||||
class HyprlandSurface: public QtWayland::hyprland_surface_v1 {
 | 
			
		||||
public:
 | 
			
		||||
	explicit HyprlandSurface(::hyprland_surface_v1* surface);
 | 
			
		||||
	explicit HyprlandSurface(::hyprland_surface_v1* surface, QtWaylandClient::QWaylandWindow* backer);
 | 
			
		||||
	~HyprlandSurface() override;
 | 
			
		||||
	Q_DISABLE_COPY_MOVE(HyprlandSurface);
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] bool surfaceEq(wl_surface* surface) const;
 | 
			
		||||
 | 
			
		||||
	void setOpacity(qreal opacity);
 | 
			
		||||
	void setVisibleRegion(const QRegion& region);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QtWaylandClient::QWaylandWindow* backer;
 | 
			
		||||
	wl_surface* backerSurface = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace qs::hyprland::surface::impl
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue