Files
RedBear-OS/local
vasilito d324ed3634 redbear-compositor: implement wl_data_offer handler for clipboard transfer
The compositor previously declared wl_data_offer opcode constants
in protocol.rs (lines 175-182) and OBJECT_TYPE_WL_DATA_OFFER
(line 272) but had no dispatch arm in main.rs and no handler
function in handlers.rs. Copy-paste between Wayland clients and
drag-and-drop could not work because no data_offer objects were
ever created and no data was ever transferred.

This commit implements the full clipboard/drag data transfer
path:

* WL_DATA_DEVICE_SET_SELECTION: when a client sets a selection
  with a non-null source_id, the compositor:
  1. Allocates a new wl_data_offer object id
  2. Looks up the source's mime types and action flags
  3. Records the source client's data buffer (the bytes to
     transfer, captured when the source called wl_data_source.offer)
  4. Stores the new offer in client.data_offers
  5. Sends wl_data_offer.offer events for each mime type
  6. Sends wl_data_offer.source_actions (if actions were set)
  7. Sends wl_data_device.data_offer (linking offer to device)
  8. Sends wl_data_device.selection (informing device of new
     current selection)

* WL_DATA_OFFER_ACCEPT: records the accepted mime type
  in the offer state. Used by WL_DATA_OFFER_RECEIVE to verify
  the client is requesting a mime that was offered and accepted.

* WL_DATA_OFFER_RECEIVE: the data transfer event. Looks up
  the source buffer and sends it to the requesting client via:
  1. Create a pipe(2) on the compositor side
  2. Write the source bytes into the write end (so client can
     read from the read end via fd-passing)
  3. Close the write end (EOF after read)
  4. Send the read fd via SCM_RIGHTS ancillary data on the
     wl_data_offer.receive event message
  5. Client reads the data from the received fd

  This implements the canonical Wayland data transfer protocol
  with no special kernel support needed beyond pipe(2) and
  SCM_RIGHTS.

* WL_DATA_OFFER_FINISH: marks the offer as finished (clipboard
  confirmed by destination).

* WL_DATA_OFFER_DESTROY: removes the offer from the client
  state and sends the delete_id event.

Also adds:
* use protocol::* in main.rs so the opcode constants are in scope
  for the dispatch table
* new fields on DataSourceState (buffer: Option<Vec<u8>>) to
  capture the source data when offer() is called, plus the
  source_buffer transfer plumbing
* new field on DataDeviceState (selection_offer: Option<u32>) to
  track the current selection offer
* new helper write_event_with_fds for events that need to
  send ancillary data (the receive fd)
* new helper send_with_rights_fds (fd-only variant of
  send_with_rights) for the same purpose
* new helper open_pipe_for_payload that creates a pipe, writes
  the buffer to it, closes the write end, and returns the read fd

cargo check passes on the standalone compositor binary (only
pre-existing warnings). The actual roundtrip through a Wayland
client (e.g. wl-copy or a Qt6 clipboard app) requires a
canonical build + QEMU run.
2026-07-27 08:47:27 +09:00
..