#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/math/Math.hpp" #include "../types/DataDevice.hpp" class CWLDataDeviceResource; class CWLDataDeviceManagerResource; class CWLDataSourceResource; class CWLDataOfferResource; class CWLSurfaceResource; class CMonitor; class CWLDataOfferResource { public: CWLDataOfferResource(SP resource_, SP source_); ~CWLDataOfferResource(); 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); virtual void sendDndFinished(); virtual uint32_t actions(); // wl_data_device_manager.dnd_action void sendDndDropPerformed(); void sendDndAction(wl_data_device_manager_dnd_action a); bool used = false; bool dnd = false; bool dndSuccess = false; bool dropped = false; WP device; WP self; std::vector mimeTypes; uint32_t supportedActions = 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, SP 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(PHLMONITOR 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; WP dndSurface; WP originSurface; bool overriddenCursor = false; CHyprSignalListener dndSurfaceDestroy; CHyprSignalListener dndSurfaceCommit; // for ending a dnd SP mouseMove; SP mouseButton; SP touchUp; SP touchMove; } dnd; void abortDrag(); void initiateDrag(WP currentSource, SP dragSurface, SP origin); void updateDrag(); void dropDrag(); void completeDrag(); void resetDndState(); bool wasDragSuccessful(); // 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; };