refactor: replaced dirty solution with real exclusive fullscreen
This commit is contained in:
parent
4fc4ee149e
commit
87f924ce8e
@ -4,10 +4,20 @@ import net.deechael.concentration.FullscreenMode;
|
||||
|
||||
public interface Config {
|
||||
|
||||
boolean customized();
|
||||
|
||||
FullscreenMode getFullscreenMode();
|
||||
|
||||
void setFullscreenMode(FullscreenMode fullscreenMode);
|
||||
|
||||
void save();
|
||||
|
||||
static boolean isBorderless() {
|
||||
return ConfigProvider.INSTANCE.ensureLoaded().getFullscreenMode() == FullscreenMode.BORDERLESS;
|
||||
}
|
||||
|
||||
static boolean isCustomized() {
|
||||
return ConfigProvider.INSTANCE.ensureLoaded().customized();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package net.deechael.concentration.mixin;
|
||||
|
||||
import net.minecraft.client.main.Main;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(Main.class)
|
||||
public class MainMixin {
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package net.deechael.concentration.util;
|
||||
|
||||
import net.deechael.concentration.mixin.accessor.WindowAccessor;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public final class Accessors {
|
||||
|
||||
public static WindowAccessor window() {
|
||||
return ((WindowAccessor) (Object) Minecraft.getInstance().getWindow());
|
||||
}
|
||||
|
||||
private Accessors() {
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
"mixins": [],
|
||||
"client": [
|
||||
"KeyboardHandlerMixin",
|
||||
"MainMixin",
|
||||
"VideoSettingsScreenMixin",
|
||||
"accessor.WindowAccessor"
|
||||
],
|
||||
|
@ -43,6 +43,11 @@ public class ConcentrationConfigFabric implements Config {
|
||||
public int height = 600;
|
||||
public FullscreenMode fullscreen = FullscreenMode.BORDERLESS;
|
||||
|
||||
@Override
|
||||
public boolean customized() {
|
||||
return this.customized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FullscreenMode getFullscreenMode() {
|
||||
return this.fullscreen;
|
||||
|
@ -5,12 +5,16 @@ import com.mojang.blaze3d.platform.VideoMode;
|
||||
import com.mojang.blaze3d.platform.Window;
|
||||
import net.deechael.concentration.ConcentrationConstants;
|
||||
import net.deechael.concentration.FullscreenMode;
|
||||
import net.deechael.concentration.config.Config;
|
||||
import net.deechael.concentration.fabric.ConcentrationFabricCaching;
|
||||
import net.deechael.concentration.fabric.config.ConcentrationConfigFabric;
|
||||
import net.deechael.concentration.mixin.accessor.WindowAccessor;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWNativeWin32;
|
||||
import org.lwjgl.system.windows.User32;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@ -27,112 +31,94 @@ public class GLFWMixin {
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration Start] =================");
|
||||
ConcentrationConstants.LOGGER.info("Trying to modify window monitor");
|
||||
|
||||
// Monitor is 0 means the game is windowed mode, so the expression means if is toggling to fullscreen
|
||||
Window windowInstance = Minecraft.getInstance().getWindow();
|
||||
WindowAccessor accessor = (WindowAccessor) (Object) windowInstance;
|
||||
|
||||
if (windowInstance.isFullscreen())
|
||||
if (monitor == 0L)
|
||||
monitor = windowInstance.findBestMonitor().getMonitor();
|
||||
|
||||
Monitor monitorInstance = accessor.getScreenManager().getMonitor(monitor);
|
||||
ConcentrationConstants.LOGGER.info("Current fullscreen monitor is {}", monitor);
|
||||
|
||||
if (monitor != 0L) {
|
||||
VideoMode currentMode = monitorInstance.getCurrentMode();
|
||||
ConcentrationConstants.LOGGER.info("Modifying window size limits");
|
||||
GLFW.glfwSetWindowSizeLimits(window, 0, 0, width, height);
|
||||
GLFW.glfwSetWindowSizeLimits(window, 0, 0, currentMode.getWidth(), currentMode.getHeight());
|
||||
}
|
||||
|
||||
// Because whether in fullscreen mode or windowed mode
|
||||
// The final step is same
|
||||
// So I extracted the value then execute the final step
|
||||
long finalMonitor;
|
||||
|
||||
int finalWidth;
|
||||
int finalHeight;
|
||||
|
||||
int finalX;
|
||||
int finalY;
|
||||
|
||||
Window windowInstance = Minecraft.getInstance().getWindow();
|
||||
WindowAccessor accessor = (WindowAccessor) (Object) windowInstance;
|
||||
|
||||
if (windowInstance != null && windowInstance.isFullscreen()) {
|
||||
VideoMode currentMode = monitorInstance.getCurrentMode();
|
||||
|
||||
ConcentrationConfigFabric config = ConcentrationConfigFabric.getInstance();
|
||||
|
||||
// If the game started with fullscreen mode, when switching to windowed mode, it will be forced to move to the primary monitor
|
||||
// Though size and position isn't be set at initialization, but I think the window should be at the initial monitor
|
||||
// So save the monitor and use the monitor value when the size isn't cached
|
||||
ConcentrationFabricCaching.lastMonitor = monitor;
|
||||
|
||||
// Lock caching, because when switching back, the window will be once resized to the maximum value and the cache value will be wrong
|
||||
// Position won't be affected, so it doesn't need lock
|
||||
ConcentrationFabricCaching.cacheSizeLock = true;
|
||||
ConcentrationConstants.LOGGER.info("Locked size caching");
|
||||
|
||||
if (config.fullscreen == FullscreenMode.NATIVE) {
|
||||
ConcentrationConstants.LOGGER.info("Fullscreen mode is native, apply now!");
|
||||
if (monitor == 0L)
|
||||
monitor = windowInstance.findBestMonitor().getMonitor();
|
||||
finalExecute(window, monitor, xpos, ypos, width, height, -1);
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration End] =================");
|
||||
return;
|
||||
}
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to borderless fullscreen mode");
|
||||
|
||||
// Get the monitor the user want to use and get the relative position in the system
|
||||
// The monitor is always non-null because when switching fullscreen mode, there must be a monitor to put the window
|
||||
Monitor monitorInstance = accessor.getScreenManager().getMonitor(monitor);
|
||||
ConcentrationConstants.LOGGER.info("Current fullscreen monitor is {}", monitor);
|
||||
|
||||
// Remove the title bar to prevent that user can see the title bar if they put their monitors vertically connected
|
||||
GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_DECORATED, GLFW.GLFW_FALSE);
|
||||
ConcentrationConstants.LOGGER.info("Trying to remove the title bar");
|
||||
|
||||
if (ConcentrationConfigFabric.getInstance().customized) {
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Customization enabled, so replace the fullscreen size with customized size");
|
||||
finalX = config.x + (config.related ? monitorInstance.getX() : 0);
|
||||
finalY = config.y - (config.height == height ? 1 : 0) + (config.related ? monitorInstance.getY() : 0);
|
||||
finalWidth = config.width;
|
||||
finalHeight = config.height + (config.height == height ? 1 : 0);
|
||||
} else {
|
||||
// If we make the window not decorated and set the window size exactly the same with the screen size, it will become native fullscreen mode
|
||||
// to prevent this, I enlarge the height by 1 pixel and move up the window by 1 pixel which won't affect anything (unless you have a screen
|
||||
// which is added above the monitor which holds the game) and will have a good experience
|
||||
// Actually this is a little bit dirty, needs to find a better way to solve it
|
||||
finalMonitor = monitor;
|
||||
finalX = monitorInstance.getX();
|
||||
finalY = monitorInstance.getY() - 1;
|
||||
finalWidth = width;
|
||||
finalHeight = height + 1;
|
||||
}
|
||||
finalY = monitorInstance.getY();
|
||||
finalWidth = currentMode.getWidth();
|
||||
finalHeight = currentMode.getHeight();
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration End] =================");
|
||||
} else {
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to borderless fullscreen mode");
|
||||
|
||||
accessor.setX(finalX);
|
||||
accessor.setY(finalY);
|
||||
accessor.setWidth(finalWidth);
|
||||
accessor.setHeight(finalHeight);
|
||||
/*if (ConcentrationConfigFabric.getInstance().customized) {
|
||||
ConcentrationConstants.LOGGER.info("Customization enabled, so replace the fullscreen size with customized size");
|
||||
finalX = config.x + (config.related ? monitorInstance.getX() : 0);
|
||||
finalY = config.y - (config.height == height ? 1 : 0) + (config.related ? monitorInstance.getY() : 0);
|
||||
finalWidth = config.width;
|
||||
finalHeight = config.height + (config.height == height ? 1 : 0);
|
||||
} else */
|
||||
{
|
||||
finalMonitor = monitor;
|
||||
finalX = monitorInstance.getX();
|
||||
finalY = monitorInstance.getY();
|
||||
finalWidth = currentMode.getWidth();
|
||||
finalHeight = currentMode.getHeight();
|
||||
}
|
||||
|
||||
accessor.setX(finalX);
|
||||
accessor.setY(finalY);
|
||||
accessor.setWidth(finalWidth);
|
||||
accessor.setHeight(finalHeight);
|
||||
}
|
||||
} else {
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to windowed mode");
|
||||
|
||||
// Re-add the title bar so user can move the window and minimize, maximize and close the window
|
||||
ConcentrationConstants.LOGGER.info("Trying to add title bar back");
|
||||
GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_DECORATED, GLFW.GLFW_TRUE);
|
||||
finalMonitor = 0L;
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to use cached value to resize the window");
|
||||
|
||||
// Make sure that Concentration has cached position and size, because position size won't be cached when the game starting in fullscreen mode
|
||||
finalWidth = ConcentrationFabricCaching.cachedSize ? ConcentrationFabricCaching.cachedWidth : width;
|
||||
finalHeight = ConcentrationFabricCaching.cachedSize ? ConcentrationFabricCaching.cachedHeight : height;
|
||||
|
||||
// To make sure that even starting with fullscreen mode can also make the window stay at the current monitor
|
||||
// So I set two ways to ensure the position
|
||||
if (ConcentrationFabricCaching.cachedPos) {
|
||||
// If Concentration cached the pos, use the cached value
|
||||
finalX = ConcentrationFabricCaching.cachedX;
|
||||
finalY = ConcentrationFabricCaching.cachedY;
|
||||
} else if (ConcentrationFabricCaching.lastMonitor != -1) {
|
||||
// or else maybe the game started with fullscreen mode, so I don't need to care about the size
|
||||
// only need to make sure that the position is in the correct monitor
|
||||
Monitor monitorInstance = accessor.getScreenManager().getMonitor(ConcentrationFabricCaching.lastMonitor);
|
||||
VideoMode videoMode = monitorInstance.getCurrentMode();
|
||||
Monitor lastMonitor = accessor.getScreenManager().getMonitor(ConcentrationFabricCaching.lastMonitor);
|
||||
VideoMode videoMode = lastMonitor.getCurrentMode();
|
||||
finalX = (videoMode.getWidth() - finalWidth) / 2;
|
||||
finalY = (videoMode.getHeight() - finalHeight) / 2;
|
||||
} else {
|
||||
// if both value are missed, use the default value to prevent errors
|
||||
finalX = xpos;
|
||||
finalY = ypos;
|
||||
}
|
||||
|
||||
// Unlock caching, because user can change the window size now
|
||||
ConcentrationFabricCaching.cacheSizeLock = false;
|
||||
ConcentrationConstants.LOGGER.info("Unlocked size caching");
|
||||
}
|
||||
@ -140,12 +126,52 @@ public class GLFWMixin {
|
||||
ConcentrationConstants.LOGGER.info("Window size: {}, {}, position: {}, {}", finalWidth, finalHeight, finalX, finalY);
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to resize and reposition the window");
|
||||
finalExecute(window, 0L, finalX, finalY, finalWidth, finalHeight, -1);
|
||||
finalExecute(window, finalMonitor, finalX, finalY, finalWidth, finalHeight, -1);
|
||||
|
||||
if (windowInstance.isFullscreen() && !(Config.isBorderless() && Config.isCustomized())) {
|
||||
GLFW.glfwSetWindowAttrib(windowInstance.getWindow(), 0x20006, 1);
|
||||
|
||||
long hWnd = GLFWNativeWin32.glfwGetWin32Window(windowInstance.getWindow());
|
||||
if (hWnd != 0) {
|
||||
User32.SetWindowPos(
|
||||
hWnd,
|
||||
User32.HWND_TOPMOST,
|
||||
windowInstance.getX(),
|
||||
windowInstance.getY(),
|
||||
windowInstance.getScreenWidth(),
|
||||
windowInstance.getScreenHeight(),
|
||||
1027
|
||||
);
|
||||
User32.SetWindowLongPtr(hWnd, -16, 0x960A0000L);
|
||||
User32.SetWindowLongPtr(hWnd, -20, 0x40010L);
|
||||
}
|
||||
|
||||
if (Config.isBorderless()) {
|
||||
GLFW.glfwSetWindowAttrib(windowInstance.getWindow(), 0x20006, 0);
|
||||
|
||||
if (System.getProperty("os.name").contains("Windows")) {
|
||||
if (hWnd != 0) {
|
||||
User32.SetWindowPos(
|
||||
hWnd,
|
||||
User32.HWND_NOTOPMOST,
|
||||
windowInstance.getX(),
|
||||
windowInstance.getY(),
|
||||
windowInstance.getScreenWidth(),
|
||||
windowInstance.getScreenHeight(),
|
||||
1027
|
||||
);
|
||||
User32.SetWindowLongPtr(hWnd, -16, 369229824);
|
||||
User32.SetWindowLongPtr(hWnd, -20, 34340880);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration End] =================");
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static void finalExecute(long window, long monitor, int xpos, int ypos, int width, int height, int refreshRate) {
|
||||
long __functionAddress = GLFW.Functions.SetWindowMonitor;
|
||||
if (CHECKS) {
|
||||
|
@ -6,9 +6,12 @@ import com.mojang.blaze3d.platform.VideoMode;
|
||||
import com.mojang.blaze3d.platform.Window;
|
||||
import net.deechael.concentration.ConcentrationConstants;
|
||||
import net.deechael.concentration.FullscreenMode;
|
||||
import net.deechael.concentration.config.Config;
|
||||
import net.deechael.concentration.fabric.ConcentrationFabricCaching;
|
||||
import net.deechael.concentration.fabric.config.ConcentrationConfigFabric;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWNativeWin32;
|
||||
import org.lwjgl.system.windows.User32;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -41,6 +44,10 @@ public abstract class WindowMixin {
|
||||
@Shadow
|
||||
private int height;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private long window;
|
||||
|
||||
@Inject(method = "onMove", at = @At("HEAD"))
|
||||
private void inject$onMove$head(long window, int x, int y, CallbackInfo ci) {
|
||||
if (!this.fullscreen) {
|
||||
@ -66,19 +73,21 @@ public abstract class WindowMixin {
|
||||
}
|
||||
|
||||
@Redirect(method = "setMode", at = @At(value = "INVOKE", remap = false, target = "Lorg/lwjgl/glfw/GLFW;glfwSetWindowMonitor(JJIIIII)V"))
|
||||
private void redirect$glfwSetWindowMonitor(long window, long monitor, int xpos, int ypos, int width, int height, int refreshRate) {
|
||||
private void redirect$glfwSetWindowMonitor(long window, long monitor, int xpos, int ypos, int ignored$width, int ignored$height, int ignored$refreshRate) {
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration Start] =================");
|
||||
ConcentrationConstants.LOGGER.info("Trying to modify window monitor");
|
||||
|
||||
// Monitor is 0 means the game is windowed mode, so the expression means if is toggling to fullscreen
|
||||
Monitor monitorInstance = this.screenManager.getMonitor(monitor);
|
||||
ConcentrationConstants.LOGGER.info("Current fullscreen monitor is {}", monitor);
|
||||
|
||||
if (monitor != 0L) {
|
||||
VideoMode currentMode = monitorInstance.getCurrentMode();
|
||||
ConcentrationConstants.LOGGER.info("Modifying window size limits");
|
||||
GLFW.glfwSetWindowSizeLimits(window, 0, 0, width, height);
|
||||
GLFW.glfwSetWindowSizeLimits(window, 0, 0, currentMode.getWidth(), currentMode.getHeight());
|
||||
}
|
||||
|
||||
// Because whether in fullscreen mode or windowed mode
|
||||
// The final step is same
|
||||
// So I extracted the value then execute the final step
|
||||
long finalMonitor;
|
||||
|
||||
int finalWidth;
|
||||
int finalHeight;
|
||||
|
||||
@ -86,90 +95,67 @@ public abstract class WindowMixin {
|
||||
int finalY;
|
||||
|
||||
if (this.fullscreen) {
|
||||
VideoMode currentMode = monitorInstance.getCurrentMode();
|
||||
|
||||
ConcentrationConfigFabric config = ConcentrationConfigFabric.getInstance();
|
||||
|
||||
// If the game started with fullscreen mode, when switching to windowed mode, it will be forced to move to the primary monitor
|
||||
// Though size and position isn't be set at initialization, but I think the window should be at the initial monitor
|
||||
// So save the monitor and use the monitor value when the size isn't cached
|
||||
ConcentrationFabricCaching.lastMonitor = monitor;
|
||||
|
||||
// Lock caching, because when switching back, the window will be once resized to the maximum value and the cache value will be wrong
|
||||
// Position won't be affected, so it doesn't need lock
|
||||
ConcentrationFabricCaching.cacheSizeLock = true;
|
||||
ConcentrationConstants.LOGGER.info("Locked size caching");
|
||||
|
||||
if (config.fullscreen == FullscreenMode.NATIVE) {
|
||||
ConcentrationConstants.LOGGER.info("Fullscreen mode is native, apply now!");
|
||||
GLFW.glfwSetWindowMonitor(window, monitor, xpos, ypos, width, height, -1);
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration End] =================");
|
||||
return;
|
||||
}
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to borderless fullscreen mode");
|
||||
|
||||
// Get the monitor the user want to use and get the relative position in the system
|
||||
// The monitor is always non-null because when switching fullscreen mode, there must be a monitor to put the window
|
||||
Monitor monitorInstance = this.screenManager.getMonitor(monitor);
|
||||
ConcentrationConstants.LOGGER.info("Current fullscreen monitor is {}", monitor);
|
||||
|
||||
// Remove the title bar to prevent that user can see the title bar if they put their monitors vertically connected
|
||||
GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_DECORATED, GLFW.GLFW_FALSE);
|
||||
ConcentrationConstants.LOGGER.info("Trying to remove the title bar");
|
||||
|
||||
if (ConcentrationConfigFabric.getInstance().customized) {
|
||||
ConcentrationConstants.LOGGER.info("Customization enabled, so replace the fullscreen size with customized size");
|
||||
finalX = config.x + (config.related ? monitorInstance.getX() : 0);
|
||||
finalY = config.y - (config.height == height ? 1 : 0) + (config.related ? monitorInstance.getY() : 0);
|
||||
finalWidth = config.width;
|
||||
finalHeight = config.height + (config.height == height ? 1 : 0);
|
||||
} else {
|
||||
// If we make the window not decorated and set the window size exactly the same with the screen size, it will become native fullscreen mode
|
||||
// to prevent this, I enlarge the height by 1 pixel and move up the window by 1 pixel which won't affect anything (unless you have a screen
|
||||
// which is added above the monitor which holds the game) and will have a good experience
|
||||
// Actually this is a little bit dirty, needs to find a better way to solve it
|
||||
ConcentrationConstants.LOGGER.info("Fullscreen mode is native");
|
||||
finalMonitor = monitor;
|
||||
finalX = monitorInstance.getX();
|
||||
finalY = monitorInstance.getY() - 1;
|
||||
finalWidth = width;
|
||||
finalHeight = height + 1;
|
||||
}
|
||||
finalY = monitorInstance.getY();
|
||||
finalWidth = currentMode.getWidth();
|
||||
finalHeight = currentMode.getHeight();
|
||||
} else {
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to borderless fullscreen mode");
|
||||
|
||||
this.x = finalX;
|
||||
this.y = finalY;
|
||||
this.width = finalWidth;
|
||||
this.height = finalHeight;
|
||||
/*if (ConcentrationConfigFabric.getInstance().customized) {
|
||||
GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_DECORATED, GLFW.GLFW_FALSE);
|
||||
finalMonitor = 0L;
|
||||
ConcentrationConstants.LOGGER.info("Customization enabled, so replace the fullscreen size with customized size");
|
||||
finalX = config.x + (config.related ? monitorInstance.getX() : 0);
|
||||
finalY = config.y - (config.height == height ? 1 : 0) + (config.related ? monitorInstance.getY() : 0);
|
||||
finalWidth = config.width;
|
||||
finalHeight = config.height + (config.height == height ? 1 : 0);
|
||||
} else */
|
||||
{
|
||||
finalMonitor = monitor;
|
||||
finalX = monitorInstance.getX();
|
||||
finalY = monitorInstance.getY();
|
||||
finalWidth = currentMode.getWidth();
|
||||
finalHeight = currentMode.getHeight();
|
||||
}
|
||||
this.x = finalX;
|
||||
this.y = finalY;
|
||||
this.width = finalWidth;
|
||||
this.height = finalHeight;
|
||||
}
|
||||
} else {
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to windowed mode");
|
||||
|
||||
// Re-add the title bar so user can move the window and minimize, maximize and close the window
|
||||
ConcentrationConstants.LOGGER.info("Trying to add title bar back");
|
||||
GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_DECORATED, GLFW.GLFW_TRUE);
|
||||
finalMonitor = 0L;
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to use cached value to resize the window");
|
||||
|
||||
// Make sure that Concentration has cached position and size, because position size won't be cached when the game starting in fullscreen mode
|
||||
finalWidth = ConcentrationFabricCaching.cachedSize ? ConcentrationFabricCaching.cachedWidth : width;
|
||||
finalHeight = ConcentrationFabricCaching.cachedSize ? ConcentrationFabricCaching.cachedHeight : height;
|
||||
|
||||
// To make sure that even starting with fullscreen mode can also make the window stay at the current monitor
|
||||
// So I set two ways to ensure the position
|
||||
if (ConcentrationFabricCaching.cachedPos) {
|
||||
// If Concentration cached the pos, use the cached value
|
||||
finalX = ConcentrationFabricCaching.cachedX;
|
||||
finalY = ConcentrationFabricCaching.cachedY;
|
||||
} else if (ConcentrationFabricCaching.lastMonitor != -1) {
|
||||
// or else maybe the game started with fullscreen mode, so I don't need to care about the size
|
||||
// only need to make sure that the position is in the correct monitor
|
||||
Monitor monitorInstance = this.screenManager.getMonitor(ConcentrationFabricCaching.lastMonitor);
|
||||
VideoMode videoMode = monitorInstance.getCurrentMode();
|
||||
} else if (ConcentrationFabricCaching.lastMonitor != -1 && this.screenManager.getMonitor(ConcentrationFabricCaching.lastMonitor) != null) {
|
||||
Monitor lastMonitor = this.screenManager.getMonitor(ConcentrationFabricCaching.lastMonitor);
|
||||
VideoMode videoMode = lastMonitor.getCurrentMode();
|
||||
finalX = (videoMode.getWidth() - finalWidth) / 2;
|
||||
finalY = (videoMode.getHeight() - finalHeight) / 2;
|
||||
} else {
|
||||
// if both value are missed, use the default value to prevent errors
|
||||
finalX = xpos;
|
||||
finalY = ypos;
|
||||
}
|
||||
|
||||
// Unlock caching, because user can change the window size now
|
||||
ConcentrationFabricCaching.cacheSizeLock = false;
|
||||
ConcentrationConstants.LOGGER.info("Unlocked size caching");
|
||||
}
|
||||
@ -177,14 +163,32 @@ public abstract class WindowMixin {
|
||||
ConcentrationConstants.LOGGER.info("Window size: {}, {}, position: {}, {}", finalWidth, finalHeight, finalX, finalY);
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to resize and reposition the window");
|
||||
GLFW.glfwSetWindowMonitor(window, 0L, finalX, finalY, finalWidth, finalHeight, -1);
|
||||
GLFW.glfwSetWindowMonitor(window, finalMonitor, finalX, finalY, finalWidth, finalHeight, -1);
|
||||
|
||||
if (this.fullscreen && !(Config.isBorderless() && Config.isCustomized())) {
|
||||
GLFW.glfwSetWindowAttrib(this.window, 0x20006, 1);
|
||||
|
||||
long hWnd = GLFWNativeWin32.glfwGetWin32Window(this.window);
|
||||
if (hWnd != 0) {
|
||||
User32.SetWindowPos(hWnd, User32.HWND_TOPMOST, this.x, this.y, this.width, this.height, 1027);
|
||||
User32.SetWindowLongPtr(hWnd, -16, 0x960A0000L);
|
||||
User32.SetWindowLongPtr(hWnd, -20, 0x40010L);
|
||||
}
|
||||
|
||||
if (Config.isBorderless()) {
|
||||
GLFW.glfwSetWindowAttrib(this.window, 0x20006, 0);
|
||||
|
||||
if (System.getProperty("os.name").contains("Windows")) {
|
||||
if (hWnd != 0) {
|
||||
User32.SetWindowPos(hWnd, User32.HWND_NOTOPMOST, this.x, this.y, this.width, this.height, 1027);
|
||||
User32.SetWindowLongPtr(hWnd, -16, 369229824);
|
||||
User32.SetWindowLongPtr(hWnd, -20, 34340880);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration End] =================");
|
||||
}
|
||||
|
||||
@Redirect(method = "setMode", at = @At(value = "INVOKE", remap = false, target = "Lorg/lwjgl/glfw/GLFW;glfwGetWindowMonitor(J)J"))
|
||||
private long redirect$glfwGetWindowMonitor(long window) {
|
||||
return 1L;
|
||||
}
|
||||
|
||||
}
|
@ -71,6 +71,11 @@ public final class ConcentrationConfigForge implements Config {
|
||||
private ConcentrationConfigForge() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean customized() {
|
||||
return CUSTOMIZED.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FullscreenMode getFullscreenMode() {
|
||||
return FULLSCREEN.get();
|
||||
|
@ -6,8 +6,11 @@ import com.mojang.blaze3d.platform.VideoMode;
|
||||
import com.mojang.blaze3d.platform.Window;
|
||||
import net.deechael.concentration.ConcentrationConstants;
|
||||
import net.deechael.concentration.FullscreenMode;
|
||||
import net.deechael.concentration.config.Config;
|
||||
import net.deechael.concentration.forge.config.ConcentrationConfigForge;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWNativeWin32;
|
||||
import org.lwjgl.system.windows.User32;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -41,6 +44,9 @@ public abstract class WindowMixin {
|
||||
@Shadow
|
||||
private int height;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private long window;
|
||||
@Unique
|
||||
private long concentration$lastMonitor = -1;
|
||||
|
||||
@ -89,15 +95,17 @@ public abstract class WindowMixin {
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration Start] =================");
|
||||
ConcentrationConstants.LOGGER.info("Trying to modify window monitor");
|
||||
|
||||
// Monitor is 0 means the game is windowed mode, so the expression means if is toggling to fullscreen
|
||||
Monitor monitorInstance = this.screenManager.getMonitor(monitor);
|
||||
ConcentrationConstants.LOGGER.info("Current fullscreen monitor is {}", monitor);
|
||||
|
||||
if (monitor != 0L) {
|
||||
VideoMode currentMode = monitorInstance.getCurrentMode();
|
||||
ConcentrationConstants.LOGGER.info("Modifying window size limits");
|
||||
GLFW.glfwSetWindowSizeLimits(window, 0, 0, width, height);
|
||||
GLFW.glfwSetWindowSizeLimits(window, 0, 0, currentMode.getWidth(), currentMode.getHeight());
|
||||
}
|
||||
|
||||
// Because whether in fullscreen mode or windowed mode
|
||||
// The final step is same
|
||||
// So I extracted the value then execute the final step
|
||||
long finalMonitor;
|
||||
|
||||
int finalWidth;
|
||||
int finalHeight;
|
||||
|
||||
@ -105,97 +113,71 @@ public abstract class WindowMixin {
|
||||
int finalY;
|
||||
|
||||
if (this.fullscreen) {
|
||||
VideoMode currentMode = monitorInstance.getCurrentMode();
|
||||
ConcentrationConfigForge.ensureLoaded();
|
||||
|
||||
// If the game started with fullscreen mode, when switching to windowed mode, it will be forced to move to the primary monitor
|
||||
// Though size and position isn't be set at initialization, but I think the window should be at the initial monitor
|
||||
// So save the monitor and use the monitor value when the size isn't cached
|
||||
this.concentration$lastMonitor = monitor;
|
||||
|
||||
// Lock caching, because when switching back, the window will be once resized to the maximum value and the cache value will be wrong
|
||||
// Position won't be affected, so it doesn't need lock
|
||||
this.concentration$cacheSizeLock = true;
|
||||
ConcentrationConstants.LOGGER.info("Locked size caching");
|
||||
|
||||
if (ConcentrationConfigForge.FULLSCREEN.get() == FullscreenMode.NATIVE) {
|
||||
ConcentrationConstants.LOGGER.info("Fullscreen mode is native, apply now!");
|
||||
GLFW.glfwSetWindowMonitor(window, monitor, xpos, ypos, width, height, -1);
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration End] =================");
|
||||
return;
|
||||
}
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to borderless fullscreen mode");
|
||||
|
||||
// Get the monitor the user want to use and get the relative position in the system
|
||||
// The monitor is always non-null because when switching fullscreen mode, there must be a monitor to put the window
|
||||
Monitor monitorInstance = this.screenManager.getMonitor(monitor);
|
||||
ConcentrationConstants.LOGGER.info("Current fullscreen monitor is {}", monitor);
|
||||
|
||||
// Remove the title bar to prevent that user can see the title bar if they put their monitors vertically connected
|
||||
GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_DECORATED, GLFW.GLFW_FALSE);
|
||||
ConcentrationConstants.LOGGER.info("Trying to remove the title bar");
|
||||
|
||||
if (ConcentrationConfigForge.CUSTOMIZED.get()) {
|
||||
final boolean related = ConcentrationConfigForge.RELATED.get();
|
||||
final int configX = ConcentrationConfigForge.X.get();
|
||||
final int configY = ConcentrationConfigForge.Y.get();
|
||||
final int configWidth = ConcentrationConfigForge.WIDTH.get();
|
||||
final int configHeight = ConcentrationConfigForge.HEIGHT.get();
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Customization enabled, so replace the fullscreen size with customized size");
|
||||
|
||||
finalX = configX + (related ? monitorInstance.getX() : 0);
|
||||
finalY = configY - (configHeight == height ? 1 : 0) + (related ? monitorInstance.getY() : 0);
|
||||
finalWidth = configWidth;
|
||||
finalHeight = configHeight + (configHeight == height ? 1 : 0);
|
||||
} else {
|
||||
// If we make the window not decorated and set the window size exactly the same with the screen size, it will become native fullscreen mode
|
||||
// to prevent this, I enlarge the height by 1 pixel and move up the window by 1 pixel which won't affect anything (unless you have a screen
|
||||
// which is added above the monitor which holds the game) and will have a good experience
|
||||
// Actually this is a little bit dirty, needs to find a better way to solve it
|
||||
finalMonitor = monitor;
|
||||
finalX = monitorInstance.getX();
|
||||
finalY = monitorInstance.getY() - 1;
|
||||
finalWidth = width;
|
||||
finalHeight = height + 1;
|
||||
}
|
||||
finalY = monitorInstance.getY();
|
||||
finalWidth = currentMode.getWidth();
|
||||
finalHeight = currentMode.getHeight();
|
||||
} else {
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to borderless fullscreen mode");
|
||||
|
||||
this.x = finalX;
|
||||
this.y = finalY;
|
||||
this.width = finalWidth;
|
||||
this.height = finalHeight;
|
||||
/*if (ConcentrationConfigForge.CUSTOMIZED.get()) {
|
||||
final boolean related = ConcentrationConfigForge.RELATED.get();
|
||||
final int configX = ConcentrationConfigForge.X.get();
|
||||
final int configY = ConcentrationConfigForge.Y.get();
|
||||
final int configWidth = ConcentrationConfigForge.WIDTH.get();
|
||||
final int configHeight = ConcentrationConfigForge.HEIGHT.get();
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Customization enabled, so replace the fullscreen size with customized size");
|
||||
|
||||
finalX = configX + (related ? monitorInstance.getX() : 0);
|
||||
finalY = configY - (configHeight == height ? 1 : 0) + (related ? monitorInstance.getY() : 0);
|
||||
finalWidth = configWidth;
|
||||
finalHeight = configHeight + (configHeight == height ? 1 : 0);
|
||||
} else */
|
||||
{
|
||||
finalMonitor = monitor;
|
||||
finalX = monitorInstance.getX();
|
||||
finalY = monitorInstance.getY();
|
||||
finalWidth = currentMode.getWidth();
|
||||
finalHeight = currentMode.getHeight();
|
||||
}
|
||||
this.x = finalX;
|
||||
this.y = finalY;
|
||||
this.width = finalWidth;
|
||||
this.height = finalHeight;
|
||||
}
|
||||
} else {
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to windowed mode");
|
||||
|
||||
// Re-add the title bar so user can move the window and minimize, maximize and close the window
|
||||
ConcentrationConstants.LOGGER.info("Trying to add title bar back");
|
||||
GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_DECORATED, GLFW.GLFW_TRUE);
|
||||
finalMonitor = 0L;
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to use cached value to resize the window");
|
||||
|
||||
// Make sure that Concentration has cached position and size, because position size won't be cached when the game starting in fullscreen mode
|
||||
finalWidth = concentration$cachedSize ? concentration$cachedWidth : width;
|
||||
finalHeight = concentration$cachedSize ? concentration$cachedHeight : height;
|
||||
|
||||
// To make sure that even starting with fullscreen mode can also make the window stay at the current monitor
|
||||
// So I set two ways to ensure the position
|
||||
if (this.concentration$cachedPos) {
|
||||
// If Concentration cached the pos, use the cached value
|
||||
finalX = concentration$cachedX;
|
||||
finalY = concentration$cachedY;
|
||||
} else if (this.concentration$lastMonitor != -1) {
|
||||
// or else maybe the game started with fullscreen mode, so I don't need to care about the size
|
||||
// only need to make sure that the position is in the correct monitor
|
||||
Monitor monitorInstance = this.screenManager.getMonitor(this.concentration$lastMonitor);
|
||||
VideoMode videoMode = monitorInstance.getCurrentMode();
|
||||
} else if (this.concentration$lastMonitor != -1 && this.screenManager.getMonitor(this.concentration$lastMonitor) != null) {
|
||||
Monitor lastMonitor = this.screenManager.getMonitor(this.concentration$lastMonitor);
|
||||
VideoMode videoMode = lastMonitor.getCurrentMode();
|
||||
finalX = (videoMode.getWidth() - finalWidth) / 2;
|
||||
finalY = (videoMode.getHeight() - finalHeight) / 2;
|
||||
} else {
|
||||
// if both value are missed, use the default value to prevent errors
|
||||
finalX = xpos;
|
||||
finalY = ypos;
|
||||
}
|
||||
|
||||
// Unlock caching, because user can change the window size now
|
||||
this.concentration$cacheSizeLock = false;
|
||||
ConcentrationConstants.LOGGER.info("Unlocked size caching");
|
||||
}
|
||||
@ -203,14 +185,32 @@ public abstract class WindowMixin {
|
||||
ConcentrationConstants.LOGGER.info("Window size: {}, {}, position: {}, {}", finalWidth, finalHeight, finalX, finalY);
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to resize and reposition the window");
|
||||
GLFW.glfwSetWindowMonitor(window, 0L, finalX, finalY, finalWidth, finalHeight, -1);
|
||||
GLFW.glfwSetWindowMonitor(window, finalMonitor, finalX, finalY, finalWidth, finalHeight, -1);
|
||||
|
||||
if (this.fullscreen && !(Config.isBorderless() && Config.isCustomized())) {
|
||||
GLFW.glfwSetWindowAttrib(this.window, 0x20006, 1);
|
||||
|
||||
long hWnd = GLFWNativeWin32.glfwGetWin32Window(this.window);
|
||||
if (hWnd != 0) {
|
||||
User32.SetWindowPos(hWnd, User32.HWND_TOPMOST, this.x, this.y, this.width, this.height, 1027);
|
||||
User32.SetWindowLongPtr(hWnd, -16, 0x960A0000L);
|
||||
User32.SetWindowLongPtr(hWnd, -20, 0x40010L);
|
||||
}
|
||||
|
||||
if (Config.isBorderless()) {
|
||||
GLFW.glfwSetWindowAttrib(this.window, 0x20006, 0);
|
||||
|
||||
if (System.getProperty("os.name").contains("Windows")) {
|
||||
if (hWnd != 0) {
|
||||
User32.SetWindowPos(hWnd, User32.HWND_NOTOPMOST, this.x, this.y, this.width, this.height, 1027);
|
||||
User32.SetWindowLongPtr(hWnd, -16, 369229824);
|
||||
User32.SetWindowLongPtr(hWnd, -20, 34340880);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration End] =================");
|
||||
}
|
||||
|
||||
@Redirect(method = "setMode", at = @At(value = "INVOKE", remap = false, target = "Lorg/lwjgl/glfw/GLFW;glfwGetWindowMonitor(J)J"))
|
||||
private long redirect$glfwGetWindowMonitor(long window) {
|
||||
return 1L;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
version=2.0.1
|
||||
version=2.1.0
|
||||
group=net.deechael.concentration
|
||||
java_version=21
|
||||
|
||||
|
@ -5,7 +5,6 @@ import net.deechael.concentration.ConcentrationConstants;
|
||||
import net.deechael.concentration.config.ConcentrationConfigScreen;
|
||||
import net.deechael.concentration.neoforge.compat.EmbeddiumCompat;
|
||||
import net.deechael.concentration.neoforge.config.ConcentrationConfigNeoForge;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.OptionInstance;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
@ -26,8 +26,8 @@ public class ConcentrationNeoForgeMixinPlugin implements IMixinConfigPlugin {
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||
return mixinClassName.equals("net.deechael.concentration.fabric.mixin.WindowMixin")
|
||||
|| (!ModList.get().isLoaded("embeddium") && checkSodium(mixinClassName));
|
||||
return mixinClassName.equals("net.deechael.concentration.fabric.mixin.WindowMixin")
|
||||
|| (!ModList.get().isLoaded("embeddium") && checkSodium(mixinClassName));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,15 +1,9 @@
|
||||
package net.deechael.concentration.neoforge.config;
|
||||
|
||||
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
||||
import com.electronwill.nightconfig.core.io.WritingMode;
|
||||
import net.deechael.concentration.ConcentrationConstants;
|
||||
import net.deechael.concentration.FullscreenMode;
|
||||
import net.deechael.concentration.config.Config;
|
||||
import net.neoforged.fml.loading.FMLPaths;
|
||||
import net.neoforged.neoforge.common.ModConfigSpec;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public final class ConcentrationConfigNeoForge implements Config {
|
||||
|
||||
public final static ConcentrationConfigNeoForge INSTANCE = new ConcentrationConfigNeoForge();
|
||||
@ -71,6 +65,11 @@ public final class ConcentrationConfigNeoForge implements Config {
|
||||
private ConcentrationConfigNeoForge() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean customized() {
|
||||
return CUSTOMIZED.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FullscreenMode getFullscreenMode() {
|
||||
return FULLSCREEN.get();
|
||||
|
@ -6,8 +6,11 @@ import com.mojang.blaze3d.platform.VideoMode;
|
||||
import com.mojang.blaze3d.platform.Window;
|
||||
import net.deechael.concentration.ConcentrationConstants;
|
||||
import net.deechael.concentration.FullscreenMode;
|
||||
import net.deechael.concentration.config.Config;
|
||||
import net.deechael.concentration.neoforge.config.ConcentrationConfigNeoForge;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWNativeWin32;
|
||||
import org.lwjgl.system.windows.User32;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -41,6 +44,9 @@ public abstract class WindowMixin {
|
||||
@Shadow
|
||||
private int height;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private long window;
|
||||
@Unique
|
||||
private long concentration$lastMonitor = -1;
|
||||
|
||||
@ -89,15 +95,17 @@ public abstract class WindowMixin {
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration Start] =================");
|
||||
ConcentrationConstants.LOGGER.info("Trying to modify window monitor");
|
||||
|
||||
// Monitor is 0 means the game is windowed mode, so the expression means if is toggling to fullscreen
|
||||
Monitor monitorInstance = this.screenManager.getMonitor(monitor);
|
||||
ConcentrationConstants.LOGGER.info("Current fullscreen monitor is {}", monitor);
|
||||
|
||||
if (monitor != 0L) {
|
||||
VideoMode currentMode = monitorInstance.getCurrentMode();
|
||||
ConcentrationConstants.LOGGER.info("Modifying window size limits");
|
||||
GLFW.glfwSetWindowSizeLimits(window, 0, 0, width, height);
|
||||
GLFW.glfwSetWindowSizeLimits(window, 0, 0, currentMode.getWidth(), currentMode.getHeight());
|
||||
}
|
||||
|
||||
// Because whether in fullscreen mode or windowed mode
|
||||
// The final step is same
|
||||
// So I extracted the value then execute the final step
|
||||
long finalMonitor;
|
||||
|
||||
int finalWidth;
|
||||
int finalHeight;
|
||||
|
||||
@ -105,97 +113,71 @@ public abstract class WindowMixin {
|
||||
int finalY;
|
||||
|
||||
if (this.fullscreen) {
|
||||
VideoMode currentMode = monitorInstance.getCurrentMode();
|
||||
ConcentrationConfigNeoForge.ensureLoaded();
|
||||
|
||||
// If the game started with fullscreen mode, when switching to windowed mode, it will be forced to move to the primary monitor
|
||||
// Though size and position isn't be set at initialization, but I think the window should be at the initial monitor
|
||||
// So save the monitor and use the monitor value when the size isn't cached
|
||||
this.concentration$lastMonitor = monitor;
|
||||
|
||||
// Lock caching, because when switching back, the window will be once resized to the maximum value and the cache value will be wrong
|
||||
// Position won't be affected, so it doesn't need lock
|
||||
this.concentration$cacheSizeLock = true;
|
||||
ConcentrationConstants.LOGGER.info("Locked size caching");
|
||||
|
||||
if (ConcentrationConfigNeoForge.FULLSCREEN.get() == FullscreenMode.NATIVE) {
|
||||
ConcentrationConstants.LOGGER.info("Fullscreen mode is native, apply now!");
|
||||
GLFW.glfwSetWindowMonitor(window, monitor, xpos, ypos, width, height, -1);
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration End] =================");
|
||||
return;
|
||||
}
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to borderless fullscreen mode");
|
||||
|
||||
// Get the monitor the user want to use and get the relative position in the system
|
||||
// The monitor is always non-null because when switching fullscreen mode, there must be a monitor to put the window
|
||||
Monitor monitorInstance = this.screenManager.getMonitor(monitor);
|
||||
ConcentrationConstants.LOGGER.info("Current fullscreen monitor is {}", monitor);
|
||||
|
||||
// Remove the title bar to prevent that user can see the title bar if they put their monitors vertically connected
|
||||
GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_DECORATED, GLFW.GLFW_FALSE);
|
||||
ConcentrationConstants.LOGGER.info("Trying to remove the title bar");
|
||||
|
||||
if (ConcentrationConfigNeoForge.CUSTOMIZED.get()) {
|
||||
final boolean related = ConcentrationConfigNeoForge.RELATED.get();
|
||||
final int configX = ConcentrationConfigNeoForge.X.get();
|
||||
final int configY = ConcentrationConfigNeoForge.Y.get();
|
||||
final int configWidth = ConcentrationConfigNeoForge.WIDTH.get();
|
||||
final int configHeight = ConcentrationConfigNeoForge.HEIGHT.get();
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Customization enabled, so replace the fullscreen size with customized size");
|
||||
|
||||
finalX = configX + (related ? monitorInstance.getX() : 0);
|
||||
finalY = configY - (configHeight == height ? 1 : 0) + (related ? monitorInstance.getY() : 0);
|
||||
finalWidth = configWidth;
|
||||
finalHeight = configHeight + (configHeight == height ? 1 : 0);
|
||||
} else {
|
||||
// If we make the window not decorated and set the window size exactly the same with the screen size, it will become native fullscreen mode
|
||||
// to prevent this, I enlarge the height by 1 pixel and move up the window by 1 pixel which won't affect anything (unless you have a screen
|
||||
// which is added above the monitor which holds the game) and will have a good experience
|
||||
// Actually this is a little bit dirty, needs to find a better way to solve it
|
||||
finalMonitor = monitor;
|
||||
finalX = monitorInstance.getX();
|
||||
finalY = monitorInstance.getY() - 1;
|
||||
finalWidth = width;
|
||||
finalHeight = height + 1;
|
||||
}
|
||||
finalY = monitorInstance.getY();
|
||||
finalWidth = currentMode.getWidth();
|
||||
finalHeight = currentMode.getHeight();
|
||||
} else {
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to borderless fullscreen mode");
|
||||
|
||||
this.x = finalX;
|
||||
this.y = finalY;
|
||||
this.width = finalWidth;
|
||||
this.height = finalHeight;
|
||||
/*if (ConcentrationConfigForge.CUSTOMIZED.get()) {
|
||||
final boolean related = ConcentrationConfigForge.RELATED.get();
|
||||
final int configX = ConcentrationConfigForge.X.get();
|
||||
final int configY = ConcentrationConfigForge.Y.get();
|
||||
final int configWidth = ConcentrationConfigForge.WIDTH.get();
|
||||
final int configHeight = ConcentrationConfigForge.HEIGHT.get();
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Customization enabled, so replace the fullscreen size with customized size");
|
||||
|
||||
finalX = configX + (related ? monitorInstance.getX() : 0);
|
||||
finalY = configY - (configHeight == height ? 1 : 0) + (related ? monitorInstance.getY() : 0);
|
||||
finalWidth = configWidth;
|
||||
finalHeight = configHeight + (configHeight == height ? 1 : 0);
|
||||
} else */
|
||||
{
|
||||
finalMonitor = monitor;
|
||||
finalX = monitorInstance.getX();
|
||||
finalY = monitorInstance.getY();
|
||||
finalWidth = currentMode.getWidth();
|
||||
finalHeight = currentMode.getHeight();
|
||||
}
|
||||
this.x = finalX;
|
||||
this.y = finalY;
|
||||
this.width = finalWidth;
|
||||
this.height = finalHeight;
|
||||
}
|
||||
} else {
|
||||
ConcentrationConstants.LOGGER.info("Trying to switch to windowed mode");
|
||||
|
||||
// Re-add the title bar so user can move the window and minimize, maximize and close the window
|
||||
ConcentrationConstants.LOGGER.info("Trying to add title bar back");
|
||||
GLFW.glfwSetWindowAttrib(window, GLFW.GLFW_DECORATED, GLFW.GLFW_TRUE);
|
||||
finalMonitor = 0L;
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to use cached value to resize the window");
|
||||
|
||||
// Make sure that Concentration has cached position and size, because position size won't be cached when the game starting in fullscreen mode
|
||||
finalWidth = concentration$cachedSize ? concentration$cachedWidth : width;
|
||||
finalHeight = concentration$cachedSize ? concentration$cachedHeight : height;
|
||||
|
||||
// To make sure that even starting with fullscreen mode can also make the window stay at the current monitor
|
||||
// So I set two ways to ensure the position
|
||||
if (this.concentration$cachedPos) {
|
||||
// If Concentration cached the pos, use the cached value
|
||||
finalX = concentration$cachedX;
|
||||
finalY = concentration$cachedY;
|
||||
} else if (this.concentration$lastMonitor != -1) {
|
||||
// or else maybe the game started with fullscreen mode, so I don't need to care about the size
|
||||
// only need to make sure that the position is in the correct monitor
|
||||
Monitor monitorInstance = this.screenManager.getMonitor(this.concentration$lastMonitor);
|
||||
VideoMode videoMode = monitorInstance.getCurrentMode();
|
||||
} else if (this.concentration$lastMonitor != -1 && this.screenManager.getMonitor(this.concentration$lastMonitor) != null) {
|
||||
Monitor lastMonitor = this.screenManager.getMonitor(this.concentration$lastMonitor);
|
||||
VideoMode videoMode = lastMonitor.getCurrentMode();
|
||||
finalX = (videoMode.getWidth() - finalWidth) / 2;
|
||||
finalY = (videoMode.getHeight() - finalHeight) / 2;
|
||||
} else {
|
||||
// if both value are missed, use the default value to prevent errors
|
||||
finalX = xpos;
|
||||
finalY = ypos;
|
||||
}
|
||||
|
||||
// Unlock caching, because user can change the window size now
|
||||
this.concentration$cacheSizeLock = false;
|
||||
ConcentrationConstants.LOGGER.info("Unlocked size caching");
|
||||
}
|
||||
@ -203,14 +185,32 @@ public abstract class WindowMixin {
|
||||
ConcentrationConstants.LOGGER.info("Window size: {}, {}, position: {}, {}", finalWidth, finalHeight, finalX, finalY);
|
||||
|
||||
ConcentrationConstants.LOGGER.info("Trying to resize and reposition the window");
|
||||
GLFW.glfwSetWindowMonitor(window, 0L, finalX, finalY, finalWidth, finalHeight, -1);
|
||||
GLFW.glfwSetWindowMonitor(window, finalMonitor, finalX, finalY, finalWidth, finalHeight, -1);
|
||||
|
||||
if (this.fullscreen && !(Config.isBorderless() && Config.isCustomized())) {
|
||||
GLFW.glfwSetWindowAttrib(this.window, 0x20006, 1);
|
||||
|
||||
long hWnd = GLFWNativeWin32.glfwGetWin32Window(this.window);
|
||||
if (hWnd != 0) {
|
||||
User32.SetWindowPos(hWnd, User32.HWND_TOPMOST, this.x, this.y, this.width, this.height, 1027);
|
||||
User32.SetWindowLongPtr(hWnd, -16, 0x960A0000L);
|
||||
User32.SetWindowLongPtr(hWnd, -20, 0x40010L);
|
||||
}
|
||||
|
||||
if (Config.isBorderless()) {
|
||||
GLFW.glfwSetWindowAttrib(this.window, 0x20006, 0);
|
||||
|
||||
if (System.getProperty("os.name").contains("Windows")) {
|
||||
if (hWnd != 0) {
|
||||
User32.SetWindowPos(hWnd, User32.HWND_NOTOPMOST, this.x, this.y, this.width, this.height, 1027);
|
||||
User32.SetWindowLongPtr(hWnd, -16, 369229824);
|
||||
User32.SetWindowLongPtr(hWnd, -20, 34340880);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConcentrationConstants.LOGGER.info("================= [Concentration End] =================");
|
||||
}
|
||||
|
||||
@Redirect(method = "setMode", at = @At(value = "INVOKE", remap = false, target = "Lorg/lwjgl/glfw/GLFW;glfwGetWindowMonitor(J)J"))
|
||||
private long redirect$glfwGetWindowMonitor(long window) {
|
||||
return 1L;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user