feat: add a Steam settings toggle for running games on their own Xwayland

This commit is contained in:
xXJsonDeruloXx committed 2026-10-06 21:34:32 -04:00
1 parent adc86fc7df
commit 522a2d7ed2
15 files changed
+42 -1

No files matched your search

@@ -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)
@@ -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" })
@@ -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.
@@ -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"))
@@ -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(
+2
View File
@@ -269,6 +269,8 @@
<string name="mode_deck_mode_hint">La interfaz Deck de Steam y los controles de rendimiento de Quick Access. Se aplica en la próxima sesión.</string>
<string name="mode_mangoapp">Overlay de rendimiento</string>
<string name="mode_mangoapp_hint">Desactívalo si los juegos fallan o se quedan en negro en modo Deck. Se aplica en la próxima sesión.</string>
<string name="mode_dual_xwayland">Dos servidores Xwayland</string>
<string name="mode_dual_xwayland_hint">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.</string>
<string name="mode_branch">Rama del cliente</string>
<string name="mode_branch_deck">Beta pública de Steam Deck (requerida por el modo Deck).</string>
<string name="mode_branch_hint">Se aplica en la próxima sesión. Steam puede actualizarse una vez.</string>
+2
View File
@@ -263,6 +263,8 @@
<string name="mode_deck_mode_hint">Interface Steam Deck et contrôles de performance à accès rapide. Prendra effet à la prochaine session.</string>
<string name="mode_mangoapp">Superposition de performance</string>
<string name="mode_mangoapp_hint">Désactivez cette option si les jeux plantent ou affichent un écran noir en mode Deck. Prendra effet à la prochaine session.</string>
<string name="mode_dual_xwayland">Deux serveurs Xwayland</string>
<string name="mode_dual_xwayland_hint">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.</string>
<string name="mode_branch">Branche du client</string>
<string name="mode_branch_deck">Bêta Steam Deck (requis pour le mode Deck).</string>
<string name="mode_branch_hint">Prendra effet à la prochaine session. Steam peut se mettre à jour une fois de lui-même.</string>
+2
View File
@@ -263,6 +263,8 @@
<string name="mode_deck_mode_hint">Steam DeckのUIとクイックアクセスパフォーマンスコントロール。次回のセッションで有効になります。</string>
<string name="mode_mangoapp">パフォーマンスオーバーレイ</string>
<string name="mode_mangoapp_hint">Deckモードでゲームがクラッシュしたり画面が真っ暗になる場合は、これをオフにしてください。次回のセッションで有効になります。</string>
<string name="mode_dual_xwayland">2つのXwaylandサーバー</string>
<string name="mode_dual_xwayland_hint">SteamOSと同様に、ゲームを専用のXサーバーで実行します。ゲームがSteamの背後で開き、フォーカスされない場合はオフにしてください。次回のセッションで有効になります。</string>
<string name="mode_branch">クライアントブランチ</string>
<string name="mode_branch_deck">Steam Deckベータ版(Deckモードに必要)。</string>
<string name="mode_branch_hint">次回のセッションで有効になります。Steamが自動的に一度アップデートされる場合があります。</string>
+2
View File
@@ -263,6 +263,8 @@
<string name="mode_deck_mode_hint">Steam Deck UI 및 빠른 액세스 성능 제어. 다음 세션에 적용됩니다.</string>
<string name="mode_mangoapp">성능 오버레이</string>
<string name="mode_mangoapp_hint">Deck 모드에서 게임이 충돌하거나 화면이 검게 변하면 이 옵션을 끄세요. 다음 세션에 적용됩니다.</string>
<string name="mode_dual_xwayland">Xwayland 서버 2개</string>
<string name="mode_dual_xwayland_hint">SteamOS처럼 게임을 별도의 X 서버에서 실행합니다. 게임이 Steam 뒤에서 열리고 포커스를 받지 못하면 이 옵션을 끄세요. 다음 세션에 적용됩니다.</string>
<string name="mode_branch">클라이언트 브랜치</string>
<string name="mode_branch_deck">Steam Deck 베타(Deck 모드에 필요).</string>
<string name="mode_branch_hint">다음 세션에 적용됩니다. Steam이 자체적으로 한 번 업데이트될 수 있습니다.</string>
+2
View File
@@ -263,6 +263,8 @@
<string name="mode_deck_mode_hint">Интерфейс Steam Deck и управление производительностью через быстрый доступ. Вступит в силу в следующей сессии.</string>
<string name="mode_mangoapp">Оверлей производительности</string>
<string name="mode_mangoapp_hint">Отключите, если игры падают или появляется черный экран в режиме Deck. Вступит в силу в следующей сессии.</string>
<string name="mode_dual_xwayland">Два сервера Xwayland</string>
<string name="mode_dual_xwayland_hint">Запускает игры на отдельном X-сервере, как в SteamOS. Отключите, если игра открывается позади Steam и не получает фокус. Вступит в силу в следующей сессии.</string>
<string name="mode_branch">Ветка клиента</string>
<string name="mode_branch_deck">Бета-версия Steam Deck (требуется для режима Deck).</string>
<string name="mode_branch_hint">Вступит в силу в следующей сессии. Steam может обновиться самостоятельно один раз.</string>
@@ -285,6 +285,8 @@
<string name="mode_deck_mode_hint">Steam 的 Deck 界面和快捷访问性能控制。将在下次会话生效。</string>
<string name="mode_mangoapp">性能覆盖层</string>
<string name="mode_mangoapp_hint">若游戏在 Deck 模式下崩溃或黑屏,请关闭性能覆盖层。将在下次会话生效。</string>
<string name="mode_dual_xwayland">双 Xwayland 服务器</string>
<string name="mode_dual_xwayland_hint">像 SteamOS 一样在独立的 X 服务器上运行游戏。若游戏在 Steam 后面打开且始终无法获得焦点,请关闭此项。将在下次会话生效。</string>
<string name="mode_branch">客户端分支</string>
<string name="mode_branch_deck">Steam Deck 公开测试版(Deck 模式所必需)。</string>
<string name="mode_branch_hint">将在下次会话生效。Steam 可能会自行更新一次。</string>
@@ -263,6 +263,8 @@
<string name="mode_deck_mode_hint">Steam Deck 界面和快速訪問性能控制。下次會話生效。</string>
<string name="mode_mangoapp">性能疊加層</string>
<string name="mode_mangoapp_hint">如果 Deck 模式下遊戲崩潰或黑屏,請關閉此項。下次會話生效。</string>
<string name="mode_dual_xwayland">雙 Xwayland 伺服器</string>
<string name="mode_dual_xwayland_hint">像 SteamOS 一樣在獨立的 X 伺服器上執行遊戲。如果遊戲在 Steam 後面開啟且一直無法取得焦點,請關閉此項。下次會話生效。</string>
<string name="mode_branch">客戶端分支</string>
<string name="mode_branch_deck">Steam Deck 公測版(Deck 模式所需)。</string>
<string name="mode_branch_hint">下次會話生效。Steam 可能會自行更新一次。</string>
@@ -263,6 +263,8 @@
<string name="mode_deck_mode_hint">Steam Deck 介面和快速存取效能控制。下次工作階段生效。</string>
<string name="mode_mangoapp">效能重疊層</string>
<string name="mode_mangoapp_hint">如果 Deck 模式下遊戲崩潰或黑畫面,請關閉此項。下次工作階段生效。</string>
<string name="mode_dual_xwayland">雙 Xwayland 伺服器</string>
<string name="mode_dual_xwayland_hint">像 SteamOS 一樣在獨立的 X 伺服器上執行遊戲。如果遊戲在 Steam 後面開啟且一直無法取得焦點,請關閉此項。下次工作階段生效。</string>
<string name="mode_branch">用戶端分支</string>
<string name="mode_branch_deck">Steam Deck 公開測試版(Deck 模式所需)。</string>
<string name="mode_branch_hint">下次工作階段生效。Steam 可能會自行更新一次。</string>
+2
View File
@@ -287,6 +287,8 @@
<string name="mode_deck_mode_hint">Steam\'s Deck interface and Quick Access performance controls. Applies next session.</string>
<string name="mode_mangoapp">Performance overlay</string>
<string name="mode_mangoapp_hint">Turn off if games crash or go black in Deck mode. Applies next session.</string>
<string name="mode_dual_xwayland">Two Xwayland servers</string>
<string name="mode_dual_xwayland_hint">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.</string>
<string name="mode_branch">Client branch</string>
<string name="mode_branch_deck">Steam Deck public beta (required by Deck mode).</string>
<string name="mode_branch_hint">Applies next session. Steam may update itself once.</string>
@@ -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