Desktop starting size fix (#8973)

* Fix initial size jumps of windowed desktop

* Fix window jumping back to previous size on changes to mode
This commit is contained in:
SomeTroglodyte 2023-03-21 13:39:55 +01:00 committed by GitHub
parent 11be6e2804
commit 882f6a6ab2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 60 deletions

View File

@ -1,6 +1,6 @@
package com.unciv.models.metadata package com.unciv.models.metadata
import com.badlogic.gdx.Application import com.badlogic.gdx.Application.ApplicationType
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.utils.Base64Coder import com.badlogic.gdx.utils.Base64Coder
import com.unciv.Constants import com.unciv.Constants
@ -11,6 +11,7 @@ import com.unciv.ui.components.FontFamilyData
import com.unciv.ui.components.Fonts import com.unciv.ui.components.Fonts
import com.unciv.ui.components.KeyboardBindings import com.unciv.ui.components.KeyboardBindings
import com.unciv.ui.screens.overviewscreen.EmpireOverviewCategories import com.unciv.ui.screens.overviewscreen.EmpireOverviewCategories
import com.unciv.utils.Display
import com.unciv.utils.ScreenOrientation import com.unciv.utils.ScreenOrientation
import java.text.Collator import java.text.Collator
import java.time.Duration import java.time.Duration
@ -110,17 +111,20 @@ class GameSettings {
init { init {
// 26 = Android Oreo. Versions below may display permanent icon in notification bar. // 26 = Android Oreo. Versions below may display permanent icon in notification bar.
if (Gdx.app?.type == Application.ApplicationType.Android && Gdx.app.version < 26) { if (Gdx.app?.type == ApplicationType.Android && Gdx.app.version < 26) {
multiplayer.turnCheckerPersistentNotificationEnabled = false multiplayer.turnCheckerPersistentNotificationEnabled = false
} }
} }
fun save() { fun save() {
if (!isFreshlyCreated && Gdx.app?.type == Application.ApplicationType.Desktop) { refreshWindowSize()
windowState = WindowState(Gdx.graphics.width, Gdx.graphics.height)
}
UncivGame.Current.files.setGeneralSettings(this) UncivGame.Current.files.setGeneralSettings(this)
} }
fun refreshWindowSize() {
if (isFreshlyCreated || Gdx.app.type != ApplicationType.Desktop) return
if (!Display.hasUserSelectableSize(screenMode)) return
windowState = WindowState(Gdx.graphics.width, Gdx.graphics.height)
}
fun addCompletedTutorialTask(tutorialTask: String): Boolean { fun addCompletedTutorialTask(tutorialTask: String): Boolean {
if (!tutorialTasksCompleted.add(tutorialTask)) return false if (!tutorialTasksCompleted.add(tutorialTask)) return false

View File

@ -149,6 +149,7 @@ private fun addScreenModeSelectBox(table: Table, settings: GameSettings, selectB
selectBox.items = Array(modes.values.toTypedArray()) selectBox.items = Array(modes.values.toTypedArray())
selectBox.selected = current selectBox.selected = current
selectBox.onChange { selectBox.onChange {
settings.refreshWindowSize()
val mode = selectBox.selected val mode = selectBox.selected
settings.screenMode = mode.getId() settings.screenMode = mode.getId()
Display.setScreenMode(mode.getId(), settings) Display.setScreenMode(mode.getId(), settings)

View File

@ -15,6 +15,7 @@ enum class ScreenOrientation(val description: String) {
interface ScreenMode { interface ScreenMode {
fun getId(): Int fun getId(): Int
fun hasUserSelectableSize(): Boolean = false
} }
interface PlatformDisplay { interface PlatformDisplay {
@ -27,6 +28,8 @@ interface PlatformDisplay {
fun hasOrientation(): Boolean { return false } fun hasOrientation(): Boolean { return false }
fun setOrientation(orientation: ScreenOrientation) {} fun setOrientation(orientation: ScreenOrientation) {}
fun hasUserSelectableSize(id: Int): Boolean = false
} }
object Display { object Display {
@ -42,4 +45,5 @@ object Display {
fun getScreenModes(): Map<Int, ScreenMode> { return platform.getScreenModes() } fun getScreenModes(): Map<Int, ScreenMode> { return platform.getScreenModes() }
fun setScreenMode(id: Int, settings: GameSettings) { platform.setScreenMode(id, settings) } fun setScreenMode(id: Int, settings: GameSettings) { platform.setScreenMode(id, settings) }
fun hasUserSelectableSize(id: Int) = platform.hasUserSelectableSize(id)
} }

View File

@ -1,75 +1,70 @@
package com.unciv.app.desktop package com.unciv.app.desktop
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
import com.unciv.models.metadata.GameSettings import com.unciv.models.metadata.GameSettings
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.utils.PlatformDisplay import com.unciv.utils.PlatformDisplay
import com.unciv.utils.ScreenMode import com.unciv.utils.ScreenMode
enum class ScreenWindowType {
Windowed,
Borderless,
Fullscreen
}
// TODO convert to Enum enum class DesktopScreenMode : ScreenMode {
class DesktopScreenMode( // Order will be preserved in Options Popup
private val modeId: Int, Windowed {
val windowType: ScreenWindowType) : ScreenMode { override fun activate(settings: GameSettings) {
Gdx.graphics.setUndecorated(false)
setWindowedMode(settings)
}
override fun getId(): Int { override fun hasUserSelectableSize() = true
return modeId },
Fullscreen {
override fun activate(settings: GameSettings) {
Gdx.graphics.setFullscreenMode(Gdx.graphics.displayMode)
}
override fun hasUserSelectableSize() = false
},
Borderless {
override fun activate(settings: GameSettings) {
Gdx.graphics.setUndecorated(true)
setWindowedMode(settings)
}
override fun hasUserSelectableSize() = true
},
;
override fun getId() = ordinal
override fun toString() = name.tr()
abstract fun activate(settings: GameSettings)
protected fun setWindowedMode(settings: GameSettings) {
val width = settings.windowState.width.coerceAtLeast(120)
val height = settings.windowState.height.coerceAtLeast(80)
// Kludge - see also DesktopLauncher - without, moving the window might revert to the size stored in config
(Lwjgl3Application::class.java).getDeclaredField("config").run {
isAccessible = true
get(Gdx.app) as Lwjgl3ApplicationConfiguration
}.setWindowedMode(width, height)
Gdx.graphics.setWindowedMode(width, height)
} }
override fun toString(): String { companion object {
return when (windowType) { operator fun get(id: Int) = values()[id]
ScreenWindowType.Windowed -> "Windowed".tr()
ScreenWindowType.Borderless -> "Borderless".tr()
ScreenWindowType.Fullscreen -> "Fullscreen".tr()
}
} }
} }
class DesktopDisplay : PlatformDisplay { class DesktopDisplay : PlatformDisplay {
private val modes = HashMap<Int, DesktopScreenMode>() override fun getScreenModes() =
DesktopScreenMode.values().associateBy { it.getId() }
init {
modes[0] = DesktopScreenMode(0, ScreenWindowType.Windowed)
modes[1] = DesktopScreenMode(1, ScreenWindowType.Fullscreen)
modes[2] = DesktopScreenMode(2, ScreenWindowType.Borderless)
}
override fun getScreenModes(): Map<Int, ScreenMode> {
return modes
}
override fun setScreenMode(id: Int, settings: GameSettings) { override fun setScreenMode(id: Int, settings: GameSettings) {
DesktopScreenMode[id].activate(settings)
val mode = modes[id] ?: return
when (mode.windowType) {
ScreenWindowType.Fullscreen -> {
Gdx.graphics.setFullscreenMode(Gdx.graphics.displayMode)
}
ScreenWindowType.Windowed -> {
Gdx.graphics.setUndecorated(false)
Gdx.graphics.setWindowedMode(
settings.windowState.width.coerceAtLeast(120),
settings.windowState.height.coerceAtLeast(80)
)
}
ScreenWindowType.Borderless -> {
Gdx.graphics.setUndecorated(true)
Gdx.graphics.setWindowedMode(
settings.windowState.width.coerceAtLeast(120),
settings.windowState.height.coerceAtLeast(80)
)
}
}
} }
override fun hasUserSelectableSize(id: Int) =
DesktopScreenMode[id].hasUserSelectableSize()
} }

View File

@ -47,7 +47,6 @@ internal object DesktopLauncher {
config.setWindowIcon("ExtraImages/Icon.png") config.setWindowIcon("ExtraImages/Icon.png")
config.setTitle("Unciv") config.setTitle("Unciv")
config.setHdpiMode(HdpiMode.Logical) config.setHdpiMode(HdpiMode.Logical)
config.setMaximized(true)
config.setWindowSizeLimits(120, 80, -1, -1) config.setWindowSizeLimits(120, 80, -1, -1)
// We don't need the initial Audio created in Lwjgl3Application, HardenGdxAudio will replace it anyway. // We don't need the initial Audio created in Lwjgl3Application, HardenGdxAudio will replace it anyway.
@ -66,6 +65,10 @@ internal object DesktopLauncher {
) )
FileHandle(SETTINGS_FILE_NAME).writeString(json().toJson(settings), false) // so when we later open the game we get fullscreen FileHandle(SETTINGS_FILE_NAME).writeString(json().toJson(settings), false) // so when we later open the game we get fullscreen
} }
// Kludge! This is a workaround - the matching call in DesktopDisplay doesn't "take" quite permanently,
// the window might revert to the "config" values when the user moves the window - worse if they
// minimize/restore. And the config default is 640x480 unless we set something here.
config.setWindowedMode(settings.windowState.width, settings.windowState.height)
if (!isRunFromJAR) { if (!isRunFromJAR) {
UniqueDocsWriter().write() UniqueDocsWriter().write()