Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix: Initial window size limits weren't properly applied
  • Loading branch information
anonl committed Apr 8, 2021
1 parent 150eb6a commit 9db0ddd
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 24 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
@@ -1,4 +1,7 @@

# v4.10.0
- fix: Initial window size limits are now properly applied when the window is (almost) larger than the screen.

# v4.9.6
- fix: File permissions were broken for Linux/Mac builds when building on a file system which doesn't support permissions (e.g. NTFS on Windows)

Expand Down
4 changes: 2 additions & 2 deletions desktop/build.gradle
Expand Up @@ -5,11 +5,11 @@ apply plugin: 'maven-publish'

dependencies {
api project(":nvlist-core")

implementation deps.gdx_desktop
implementation deps.jopt_simple
implementation deps.lsp4j_debug
implementation deps.lua_core

runtimeOnly deps.slf4j_desktop

testFixturesApi testFixtures(project(':nvlist-core'))
}
Expand Up @@ -4,6 +4,8 @@
import java.io.IOException;
import java.util.List;

import javax.annotation.CheckForNull;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -32,7 +34,7 @@ private DesktopGraphicsUtil() {
}

static void setWindowIcon(IFileSystem fileSystem) {
Lwjgl3Window window = getCurrentWindow();
Lwjgl3Window window = getCurrentWindow(Gdx.graphics);

// Try to load icons in various sizes
List<Pixmap> pixmaps = Lists.newArrayList();
Expand Down Expand Up @@ -74,10 +76,13 @@ static void setWindowIcon(IFileSystem fileSystem) {
}
}

private static Lwjgl3Window getCurrentWindow() {
@CheckForNull
private static Lwjgl3Window getCurrentWindow(Graphics graphics) {
if (!(graphics instanceof Lwjgl3Graphics)) {
return null;
}
// Oddly, the only public way to get a reference to the main window is through the graphics object...
Lwjgl3Graphics graphics = (Lwjgl3Graphics)Gdx.graphics;
return graphics.getWindow();
return ((Lwjgl3Graphics)Gdx.graphics).getWindow();
}

/**
Expand All @@ -86,26 +91,24 @@ private static Lwjgl3Window getCurrentWindow() {
public static Dim limitInitialWindowSize(Graphics graphics) {
if (graphics.isFullscreen()) {
// If fullscreen, we fill the entire screen already so nothing needs to be done
} else {
// Width/height of the window in physical pixels
int w = graphics.getBackBufferWidth();
int h = graphics.getBackBufferHeight();

// Limit window size so it fits inside the current monitor (with a margin for OS bars/decorations)
DisplayMode displayMode = graphics.getDisplayMode();
int maxW = displayMode.width - 100;
int maxH = displayMode.height - 150;

int dw = Math.min(0, maxW - w);
int dh = Math.min(0, maxH - h);
graphics.setWindowedMode(w + dw, h + dh);

// Also change the window's position so it's centered on its previous location
Lwjgl3Window window = getCurrentWindow();
window.setPosition(window.getPositionX() - dw / 2, window.getPositionY() - dh / 2);
return Dim.of(graphics.getBackBufferWidth(), graphics.getBackBufferHeight());
}

return Dim.of(graphics.getBackBufferWidth(), graphics.getBackBufferHeight());
// Width/height of the window in physical pixels
int w = graphics.getBackBufferWidth();
int h = graphics.getBackBufferHeight();

// Limit window size so it fits inside the current monitor (with a margin for OS bars/decorations)
DisplayMode displayMode = graphics.getDisplayMode();
int targetW = Math.min(w, displayMode.width - 100);
int targetH = Math.min(h, displayMode.height - 150);

float scale = Math.min(targetW / (float)w, targetH / (float)h);
targetW = Math.round(w * scale);
targetH = Math.round(h * scale);
graphics.setWindowedMode(targetW, targetH);

return Dim.of(targetW, targetH);
}

}
@@ -0,0 +1,46 @@
package nl.weeaboo.vn.desktop;

import org.junit.Assert;
import org.junit.Test;

import com.badlogic.gdx.backends.headless.mock.graphics.MockGraphics;

import nl.weeaboo.common.Dim;

public final class DesktopGraphicsUtilTest {

private static final Dim LARGE = Dim.of(1920, 1080);
private static final Dim MEDIUM = Dim.of(1280, 720);

@Test
public void testLimitWindowSize() {
assertLimitWindowSize(MEDIUM, LARGE, MEDIUM);

// Safety margins of 100px (horizontal) and 150px (vertical) are subtracted
// If the window is too large, it's proportionally resized within those limits
assertLimitWindowSize(MEDIUM, MEDIUM, Dim.of(1013, 570));

// Large has the same proportions as medium
assertLimitWindowSize(LARGE, MEDIUM, Dim.of(1013, 570));
}

private static void assertLimitWindowSize(Dim window, Dim screen, Dim expectedResult) {
Dim actual = DesktopGraphicsUtil.limitInitialWindowSize(new MockGraphics() {
@Override
public int getBackBufferWidth() {
return window.w;
}

@Override
public int getBackBufferHeight() {
return window.h;
}

@Override
public DisplayMode getDisplayMode() {
return new DisplayMode(screen.w, screen.h, 60, 24) { };
}
});
Assert.assertEquals(expectedResult, actual);
}
}

0 comments on commit 9db0ddd

Please sign in to comment.