@@ -62,6 +62,15 @@ public class BlightGame extends SimpleApplication {
private long startTimeMs = 0 ;
private long lastFullscreenFix = 0 ;
private long pendingFullscreenFixAt = Long . MAX_VALUE ;
// Cinnamons Display-Daemon interpretiert den glfwSetWindowMonitor()-Toggle in
// fixFullscreenMonitor() offenbar als Monitor-Neukonfiguration und setzt dabei
// "scaling-factor" (org.cinnamon.desktop.interface) auf 0 (=Auto) zurück, auch wenn
// der Nutzer explizit 100% (Wert 1) eingestellt hatte – das bleibt dann auch nach dem
// Spielende so stehen. Wir sichern den Wert vor dem Fix und schreiben ihn zeitversetzt
// zurück (Cinnamon braucht etwas, bis es reagiert – sofortiges Zurückschreiben würde
// von Cinnamons eigenem Reset kurz danach wieder überschrieben).
private String savedScalingFactor = null ;
private long pendingScalingRestoreAt = Long . MAX_VALUE ;
private boolean firstLaunch = true ; // false nach dem ersten simpleInitApp()
private boolean initialFixDone = false ; // Initial-Fix bei 0.5s bereits gelaufen
private boolean pendingMenuRebuild = false ; // nur true nach explizitem app.restart()
@@ -202,6 +211,7 @@ public class BlightGame extends SimpleApplication {
audioSettings = AudioSettingsStore . load ( ) ;
de . blight . game . state . ModelLodControl . debugLod2 = graphicsSettings . debugLod2 ;
captureScalingFactor ( ) ;
startTimeMs = System . currentTimeMillis ( ) ;
initialFixDone = false ;
@@ -226,6 +236,16 @@ public class BlightGame extends SimpleApplication {
// Fullscreen-Zustand war (wie beim 5s-Watchdog). Aus dem Hidden-Zustand behandelt
// Cinnamon den nächsten Fullscreen-Übergang als Neuerstplatzierung und ignoriert
// den Ziel-Monitor zugunsten des aktiven Workspaces (Editor-Monitor).
//
// mainMenuState wird weiter unten in dieser Methode gebaut – mit der JETZT
// aktuellen (noch nicht fullscreen-korrigierten) Kamera-Größe. Der Vollbild-Fix
// läuft aber erst ~200ms später in simpleUpdate() und löst dann reshape() aus.
// Ohne pendingMenuRebuild würde rebuildScreenDependentStates() dabei NUR HUD/
// Hotbar/LoadingScreen neu aufbauen (siehe dortige Kommentare: das ist normalerweise
// extra vor app.restart() gesetzt) – das Menü bliebe dauerhaft auf der falschen,
// zu kleinen Ausgangsgröße stehen und würde nur einen Bildschirm-Ausschnitt
// (unten links) füllen, obwohl das Fenster längst auf volle Auflösung steht.
pendingMenuRebuild = true ;
}
// Restart nach Einstellungsänderung: pendingFullscreenFixAt (scheduleFullscreenFix)
// bleibt gesetzt und übernimmt den Fix nach 1 s.
@@ -493,6 +513,11 @@ public class BlightGame extends SimpleApplication {
fixFullscreenMonitor ( ) ;
}
if ( now > = pendingScalingRestoreAt ) {
pendingScalingRestoreAt = Long . MAX_VALUE ;
restoreScalingFactor ( ) ;
}
// Watchdog: Vollbild-Verlust durch GNOME/WM (erkennbar an Auflösungs-Mismatch).
if ( graphicsSettings ! = null & & graphicsSettings . fullscreen ) {
if ( now - startTimeMs > 5_000
@@ -798,8 +823,56 @@ public class BlightGame extends SimpleApplication {
glfwSleep ( 200 ) ;
GLFW . glfwFocusWindow ( win ) ;
// scaling-factor zeitversetzt zurückschreiben, siehe Feld-Kommentar oben bei
// savedScalingFactor – Cinnamon reagiert erst mit etwas Verzögerung auf den
// Monitor-Toggle, ein sofortiger Restore würde von Cinnamons eigenem Reset
// wieder überschrieben.
pendingScalingRestoreAt = System . currentTimeMillis ( ) + 2_000 ;
} catch ( Throwable e ) {
log . warn ( " [Grafik] Vollbild-Fix fehlgeschlagen: {} " , e . getMessage ( ) , e ) ;
}
}
/** Liest den aktuellen Cinnamon-Skalierungsfaktor, um ihn nach dem Vollbild-Fix
* wiederherzustellen (siehe Feld-Kommentar bei savedScalingFactor). */
private void captureScalingFactor ( ) {
try {
Process p = new ProcessBuilder (
" gsettings " , " get " , " org.cinnamon.desktop.interface " , " scaling-factor " )
. redirectErrorStream ( true ) . start ( ) ;
String out = new String ( p . getInputStream ( ) . readAllBytes ( ) ) . trim ( ) ;
p . waitFor ( ) ;
// Format ist z.B. "uint32 1" – letztes Token ist der Wert. Nicht per
// replaceAll("[^0-9]","") Ziffern rausfiltern: "uint32" enthält selbst
// die Ziffern 3 und 2, das hängt sie vor den echten Wert (1 -> "321",
// 321 -> "32321", ...) und schaukelt sich exponentiell hoch.
String [ ] parts = out . split ( " \\ s+ " ) ;
String value = parts [ parts . length - 1 ] ;
savedScalingFactor = value . matches ( " [0-9]+ " ) ? value : null ;
log . info ( " [Grafik] scaling-factor gesichert: {} " , savedScalingFactor ) ;
} catch ( Exception e ) {
log . debug ( " [Grafik] scaling-factor konnte nicht gelesen werden (evtl. kein Cinnamon): {} " , e . getMessage ( ) ) ;
savedScalingFactor = null ;
}
}
/** Schreibt den zuvor gesicherten Cinnamon-Skalierungsfaktor zurück. */
private void restoreScalingFactor ( ) {
if ( savedScalingFactor = = null ) return ;
try {
new ProcessBuilder (
" gsettings " , " set " , " org.cinnamon.desktop.interface " , " scaling-factor " , savedScalingFactor )
. start ( ) . waitFor ( ) ;
log . info ( " [Grafik] scaling-factor wiederhergestellt: {} " , savedScalingFactor ) ;
} catch ( Exception e ) {
log . warn ( " [Grafik] scaling-factor konnte nicht wiederhergestellt werden: {} " , e . getMessage ( ) ) ;
}
}
@Override
public void stop ( ) {
restoreScalingFactor ( ) ;
super . stop ( ) ;
}
}