--- a/net/minecraft/world/item/LeadItem.java
+++ b/net/minecraft/world/item/LeadItem.java
@@ -26,24 +_,46 @@
         if (blockState.is(BlockTags.FENCES)) {
             Player player = context.getPlayer();
             if (!level.isClientSide && player != null) {
-                return bindPlayerMobs(player, level, clickedPos);
+                return bindPlayerMobs(player, level, clickedPos, context.getHand()); // CraftBukkit - Pass hand
             }
         }
 
         return InteractionResult.PASS;
     }
 
-    public static InteractionResult bindPlayerMobs(Player player, Level level, BlockPos pos) {
+    public static InteractionResult bindPlayerMobs(Player player, Level level, BlockPos pos, net.minecraft.world.InteractionHand interactionHand) { // CraftBukkit - Add InteractionHand
         LeashFenceKnotEntity leashFenceKnotEntity = null;
         List<Leashable> list = Leashable.leashableInArea(level, Vec3.atCenterOf(pos), leashable1 -> leashable1.getLeashHolder() == player);
         boolean flag = false;
 
-        for (Leashable leashable : list) {
+        for (java.util.Iterator<Leashable> iterator = list.iterator(); iterator.hasNext();) { // Paper - use iterator to remove
+            Leashable leashable = iterator.next(); // Paper - use iterator to remove
             if (leashFenceKnotEntity == null) {
-                leashFenceKnotEntity = LeashFenceKnotEntity.getOrCreateKnot(level, pos);
+                // CraftBukkit start - fire HangingPlaceEvent
+                org.apache.commons.lang3.mutable.MutableBoolean created = new org.apache.commons.lang3.mutable.MutableBoolean(false);
+                leashFenceKnotEntity = LeashFenceKnotEntity.getOrCreateKnot(level, pos, created);
+                if (created.booleanValue()) {
+                    org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(interactionHand);
+                    org.bukkit.event.hanging.HangingPlaceEvent event = new org.bukkit.event.hanging.HangingPlaceEvent((org.bukkit.entity.Hanging) leashFenceKnotEntity.getBukkitEntity(), player != null ? (org.bukkit.entity.Player) player.getBukkitEntity() : null, org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), org.bukkit.block.BlockFace.SELF, hand);
+                    level.getCraftServer().getPluginManager().callEvent(event);
+
+                    if (event.isCancelled()) {
+                        leashFenceKnotEntity.discard(null); // CraftBukkit - add Bukkit remove cause
+                        return InteractionResult.PASS;
+                    }
+                }
+                // CraftBukkit end
                 leashFenceKnotEntity.playPlacementSound();
             }
 
+            // CraftBukkit start
+            if (leashable instanceof net.minecraft.world.entity.Entity leashed) {
+                if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(leashed, leashFenceKnotEntity, player, interactionHand).isCancelled()) {
+                    iterator.remove();
+                    continue;
+                }
+            }
+            // CraftBukkit end
             if (leashable.canHaveALeashAttachedTo(leashFenceKnotEntity)) {
                 leashable.setLeashedTo(leashFenceKnotEntity, true);
                 flag = true;
@@ -54,7 +_,18 @@
             level.gameEvent(GameEvent.BLOCK_ATTACH, pos, GameEvent.Context.of(player));
             return InteractionResult.SUCCESS_SERVER;
         } else {
+            // CraftBukkit start - remove leash if we do not leash any entity because of the cancelled event
+            if (leashFenceKnotEntity != null) {
+                leashFenceKnotEntity.discard(null);
+            }
+            // CraftBukkit end
             return InteractionResult.PASS;
         }
     }
+
+    // CraftBukkit start
+    public static InteractionResult bindPlayerMobs(Player player, Level world, BlockPos pos) {
+        return LeadItem.bindPlayerMobs(player, world, pos, net.minecraft.world.InteractionHand.MAIN_HAND);
+    }
+    // CraftBukkit end
 }
