mirror of
https://github.com/yairm210/Unciv.git
synced 2024-12-23 01:24:26 +07:00
Create turn notifier for when the game is running for Windows (#6682)
* Create turn notifier for when the game is running for Windows If playing on Desktop, you often put the game into background, but still want to know if it's your turn. A standard Windows function for that is `FlashWindow` from winuser.h, which is implemented here * Fix: Use the window from the listener instead of the static one from libGDL * Only notify if it's the turn of the player that is playing * Always notify spectators of the next players' turn * Refactor: Move notifier into GeneralPlatformSpecificHelpers * Only load Windows DLL when we're actually on Windows
This commit is contained in:
parent
822ce5e041
commit
ceeb547fb8
@ -71,6 +71,9 @@ project(":desktop") {
|
|||||||
|
|
||||||
"implementation"("com.github.MinnDevelopment:java-discord-rpc:v2.0.1")
|
"implementation"("com.github.MinnDevelopment:java-discord-rpc:v2.0.1")
|
||||||
|
|
||||||
|
"implementation"("net.java.dev.jna:jna:5.11.0")
|
||||||
|
"implementation"("net.java.dev.jna:jna-platform:5.11.0")
|
||||||
|
|
||||||
// For server-side
|
// For server-side
|
||||||
|
|
||||||
"implementation"("io.ktor:ktor-server-core:1.6.8")
|
"implementation"("io.ktor:ktor-server-core:1.6.8")
|
||||||
|
@ -11,7 +11,12 @@ interface GeneralPlatformSpecificHelpers {
|
|||||||
* @param allow `true`: allow all orientations (follows sensor as limited by OS settings)
|
* @param allow `true`: allow all orientations (follows sensor as limited by OS settings)
|
||||||
* `false`: allow only landscape orientations (both if supported, otherwise default landscape only)
|
* `false`: allow only landscape orientations (both if supported, otherwise default landscape only)
|
||||||
*/
|
*/
|
||||||
fun allowPortrait(allow: Boolean)
|
fun allowPortrait(allow: Boolean) {}
|
||||||
|
|
||||||
fun isInternetConnected(): Boolean
|
fun isInternetConnected(): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the user that it's their turn while the game is running
|
||||||
|
*/
|
||||||
|
fun notifyTurnStarted() {}
|
||||||
}
|
}
|
||||||
|
@ -363,6 +363,9 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas
|
|||||||
// stuff has changed and the "waiting for X" will now show the correct civ
|
// stuff has changed and the "waiting for X" will now show the correct civ
|
||||||
stopMultiPlayerRefresher()
|
stopMultiPlayerRefresher()
|
||||||
latestGame.isUpToDate = true
|
latestGame.isUpToDate = true
|
||||||
|
if (viewingCiv.civName == latestGame.currentPlayer || viewingCiv.civName == Constants.spectator) {
|
||||||
|
game.platformSpecificHelper?.notifyTurnStarted()
|
||||||
|
}
|
||||||
postCrashHandlingRunnable { createNewWorldScreen(latestGame) }
|
postCrashHandlingRunnable { createNewWorldScreen(latestGame) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,13 +46,14 @@ internal object DesktopLauncher {
|
|||||||
UniqueDocsWriter().write()
|
UniqueDocsWriter().write()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val platformSpecificHelper = PlatformSpecificHelpersDesktop(config)
|
||||||
val desktopParameters = UncivGameParameters(
|
val desktopParameters = UncivGameParameters(
|
||||||
versionFromJar,
|
versionFromJar,
|
||||||
cancelDiscordEvent = { discordTimer?.cancel() },
|
cancelDiscordEvent = { discordTimer?.cancel() },
|
||||||
fontImplementation = NativeFontDesktop(Fonts.ORIGINAL_FONT_SIZE.toInt(), settings.fontFamily),
|
fontImplementation = NativeFontDesktop(Fonts.ORIGINAL_FONT_SIZE.toInt(), settings.fontFamily),
|
||||||
customSaveLocationHelper = CustomSaveLocationHelperDesktop(),
|
customSaveLocationHelper = CustomSaveLocationHelperDesktop(),
|
||||||
crashReportSysInfo = CrashReportSysInfoDesktop(),
|
crashReportSysInfo = CrashReportSysInfoDesktop(),
|
||||||
platformSpecificHelper = PlatformSpecificHelpersDesktop(),
|
platformSpecificHelper = platformSpecificHelper,
|
||||||
audioExceptionHelper = HardenGdxAudio()
|
audioExceptionHelper = HardenGdxAudio()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.unciv.app.desktop
|
||||||
|
|
||||||
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window
|
||||||
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3WindowAdapter
|
||||||
|
import com.sun.jna.Native
|
||||||
|
import com.sun.jna.Pointer
|
||||||
|
import com.sun.jna.platform.win32.User32
|
||||||
|
import com.sun.jna.platform.win32.WinNT
|
||||||
|
import com.sun.jna.platform.win32.WinUser
|
||||||
|
import org.lwjgl.glfw.GLFWNativeWin32
|
||||||
|
|
||||||
|
class MultiplayerTurnNotifierDesktop: Lwjgl3WindowAdapter() {
|
||||||
|
companion object {
|
||||||
|
val user32: User32? = try {
|
||||||
|
if (System.getProperty("os.name")?.contains("Windows") == true) {
|
||||||
|
Native.load(User32::class.java)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
} catch (e: UnsatisfiedLinkError) {
|
||||||
|
println("Error while initializing turn notifier: " + e.message)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private var window: Lwjgl3Window? = null
|
||||||
|
private var hasFocus: Boolean = true
|
||||||
|
|
||||||
|
override fun created(window: Lwjgl3Window?) {
|
||||||
|
this.window = window
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun focusLost() {
|
||||||
|
hasFocus = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun focusGained() {
|
||||||
|
hasFocus = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun turnStarted() {
|
||||||
|
flashWindow()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-flashwindowex
|
||||||
|
*
|
||||||
|
* We should've used FlashWindow instead of FlashWindowEx, but for some reason the former has no binding in Java's User32
|
||||||
|
*/
|
||||||
|
private fun flashWindow() {
|
||||||
|
try {
|
||||||
|
if (user32 == null || window == null || hasFocus) return
|
||||||
|
val flashwinfo = WinUser.FLASHWINFO()
|
||||||
|
val hwnd = GLFWNativeWin32.glfwGetWin32Window(window!!.windowHandle)
|
||||||
|
flashwinfo.hWnd = WinNT.HANDLE(Pointer.createConstant(hwnd))
|
||||||
|
flashwinfo.dwFlags = 3 // FLASHW_ALL
|
||||||
|
flashwinfo.uCount = 3
|
||||||
|
user32.FlashWindowEx(flashwinfo)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
/** try to ignore even if we get an [Error], just log it */
|
||||||
|
println("Error while notifying the user of their turn: " + e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,13 @@
|
|||||||
package com.unciv.app.desktop
|
package com.unciv.app.desktop
|
||||||
|
|
||||||
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
|
||||||
import com.unciv.ui.utils.GeneralPlatformSpecificHelpers
|
import com.unciv.ui.utils.GeneralPlatformSpecificHelpers
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
|
|
||||||
class PlatformSpecificHelpersDesktop : GeneralPlatformSpecificHelpers {
|
class PlatformSpecificHelpersDesktop(config: Lwjgl3ApplicationConfiguration) : GeneralPlatformSpecificHelpers {
|
||||||
override fun allowPortrait(allow: Boolean) {
|
val turnNotifier = MultiplayerTurnNotifierDesktop()
|
||||||
// No need to do anything
|
init {
|
||||||
|
config.setWindowListener(turnNotifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isInternetConnected(): Boolean {
|
override fun isInternetConnected(): Boolean {
|
||||||
@ -15,4 +17,9 @@ class PlatformSpecificHelpersDesktop : GeneralPlatformSpecificHelpers {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun notifyTurnStarted() {
|
||||||
|
turnNotifier.turnStarted()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user