Skip to content

Commit

Permalink
basically complete
Browse files Browse the repository at this point in the history
  • Loading branch information
not-coded committed Aug 27, 2024
1 parent 3b62819 commit 89e3313
Show file tree
Hide file tree
Showing 16 changed files with 346 additions and 11 deletions.
3 changes: 1 addition & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ dependencies {
mappings "net.fabricmc:yarn:${property('deps.yarn_mappings')}:v2"
modImplementation "net.fabricmc:fabric-loader:${property('deps.fabric_loader')}"

include(implementation(annotationProcessor("io.github.llamalad7:mixinextras-fabric:${property('deps.mixin_extras_version')}")))
implementation "org.lwjgl:lwjgl-glfw:3.3.1"
implementation "org.lwjgl:lwjgl-glfw:3.3.2"
}

loom {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod.max_target=[VERSIONED]
# Dependencies
# https://fabricmc.net/develop
deps.yarn=[VERSIONED]
deps.fabric_loader=0.14.12
deps.fabric_loader=0.14.20
deps.mixin_extras_version=0.4.0
deps.fabric_api=[VERSIONED]
deps.java=[VERSIONED]
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ plugins {

stonecutter {
shared {
versions "1.16.5", "1.20.6"
versions "1.16.5", "1.19.3", "1.20.6"
}

create(rootProject);
Expand Down
29 changes: 28 additions & 1 deletion src/main/java/net/notcoded/wayfix/WayFix.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,36 @@
package net.notcoded.wayfix;

import net.fabricmc.api.ClientModInitializer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFW;

public class WayFix implements ClientModInitializer {
public static final Logger LOGGER = LogManager.getLogger(WayFix.class);

@Override
public void onInitializeClient() {
// TODO:

// fix fullscreen in wrong location
// add config option to let user specify fullscreen location (screen) (default option: primary monitor)
}

public static boolean isWayland() {
try {
return GLFW.glfwGetPlatform() == GLFW.GLFW_PLATFORM_WAYLAND;
} catch (NoSuchMethodError ignored) { // <3.3.0
return false;
}
}

public static boolean supportsWayland() {
try {
return GLFW.glfwPlatformSupported(GLFW.GLFW_PLATFORM_WAYLAND);
} catch (NoSuchMethodError ignored) { // <3.3.0
LOGGER.warn("WayFix is disabling itself due to the LWJGL Version being too low.");
LOGGER.warn("Please update to a LWJGL version such as '3.3.1' or higher.");
return false;
}
}
}
}
27 changes: 27 additions & 0 deletions src/main/java/net/notcoded/wayfix/mixin/GLXMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package net.notcoded.wayfix.mixin;

import com.mojang.blaze3d.platform.GLX;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.function.LongSupplier;

import static net.notcoded.wayfix.WayFix.supportsWayland;

/*
- Credits to moehreag
- https://github.com/moehreag/wayland-fixes
*/

@Mixin(GLX.class)
public abstract class GLXMixin {
@Inject(method = "_initGlfw", at = @At("HEAD"), remap = false)
private static void preGLFWInit(CallbackInfoReturnable<LongSupplier> cir) {
if (supportsWayland()) {
GLFW.glfwInitHint(GLFW.GLFW_PLATFORM, GLFW.GLFW_PLATFORM_WAYLAND); // enable wayland backend if supported
}
}
}
40 changes: 40 additions & 0 deletions src/main/java/net/notcoded/wayfix/mixin/MinecraftClientMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package net.notcoded.wayfix.mixin;

import net.minecraft.client.MinecraftClient;
import net.minecraft.client.option.GameOptions;
import net.minecraft.client.util.Window;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;

@Mixin(MinecraftClient.class)
public abstract class MinecraftClientMixin {
@Shadow @Final private Window window;

@Shadow @Final public GameOptions options;

@ModifyArg(method = "onResolutionChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/Window;setScaleFactor(D)V"))
private double fixHiDPIScaling(double d) {
int guiScale;
//? if >=1.19.3 {
guiScale = this.options.getGuiScale().getValue();
//?} elif <1.19.3 {
/*guiScale = this.options.guiScale;
*///?}

// "Auto" or Gui Scale 0 already auto-scales it
return guiScale != 0 ? d * getScaleFactor() : d;
}

@Unique
private float getScaleFactor() {
float[] pos = new float[1];
GLFW.glfwGetWindowContentScale(this.window.getHandle(), pos, pos);

return pos[0]; // using x or y doesn't matter
}
}
72 changes: 72 additions & 0 deletions src/main/java/net/notcoded/wayfix/mixin/WindowMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package net.notcoded.wayfix.mixin;

import net.minecraft.client.WindowEventHandler;
import net.minecraft.client.WindowSettings;
import net.minecraft.client.util.MonitorTracker;
import net.minecraft.client.util.Window;
import net.notcoded.wayfix.util.DesktopFileInjector;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import static net.notcoded.wayfix.WayFix.isWayland;

//? if >=1.20 {

/*import net.minecraft.client.util.Icons;
import net.minecraft.resource.ResourcePack;
import java.io.IOException;
*///?} elif 1.19.3 {
import java.util.ArrayList;
import java.util.Arrays;
import net.minecraft.resource.InputSupplier;
//?}

//? if <1.20 {
import java.io.InputStream;
//?}

/*
- Credits to moehreag
- https://github.com/moehreag/wayland-fixes
*/

@Mixin(Window.class)
public class WindowMixin {
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwDefaultWindowHints()V", shift = At.Shift.AFTER, remap = false))
private void onWindowHints(WindowEventHandler windowEventHandler, MonitorTracker monitorTracker, WindowSettings windowSettings, String string, String string2, CallbackInfo ci) {
if (isWayland()) {
GLFW.glfwWindowHint(GLFW.GLFW_FOCUS_ON_SHOW, GLFW.GLFW_FALSE);
DesktopFileInjector.inject();
GLFW.glfwWindowHintString(GLFW.GLFW_WAYLAND_APP_ID, DesktopFileInjector.APP_ID);
}
}

@Inject(method = "setIcon", at = @At("HEAD"), cancellable = true)
//? if >=1.20 {

/*private void injectIcon(ResourcePack resourcePack, Icons icons, CallbackInfo ci) {
*///?} elif 1.19.3 {
private void injectIcon(InputSupplier<InputStream> smallIconSupplier, InputSupplier<InputStream> bigIconSupplier, CallbackInfo ci) {
//?} elif <1.19.3 {

/*private void injectIcon(InputStream icon16, InputStream icon32, CallbackInfo ci) {
*///?}
if (isWayland()) {
//? if >=1.20 {
/*try {
DesktopFileInjector.setIcon(icons.getIcons(resourcePack));
} catch (IOException ignored) { }
*///?} elif 1.19.3 {
DesktopFileInjector.setIcon(new ArrayList<>(Arrays.asList(smallIconSupplier, bigIconSupplier)));
//?} elif <1.19.3 {

/*DesktopFileInjector.setIcon(icon16, icon32);
*///?}

ci.cancel();
}
}
}
122 changes: 122 additions & 0 deletions src/main/java/net/notcoded/wayfix/util/DesktopFileInjector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package net.notcoded.wayfix.util;

import net.minecraft.client.MinecraftClient;
//? if >=1.19 {
import net.minecraft.resource.InputSupplier;
//?} elif <1.19 {
/*import java.util.ArrayList;
import java.util.Arrays;
import java.io.ByteArrayInputStream;
*///?}
import net.notcoded.wayfix.WayFix;
import org.apache.commons.io.IOUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;

/*
- Credits to moehreag for most of the code
- https://github.com/moehreag/wayland-fixes
*/

public class DesktopFileInjector {
// The taskbar icon is set to the minecraft launcher's icon if you have it installed
// Adding '.java-edition' fixes it (due to being recognized as a new app)
public static final String APP_ID = "com.mojang.minecraft.java-edition";

private static final String ICON_NAME = "minecraft.png";
private static final String FILE_NAME = APP_ID + ".desktop";
private static final String RESOURCE_LOCATION = "/assets/wayfix/" + FILE_NAME;

public static void inject() {
try (InputStream stream = DesktopFileInjector.class.getResourceAsStream(RESOURCE_LOCATION)) {
Path location = getDesktopFileLocation();

String version = MinecraftClient.getInstance().getGameVersion();

injectFile(location, String.format(IOUtils.toString(Objects.requireNonNull(stream), StandardCharsets.UTF_8),
version, ICON_NAME.substring(0, ICON_NAME.lastIndexOf("."))).getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
WayFix.LOGGER.error("Failed to inject icon: ", e);
}

}

//? if >=1.19.3 {
public static void setIcon(List<InputSupplier<InputStream>> icons) {
for (InputSupplier<InputStream> supplier : icons) {
try {
BufferedImage image = ImageIO.read(supplier.get());
Path target = getIconFileLocation(image.getWidth(), image.getHeight());
injectFile(target, IOUtils.toByteArray(supplier.get()));

} catch (IOException e) {
return;
}
}
updateIconSystem();
}
//?} elif <1.19.3 {

/*public static void setIcon(InputStream icon16, InputStream icon32) {
byte[] icon16Byte;
byte[] icon32Byte;
try {
// https://stackoverflow.com/questions/58534138/does-files-readallbytes-closes-the-inputstream-after-reading-the-file
icon16Byte = icon16.readAllBytes();
icon32Byte = icon32.readAllBytes();
} catch (IOException e) {
e.printStackTrace();
return;
}
ArrayList<byte[]> icons = new ArrayList<>(Arrays.asList(icon16Byte, icon32Byte));
for(byte[] bytes : icons) {
try {
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
Path target = getIconFileLocation(image.getWidth(), image.getHeight());
injectFile(target, bytes);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
updateIconSystem();
}
*///?}

private static void injectFile(Path target, byte[] data) {
try {
Files.createDirectories(target.getParent());
new File(String.valueOf(Files.write(target, data))).deleteOnExit();
} catch (IOException e) {
WayFix.LOGGER.error("Failed to inject file: ", e);
}
}


private static Path getIconFileLocation(int width, int height) {
return XDGPathResolver.getUserDataLocation().resolve("icons/hicolor").resolve(width + "x" + height)
.resolve("apps").resolve(ICON_NAME);
}

private static Path getDesktopFileLocation() {
return XDGPathResolver.getUserDataLocation().resolve("applications").resolve(FILE_NAME);
}

private static void updateIconSystem() {
ProcessBuilder builder = new ProcessBuilder("xdg-icon-resource", "forceupdate");
try {
builder.start();
} catch (IOException ignored) { }
}
}
28 changes: 28 additions & 0 deletions src/main/java/net/notcoded/wayfix/util/XDGPathResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package net.notcoded.wayfix.util;

import java.nio.file.Path;
import java.nio.file.Paths;

/*
- Credits to moehreag
- https://github.com/moehreag/wayland-fixes
*/

public class XDGPathResolver {

private static Path getHome(){
String home = System.getenv().getOrDefault("HOME", System.getProperty("user.home"));
if (home == null || home.isEmpty()) {
throw new IllegalStateException("could not resolve user home");
}
return Paths.get(home);
}

public static Path getUserDataLocation() {
String xdgDataHome = System.getenv("XDG_DATA_HOME");
if (xdgDataHome == null || xdgDataHome.isEmpty()) {
return getHome().resolve(".local/share/");
}
return Paths.get(xdgDataHome);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Desktop Entry]
Name=Minecraft %s
Comment=Explore your own unique world, survive the night, and create anything you can imagine!
Icon=%s
Exec=true
Hidden=true
Terminal=false
Type=Application
Categories=Game;
2 changes: 1 addition & 1 deletion src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
],

"depends": {
"fabricloader": ">=0.13.3",
"fabricloader": ">=0.14.20",
"minecraft": "${minecraftVersion}",
"java": ">=${javaVersion}"
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/wayfix.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"package": "net.notcoded.wayfix.mixin",
"compatibilityLevel": "JAVA_8",
"client": [
"GLXMixin",
"MinecraftClientMixin",
"WindowMixin"
],
"injectors": {
"defaultRequire": 1
Expand Down
Loading

0 comments on commit 89e3313

Please sign in to comment.