#pragma once #include "../macros.hpp" #include "XDataSource.hpp" #include "Dnd.hpp" #include "../helpers/memory/Memory.hpp" #include "../helpers/signal/Signal.hpp" #include #include #include #include #include struct wl_event_source; class CXWaylandSurfaceResource; struct SXSelection; struct SXTransfer { ~SXTransfer(); SXSelection& selection; bool out = true; bool incremental = false; bool flushOnDelete = false; bool propertySet = false; int wlFD = -1; wl_event_source* eventSource = nullptr; std::vector data; xcb_selection_request_event_t request; int propertyStart; xcb_get_property_reply_t* propertyReply; xcb_window_t incomingWindow; bool getIncomingSelectionProp(bool erase); }; struct SXSelection { xcb_window_t window = 0; xcb_window_t owner = 0; xcb_timestamp_t timestamp = 0; SP dataSource; void onSelection(); bool sendData(xcb_selection_request_event_t* e, std::string mime); int onRead(int fd, uint32_t mask); struct { CHyprSignalListener setSelection; } listeners; std::unique_ptr transfer; }; class CXCBConnection { public: CXCBConnection(int fd) : connection{xcb_connect_to_fd(fd, nullptr)} { ; } ~CXCBConnection() { if (connection) xcb_disconnect(connection); } bool hasError() const { return xcb_connection_has_error(connection); } operator xcb_connection_t*() const { return connection; } private: xcb_connection_t* connection = nullptr; }; class CXCBErrorContext { public: explicit CXCBErrorContext(xcb_connection_t* connection) { if (xcb_errors_context_new(connection, &errors) != 0) errors = nullptr; } ~CXCBErrorContext() { if (errors) xcb_errors_context_free(errors); } bool isValid() const { return errors != nullptr; } private: xcb_errors_context_t* errors = nullptr; }; class CXWM { public: CXWM(); ~CXWM(); int onEvent(int fd, uint32_t mask); SP getDataDevice(); SP createX11DataOffer(SP surf, SP source); private: void setCursor(unsigned char* pixData, uint32_t stride, const Vector2D& size, const Vector2D& hotspot); void gatherResources(); void getVisual(); void getRenderFormat(); void createWMWindow(); void initSelection(); void onNewSurface(SP surf); void onNewResource(SP resource); void setActiveWindow(xcb_window_t window); void sendState(SP surf); void focusWindow(SP surf); void activateSurface(SP surf, bool activate); bool isWMWindow(xcb_window_t w); void updateOverrideRedirect(SP surf, bool overrideRedirect); void sendWMMessage(SP surf, xcb_client_message_data_t* data, uint32_t mask); SP windowForXID(xcb_window_t wid); SP windowForWayland(SP surf); void readWindowData(SP surf); void associate(SP surf, SP wlSurf); void dissociate(SP surf); void updateClientList(); void sendDndEvent(SP destination, xcb_atom_t type, xcb_client_message_data_t& data); // event handlers void handleCreate(xcb_create_notify_event_t* e); void handleDestroy(xcb_destroy_notify_event_t* e); void handleConfigure(xcb_configure_request_event_t* e); void handleConfigureNotify(xcb_configure_notify_event_t* e); void handleMapRequest(xcb_map_request_event_t* e); void handleMapNotify(xcb_map_notify_event_t* e); void handleUnmapNotify(xcb_unmap_notify_event_t* e); void handlePropertyNotify(xcb_property_notify_event_t* e); void handleClientMessage(xcb_client_message_event_t* e); void handleFocusIn(xcb_focus_in_event_t* e); void handleFocusOut(xcb_focus_out_event_t* e); void handleError(xcb_value_error_t* e); bool handleSelectionEvent(xcb_generic_event_t* e); void handleSelectionNotify(xcb_selection_notify_event_t* e); bool handleSelectionPropertyNotify(xcb_property_notify_event_t* e); void handleSelectionRequest(xcb_selection_request_event_t* e); bool handleSelectionXFixesNotify(xcb_xfixes_selection_notify_event_t* e); void selectionSendNotify(xcb_selection_request_event_t* e, bool success); xcb_atom_t mimeToAtom(const std::string& mime); std::string mimeFromAtom(xcb_atom_t atom); void setClipboardToWayland(SXSelection& sel); void getTransferData(SXSelection& sel); std::string getAtomName(uint32_t atom); void readProp(SP XSURF, uint32_t atom, xcb_get_property_reply_t* reply); SXSelection* getSelection(xcb_atom_t atom); // CXCBConnection connection; xcb_errors_context_t* errors = nullptr; xcb_screen_t* screen = nullptr; xcb_window_t wmWindow; wl_event_source* eventSource = nullptr; const xcb_query_extension_reply_t* xfixes = nullptr; const xcb_query_extension_reply_t* xres = nullptr; int xfixesMajor = 0; xcb_visualid_t visual_id; xcb_colormap_t colormap; uint32_t cursorXID = 0; xcb_render_pictformat_t render_format_id; std::vector> shellResources; std::vector> surfaces; std::vector> mappedSurfaces; // ordered by map time std::vector> mappedSurfacesStacking; // ordered by stacking WP focusedSurface; uint64_t lastFocusSeq = 0; SXSelection clipboard; SXSelection dndSelection; SP dndDataDevice = makeShared(); std::vector> dndDataOffers; struct { CHyprSignalListener newWLSurface; CHyprSignalListener newXShellSurface; } listeners; friend class CXWaylandSurface; friend class CXWayland; friend class CXDataSource; friend class CX11DataDevice; friend class CX11DataSource; friend class CX11DataOffer; friend class CWLDataDeviceProtocol; friend struct SXSelection; friend struct SXTransfer; };