diff --git a/app/src/main/java/com/droiddeck/launcher/SessionActivity.kt b/app/src/main/java/com/droiddeck/launcher/SessionActivity.kt index 269fa9edc..96f10bb10 100644 --- a/app/src/main/java/com/droiddeck/launcher/SessionActivity.kt +++ b/app/src/main/java/com/droiddeck/launcher/SessionActivity.kt @@ -147,7 +147,6 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback { private var onScreenControls: OnScreenControls? = null /** Steam's touch controls (SteamTouchControls), made once the session offers the device. */ private var steamTouchControls: com.droiddeck.launcher.input.SteamTouchControls? = null - private var oscStyle by mutableStateOf(SessionPrefs.OSC_STYLE_DROIDDECK) private var steamTouchAvailable by mutableStateOf(false) private val steamTouchRetry = Runnable { updateOnScreenControls() } /** While Steam's touch controls are up: how the game's touch config says touches outside them @@ -571,16 +570,14 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback { SessionPrefs.setBackActionsInverted(this@SessionActivity, inverted) backActionsInverted = inverted }, - onOsc = { v -> SessionPrefs.setOscMode(this@SessionActivity, v); readPrefs(); updateOnScreenControls() }, - oscStyle = if (SessionState.mode == SessionService.MODE_STEAM) oscStyle else null, - onOscStyle = { v -> - SessionPrefs.setOscStyle(this@SessionActivity, v) + onOsc = { v -> + SessionPrefs.setOscMode(this@SessionActivity, v) readPrefs() updateOnScreenControls() - if (v == SessionPrefs.OSC_STYLE_STEAM && com.droiddeck.launcher.input.SteamTouchDevice.current == null) + if (v == SessionPrefs.OSC_STEAM_TOUCH && com.droiddeck.launcher.input.SteamTouchDevice.current == null) Toast.makeText(this@SessionActivity, R.string.osc_style_next_session, Toast.LENGTH_LONG).show() }, - onEditSteamTouch = if (steamTouchAvailable && oscStyle == SessionPrefs.OSC_STYLE_STEAM && onScreenButtonsVisible) ({ + onEditSteamTouch = if (steamTouchAvailable && oscMode == SessionPrefs.OSC_STEAM_TOUCH && onScreenButtonsVisible) ({ drawerOpen = false steamTouchControls?.startEditing() }) else null, @@ -824,7 +821,6 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback { suspendPolicy = SessionPrefs.suspendPolicy(this, SessionState.mode) steamDownloadsInBackground = SessionPrefs.steamDownloadsInBackground(this) oscMode = SessionPrefs.oscMode(this) - oscStyle = SessionPrefs.oscStyle(this) backActionsInverted = SessionPrefs.backActionsInverted(this) } @@ -1897,8 +1893,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback { val buttonsOnly = forced == SessionPrefs.OSC_STEAM_QAM // Steam's touch controller stands in for the app's pad, and is plugged into the client only // while it is shown - as Steam Link withdraws its controls when a physical pad is in use. - val wantsSteam = !buttonsOnly && SessionState.mode == SessionService.MODE_STEAM && - SessionPrefs.oscStyle(this) == SessionPrefs.OSC_STYLE_STEAM + val wantsSteam = forced == SessionPrefs.OSC_STEAM_TOUCH && SessionState.mode == SessionService.MODE_STEAM val steam = if (wantsSteam) steamTouch() else null // The service makes the device while the session starts, after this activity: the app's // own pad until then, and another look in a moment. @@ -1915,6 +1910,10 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback { SessionPrefs.OSC_ALWAYS -> true SessionPrefs.OSC_STEAM_QAM -> true SessionPrefs.OSC_NEVER -> false + // Shown throughout a Steam session: a handheld's built-in pad would keep Auto off for good. + // Outside Steam it is Auto. + SessionPrefs.OSC_STEAM_TOUCH -> SessionState.mode == SessionService.MODE_STEAM || + (!PadBridge.anyControllerConnected() && SessionState.mode != SessionService.MODE_DESKTOP) // Auto: the touch pad when there is no controller - except on the desktop, where the // screen is a touchpad for the pointer and a pad over it would be in the way. A game // started from the rail, or Steam, gets it; the drawer turns it on anywhere. 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 b390ce7ba..83624a80a 100644 --- a/app/src/main/java/com/droiddeck/launcher/session/SessionPrefs.kt +++ b/app/src/main/java/com/droiddeck/launcher/session/SessionPrefs.kt @@ -22,9 +22,8 @@ object SessionPrefs { const val OSC_ALWAYS = "always" const val OSC_STEAM_QAM = "steam-qam" const val OSC_NEVER = "never" - /** Whose on-screen controls: the app's own pad, or Steam's touch controller (SteamTouchControls). */ - const val OSC_STYLE_DROIDDECK = "droiddeck" - const val OSC_STYLE_STEAM = "steam" + /** Steam's touch controller (SteamTouchControls) in place of the app's pad; Steam sessions only. */ + const val OSC_STEAM_TOUCH = "steam-touch" /** What Back does in a Steam session, first press then second: the labels of the two orders. */ val BACK_MENU_THEN_QAM = R.string.back_menu_then_qam @@ -114,12 +113,6 @@ object SessionPrefs { prefs(context).edit().putString("osc", mode).apply() } - fun oscStyle(context: Context): String = prefs(context).getString("oscStyle", OSC_STYLE_DROIDDECK) ?: OSC_STYLE_DROIDDECK - - fun setOscStyle(context: Context, style: String) { - prefs(context).edit().putString("oscStyle", style).apply() - } - /** * The imported glibc Turnip every session draws with inside the runtime - Steam, its games and * the desktop alike, as they run on the same GPU; "" = the driver built into the runtime. diff --git a/app/src/main/java/com/droiddeck/launcher/ui/ControllerSettings.kt b/app/src/main/java/com/droiddeck/launcher/ui/ControllerSettings.kt index 25e6bc4d9..8785c4ef0 100644 --- a/app/src/main/java/com/droiddeck/launcher/ui/ControllerSettings.kt +++ b/app/src/main/java/com/droiddeck/launcher/ui/ControllerSettings.kt @@ -43,7 +43,7 @@ private fun Swatch(color: Int) { fun ColumnScope.ControllerRows(host: MenuHost, oscMode: String, c: ControllerPrefs.Settings, a: ControllerActions) { ChoiceRow( host, "controller-osc", stringResource(R.string.mode_osc), stringResource(R.string.ctrl_osc_hint), - listOf(SessionPrefs.OSC_AUTO to stringResource(R.string.common_auto), SessionPrefs.OSC_ALWAYS to stringResource(R.string.common_always), SessionPrefs.OSC_STEAM_QAM to stringResource(R.string.mode_osc_qam), SessionPrefs.OSC_NEVER to stringResource(R.string.common_never)), + listOf(SessionPrefs.OSC_AUTO to stringResource(R.string.common_auto), SessionPrefs.OSC_ALWAYS to stringResource(R.string.common_always), SessionPrefs.OSC_STEAM_TOUCH to stringResource(R.string.osc_steam_touch), SessionPrefs.OSC_STEAM_QAM to stringResource(R.string.mode_osc_qam), SessionPrefs.OSC_NEVER to stringResource(R.string.common_never)), oscMode, note = stringResource(R.string.mode_osc_note), onPick = a.onOsc, ) val tintOpen = host.open == "controller-tint" 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 c2ae73bd1..fc7d521df 100644 --- a/app/src/main/java/com/droiddeck/launcher/ui/ModeSettingsDialog.kt +++ b/app/src/main/java/com/droiddeck/launcher/ui/ModeSettingsDialog.kt @@ -270,6 +270,7 @@ fun ModeSettingsPage(s: ModeSettings, a: ModeSettingsActions) { listOf( SessionPrefs.OSC_AUTO to stringResource(R.string.common_auto), SessionPrefs.OSC_ALWAYS to stringResource(R.string.common_always), + SessionPrefs.OSC_STEAM_TOUCH to stringResource(R.string.osc_steam_touch), SessionPrefs.OSC_STEAM_QAM to stringResource(R.string.mode_osc_qam), SessionPrefs.OSC_NEVER to stringResource(R.string.common_never), ), s.oscMode, diff --git a/app/src/main/java/com/droiddeck/launcher/ui/SessionOverlay.kt b/app/src/main/java/com/droiddeck/launcher/ui/SessionOverlay.kt index ec5ed505f..a4fac96e0 100644 --- a/app/src/main/java/com/droiddeck/launcher/ui/SessionOverlay.kt +++ b/app/src/main/java/com/droiddeck/launcher/ui/SessionOverlay.kt @@ -217,9 +217,6 @@ class DrawerActions( val onSteamMenu: (() -> Unit)?, val onQam: (() -> Unit)?, val onOsc: (String) -> Unit, - /** Whose on-screen controls (SessionPrefs.OSC_STYLE_*); null where Steam's are not offered. */ - val oscStyle: String? = null, - val onOscStyle: (String) -> Unit = {}, /** Edits the Steam touch layout of the game in front, when Steam's controls are up. */ val onEditSteamTouch: (() -> Unit)? = null, val controller: com.droiddeck.launcher.input.ControllerPrefs.Settings? = null, @@ -423,14 +420,11 @@ internal fun SessionDrawer(open: Boolean, requestedPage: SessionDrawerPage, cont listOf(SessionPrefs.TOUCH_AUTO to stringResource(R.string.drawer_touch_auto, a.touchAuto), SessionPrefs.TOUCH_PAD to stringResource(R.string.mode_touch_touchpad), SessionPrefs.TOUCH_DIRECT to stringResource(R.string.mode_touch_direct), SessionPrefs.TOUCH_OFF to stringResource(R.string.widgets_off)), a.touchMode, chipModifier = focus.track(page, "touch"), onPick = a.onTouch) ChoiceRow(host, "osc", stringResource(R.string.mode_osc), null, - if (a.steam) listOf(SessionPrefs.OSC_AUTO to stringResource(R.string.common_auto), SessionPrefs.OSC_ALWAYS to stringResource(R.string.common_always), SessionPrefs.OSC_STEAM_QAM to stringResource(R.string.mode_osc_qam), SessionPrefs.OSC_NEVER to stringResource(R.string.common_never)) + if (a.steam) listOf(SessionPrefs.OSC_AUTO to stringResource(R.string.common_auto), SessionPrefs.OSC_ALWAYS to stringResource(R.string.common_always), SessionPrefs.OSC_STEAM_TOUCH to stringResource(R.string.osc_steam_touch), SessionPrefs.OSC_STEAM_QAM to stringResource(R.string.mode_osc_qam), SessionPrefs.OSC_NEVER to stringResource(R.string.common_never)) else listOf(SessionPrefs.OSC_AUTO to stringResource(R.string.common_auto), SessionPrefs.OSC_ALWAYS to stringResource(R.string.common_always), SessionPrefs.OSC_NEVER to stringResource(R.string.common_never)), - a.oscMode, chipModifier = focus.track(page, "osc"), onPick = a.onOsc) - a.oscStyle?.let { style -> - ChoiceRow(host, "osc-style", stringResource(R.string.osc_style), stringResource(R.string.osc_style_hint), - listOf(SessionPrefs.OSC_STYLE_DROIDDECK to stringResource(R.string.osc_style_droiddeck), SessionPrefs.OSC_STYLE_STEAM to stringResource(R.string.osc_style_steam)), - style, chipModifier = focus.track(page, "osc-style"), onPick = a.onOscStyle) - } + // Steam's touch controller is Steam's alone; elsewhere that choice behaves as Auto. + if (!a.steam && a.oscMode == SessionPrefs.OSC_STEAM_TOUCH) SessionPrefs.OSC_AUTO else a.oscMode, + chipModifier = focus.track(page, "osc"), onPick = a.onOsc) a.onEditSteamTouch?.let { edit -> ActionRow(stringResource(R.string.osc_steam_layout), stringResource(R.string.osc_steam_layout_hint), stringResource(R.string.ctrl_edit), edit) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 90f3f1429..c89c9a785 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -257,10 +257,7 @@ On-screen controls Steam + QAM Auto shows the controls when no controller is connected. - Touch controls - DroidDeck\'s own pad, or Steam\'s touch controller: per-game layouts and configs from Steam - DroidDeck - Steam (beta) + Steam touch (beta) Steam\'s touch controls start with the next Steam session Steam touch layout Move, resize or hide this game\'s touch controls; saved to Steam diff --git a/docs/development/steam-touch-controls.md b/docs/development/steam-touch-controls.md index 7163a1b83..9cb6bc1bb 100644 --- a/docs/development/steam-touch-controls.md +++ b/docs/development/steam-touch-controls.md @@ -1,6 +1,6 @@ # Steam's touch controls -Drawer → Controller → **Touch controls: Steam (beta)** replaces DroidDeck's own on-screen pad, in a +Drawer → Controller → **On-screen controls: Steam touch (beta)** replaces DroidDeck's own on-screen pad, in a Steam session, with Steam's touch controller: the one the Steam Link apps use. Bindings, action sets, per-game configs, Valve's touch templates, official and community touch configs and Steam Cloud sync are all Steam's; DroidDeck draws the controls and turns touches into the controller's @@ -35,8 +35,8 @@ SteamTouchConfig (Steam's configs) ←─── output reports ←── Ste - **Output reports from the client:** 4 = app id and action set (decides which layout is shown), 5/6 = action set layer added/removed, 1 = rumble (also sent to the app's vibration like any pad's), 3 = a setting. Feature report 2 is the battery. -- **Plugging.** The device is plugged in only while Steam's controls are shown: with Auto it steps - aside when a controller is connected, as Steam Link withdraws its touch controls. Unplugging +- **Plugging.** The device is plugged in only while Steam's controls are shown: always in a Steam + session with that choice, since a handheld's built-in pad would keep Auto off for good. Unplugging ends the device's report stream (the client lets the controller go); either way libfakeinput sends a udev event through `udevmon.c`'s stand-in monitor (`bl_udevmon_inject`), since the sandbox gives the client no kernel uevents and its HID discovery would never look again.