From 0cfdde3d1acbfbf698af17f6986fbc4d644214da Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 10 May 2024 23:28:33 +0100 Subject: xdg-shell: move to new impl --- src/protocols/XDGShell.hpp | 256 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 src/protocols/XDGShell.hpp (limited to 'src/protocols/XDGShell.hpp') diff --git a/src/protocols/XDGShell.hpp b/src/protocols/XDGShell.hpp new file mode 100644 index 00000000..e214b6ac --- /dev/null +++ b/src/protocols/XDGShell.hpp @@ -0,0 +1,256 @@ +#pragma once + +#include +#include +#include +#include +#include "WaylandProtocol.hpp" +#include "xdg-shell.hpp" +#include "../helpers/Vector2D.hpp" +#include "../helpers/Box.hpp" +#include "../helpers/signal/Signal.hpp" + +class CXDGWMBase; +class CXDGPositionerResource; +class CXDGSurfaceResource; +class CXDGToplevelResource; +class CXDGPopupResource; +class CSeatGrab; + +struct SXDGPositionerState { + Vector2D requestedSize; + CBox anchorRect; + xdgPositionerAnchor anchor = XDG_POSITIONER_ANCHOR_NONE; + xdgPositionerGravity gravity = XDG_POSITIONER_GRAVITY_NONE; + uint32_t constraintAdjustment = 0; + Vector2D offset; + bool reactive = false; + Vector2D parentSize; +}; + +class CXDGPositionerRules { + public: + CXDGPositionerRules(SP positioner); + + CBox getPosition(const CBox& constraint, const Vector2D& parentPos); + + private: + SXDGPositionerState state; +}; + +class CXDGPopupResource { + public: + CXDGPopupResource(SP resource_, SP parent_, SP surface_, SP positioner_); + ~CXDGPopupResource(); + + static SP fromResource(wl_resource*); + + bool good(); + + void applyPositioning(const CBox& availableBox, const Vector2D& t1coord /* relative to box */); + + WP surface; + WP parent; + WP self; + + bool taken = false; + + CBox geometry; + + struct { + CSignal reposition; + CSignal destroy; // only the role + } events; + + // schedules a configure event + void configure(const CBox& box); + + void done(); + void repositioned(); + + private: + SP resource; + + uint32_t lastRepositionToken = 0; + + Vector2D accumulateParentOffset(); + + CXDGPositionerRules positionerRules; +}; + +class CXDGToplevelResource { + public: + CXDGToplevelResource(SP resource_, SP owner_); + ~CXDGToplevelResource(); + + static SP fromResource(wl_resource*); + + WP owner; + WP self; + + PHLWINDOWREF window; + + bool good(); + + // schedule a configure event + uint32_t setSize(const Vector2D& size); + uint32_t setMaximized(bool maximized); + uint32_t setFullscreen(bool fullscreen); + uint32_t setActive(bool active); + uint32_t setSuspeneded(bool sus); + + void close(); + + struct { + CSignal sizeLimitsChanged; + CSignal stateChanged; // maximized, fs, minimized, etc. + CSignal metadataChanged; // title, appid + CSignal destroy; // only the role + } events; + + struct { + std::string title; + std::string appid; + + // volatile state: is reset after the stateChanged signal fires + std::optional requestsMaximize; + std::optional requestsFullscreen; + std::optional requestsMinimize; + } state; + + struct { + Vector2D size; + std::vector states; + } pendingApply; + + struct { + Vector2D minSize = {1, 1}; + Vector2D maxSize = {1337420, 694200}; + } pending, current; + + WP parent; + + private: + SP resource; + void applyState(); +}; + +class CXDGSurfaceResource { + public: + CXDGSurfaceResource(SP resource_, SP owner_, wlr_surface* surface_); + ~CXDGSurfaceResource(); + + static SP fromResource(wl_resource*); + + bool good(); + + WP owner; + wlr_surface* surface = nullptr; + + WP toplevel; + WP popup; + + WP self; + + struct { + CBox geometry; + } pending, current; + + struct { + CSignal ack; + CSignal commit; + CSignal map; + CSignal unmap; + CSignal destroy; + CSignal newPopup; // SP + } events; + + bool initialCommit = true; + bool mapped = false; + + uint32_t scheduleConfigure(); + // do not call directly + void configure(); + + private: + SP resource; + + uint32_t lastConfigureSerial = 0; + uint32_t scheduledSerial = 0; + + wl_event_source* configureSource = nullptr; + + // + std::vector> popups; + + DYNLISTENER(surfaceDestroy); + DYNLISTENER(surfaceCommit); + + friend class CXDGPopupResource; + friend class CXDGToplevelResource; +}; + +class CXDGPositionerResource { + public: + CXDGPositionerResource(SP resource_, SP owner_); + + static SP fromResource(wl_resource*); + + bool good(); + + SXDGPositionerState state; + + WP owner; + WP self; + + private: + SP resource; +}; + +class CXDGWMBase { + public: + CXDGWMBase(SP resource_); + + bool good(); + wl_client* client(); + + std::vector> positioners; + std::vector> surfaces; + + WP self; + + private: + SP resource; + wl_client* pClient = nullptr; +}; + +class CXDGShellProtocol : public IWaylandProtocol { + public: + CXDGShellProtocol(const wl_interface* iface, const int& ver, const std::string& name); + + virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); + + private: + void destroyResource(CXDGWMBase* resource); + void destroyResource(CXDGPositionerResource* resource); + void destroyResource(CXDGSurfaceResource* resource); + void destroyResource(CXDGToplevelResource* resource); + void destroyResource(CXDGPopupResource* resource); + + // + std::vector> m_vWMBases; + std::vector> m_vPositioners; + std::vector> m_vSurfaces; + std::vector> m_vToplevels; + std::vector> m_vPopups; + + friend class CXDGWMBase; + friend class CXDGPositionerResource; + friend class CXDGSurfaceResource; + friend class CXDGToplevelResource; + friend class CXDGPopupResource; +}; + +namespace PROTO { + inline UP xdgShell; +}; -- cgit v1.2.3