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

Code before:

	if (ss) {
		seat_state_echo_keys(ss);
	}
}

void WaylandThread::selection_set_text(const String &p_text) {
	SeatState *ss = wl_seat_get_seat_state(wl_seat_current);

	if (registry.wl_data_device_manager == nullptr) {
		DEBUG_LOG_WAYLAND_THREAD("Couldn't set selection, wl_data_device_manager global not available.");
		return;
	}

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

	if (ss->wl_data_device == nullptr) {
		DEBUG_LOG_WAYLAND_THREAD("Couldn't set selection, seat doesn't have wl_data_device.");
		return;
	}

	ss->selection_data = p_text.to_utf8_buffer();

	if (ss->wl_data_source_selection == nullptr) {
		ss->wl_data_source_selection = wl_data_device_manager_create_data_source(registry.wl_data_device_manager);
		wl_data_source_add_listener(ss->wl_data_source_selection, &wl_data_source_listener, ss);
		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) {

Review comment (suggestion):
Probably should be:

```c++
	if (!ws) {
		return;
	}

	int wl_pos_x = std::round(p_to.x / window_....
```

Warping to 0,0 is not expected behavior if there's no active window.

Code after:
	}
}

void WaylandThread::pointer_warp(const Point2i &p_to) {
	// NOTE: This is for compositors that don't support the pointer-warp protocol.
	// It's hacked together and not guaranteed to work.
	if (registry.wp_pointer_warp == nullptr) {
		PointerConstraint old_constraint = pointer_get_constraint();

		pointer_set_constraint(PointerConstraint::LOCKED);
		pointer_set_hint(p_to);

		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;
	}