diff --git a/fabric/build.gradle b/fabric/build.gradle index 83353a7a..73cb6077 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -41,7 +41,7 @@ dependencies { transitive = false } - testCompile project(":common").sourceSets.test.output + testCompile project(path: ":common").sourceSets.test.output } processResources { diff --git a/fabric/src/main/java/me/shedaniel/architectury/impl/fabric/ScreenInputDelegate.java b/fabric/src/main/java/me/shedaniel/architectury/impl/fabric/ScreenInputDelegate.java new file mode 100644 index 00000000..05dba894 --- /dev/null +++ b/fabric/src/main/java/me/shedaniel/architectury/impl/fabric/ScreenInputDelegate.java @@ -0,0 +1,39 @@ +package me.shedaniel.architectury.impl.fabric; + +import me.shedaniel.architectury.event.events.client.ClientScreenInputEvent; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.world.InteractionResult; + +public interface ScreenInputDelegate { + GuiEventListener architectury_delegateInputs(); + + class DelegateScreen extends Screen { + private Screen parent; + + public DelegateScreen(Screen parent) { + super(TextComponent.EMPTY); + this.parent = parent; + } + + @Override + public boolean mouseDragged(double d, double e, int i, double f, double g) { + if (ClientScreenInputEvent.MOUSE_DRAGGED_PRE.invoker().mouseDragged(Minecraft.getInstance(), parent, d, e, i, f, g) != InteractionResult.PASS) + return true; + if (parent.mouseDragged(d, e, i, f, g)) + return true; + return ClientScreenInputEvent.MOUSE_DRAGGED_PRE.invoker().mouseDragged(Minecraft.getInstance(), parent, d, e, i, f, g) != InteractionResult.PASS; + } + + @Override + public boolean charTyped(char c, int i) { + if (ClientScreenInputEvent.CHAR_TYPED_PRE.invoker().charTyped(Minecraft.getInstance(), parent, c, i) != InteractionResult.PASS) + return true; + if (parent.charTyped(c, i)) + return true; + return ClientScreenInputEvent.CHAR_TYPED_POST.invoker().charTyped(Minecraft.getInstance(), parent, c, i) != InteractionResult.PASS; + } + } +} diff --git a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinKeyboardHandler.java b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinKeyboardHandler.java index de1e0f03..bce9790d 100644 --- a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinKeyboardHandler.java +++ b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinKeyboardHandler.java @@ -20,15 +20,18 @@ package me.shedaniel.architectury.mixin.fabric.client; import me.shedaniel.architectury.event.events.client.ClientScreenInputEvent; +import me.shedaniel.architectury.impl.fabric.ScreenInputDelegate; import net.minecraft.client.KeyboardHandler; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.events.ContainerEventHandler; +import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.world.InteractionResult; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -41,48 +44,22 @@ public class MixinKeyboardHandler { @Shadow private boolean sendRepeatsToGui; - @Inject(method = "charTyped", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/gui/screens/Screen;wrapScreenError(Ljava/lang/Runnable;Ljava/lang/String;Ljava/lang/String;)V", - ordinal = 0), cancellable = true) - public void onCharFirst(long long_1, int int_1, int int_2, CallbackInfo info) { - if (!info.isCancelled()) { - InteractionResult result = ClientScreenInputEvent.CHAR_TYPED_PRE.invoker().charTyped(minecraft, minecraft.screen, (char) int_1, int_2); - if (result != InteractionResult.PASS) - info.cancel(); + @SuppressWarnings("UnresolvedMixinReference") + @ModifyVariable(method = {"method_1458", "lambda$charTyped$5"}, at = @At("HEAD"), ordinal = 0, argsOnly = true) + private static GuiEventListener wrapCharTypedFirst(GuiEventListener screen) { + if (screen instanceof ScreenInputDelegate) { + return ((ScreenInputDelegate) screen).architectury_delegateInputs(); } + return screen; } - @Inject(method = "charTyped", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/gui/screens/Screen;wrapScreenError(Ljava/lang/Runnable;Ljava/lang/String;Ljava/lang/String;)V", - ordinal = 1), cancellable = true) - public void onCharSecond(long long_1, int int_1, int int_2, CallbackInfo info) { - if (!info.isCancelled()) { - InteractionResult result = ClientScreenInputEvent.CHAR_TYPED_PRE.invoker().charTyped(minecraft, minecraft.screen, (char) int_1, int_2); - if (result != InteractionResult.PASS) - info.cancel(); - } - } - - @Inject(method = "charTyped", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/gui/screens/Screen;wrapScreenError(Ljava/lang/Runnable;Ljava/lang/String;Ljava/lang/String;)V", - ordinal = 0, shift = At.Shift.AFTER), cancellable = true) - public void onCharFirstPost(long long_1, int int_1, int int_2, CallbackInfo info) { - if (!info.isCancelled()) { - InteractionResult result = ClientScreenInputEvent.CHAR_TYPED_POST.invoker().charTyped(minecraft, minecraft.screen, (char) int_1, int_2); - if (result != InteractionResult.PASS) - info.cancel(); - } - } - - @Inject(method = "charTyped", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/gui/screens/Screen;wrapScreenError(Ljava/lang/Runnable;Ljava/lang/String;Ljava/lang/String;)V", - ordinal = 1, shift = At.Shift.AFTER), cancellable = true) - public void onCharSecondPost(long long_1, int int_1, int int_2, CallbackInfo info) { - if (!info.isCancelled()) { - InteractionResult result = ClientScreenInputEvent.CHAR_TYPED_POST.invoker().charTyped(minecraft, minecraft.screen, (char) int_1, int_2); - if (result != InteractionResult.PASS) - info.cancel(); + @SuppressWarnings("UnresolvedMixinReference") + @ModifyVariable(method = {"method_1473", "lambda$charTyped$6"}, at = @At("HEAD"), ordinal = 0, argsOnly = true) + private static GuiEventListener wrapCharTypedSecond(GuiEventListener screen) { + if (screen instanceof ScreenInputDelegate) { + return ((ScreenInputDelegate) screen).architectury_delegateInputs(); } + return screen; } @Inject(method = "keyPress", at = @At(value = "INVOKE", diff --git a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinMouseHandler.java b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinMouseHandler.java index 20f12bf5..840abd51 100644 --- a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinMouseHandler.java +++ b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinMouseHandler.java @@ -20,16 +20,17 @@ package me.shedaniel.architectury.mixin.fabric.client; import me.shedaniel.architectury.event.events.client.ClientScreenInputEvent; +import me.shedaniel.architectury.impl.fabric.ScreenInputDelegate; import net.minecraft.client.Minecraft; import net.minecraft.client.MouseHandler; import net.minecraft.client.gui.components.events.GuiEventListener; -import net.minecraft.client.gui.screens.Screen; import net.minecraft.world.InteractionResult; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -115,20 +116,11 @@ public class MixinMouseHandler { } @SuppressWarnings("UnresolvedMixinReference") - @Inject(method = {"method_1602", "lambda$onMove$11"}, at = @At("HEAD"), cancellable = true, remap = false) - public void onMouseDragged(GuiEventListener element, double d, double e, double f, double g, CallbackInfo info) { - if (!info.isCancelled()) { - InteractionResult result = ClientScreenInputEvent.MOUSE_DRAGGED_PRE.invoker().mouseDragged(minecraft, (Screen) element, d, e, activeButton, f, g); - if (result != InteractionResult.PASS) - info.cancel(); - } - } - - @SuppressWarnings("UnresolvedMixinReference") - @Inject(method = {"method_1602", "lambda$onMove$11"}, at = @At("RETURN"), remap = false) - public void onMouseDraggedPost(GuiEventListener element, double d, double e, double f, double g, CallbackInfo info) { - if (!info.isCancelled()) { - ClientScreenInputEvent.MOUSE_DRAGGED_POST.invoker().mouseDragged(minecraft, (Screen) element, d, e, activeButton, f, g); + @ModifyVariable(method = {"method_1602", "lambda$onMove$11"}, at = @At("HEAD"), ordinal = 0, argsOnly = true) + private GuiEventListener wrapMouseDragged(GuiEventListener screen) { + if (screen instanceof ScreenInputDelegate) { + return ((ScreenInputDelegate) screen).architectury_delegateInputs(); } + return screen; } } diff --git a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinScreen.java b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinScreen.java index ba6ce993..017e3eb8 100644 --- a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinScreen.java +++ b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinScreen.java @@ -25,6 +25,7 @@ import me.shedaniel.architectury.event.events.TooltipEvent; import me.shedaniel.architectury.event.events.client.ClientChatEvent; import me.shedaniel.architectury.impl.TooltipEventColorContextImpl; import me.shedaniel.architectury.impl.TooltipEventPositionContextImpl; +import me.shedaniel.architectury.impl.fabric.ScreenInputDelegate; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.events.GuiEventListener; @@ -42,7 +43,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; @Mixin(Screen.class) -public abstract class MixinScreen { +public abstract class MixinScreen implements ScreenInputDelegate { @Shadow @Final public List buttons; @Unique private static ThreadLocal tooltipPositionContext = ThreadLocal.withInitial(TooltipEventPositionContextImpl::new); @Unique private static ThreadLocal tooltipColorContext = ThreadLocal.withInitial(TooltipEventColorContextImpl::new); @@ -50,6 +51,17 @@ public abstract class MixinScreen { @Shadow public abstract List children(); + @Unique + private GuiEventListener inputDelegate; + + @Override + public GuiEventListener architectury_delegateInputs() { + if (inputDelegate == null) { + inputDelegate = new DelegateScreen((Screen) (Object) this); + } + return inputDelegate; + } + @Inject(method = "init(Lnet/minecraft/client/Minecraft;II)V", at = @At(value = "INVOKE", target = "Ljava/util/List;clear()V", ordinal = 0), cancellable = true) private void preInit(Minecraft minecraft, int i, int j, CallbackInfo ci) {