diff --git a/app/src/main/java/com/droiddeck/launcher/MainActivity.kt b/app/src/main/java/com/droiddeck/launcher/MainActivity.kt index 675b166bf..ceb3ddce6 100644 --- a/app/src/main/java/com/droiddeck/launcher/MainActivity.kt +++ b/app/src/main/java/com/droiddeck/launcher/MainActivity.kt @@ -116,6 +116,7 @@ class MainActivity : ComponentActivity() { private var steamDeckMode by mutableStateOf(false) private var steamRepairQueued by mutableStateOf(false) private var mangoapp by mutableStateOf(true) + private var dualXwayland by mutableStateOf(true) private var steamController by mutableStateOf(SessionPrefs.CONTROLLER_DECK) private var showProtons by mutableStateOf(false) // Components page: FEX / DXVK / VKD3D-Proton per Proton (ComponentsManager). @@ -1161,6 +1162,7 @@ class MainActivity : ComponentActivity() { steamDeckMode = mode == SessionService.MODE_STEAM && steamDeckMode, steamRepairQueued = steamRepairQueued, mangoapp = mangoapp, + dualXwayland = dualXwayland, steamController = if (mode == SessionService.MODE_STEAM) steamController else null, runSteamAtStartup = mode == SessionService.MODE_STEAM && runSteamAtStartup, wifiDiscovery = if (mode == SessionService.MODE_STEAM) wifiDiscovery else null, @@ -1243,6 +1245,7 @@ class MainActivity : ComponentActivity() { steamChannel = SessionPrefs.steamChannel(this) }, onMangoapp = { on -> SessionPrefs.setMangoapp(this, on); mangoapp = on }, + onDualXwayland = { on -> SessionPrefs.setDualXwayland(this, on); dualXwayland = on }, onSteamController = { id -> SessionPrefs.setSteamController(this, id); steamController = id }, onRunSteamAtStartup = { on -> SessionPrefs.setRunSteamAtStartup(this, on) @@ -1358,6 +1361,7 @@ class MainActivity : ComponentActivity() { steamDeckMode = SessionPrefs.steamDeckMode(this) steamRepairQueued = SteamRepair.queued(this) mangoapp = SessionPrefs.mangoapp(this) + dualXwayland = SessionPrefs.dualXwayland(this) steamController = SessionPrefs.steamController(this) runSteamAtStartup = SessionPrefs.runSteamAtStartup(this) addedGamesDirs = SessionPrefs.addedGamesDirs(this) diff --git a/app/src/main/java/com/droiddeck/launcher/core/DeviceReport.kt b/app/src/main/java/com/droiddeck/launcher/core/DeviceReport.kt index d5f9e9796..1716e3219 100644 --- a/app/src/main/java/com/droiddeck/launcher/core/DeviceReport.kt +++ b/app/src/main/java/com/droiddeck/launcher/core/DeviceReport.kt @@ -154,6 +154,7 @@ object DeviceReport { k("No GL error checks", SessionPrefs.noGlError(context)) k("Steam Deck mode", SessionPrefs.steamDeckMode(context)) k("Steam controller", SessionPrefs.steamController(context)) + k("Two Xwayland servers", SessionPrefs.dualXwayland(context)) k("Upscaler", (SessionPrefs.upscalerChoices.firstOrNull { it.first == SessionPrefs.upscaler(context) }?.second ?: "Off") + " (sharpness ${SessionPrefs.upscaleSharpness(context)}%)") k("FEX preset", SessionPrefs.fexPreset(context).ifEmpty { "FEX defaults" }) diff --git a/app/src/main/java/com/droiddeck/launcher/session/SessionPrefs.kt b/app/src/main/java/com/droiddeck/launcher/session/SessionPrefs.kt index 3489bda3b..c62c2d942 100644 --- a/app/src/main/java/com/droiddeck/launcher/session/SessionPrefs.kt +++ b/app/src/main/java/com/droiddeck/launcher/session/SessionPrefs.kt @@ -414,6 +414,14 @@ object SessionPrefs { fun mangoapp(context: Context): Boolean = prefs(context).getBoolean("mangoapp", true) fun setMangoapp(context: Context, on: Boolean) { prefs(context).edit().putBoolean("mangoapp", on).apply() } + /** + * Steam on two Xwayland servers, as SteamOS runs it: the client on one, its games on the other + * (droiddeck-session, BL_XWAYLAND_COUNT). Off puts both back on one server, for a game whose + * window opens behind the client and never takes focus. On by default. + */ + fun dualXwayland(context: Context): Boolean = prefs(context).getBoolean("dualXwayland", true) + fun setDualXwayland(context: Context, on: Boolean) { prefs(context).edit().putBoolean("dualXwayland", on).apply() } + /** * Zink's lazy descriptor mode (ZINK_DESCRIPTORS=lazy) with its compact set layout * (ZINK_DEBUG=compact) for the client's GL-on-Vulkan UI, as WinNative runs it. On by default. diff --git a/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt b/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt index ef3acc88e..a850a3335 100644 --- a/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt +++ b/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt @@ -605,6 +605,7 @@ class SessionService : Service() { guest.add("GLIBC_TUNABLES=glibc.pthread.rseq=0:glibc.malloc.top_pad=16777216") if (SessionState.mode == MODE_STEAM) guest.add("BL_STEAMDECK=" + (if (SessionPrefs.steamDeckMode(this)) "1" else "0")) if (SessionState.mode == MODE_STEAM) guest.add("BL_MANGOAPP=" + (if (SessionPrefs.mangoapp(this)) "1" else "0")) + if (SessionState.mode == MODE_STEAM) guest.add("BL_XWAYLAND_COUNT=" + (if (SessionPrefs.dualXwayland(this)) "2" else "1")) if (steamHere) guest.add("BL_STEAM_CHANNEL=" + SessionPrefs.steamChannel(this)) if (SessionState.mode == MODE_STEAM) { guest.add("BL_GAMESCOPE_STRETCH_16X9=" + (if (SessionPrefs.stretch16x9(this)) "1" else "0")) diff --git a/app/src/main/java/com/droiddeck/launcher/ui/ModeSettingsDialog.kt b/app/src/main/java/com/droiddeck/launcher/ui/ModeSettingsDialog.kt index 68962975f..1e30b01eb 100644 --- a/app/src/main/java/com/droiddeck/launcher/ui/ModeSettingsDialog.kt +++ b/app/src/main/java/com/droiddeck/launcher/ui/ModeSettingsDialog.kt @@ -82,6 +82,8 @@ class ModeSettings( val steamRepairQueued: Boolean = false, /** Steam, Deck mode: the QAM's performance overlay (mangoapp) is started. */ val mangoapp: Boolean = true, + /** Steam only: the client and its games on separate Xwayland servers. */ + val dualXwayland: Boolean = true, /** Steam only: what the pad is to the client (SessionPrefs.CONTROLLER_*); null outside Steam. */ val steamController: String? = null, /** Steam only: start a Steam session when DroidDeck opens. */ @@ -138,6 +140,7 @@ class ModeSettingsActions( val onSteamRepair: () -> Unit = {}, val onSteamDeckMode: (Boolean) -> Unit = {}, val onMangoapp: (Boolean) -> Unit = {}, + val onDualXwayland: (Boolean) -> Unit = {}, val onSteamController: (String) -> Unit = {}, val onRunSteamAtStartup: (Boolean) -> Unit = {}, val onWifiDiscovery: (Boolean) -> Unit = {}, @@ -376,6 +379,11 @@ fun ModeSettingsPage(s: ModeSettings, a: ModeSettingsActions) { stringResource(R.string.mode_mangoapp_hint), s.mangoapp, onChange = a.onMangoapp, ) + ToggleRow( + host, "dualxwayland", stringResource(R.string.mode_dual_xwayland), + stringResource(R.string.mode_dual_xwayland_hint), + s.dualXwayland, onChange = a.onDualXwayland, + ) // Deck mode fixes the branch (SessionPrefs.steamChannel); the choice is for Deck mode off. if (s.steamDeckMode) SettingsRow(stringResource(R.string.mode_branch), stringResource(R.string.mode_branch_deck)) {} else ChoiceRow( diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 0b875d026..a758f9f29 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -269,6 +269,8 @@ La interfaz Deck de Steam y los controles de rendimiento de Quick Access. Se aplica en la próxima sesión. Overlay de rendimiento Desactívalo si los juegos fallan o se quedan en negro en modo Deck. Se aplica en la próxima sesión. + Dos servidores Xwayland + Ejecuta los juegos en su propio servidor X, como SteamOS. Desactívalo si un juego se abre detrás de Steam y nunca toma el foco. Se aplica en la próxima sesión. Rama del cliente Beta pública de Steam Deck (requerida por el modo Deck). Se aplica en la próxima sesión. Steam puede actualizarse una vez. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 2255f73d4..315a84755 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -263,6 +263,8 @@ Interface Steam Deck et contrôles de performance à accès rapide. Prendra effet à la prochaine session. Superposition de performance Désactivez cette option si les jeux plantent ou affichent un écran noir en mode Deck. Prendra effet à la prochaine session. + Deux serveurs Xwayland + Lance les jeux sur leur propre serveur X, comme SteamOS. Désactivez cette option si un jeu s’ouvre derrière Steam et ne prend jamais le focus. Prendra effet à la prochaine session. Branche du client Bêta Steam Deck (requis pour le mode Deck). Prendra effet à la prochaine session. Steam peut se mettre à jour une fois de lui-même. diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index b181ddb8a..dbafa732c 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -263,6 +263,8 @@ Steam DeckのUIとクイックアクセスパフォーマンスコントロール。次回のセッションで有効になります。 パフォーマンスオーバーレイ Deckモードでゲームがクラッシュしたり画面が真っ暗になる場合は、これをオフにしてください。次回のセッションで有効になります。 + 2つのXwaylandサーバー + SteamOSと同様に、ゲームを専用のXサーバーで実行します。ゲームがSteamの背後で開き、フォーカスされない場合はオフにしてください。次回のセッションで有効になります。 クライアントブランチ Steam Deckベータ版(Deckモードに必要)。 次回のセッションで有効になります。Steamが自動的に一度アップデートされる場合があります。 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 62e3ee42f..0c03134ed 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -263,6 +263,8 @@ Steam Deck UI 및 빠른 액세스 성능 제어. 다음 세션에 적용됩니다. 성능 오버레이 Deck 모드에서 게임이 충돌하거나 화면이 검게 변하면 이 옵션을 끄세요. 다음 세션에 적용됩니다. + Xwayland 서버 2개 + SteamOS처럼 게임을 별도의 X 서버에서 실행합니다. 게임이 Steam 뒤에서 열리고 포커스를 받지 못하면 이 옵션을 끄세요. 다음 세션에 적용됩니다. 클라이언트 브랜치 Steam Deck 베타(Deck 모드에 필요). 다음 세션에 적용됩니다. Steam이 자체적으로 한 번 업데이트될 수 있습니다. diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 0013f3912..6e99ce670 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -263,6 +263,8 @@ Интерфейс Steam Deck и управление производительностью через быстрый доступ. Вступит в силу в следующей сессии. Оверлей производительности Отключите, если игры падают или появляется черный экран в режиме Deck. Вступит в силу в следующей сессии. + Два сервера Xwayland + Запускает игры на отдельном X-сервере, как в SteamOS. Отключите, если игра открывается позади Steam и не получает фокус. Вступит в силу в следующей сессии. Ветка клиента Бета-версия Steam Deck (требуется для режима Deck). Вступит в силу в следующей сессии. Steam может обновиться самостоятельно один раз. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 0143df8d7..b46bbe804 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -285,6 +285,8 @@ Steam 的 Deck 界面和快捷访问性能控制。将在下次会话生效。 性能覆盖层 若游戏在 Deck 模式下崩溃或黑屏,请关闭性能覆盖层。将在下次会话生效。 + 双 Xwayland 服务器 + 像 SteamOS 一样在独立的 X 服务器上运行游戏。若游戏在 Steam 后面打开且始终无法获得焦点,请关闭此项。将在下次会话生效。 客户端分支 Steam Deck 公开测试版(Deck 模式所必需)。 将在下次会话生效。Steam 可能会自行更新一次。 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 6dcd11abd..77c8e0cd2 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -263,6 +263,8 @@ Steam Deck 界面和快速訪問性能控制。下次會話生效。 性能疊加層 如果 Deck 模式下遊戲崩潰或黑屏,請關閉此項。下次會話生效。 + 雙 Xwayland 伺服器 + 像 SteamOS 一樣在獨立的 X 伺服器上執行遊戲。如果遊戲在 Steam 後面開啟且一直無法取得焦點,請關閉此項。下次會話生效。 客戶端分支 Steam Deck 公測版(Deck 模式所需)。 下次會話生效。Steam 可能會自行更新一次。 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index a60d74af7..a78402a16 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -263,6 +263,8 @@ Steam Deck 介面和快速存取效能控制。下次工作階段生效。 效能重疊層 如果 Deck 模式下遊戲崩潰或黑畫面,請關閉此項。下次工作階段生效。 + 雙 Xwayland 伺服器 + 像 SteamOS 一樣在獨立的 X 伺服器上執行遊戲。如果遊戲在 Steam 後面開啟且一直無法取得焦點,請關閉此項。下次工作階段生效。 用戶端分支 Steam Deck 公開測試版(Deck 模式所需)。 下次工作階段生效。Steam 可能會自行更新一次。 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9132f7261..6394e6a02 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -287,6 +287,8 @@ Steam\'s Deck interface and Quick Access performance controls. Applies next session. Performance overlay Turn off if games crash or go black in Deck mode. Applies next session. + Two Xwayland servers + Runs games on their own X server, as SteamOS does. Turn off if a game opens behind Steam and never takes focus. Applies next session. Client branch Steam Deck public beta (required by Deck mode). Applies next session. Steam may update itself once. diff --git a/tools/linuxfs/overlay/usr/local/bin/droiddeck-session b/tools/linuxfs/overlay/usr/local/bin/droiddeck-session index a043a7bed..a699dc33c 100755 --- a/tools/linuxfs/overlay/usr/local/bin/droiddeck-session +++ b/tools/linuxfs/overlay/usr/local/bin/droiddeck-session @@ -182,7 +182,8 @@ if [ -z "${BL_INSIDE:-}" ]; then # Resolution never reaches its display (docs/development/steam-display-scaling.md). The client's # overlay is also on another server than the game, so opening it no longer takes the game's X # keyboard focus, which made games like FlatOut shrink their window. - # BL_XWAYLAND_COUNT=1 in Download/droiddeck-env goes back to one. + # The app sends BL_XWAYLAND_COUNT from Steam settings (Two Xwayland servers); 1 goes back to one, + # and a line in Download/droiddeck-env still wins. if [ "$mode" = steam ] && [ "${BL_XWAYLAND_COUNT:-2}" -gt 1 ]; then args+=(--xwayland-count "${BL_XWAYLAND_COUNT:-2}") export STEAM_MULTIPLE_XWAYLANDS=1