Hyprland/src/protocols/core/DataDevice.hpp

212 lines
7 KiB
C++
Raw Normal View History

2024-05-11 17:13:20 +01:00
#pragma once
/*
Implementations for:
- wl_data_offer
- wl_data_source
- wl_data_device
- wl_data_device_manager
*/
#include <vector>
#include <cstdint>
#include "../WaylandProtocol.hpp"
#include <wayland-server-protocol.h>
#include "wayland.hpp"
#include "../../helpers/signal/Signal.hpp"
#include "../../helpers/math/Math.hpp"
#include "../../helpers/time/Time.hpp"
2024-05-11 17:13:20 +01:00
#include "../types/DataDevice.hpp"
core: begin using CFileDescriptor from hyprutils (#9122) * config: make fd use CFileDescriptor make use of the new hyprutils CFileDescriptor instead of manual FD handling. * hyprctl: make fd use CFileDescriptor make use of the new hyprutils CFileDescriptor instead of manual FD handling. * ikeyboard: make fd use CFileDescriptor make use of the new CFileDescriptor instead of manual FD handling, also in sendKeymap remove dead code, it already early returns if keyboard isnt valid, and dont try to close the FD that ikeyboard owns. * core: make SHMFile functions use CFileDescriptor make SHMFile misc functions use CFileDescriptor and its associated usage in dmabuf and keyboard. * core: make explicit sync use CFileDescriptor begin using CFileDescriptor in explicit sync and its timelines and eglsync usage in opengl, there is still a bit left with manual handling that requires future aquamarine change aswell. * eventmgr: make fd and sockets use CFileDescriptor make use of the hyprutils CFileDescriptor instead of manual FD and socket handling and closing. * eventloopmgr: make timerfd use CFileDescriptor make the timerfd use CFileDescriptor instead of manual fd handling * opengl: make gbm fd use CFileDescriptor make the gbm rendernode fd use CFileDescriptor instead of manual fd handling * core: make selection source/offer use CFileDescriptor make data selection source and offers use CFileDescriptor and its associated use in xwm and protocols * protocols: convert protocols fd to CFileDescriptor make most fd handling use CFileDescriptor in protocols * shm: make SHMPool use CfileDescriptor make SHMPool use CFileDescriptor instead of manual fd handling. * opengl: duplicate fd with CFileDescriptor duplicate fenceFD with CFileDescriptor duplicate instead. * xwayland: make sockets and fds use CFileDescriptor instead of manual opening/closing make sockets and fds use CFileDescriptor * keybindmgr: make sockets and fds use CFileDescriptor make sockets and fds use CFileDescriptor instead of manual handling.
2025-01-30 12:30:12 +01:00
#include <hyprutils/os/FileDescriptor.hpp>
2024-05-11 17:13:20 +01:00
class CWLDataDeviceResource;
class CWLDataDeviceManagerResource;
class CWLDataSourceResource;
class CWLDataOfferResource;
class CWLSurfaceResource;
2024-05-11 17:13:20 +01:00
class CMonitor;
class CWLDataOfferResource : public IDataOffer {
2024-05-11 17:13:20 +01:00
public:
CWLDataOfferResource(SP<CWlDataOffer> resource_, SP<IDataSource> source_);
~CWLDataOfferResource();
2024-05-11 17:13:20 +01:00
bool good();
void sendData();
virtual eDataSourceType type();
virtual SP<CWLDataOfferResource> getWayland();
virtual SP<CX11DataOffer> getX11();
virtual SP<IDataSource> getSource();
2024-05-11 17:13:20 +01:00
WP<IDataSource> m_source;
WP<CWLDataOfferResource> m_self;
2024-05-11 17:13:20 +01:00
bool m_dead = false;
bool m_accepted = false;
bool m_recvd = false;
2024-05-11 17:13:20 +01:00
private:
SP<CWlDataOffer> m_resource;
2024-05-11 17:13:20 +01:00
friend class CWLDataDeviceResource;
};
class CWLDataSourceResource : public IDataSource {
public:
CWLDataSourceResource(SP<CWlDataSource> resource_, SP<CWLDataDeviceResource> device_);
~CWLDataSourceResource();
static SP<CWLDataSourceResource> fromResource(wl_resource*);
bool good();
virtual std::vector<std::string> mimes();
core: begin using CFileDescriptor from hyprutils (#9122) * config: make fd use CFileDescriptor make use of the new hyprutils CFileDescriptor instead of manual FD handling. * hyprctl: make fd use CFileDescriptor make use of the new hyprutils CFileDescriptor instead of manual FD handling. * ikeyboard: make fd use CFileDescriptor make use of the new CFileDescriptor instead of manual FD handling, also in sendKeymap remove dead code, it already early returns if keyboard isnt valid, and dont try to close the FD that ikeyboard owns. * core: make SHMFile functions use CFileDescriptor make SHMFile misc functions use CFileDescriptor and its associated usage in dmabuf and keyboard. * core: make explicit sync use CFileDescriptor begin using CFileDescriptor in explicit sync and its timelines and eglsync usage in opengl, there is still a bit left with manual handling that requires future aquamarine change aswell. * eventmgr: make fd and sockets use CFileDescriptor make use of the hyprutils CFileDescriptor instead of manual FD and socket handling and closing. * eventloopmgr: make timerfd use CFileDescriptor make the timerfd use CFileDescriptor instead of manual fd handling * opengl: make gbm fd use CFileDescriptor make the gbm rendernode fd use CFileDescriptor instead of manual fd handling * core: make selection source/offer use CFileDescriptor make data selection source and offers use CFileDescriptor and its associated use in xwm and protocols * protocols: convert protocols fd to CFileDescriptor make most fd handling use CFileDescriptor in protocols * shm: make SHMPool use CfileDescriptor make SHMPool use CFileDescriptor instead of manual fd handling. * opengl: duplicate fd with CFileDescriptor duplicate fenceFD with CFileDescriptor duplicate instead. * xwayland: make sockets and fds use CFileDescriptor instead of manual opening/closing make sockets and fds use CFileDescriptor * keybindmgr: make sockets and fds use CFileDescriptor make sockets and fds use CFileDescriptor instead of manual handling.
2025-01-30 12:30:12 +01:00
virtual void send(const std::string& mime, Hyprutils::OS::CFileDescriptor fd);
2024-05-11 17:13:20 +01:00
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);
2024-05-11 17:13:20 +01:00
bool m_used = false;
bool m_dnd = false;
bool m_dndSuccess = false;
bool m_dropped = false;
2024-05-11 17:13:20 +01:00
WP<CWLDataDeviceResource> m_device;
WP<CWLDataSourceResource> m_self;
2024-05-11 17:13:20 +01:00
std::vector<std::string> m_mimeTypes;
uint32_t m_supportedActions = 0;
2024-05-11 17:13:20 +01:00
private:
SP<CWlDataSource> m_resource;
2024-05-11 17:13:20 +01:00
friend class CWLDataDeviceProtocol;
};
class CWLDataDeviceResource : public IDataDevice {
2024-05-11 17:13:20 +01:00
public:
CWLDataDeviceResource(SP<CWlDataDevice> resource_);
bool good();
wl_client* client();
2024-05-11 17:13:20 +01:00
virtual SP<CWLDataDeviceResource> getWayland();
virtual SP<CX11DataDevice> getX11();
virtual void sendDataOffer(SP<IDataOffer> offer);
virtual void sendEnter(uint32_t serial, SP<CWLSurfaceResource> surf, const Vector2D& local, SP<IDataOffer> offer);
virtual void sendLeave();
virtual void sendMotion(uint32_t timeMs, const Vector2D& local);
virtual void sendDrop();
virtual void sendSelection(SP<IDataOffer> offer);
virtual eDataSourceType type();
2024-05-11 17:13:20 +01:00
WP<CWLDataDeviceResource> m_self;
2024-05-11 17:13:20 +01:00
private:
SP<CWlDataDevice> m_resource;
wl_client* m_client = nullptr;
2024-05-11 17:13:20 +01:00
friend class CWLDataDeviceProtocol;
};
class CWLDataDeviceManagerResource {
public:
CWLDataDeviceManagerResource(SP<CWlDataDeviceManager> resource_);
bool good();
WP<CWLDataDeviceResource> m_device;
std::vector<WP<CWLDataSourceResource>> m_sources;
2024-05-11 17:13:20 +01:00
private:
SP<CWlDataDeviceManager> m_resource;
2024-05-11 17:13:20 +01:00
};
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);
2024-05-11 17:13:20 +01:00
// 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();
2024-05-11 17:13:20 +01:00
private:
void destroyResource(CWLDataDeviceManagerResource* resource);
void destroyResource(CWLDataDeviceResource* resource);
void destroyResource(CWLDataSourceResource* resource);
void destroyResource(CWLDataOfferResource* resource);
//
std::vector<SP<CWLDataDeviceManagerResource>> m_managers;
std::vector<SP<CWLDataDeviceResource>> m_devices;
std::vector<SP<CWLDataSourceResource>> m_sources;
std::vector<SP<CWLDataOfferResource>> m_offers;
2024-05-11 17:13:20 +01:00
//
void onDestroyDataSource(WP<CWLDataSourceResource> source);
void setSelection(SP<IDataSource> source);
void sendSelectionToDevice(SP<IDataDevice> dev, SP<IDataSource> sel);
2024-05-11 17:13:20 +01:00
void updateSelection();
void onKeyboardFocus();
void onDndPointerFocus();
2024-05-11 17:13:20 +01:00
struct {
WP<IDataDevice> focusedDevice;
WP<IDataSource> currentSource;
WP<CWLSurfaceResource> dndSurface;
WP<CWLSurfaceResource> originSurface;
bool overriddenCursor = false;
CHyprSignalListener dndSurfaceDestroy;
CHyprSignalListener dndSurfaceCommit;
2024-05-11 17:13:20 +01:00
// for ending a dnd
SP<HOOK_CALLBACK_FN> mouseMove;
SP<HOOK_CALLBACK_FN> mouseButton;
SP<HOOK_CALLBACK_FN> touchUp;
SP<HOOK_CALLBACK_FN> touchMove;
SP<HOOK_CALLBACK_FN> tabletTip;
} m_dnd;
2024-05-11 17:13:20 +01:00
void abortDrag();
void initiateDrag(WP<CWLDataSourceResource> currentSource, SP<CWLSurfaceResource> dragSurface, SP<CWLSurfaceResource> origin);
2024-05-11 17:13:20 +01:00
void updateDrag();
void dropDrag();
void completeDrag();
void cleanupDndState(bool resetDevice, bool resetSource, bool simulateInput);
bool wasDragSuccessful();
2024-05-11 17:13:20 +01:00
//
SP<IDataDevice> dataDeviceForClient(wl_client*);
2024-05-11 17:13:20 +01:00
friend class CSeatManager;
friend class CWLDataDeviceManagerResource;
friend class CWLDataDeviceResource;
friend class CWLDataSourceResource;
friend class CWLDataOfferResource;
struct {
CHyprSignalListener onKeyboardFocusChange;
CHyprSignalListener onDndPointerFocusChange;
} m_listeners;
2024-05-11 17:13:20 +01:00
};
namespace PROTO {
inline UP<CWLDataDeviceProtocol> data;
};