~sircmpwn/gdwlroots

e8686fec5719c6f886bdaf64ad03a0931f998448 — Drew DeVault 1 year, 4 months ago 53b8649
Handle pointer events for subsurfaces/popups
6 files changed, 76 insertions(+), 7 deletions(-)

M godotston/Surface.gd
M register_types.cpp
M wlr_surface.cpp
M wlr_surface.h
M wlr_xdg_shell.cpp
M wlr_xdg_shell.h
M godotston/Surface.gd => godotston/Surface.gd +11 -6
@@ 98,8 98,12 @@ func input_event_passthrough(event):
	var notify_frame = false
	if event is InputEventMouseMotion:
		var position = get_surface_coords(to_local(event.position))
		seat.pointer_notify_motion(position.x, position.y)
		notify_frame = true
		var surface = xdg_surface.surface_at(position.x, position.y)
		if surface != null:
			seat.pointer_notify_enter(surface.get_surface(),
					surface.get_sub_x(), surface.get_sub_y())
			seat.pointer_notify_motion(surface.get_sub_x(), surface.get_sub_y())
			notify_frame = true
	if event is InputEventMouseButton:
		seat.pointer_notify_button(event.button_index, event.pressed)
		notify_frame = true


@@ 124,8 128,9 @@ func _integrate_forces(state):
	state.set_linear_velocity(lv)

func _on_RigidBody2D_mouse_entered():
	var position = get_surface_coords(to_local(get_viewport().get_mouse_position()))
	# TODO: Find subsurface
	var surface = xdg_surface.get_wlr_surface()
	var position = get_surface_coords(
			to_local(get_viewport().get_mouse_position()))
	var surface = xdg_surface.surface_at(position.x, position.y)
	if surface != null:
		seat.pointer_notify_enter(surface, position.x, position.y)
		seat.pointer_notify_enter(surface.get_surface(),
				surface.get_sub_x(), surface.get_sub_y())

M register_types.cpp => register_types.cpp +1 -0
@@ 17,6 17,7 @@ void register_gdwlroots_types() {
	ClassDB::register_class<WlrOutput>();
	ClassDB::register_class<WlrSeat>();
	ClassDB::register_class<WlrSurface>();
	ClassDB::register_class<WlrSurfaceAtResult>();
	ClassDB::register_class<WlrSurfaceState>();
	ClassDB::register_class<WlrXdgShell>();
	ClassDB::register_class<WlrXdgSurface>();

M wlr_surface.cpp => wlr_surface.cpp +33 -1
@@ 107,10 107,42 @@ WlrSurface::WlrSurface(struct wlr_surface *surface) {
}

WlrSurface *WlrSurface::from_wlr_surface(struct wlr_surface *surface) {
	if (!surface) {
		return NULL;
	}
	if (surface->data) {
		auto s = (WlrSurface *)surface->data;
		wlr_log(WLR_DEBUG, "Found surface %p for %p", s, surface);
		return s;
	}
	return new WlrSurface(surface);
}

WlrSurface *WlrSurfaceAtResult::get_surface() {
	return surface;
}

double WlrSurfaceAtResult::get_sub_x() {
	return sub_x;
}

double WlrSurfaceAtResult::get_sub_y() {
	return sub_y;
}

void WlrSurfaceAtResult::_bind_methods() {
	ClassDB::bind_method(D_METHOD("get_sub_x"), &WlrSurfaceAtResult::get_sub_x);
	ClassDB::bind_method(D_METHOD("get_sub_y"), &WlrSurfaceAtResult::get_sub_y);
	ClassDB::bind_method(D_METHOD("get_surface"),
			&WlrSurfaceAtResult::get_surface);
}

WlrSurfaceAtResult::WlrSurfaceAtResult() {
	/* Not used */
}

WlrSurfaceAtResult::WlrSurfaceAtResult(WlrSurface *surface,
		double sub_x, double sub_y) {
	this->surface = surface;
	this->sub_x = sub_x;
	this->sub_y = sub_y;
}

M wlr_surface.h => wlr_surface.h +20 -0
@@ 52,4 52,24 @@ public:
	void send_frame_done();
};

class WlrSurfaceAtResult : public Reference {
	GDCLASS(WlrSurfaceAtResult, Reference);

	WlrSurface *surface;
	double sub_x, sub_y;

protected:
	static void _bind_methods();

	/* Necessary for Object */
	WlrSurfaceAtResult();

public:
	WlrSurface *get_surface();
	double get_sub_x();
	double get_sub_y();

	WlrSurfaceAtResult(WlrSurface *surface, double sub_x, double sub_y);
};

#endif

M wlr_xdg_shell.cpp => wlr_xdg_shell.cpp +10 -0
@@ 106,6 106,14 @@ void WlrXdgSurface::for_each_surface(Variant func) {
			wlr_xdg_surface, for_each_surface_iter, fn.ptr());
}

WlrSurfaceAtResult *WlrXdgSurface::surface_at(double sx, double sy) {
	double sub_x, sub_y;
	struct wlr_surface *result = wlr_xdg_surface_surface_at(
			wlr_xdg_surface, sx, sy, &sub_x, &sub_y);
	return new WlrSurfaceAtResult(
			WlrSurface::from_wlr_surface(result), sub_x, sub_y);
}

void WlrXdgSurface::_bind_methods() {
	ClassDB::bind_method(D_METHOD("get_role"), &WlrXdgSurface::get_role);
	ClassDB::bind_method(D_METHOD("get_xdg_toplevel"),


@@ 118,6 126,8 @@ void WlrXdgSurface::_bind_methods() {
			&WlrXdgSurface::get_wlr_surface);
	ClassDB::bind_method(D_METHOD("for_each_surface", "func"),
			&WlrXdgSurface::for_each_surface);
	ClassDB::bind_method(D_METHOD("surface_at", "sx", "sy"),
			&WlrXdgSurface::surface_at);

	BIND_ENUM_CONSTANT(XDG_SURFACE_ROLE_NONE);
	BIND_ENUM_CONSTANT(XDG_SURFACE_ROLE_TOPLEVEL);

M wlr_xdg_shell.h => wlr_xdg_shell.h +1 -0
@@ 128,6 128,7 @@ public:
	WlrSurface *get_wlr_surface() const;
	Rect2 get_geometry();
	void for_each_surface(Variant func);
	WlrSurfaceAtResult *surface_at(double sx, double sy);

	static WlrXdgSurface *from_wlr_xdg_surface(
			struct wlr_xdg_surface *xdg_surface);