From 4cc6bf78667b86184f6fd2d55903500355f21540 Mon Sep 17 00:00:00 2001 From: keke142 Date: Fri, 17 Apr 2026 15:59:52 +0200 Subject: [PATCH] Fix CWB borderless compat and fractional scaling click offset Two changes to MonitorFixWindowMixin: 1. Set mixin priority to 500 (lower than default 1000) so the HEAD inject on updateWindowRegion runs before CWB's cancellable HEAD inject. Without this, CWB cancels the method before WayFix can correct the window position via kdotool, causing borderless fullscreen to always target the primary monitor. 2. Add a per-frame reconciliation in swapBuffers that queries GLFW for the actual logical window size and corrects MC's width/height fields when they diverge. On Wayland with fractional scaling, MC and mods like CWB write physical monitor dimensions (e.g. 2560) to these fields, but GLFW reports cursor coords in logical surface coords (e.g. 1463 at 1.75x scale). This mismatch causes persistent click offset after fullscreen transitions. --- .../wayfix/mixin/MonitorFixWindowMixin.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/notcoded/wayfix/mixin/MonitorFixWindowMixin.java b/src/main/java/net/notcoded/wayfix/mixin/MonitorFixWindowMixin.java index 430dfe5..40d7020 100644 --- a/src/main/java/net/notcoded/wayfix/mixin/MonitorFixWindowMixin.java +++ b/src/main/java/net/notcoded/wayfix/mixin/MonitorFixWindowMixin.java @@ -16,13 +16,16 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import static net.notcoded.wayfix.WayFix.isWayland; + import java.util.ArrayList; import java.util.Collections; -@Mixin(Window.class) +@Mixin(value = Window.class, priority = 500) public abstract class MonitorFixWindowMixin { @Shadow protected abstract void onWindowPosChanged(long window, int x, int y); + @Shadow protected abstract void onWindowSizeChanged(long window, int width, int height); @Shadow @Final private long handle; @@ -50,8 +53,6 @@ private Monitor fixWrongMonitor(MonitorTracker instance, Window window) { } } - - if(monitorID <= 0 || instance.getMonitor(monitorID) == null) { WayFix.LOGGER.warn("Error occurred while trying to set monitor."); WayFix.LOGGER.warn("Using primary monitor instead."); @@ -61,7 +62,6 @@ private Monitor fixWrongMonitor(MonitorTracker instance, Window window) { return instance.getMonitor(monitorID); } - // KDE Plasma ONLY @Inject(method = "updateWindowRegion", at = @At("HEAD")) private void fixWrongMonitor(CallbackInfo ci) { @@ -72,4 +72,21 @@ private void fixWrongMonitor(CallbackInfo ci) { onWindowPosChanged(this.handle, pos[0], pos[1]); } + + // Wayland fractional scaling fix: MC and mods (e.g. CWB) write physical monitor + // dimensions to window.width/height, but GLFW cursor coords use logical (surface) + // coords. Reconcile every frame by querying GLFW for the actual logical size. + @Inject(method = "swapBuffers", at = @At("HEAD")) + private void wayfix$reconcileWindowSize(CallbackInfo ci) { + if (!isWayland()) return; + + int[] w = new int[1]; + int[] h = new int[1]; + GLFW.glfwGetWindowSize(this.handle, w, h); + + Window self = (Window)(Object)this; + if (w[0] > 0 && h[0] > 0 && (self.getWidth() != w[0] || self.getHeight() != h[0])) { + onWindowSizeChanged(this.handle, w[0], h[0]); + } + } }