--- a/net/minecraft/world/level/block/SignBlock.java
+++ b/net/minecraft/world/level/block/SignBlock.java
@@ -133,7 +_,7 @@
             } else if (!this.otherPlayerIsEditingSign(player, signBlockEntity)
                 && player.mayBuild()
                 && this.hasEditableText(player, signBlockEntity, isFacingFrontText)) {
-                this.openTextEdit(player, signBlockEntity, isFacingFrontText);
+                this.openTextEdit(player, signBlockEntity, isFacingFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent
                 return InteractionResult.SUCCESS_SERVER;
             } else {
                 return InteractionResult.PASS;
@@ -175,7 +_,34 @@
         return woodType;
     }
 
+    @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add PlayerOpenSignEvent
     public void openTextEdit(Player player, SignBlockEntity signEntity, boolean isFrontText) {
+        // Paper start - Add PlayerOpenSignEvent
+        this.openTextEdit(player, signEntity, isFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.UNKNOWN);
+    }
+
+    public void openTextEdit(Player player, SignBlockEntity signEntity, boolean isFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause cause) {
+        org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) player.getBukkitEntity();
+        org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(signEntity.getLevel(), signEntity.getBlockPos());
+        org.bukkit.craftbukkit.block.CraftSign<?> bukkitSign = (org.bukkit.craftbukkit.block.CraftSign<?>) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(bukkitBlock);
+        io.papermc.paper.event.player.PlayerOpenSignEvent event = new io.papermc.paper.event.player.PlayerOpenSignEvent(
+            bukkitPlayer,
+            bukkitSign,
+            isFrontText ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK,
+            cause);
+        if (!event.callEvent()) return;
+        if (org.bukkit.event.player.PlayerSignOpenEvent.getHandlerList().getRegisteredListeners().length > 0) {
+            final org.bukkit.event.player.PlayerSignOpenEvent.Cause legacyCause = switch (cause) {
+                case PLACE -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLACE;
+                case PLUGIN -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLUGIN;
+                case INTERACT -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.INTERACT;
+                case UNKNOWN -> org.bukkit.event.player.PlayerSignOpenEvent.Cause.UNKNOWN;
+            };
+        if (!org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerSignOpenEvent(player, signEntity, isFrontText, legacyCause)) {
+        // Paper end - Add PlayerOpenSignEvent
+            return;
+        }
+        } // Paper - Add PlayerOpenSignEvent
         signEntity.setAllowedPlayerEditor(player.getUUID());
         player.openTextEdit(signEntity, isFrontText);
     }
@@ -188,6 +_,6 @@
     @Nullable
     @Override
     public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> blockEntityType) {
-        return createTickerHelper(blockEntityType, BlockEntityType.SIGN, SignBlockEntity::tick);
+        return null; // CraftBukkit - remove unnecessary sign ticking
     }
 }
