wayland/layershell: refactor layer shell surface integration

In addition to the much needed cleanup:

- The bridge/extension type is now directly tied to the QWindow
instead of the WlrLayershell object, and is much smaller.
- Layer requests are now comitted via polish instead of for each
change individually.
This commit is contained in:
outfoxxed 2025-05-13 14:43:48 -07:00
parent 6a8284dae3
commit e0cff677a5
No known key found for this signature in database
GPG key ID: 4C88A185FB89301E
13 changed files with 366 additions and 495 deletions

View file

@ -2,6 +2,8 @@
#include <private/qwaylandshellsurface_p.h>
#include <private/qwaylandwindow_p.h>
#include <qobject.h>
#include <qsize.h>
#include <qtclasshelpermacros.h>
#include <qtwaylandclientexports.h>
#include <qtypes.h>
@ -9,40 +11,76 @@
#include <qwindow.h>
#include "shell_integration.hpp"
#include "window.hpp"
#include "wlr_layershell.hpp"
class QSWaylandLayerSurface
namespace qs::wayland::layershell {
struct LayerSurfaceState {
QSize implicitSize;
Anchors anchors;
Margins margins;
WlrLayer::Enum layer = WlrLayer::Top;
qint32 exclusiveZone = 0;
WlrKeyboardFocus::Enum keyboardFocus = WlrKeyboardFocus::None;
bool compositorPickesScreen = true;
QString mNamespace = "quickshell";
[[nodiscard]] bool isCompatible(const LayerSurfaceState& other) const {
return other.mNamespace == this->mNamespace;
}
};
class LayerSurface;
class LayerSurfaceBridge: public QObject {
public:
LayerSurfaceState state;
void commitState();
// Returns a bridge if attached, otherwise nullptr.
static LayerSurfaceBridge* get(QWindow* window);
// Creates or reuses a bridge on the given window and returns if it compatible, otherwise nullptr.
static LayerSurfaceBridge* init(QWindow* window, LayerSurfaceState state);
private:
explicit LayerSurfaceBridge(QWindow* parent): QObject(parent) {}
LayerSurface* surface = nullptr;
friend class LayerSurface;
};
class LayerSurface
: public QtWaylandClient::QWaylandShellSurface
, public QtWayland::zwlr_layer_surface_v1 {
public:
QSWaylandLayerSurface(
QSWaylandLayerShellIntegration* shell,
QtWaylandClient::QWaylandWindow* window
);
LayerSurface(LayerShellIntegration* shell, QtWaylandClient::QWaylandWindow* window);
~QSWaylandLayerSurface() override;
Q_DISABLE_COPY_MOVE(QSWaylandLayerSurface);
~LayerSurface() override;
Q_DISABLE_COPY_MOVE(LayerSurface);
[[nodiscard]] bool isExposed() const override;
void applyConfigure() override;
void setWindowGeometry(const QRect& geometry) override;
void setWindowGeometry(const QRect& /*geometry*/) override {}
void attachPopup(QtWaylandClient::QWaylandShellSurface* popup) override;
void commit();
private:
void zwlr_layer_surface_v1_configure(quint32 serial, quint32 width, quint32 height) override;
void zwlr_layer_surface_v1_closed() override;
QWindow* qwindow();
void updateLayer();
void updateAnchors();
void updateMargins();
void updateExclusiveZone();
void updateKeyboardFocus();
LayershellWindowExtension* ext;
QSize size;
LayerSurfaceBridge* bridge;
bool configured = false;
QSize size;
friend class LayershellWindowExtension;
LayerSurfaceState committed;
};
} // namespace qs::wayland::layershell