53b8649c408e20da47580a73237dd5d4850348d5 — Drew DeVault 8 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 @@
 	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 @@
 	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 @@
 
 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 _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 _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 @@
 	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 @@
 			&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 @@
 
 	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);