Repository: godotengine/godot
File: platform/linuxbsd/wayland/wayland_thread.cpp (C++)

Code before:
		wl_data_source_offer(ss->wl_data_source_selection, "text/plain;charset=utf-8");
		wl_data_source_offer(ss->wl_data_source_selection, "text/plain");

		// TODO: Implement a good way of getting the latest serial from the user.
		wl_data_device_set_selection(ss->wl_data_device, ss->wl_data_source_selection, MAX(ss->pointer_data.button_serial, ss->last_key_pressed_serial));
	}

	// Wait for the message to get to the server before continuing, otherwise the
	// clipboard update might come with a delay.
	wl_display_roundtrip(wl_display);
}

bool WaylandThread::selection_has_mime(const String &p_mime) const {
	SeatState *ss = wl_seat_get_seat_state(wl_seat_current);

	if (ss == nullptr) {
		DEBUG_LOG_WAYLAND_THREAD("Couldn't get selection, current seat not set.");
		return false;
	}

	OfferState *os = wl_data_offer_get_offer_state(ss->wl_data_offer_selection);
	if (!os) {
		return false;
	}

	return os->mime_types.has(p_mime);
}

Vector<uint8_t> WaylandThread::selection_get_mime(const String &p_mime) const {
	SeatState *ss = wl_seat_get_seat_state(wl_seat_current);
	if (ss == nullptr) {
		DEBUG_LOG_WAYLAND_THREAD("Couldn't get selection, current seat not set.");
		return Vector<uint8_t>();
	}

	if (ss->wl_data_source_selection) {
		// We have a source so the stuff we're pasting is ours. We'll have to pass the
		// data directly or we'd stall waiting for Godot (ourselves) to send us the
		// data :P

		OfferState *os = wl_data_offer_get_offer_state(ss->wl_data_offer_selection);
		ERR_FAIL_NULL_V(os, Vector<uint8_t>());

		if (os->mime_types.has(p_mime)) {
			// All righty, we're offering this type. Let's just return the data as is.
			return ss->selection_data;
		}

		// ... we don't offer that type. Oh well.
		return Vector<uint8_t>();
	}

Review comment (refactor):
Copied this code from `pointer_set_hint`, should there be a function to remove the duplicate scaling code?
What about the comment?

Code after:
		pointer_set_constraint(old_constraint);

		return;
	}

	SeatState *ss = wl_seat_get_seat_state(wl_seat_current);
	if (!ss) {
		return;
	}

	WindowState *ws = window_get_state(ss->pointer_data.pointed_id);
	if (!ws) {
		return;
	}

	// NOTE: It looks like it's not really recommended to convert from
	// "godot-space" to "wayland-space" and in general I received mixed feelings
	// discussing about this. I'm not really sure about the maths behind this but,
	// oh well. ¯\_(ツ)_/¯
	// See: https://oftc.irclog.whitequark.org/wayland/2023-08-23#1692756914-1692816818
	int wl_pos_x = Math::round(p_to.x / window_state_get_scale_factor(ws));
	int wl_pos_y = Math::round(p_to.y / window_state_get_scale_factor(ws));

	if (ss) {
		seat_state_warp_pointer(ss, wl_pos_x, wl_pos_y);
	}
}

WaylandThread::PointerConstraint WaylandThread::pointer_get_constraint() const {
	return pointer_constraint;
}

BitField<MouseButtonMask> WaylandThread::pointer_get_button_mask() const {
	SeatState *ss = wl_seat_get_seat_state(wl_seat_current);

	if (ss) {
		return ss->pointer_data.pressed_button_mask;
	}

	return BitField<MouseButtonMask>();
}

Error WaylandThread::init() {
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
	int dylibloader_verbose = 1;
#else
	int dylibloader_verbose = 0;
#endif // DEBUG_ENABLED

	if (initialize_wayland_client(dylibloader_verbose) != 0) {