// Minimal reproducer for Qt 6 Wayland screen use-after-free (QTBUG-XXXXXX). // // Creates many layer-shell surfaces bound to each screen. When an output is // removed, the compositor sends wl_surface.leave + wl_registry.global_remove // in the same event batch. libwayland resolves the wl_output proxy pointer at // demarshal time; if the global_remove handler destroys the proxy first, the // surface.leave handler receives a dangling pointer and crashes in // QWaylandScreen::fromWlOutput / QPlatformScreen::screen(). // // Run with unpatched Qt 6.10.2: // quickshell -p ./shell.qml // // Then toggle an output: // niri msg action power-off-monitors (move mouse to wake) // wlr-randr --output eDP-1 --off && sleep 0.3 && wlr-randr --output eDP-1 --on // or unplug/replug an external monitor // // Should crash within a few seconds of the output toggle. import Quickshell import Quickshell.Wayland ShellRoot { // 20 layer-shell surfaces per screen - all bound to the output, // so the compositor must send enter/leave for each on removal. Variants { model: Quickshell.screens Scope { required property var modelData Repeater { model: 20 PanelWindow { screen: modelData anchors { top: true left: true } width: 60 height: 20 margins.top: index * 22 margins.left: 4 exclusiveZone: 0 color: "#80ff00ff" } } } } }