From f95c3873a6b4d3f906e8a2c5578d927a51e670d9 Mon Sep 17 00:00:00 2001 From: RootBeer Date: Sat, 14 Nov 2026 21:19:51 -0500 Subject: [PATCH] Close non-InvUI containers before opening a window Opening a window replaced a container that wasn't opened by InvUI (e.g. a crafting table) without closing it, so no InventoryCloseEvent was called and the items in its crafting grid and on the cursor were lost. --- .../java/xyz/xenondevs/invui/window/AbstractWindow.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/invui/src/main/java/xyz/xenondevs/invui/window/AbstractWindow.java b/invui/src/main/java/xyz/xenondevs/invui/window/AbstractWindow.java index 7f4fb88e..1670aa2a 100644 --- a/invui/src/main/java/xyz/xenondevs/invui/window/AbstractWindow.java +++ b/invui/src/main/java/xyz/xenondevs/invui/window/AbstractWindow.java @@ -9,6 +9,7 @@ import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.event.inventory.*; @@ -538,6 +539,14 @@ public void open() { throw new IllegalStateException("Opening a window is not allowed while handling window close. Consider setting a fallback window or scheduling a task instead."); ThreadCheck.checkOwnedBy(viewer); + // close containers that weren't opened by InvUI, so that they return their items and call their close event + var serverPlayer = ((CraftPlayer) viewer).getHandle(); + if (serverPlayer.containerMenu != serverPlayer.inventoryMenu && WindowManager.getInstance().getOpenWindow(viewer) == null) { + viewer.closeInventory(Reason.OPEN_NEW); + if (isOpen || !viewer.isValid() || !viewer.isConnected()) + return; + } + try { isInOpeningContext.set(true);