#pragma once /* Implementations for: - wl_data_offer - wl_data_source - wl_data_device - wl_data_device_manager */ #include #include #include "../WaylandProtocol.hpp" #include #include "wayland.hpp" #include "../../helpers/signal/Signal.hpp" #include "../../helpers/math/Math.hpp" #include "../../helpers/time/Time.hpp" #include "../types/DataDevice.hpp" #include class CWLDataDeviceResource; class CWLDataDeviceManagerResource; class CWLDataSourceResource; class CWLDataOfferResource; class CWLSurfaceResource; class CMonitor; class CWLDataOfferResource : public IDataOffer { public: CWLDataOfferResource(SP resource_, SP source_); ~CWLDataOfferResource(); bool good(); void sendData(); virtual eDataSourceType type(); virtual SP getWayland(); virtual SP getX11(); virtual SP getSource(); WP m_source; WP m_self; bool m_dead = false; bool m_accepted = false; bool m_recvd = false; private: SP m_resource; 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, Hyprutils::OS::CFileDescriptor 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 virtual eDataSourceType type(); virtual void sendDndDropPerformed(); virtual void sendDndAction(wl_data_device_manager_dnd_action a); bool m_used = false; bool m_dnd = false; bool m_dndSuccess = false; bool m_dropped = false; WP m_device; WP m_self; std::vector m_mimeTypes; uint32_t m_supportedActions = 0; private: SP m_resource; friend class CWLDataDeviceProtocol; }; class CWLDataDeviceResource : public IDataDevice { public: CWLDataDeviceResource(SP resource_); bool good(); wl_client* client(); virtual SP getWayland(); virtual SP getX11(); virtual void sendDataOffer(SP offer); virtual void sendEnter(uint32_t serial, SP surf, const Vector2D& local, SP offer); virtual void sendLeave(); virtual void sendMotion(uint32_t timeMs, const Vector2D& local); virtual void sendDrop(); virtual void sendSelection(SP offer); virtual eDataSourceType type(); WP m_self; private: SP m_resource; wl_client* m_client = nullptr; friend class CWLDataDeviceProtocol; }; class CWLDataDeviceManagerResource { public: CWLDataDeviceManagerResource(SP resource_); bool good(); WP m_device; std::vector> m_sources; private: SP m_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, const Time::steady_tp& when); // for inputmgr to force refocus // TODO: move handling to seatmgr bool dndActive(); // called on an escape key pressed, for moments where it gets stuck void abortDndIfPresent(); private: void destroyResource(CWLDataDeviceManagerResource* resource); void destroyResource(CWLDataDeviceResource* resource); void destroyResource(CWLDataSourceResource* resource); void destroyResource(CWLDataOfferResource* resource); // std::vector> m_managers; std::vector> m_devices; std::vector> m_sources; std::vector> m_offers; // void onDestroyDataSource(WP source); void setSelection(SP source); void sendSelectionToDevice(SP dev, SP sel); void updateSelection(); void onKeyboardFocus(); void onDndPointerFocus(); 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; SP tabletTip; } m_dnd; void abortDrag(); void initiateDrag(WP currentSource, SP dragSurface, SP origin); void updateDrag(); void dropDrag(); void completeDrag(); void cleanupDndState(bool resetDevice, bool resetSource, bool simulateInput); bool wasDragSuccessful(); // SP dataDeviceForClient(wl_client*); friend class CSeatManager; friend class CWLDataDeviceManagerResource; friend class CWLDataDeviceResource; friend class CWLDataSourceResource; friend class CWLDataOfferResource; struct { CHyprSignalListener onKeyboardFocusChange; CHyprSignalListener onDndPointerFocusChange; } m_listeners; }; namespace PROTO { inline UP data; };