From 7eeee2c94e882a5df1914234df0571b221f9aa35 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 11 May 2024 17:13:20 +0100 Subject: wl-data-device: move to hyprland impl --- src/protocols/core/DataDevice.hpp | 194 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 src/protocols/core/DataDevice.hpp (limited to 'src/protocols/core/DataDevice.hpp') diff --git a/src/protocols/core/DataDevice.hpp b/src/protocols/core/DataDevice.hpp new file mode 100644 index 00000000..3112b720 --- /dev/null +++ b/src/protocols/core/DataDevice.hpp @@ -0,0 +1,194 @@ +#pragma once + +/* + Implementations for: + - wl_data_offer + - wl_data_source + - wl_data_device + - wl_data_device_manager +*/ + +#include +#include +#include +#include "../WaylandProtocol.hpp" +#include +#include "wayland.hpp" +#include "../../helpers/signal/Signal.hpp" +#include "../../helpers/Vector2D.hpp" +#include "../types/DataDevice.hpp" + +class CWLDataDeviceResource; +class CWLDataDeviceManagerResource; +class CWLDataSourceResource; +class CWLDataOfferResource; + +class CMonitor; + +class CWLDataOfferResource { + public: + CWLDataOfferResource(SP resource_, SP source_); + + bool good(); + void sendData(); + + WP source; + + bool dead = false; + bool accepted = false; + bool recvd = false; + + uint32_t actions = 0; + + private: + SP resource; + wl_client* pClient = nullptr; + + friend class CWLDataDeviceResource; +}; + +class CWLDataSourceResource : public IDataSource { + public: + CWLDataSourceResource(SP resource_, SP device_); + ~CWLDataSourceResource(); + static SP fromResource(wl_resource*); + + bool good(); + + virtual std::vector mimes(); + virtual void send(const std::string& mime, uint32_t fd); + virtual void accepted(const std::string& mime); + virtual void cancelled(); + virtual bool hasDnd(); + virtual bool dndDone(); + virtual void error(uint32_t code, const std::string& msg); + + void sendDndDropPerformed(); + void sendDndFinished(); + void sendDndAction(wl_data_device_manager_dnd_action a); + + bool used = false; + bool dnd = false; + bool dndSuccess = false; + + WP device; + WP self; + + std::vector mimeTypes; + uint32_t actions = 0; + + private: + SP resource; + wl_client* pClient = nullptr; + + friend class CWLDataDeviceProtocol; +}; + +class CWLDataDeviceResource { + public: + CWLDataDeviceResource(SP resource_); + + bool good(); + wl_client* client(); + + void sendDataOffer(SP offer); + void sendEnter(uint32_t serial, wlr_surface* surf, const Vector2D& local, SP offer); + void sendLeave(); + void sendMotion(uint32_t timeMs, const Vector2D& local); + void sendDrop(); + void sendSelection(SP offer); + + WP self; + + private: + SP resource; + wl_client* pClient = nullptr; + + friend class CWLDataDeviceProtocol; +}; + +class CWLDataDeviceManagerResource { + public: + CWLDataDeviceManagerResource(SP resource_); + + bool good(); + + WP device; + std::vector> sources; + + private: + SP resource; +}; + +class CWLDataDeviceProtocol : public IWaylandProtocol { + public: + CWLDataDeviceProtocol(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); + + // renders and damages the dnd icon, if present + void renderDND(CMonitor* pMonitor, timespec* when); + // for inputmgr to force refocus + // TODO: move handling to seatmgr + bool dndActive(); + + private: + void destroyResource(CWLDataDeviceManagerResource* resource); + void destroyResource(CWLDataDeviceResource* resource); + void destroyResource(CWLDataSourceResource* resource); + void destroyResource(CWLDataOfferResource* resource); + + // + std::vector> m_vManagers; + std::vector> m_vDevices; + std::vector> m_vSources; + std::vector> m_vOffers; + + // + + void onDestroyDataSource(WP source); + void setSelection(SP source); + void sendSelectionToDevice(SP dev, SP sel); + void updateSelection(); + void onKeyboardFocus(); + + struct { + WP focusedDevice; + WP currentSource; + wlr_surface* dndSurface = nullptr; + wlr_surface* originSurface = nullptr; // READ-ONLY + bool overriddenCursor = false; + DYNLISTENER(dndSurfaceDestroy); + DYNLISTENER(dndSurfaceCommit); + + // for ending a dnd + SP mouseMove; + SP mouseButton; + SP touchUp; + SP touchMove; + } dnd; + + void abortDrag(); + void initiateDrag(WP currentSource, wlr_surface* dragSurface, wlr_surface* origin); + void updateDrag(); + void dropDrag(); + void completeDrag(); + void resetDndState(); + + // + SP dataDeviceForClient(wl_client*); + + friend class CSeatManager; + friend class CWLDataDeviceManagerResource; + friend class CWLDataDeviceResource; + friend class CWLDataSourceResource; + friend class CWLDataOfferResource; + + struct { + CHyprSignalListener onKeyboardFocusChange; + } listeners; +}; + +namespace PROTO { + inline UP data; +}; -- cgit v1.2.3