Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ build
# other
eclipse
run
runs

# Files from Forge MDK
forge*changelog.txt
20 changes: 13 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
# MC-122477 Fix
[![CurseForge](https://cf.way2muchnoise.eu/versions/432448.svg)](https://www.curseforge.com/minecraft/mc-mods/mc122477fix)
# Linux T Prefix on Opening Chat
![GitHub License](https://img.shields.io/github/license/RecursiveG/Mc122477Fix)
[![Mojira issue MC-122477](https://img.shields.io/jira/issue/MC-122477?baseUrl=https%3A%2F%2Fbugs.mojang.com)](https://bugs.mojang.com/browse/MC-122477)

Fixes the extra `t` or `/` issue on some Linux desktop environments when opening the chat window.

This is the NeoForge port of [RecursiveG's MC-122477 Fix](https://github.com/RecursiveG/Mc122477Fix). The original project and this port are licensed under the MIT License.

## NeoForge 1.21.1 port

This branch ports the client-side fix to Minecraft 1.21.1 using NeoForge 21.1 and Java 21.
Build it with `JAVA_HOME=/path/to/java-21 ./gradlew build`; the distributable JAR is written to `build/libs`.

## Downloads
- [CurseForge](https://www.curseforge.com/minecraft/mc-mods/mc122477fix)
- [Modrinth](https://modrinth.com/mod/mc122477fix)
- [GitHub releases](https://github.com/RecursiveG/Mc122477Fix/releases)
- [NeoForge port releases](https://github.com/bomxacalaka/Mc122477Fix/releases)
- [Original project on CurseForge](https://www.curseforge.com/minecraft/mc-mods/mc122477fix)
- [Original project on Modrinth](https://modrinth.com/mod/mc122477fix)

## What is this bug?
Thank you to `__null` on Mojira for their help in discovering the source of the bug. MC-122477 arises from an issue originating in GLFW (see [GLFW/glfw#1794](https://github.com/glfw/GLFW/issues/1794)). The Minecraft client polls for GLFW events twice per frame. A key press event is an event created when the player presses a key in the game. It is used to process game input like WASD. A char type event is also an event created when the player presses a key and is used to process text input. Key press events are always processed before char type events. In a normal environment, a key press and char type event would be polled at the same time. However, on some Linux desktop environments, the key press event and char type event are received on *separate* polls, allowing for the possibility of a game tick to occur between receiving the key press and char type events. Because of this possible extra game tick in between the two events, the key press event can be processed to open the chat on the game tick, and then the char type event is processed after the chat has already opened, causing an extra character to be typed. This doesn't happen on Windows, Mac OS, and the remaining Linux desktop environments because it is not possible for the chat to already be open when the char type event for opening chat (e.g. the character `t`) is processed.
Expand All @@ -18,5 +24,5 @@ Thank you to `__null` on Mojira for their help in discovering the source of the
### Fabric
The Fabric version of the mod injects Mixin callbacks into `Keyboard#onKey` and `Keyboard#onChar` to listen for key press and char type events from [GLFW](https://github.com/glfw/GLFW). A Mixin is also injected into `MinecraftClient#tick` on 1.14 and `RenderSystem#flipFrame` on 1.15+ to listen for GLFW event polls. The mod then keeps track of how many polls have been processed since the game started in a poll counter. The mod stores this poll count separately when a key press event is detected for the chat open key or command key. The first char type event that is received within 5 polls after the poll of the original key press is then canceled, and the stored field is reset for the next time. This fixes the bug because it stops the char type event from ever being able to be processed and is only executed when the chat is first opened.

### Forge
The Forge version of the mod uses built-in Forge events to listen for the opening of the chat screen and then stores the timestamp at which it was opened. If a char type event is detected within 50 milliseconds of the chat screen originally opening, the char type event is canceled. This has problems because slower hardware might have the char type event processed sometime after 50 milliseconds has already occurred since the opening of the chat. This rudimentary version is similar to how the original Fabric version worked until 1.1+. However, this method is still effective at catching most of the extra char type events from being processed.
### Forge / NeoForge
The Forge-family version uses built-in client events to detect the chat or creative inventory screen opening. Key and character events arriving during the first two rendered frames are canceled, preventing the delayed opening character from reaching the newly opened text field.
11 changes: 5 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins {
id 'eclipse'
id 'idea'
id 'maven-publish'
id 'net.neoforged.gradle.userdev' version '7.0.97'
id 'net.neoforged.gradle.userdev' version '7.1.38'
}

version = mod_version
Expand All @@ -14,11 +14,11 @@ repositories {
}

base {
archivesName = mod_id
archivesName = 'linux-t-prefix-on-opening-chat'
}

// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17.
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
// Minecraft 1.21.1 requires Java 21.
java.toolchain.languageVersion = JavaLanguageVersion.of(21)

//minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg')
//minecraft.accessTransformers.entry public net.minecraft.client.Minecraft textureManager # textureManager
Expand Down Expand Up @@ -132,7 +132,7 @@ tasks.withType(ProcessResources).configureEach {
]
inputs.properties replaceProperties

filesMatching(['META-INF/mods.toml']) {
filesMatching(['META-INF/neoforge.mods.toml']) {
expand replaceProperties
}
}
Expand Down Expand Up @@ -162,4 +162,3 @@ idea {
downloadJavadoc = true
}
}

22 changes: 9 additions & 13 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,37 @@
org.gradle.daemon=false
org.gradle.debug=false

#read more on this at https://github.com/neoforged/NeoGradle/blob/NG_7.0/README.md#apply-parchment-mappings
# you can also find the latest versions at: https://parchmentmc.org/docs/getting-started
neogradle.subsystems.parchment.minecraftVersion=1.20.3
neogradle.subsystems.parchment.mappingsVersion=2023.12.31
# Environment Properties
# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge
# The Minecraft version must agree with the Neo version to get a valid artifact
minecraft_version=1.20.4
minecraft_version=1.21.1
# The Minecraft version range can use any release version of Minecraft as bounds.
# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
# as they do not follow standard versioning conventions.
minecraft_version_range=[1.20.4,1.21)
minecraft_version_range=[1.21.1,1.21.2)
# The Neo version must agree with the Minecraft version to get a valid artifact
neo_version=20.4.147-beta
neo_version=21.1.241
# The Neo version range can use any version of Neo as bounds
neo_version_range=[20.4,)
neo_version_range=[21.1,21.2)
# The loader version range can only use the major version of FML as bounds
loader_version_range=[2,)
loader_version_range=[4,)

## Mod Properties

# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63}
# Must match the String constant located in the main mod class annotated with @Mod.
mod_id=mc122477fix
# The human-readable display name for the mod.
mod_name=MC-122477 Fix
mod_name=Linux T Prefix on Opening Chat
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=MIT
# The mod version. See https://semver.org/
mod_version=1.1.2
mod_version=1.1.3-mc1.21.1-neoforge
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
mod_group_id=me.recursiveg
# The authors of the mod. This is a simple text string that is used for display purposes in the mod list.
mod_authors=RecursiveG
mod_authors=RecursiveG; NeoForge ports by bomxacalaka
# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list.
mod_description="Fix MC-122477, which causes double-typing 't' or '/' on Linux."
mod_description=Fixes the extra 't' or '/' typed when opening Minecraft chat on Linux.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
59 changes: 34 additions & 25 deletions src/main/java/me/recursiveg/Mc122477Fix.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,54 @@

import net.minecraft.client.gui.screens.ChatScreen;
import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.RenderFrameEvent;
import net.neoforged.neoforge.client.event.ScreenEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.TickEvent;

@Mod("mc122477fix")
public class Mc122477Fix {
@Mod(value = Mc122477Fix.MOD_ID, dist = Dist.CLIENT)
public final class Mc122477Fix {
public static final String MOD_ID = "mc122477fix";

public Mc122477Fix() {
NeoForge.EVENT_BUS.register(this);
}

long renderTicksSinceScreenOpen = 0;
@EventBusSubscriber(modid = MOD_ID, value = Dist.CLIENT)
public static final class ClientEvents {
private static long framesSinceScreenOpen = Long.MAX_VALUE;

@SubscribeEvent
public void onScreenOpen(ScreenEvent.Opening ev) {
if (ev.getNewScreen() instanceof ChatScreen || ev.getNewScreen() instanceof CreativeModeInventoryScreen) {
renderTicksSinceScreenOpen = 0;
private ClientEvents() {
}
}

@SubscribeEvent
public void onKeyPressed(ScreenEvent.KeyPressed.Pre ev) {
if (renderTicksSinceScreenOpen < 2) {
ev.setCanceled(true);
@SubscribeEvent
public static void onScreenOpen(ScreenEvent.Opening event) {
if (event.getNewScreen() instanceof ChatScreen
|| event.getNewScreen() instanceof CreativeModeInventoryScreen) {
framesSinceScreenOpen = 0;
}
}
}

@SubscribeEvent
public void onCharTyped(ScreenEvent.CharacterTyped.Pre ev) {
if (renderTicksSinceScreenOpen < 2) {
ev.setCanceled(true);
@SubscribeEvent
public static void onKeyPressed(ScreenEvent.KeyPressed.Pre event) {
if (framesSinceScreenOpen < 2) {
event.setCanceled(true);
}
}

@SubscribeEvent
public static void onCharTyped(ScreenEvent.CharacterTyped.Pre event) {
if (framesSinceScreenOpen < 2) {
event.setCanceled(true);
}
}
}

@SubscribeEvent
public void onPostClientTick(TickEvent.RenderTickEvent ev) {
if (ev.phase == TickEvent.Phase.END) {
renderTicksSinceScreenOpen++;
@SubscribeEvent
public static void onPostRenderFrame(RenderFrameEvent.Post event) {
if (framesSinceScreenOpen < 2) {
framesSinceScreenOpen++;
}
}
}
}
100 changes: 0 additions & 100 deletions src/main/resources/META-INF/mods.toml

This file was deleted.

26 changes: 26 additions & 0 deletions src/main/resources/META-INF/neoforge.mods.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
modLoader="javafml"
loaderVersion="${loader_version_range}"
license="${mod_license}"
issueTrackerURL="https://github.com/bomxacalaka/Mc122477Fix/issues"

[[mods]]
modId="${mod_id}"
version="${mod_version}"
displayName="${mod_name}"
displayURL="https://github.com/bomxacalaka/Mc122477Fix"
authors="${mod_authors}"
description='''${mod_description}'''

[[dependencies.${mod_id}]]
modId="neoforge"
type="required"
versionRange="${neo_version_range}"
ordering="NONE"
side="CLIENT"

[[dependencies.${mod_id}]]
modId="minecraft"
type="required"
versionRange="${minecraft_version_range}"
ordering="NONE"
side="CLIENT"