~sircmpwn/gdwlroots

53b8649c408e20da47580a73237dd5d4850348d5 — Drew DeVault 1 year, 2 months ago b94652a
Render popups & subsurfaces
4 files changed, 53 insertions(+), 13 deletions(-)

M godotston/Main.gd
M godotston/Surface.gd
M wlr_xdg_shell.cpp
M wlr_xdg_shell.h
M godotston/Main.gd => godotston/Main.gd +3 -1
@@ 16,6 16,8 @@ func handle_unmap_surface(surface):
	remove_child(surface)

func _on_WlrXdgShell_new_surface(xdg_surface):
	if xdg_surface.get_role() != WlrXdgSurface.XDG_SURFACE_ROLE_TOPLEVEL:
		return
	var surface = Surface.instance()
	surface.xdg_surface = xdg_surface
	surface.set_seat(get_node("WaylandDisplay/WlrSeat"))


@@ 28,4 30,4 @@ func _on_viewport_change():
	get_node("ViewportBounds/Right").shape.d = -vp.x

func _ready():
	get_viewport().connect("size_changed", self, "_on_viewport_change")
\ No newline at end of file
	get_viewport().connect("size_changed", self, "_on_viewport_change")

M godotston/Surface.gd => godotston/Surface.gd +20 -12
@@ 2,7 2,6 @@ extends RigidBody2D

export var xdg_surface: WlrXdgSurface = null setget _xdg_surface_set
var toplevel: WlrXdgToplevel
var surface: WlrSurface
var geometry: Rect2
var seat: WlrSeat



@@ 51,28 50,34 @@ func _handle_request_move(xdg_toplevel, serial):

func _xdg_surface_set(val):
	xdg_surface = val
	surface = xdg_surface.get_wlr_surface()
	xdg_surface.connect("destroy", self, "_handle_destroy")
	xdg_surface.connect("map", self, "_handle_map")
	xdg_surface.connect("unmap", self, "_handle_unmap")
	if xdg_surface.get_role() == WlrXdgSurface.XDG_SURFACE_ROLE_TOPLEVEL:
		toplevel = xdg_surface.get_xdg_toplevel()
		toplevel.connect("request_move", self, "_handle_request_move")
	toplevel = xdg_surface.get_xdg_toplevel()
	toplevel.connect("request_move", self, "_handle_request_move")

func _draw():
	if surface == null:
		return
func _draw_surface(surface, sx, sy):
	var texture = surface.get_texture()
	if texture == null:
		return
	var state = surface.get_current_state()
	# TODO: Draw all subsurfaces/popups/etc
	var position = Vector2(-state.get_buffer_width() / 2, -state.get_buffer_height() / 2)
	var state = xdg_surface.get_wlr_surface().get_current_state()
	var position = Vector2(
		(-state.get_buffer_width() / 2) + sx,
		(-state.get_buffer_height() / 2) + sy)
	draw_texture(texture, position)
	surface.send_frame_done()

func _draw():
	if xdg_surface != null:
		var fn = funcref(self, "_draw_surface")
		xdg_surface.for_each_surface(fn)

func _process(delta):
	var collisionShape = get_node("CollisionShape2D")
	var surface = xdg_surface.get_wlr_surface()
	if surface == null:
		update()
		return
	var state = surface.get_current_state()
	geometry = xdg_surface.get_geometry()
	var extents = collisionShape.shape.get_extents()


@@ 120,4 125,7 @@ func _integrate_forces(state):

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

M wlr_xdg_shell.cpp => wlr_xdg_shell.cpp +28 -0
@@ 1,4 1,5 @@
#include <assert.h>
#include "core/func_ref.h"
#include "core/object.h"
#include "scene/main/node.h"
#include "wayland_display.h"


@@ 80,6 81,31 @@ WlrSurface *WlrXdgSurface::get_wlr_surface() const {
	return WlrSurface::from_wlr_surface(wlr_xdg_surface->surface);
}

extern "C" {

static void for_each_surface_iter(struct wlr_surface *surface,
		int sx, int sy, void *data) {
	FuncRef *func = (FuncRef *)data;
	const Variant *args[] = {
		new Variant(WlrSurface::from_wlr_surface(surface)),
		new Variant(sx),
		new Variant(sy),
	};
	Variant::CallError error;
	func->call_func((const Variant **)&args[0], 3, error);
	if (error.error != Variant::CallError::Error::CALL_OK) {
		printf("call error %d\n", error.error);
	}
}

}

void WlrXdgSurface::for_each_surface(Variant func) {
	auto fn = (Ref<FuncRef>)func;
	wlr_xdg_surface_for_each_surface(
			wlr_xdg_surface, for_each_surface_iter, fn.ptr());
}

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


@@ 90,6 116,8 @@ void WlrXdgSurface::_bind_methods() {
			&WlrXdgSurface::get_geometry);
	ClassDB::bind_method(D_METHOD("get_wlr_surface"),
			&WlrXdgSurface::get_wlr_surface);
	ClassDB::bind_method(D_METHOD("for_each_surface", "func"),
			&WlrXdgSurface::for_each_surface);

	BIND_ENUM_CONSTANT(XDG_SURFACE_ROLE_NONE);
	BIND_ENUM_CONSTANT(XDG_SURFACE_ROLE_TOPLEVEL);

M wlr_xdg_shell.h => wlr_xdg_shell.h +2 -0
@@ 1,5 1,6 @@
#ifndef GDWLR_WLR_XDG_SHELL_H
#define GDWLR_WLR_XDG_SHELL_H
#include "core/func_ref.h"
#include "renderer.h"
#include "scene/main/node.h"
#include "wayland_display.h"


@@ 126,6 127,7 @@ public:

	WlrSurface *get_wlr_surface() const;
	Rect2 get_geometry();
	void for_each_surface(Variant func);

	static WlrXdgSurface *from_wlr_xdg_surface(
			struct wlr_xdg_surface *xdg_surface);