Replace incorrect GraphicsEnvironment.maximumWindowBounds (#10117)

This commit is contained in:
SomeTroglodyte 2023-09-18 08:46:44 +02:00 committed by GitHub
parent a3d431155d
commit 29e32303ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 5 deletions

View File

@ -1,6 +1,7 @@
package com.unciv.app.desktop
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Graphics.Monitor
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Graphics
@ -8,7 +9,11 @@ import com.unciv.models.metadata.GameSettings
import com.unciv.models.translations.tr
import com.unciv.utils.PlatformDisplay
import com.unciv.utils.ScreenMode
import java.awt.GraphicsConfiguration
import java.awt.GraphicsDevice
import java.awt.GraphicsEnvironment
import java.awt.Toolkit
import kotlin.math.roundToInt
enum class DesktopScreenMode : ScreenMode {
@ -49,8 +54,8 @@ enum class DesktopScreenMode : ScreenMode {
protected fun setWindowedMode(settings: GameSettings): Boolean {
// Calling AWT after Gdx is fully initialized seems icky, but seems to have no side effects
// Found no equivalent in Gdx - available _desktop_ surface without taskbars etc
val graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment()
val maximumWindowBounds = graphicsEnvironment.maximumWindowBounds
// *for the primary monitor* - no saving window sizes that span over several monitors
val maximumWindowBounds = getMaximumWindowBounds()
// Make sure an inappropriate saved size doesn't make the window unusable
val width = settings.windowState.width.coerceIn(120, maximumWindowBounds.width)
@ -71,6 +76,49 @@ enum class DesktopScreenMode : ScreenMode {
operator fun get(id: Int) = values()[id]
private fun getWindow() = (Gdx.graphics as? Lwjgl3Graphics)?.window
/** Replacement for buggy `GraphicsEnvironment.maximumWindowBounds` */
// Notes: maximumWindowBounds seems to scale by the High DPI setting on Windows,
// and it always uses the default device. GraphicsConfiguration.getBounds() delivers x/y
// as true pixels, while width/height are similarly scaled. Toolkit.getScreenInsets
// delivers scaled values (observed - no documentation found).
internal fun getMaximumWindowBounds(
monitor: Monitor = Lwjgl3ApplicationConfiguration.getPrimaryMonitor()
): java.awt.Rectangle {
// Identify AWT equivalent to Gdx monitor
val graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment()
for (device in graphicsEnvironment.screenDevices) {
for (config in device.configurations) {
val bounds = config.bounds
if (bounds.x == monitor.virtualX && bounds.y == monitor.virtualY)
return getMaximumWindowBounds(device, config, bounds)
}
}
// Fallback should that fail (this is without insets)
val mode = Lwjgl3ApplicationConfiguration.getDisplayMode(monitor)
return java.awt.Rectangle(monitor.virtualX, monitor.virtualY, mode.width, mode.height)
}
private fun getMaximumWindowBounds(
device: GraphicsDevice,
config: GraphicsConfiguration,
bounds: java.awt.Rectangle
): java.awt.Rectangle {
val displayWidth = device.displayMode.width
val displayHeight = device.displayMode.height
val scalePercent = (displayWidth.toDouble() / bounds.width * 100).roundToInt() * 0.01
val insets = Toolkit.getDefaultToolkit().getScreenInsets(config)
val unscaledInsetLeft = (insets.left * scalePercent).roundToInt()
val unscaledInsetRight = (insets.right * scalePercent).roundToInt()
val unscaledInsetTop = (insets.top * scalePercent).roundToInt()
val unscaledInsetBottom = (insets.bottom * scalePercent).roundToInt()
return java.awt.Rectangle(
bounds.x + unscaledInsetLeft,
bounds.y + unscaledInsetTop,
displayWidth - unscaledInsetLeft - unscaledInsetRight,
displayHeight - unscaledInsetTop - unscaledInsetBottom
)
}
}
}

View File

@ -4,6 +4,7 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.glutils.HdpiMode
import com.unciv.app.desktop.DesktopScreenMode.Companion.getMaximumWindowBounds
import com.unciv.json.json
import com.unciv.logic.files.SETTINGS_FILE_NAME
import com.unciv.logic.files.UncivFiles
@ -13,7 +14,6 @@ import com.unciv.ui.components.Fonts
import com.unciv.ui.screens.basescreen.BaseScreen
import com.unciv.utils.Display
import com.unciv.utils.Log
import java.awt.GraphicsEnvironment
import kotlin.math.max
internal object DesktopLauncher {
@ -59,8 +59,7 @@ internal object DesktopLauncher {
if (settings.isFreshlyCreated) {
settings.screenSize = ScreenSize.Large // By default we guess that Desktops have larger screens
// LibGDX not yet configured, use regular java class
val graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment()
val maximumWindowBounds = graphicsEnvironment.maximumWindowBounds
val maximumWindowBounds = getMaximumWindowBounds()
settings.windowState = WindowState(
width = maximumWindowBounds.width,
height = maximumWindowBounds.height