mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 19:11:08 +00:00
feat: let the built-in controller be turned off (#1207)
This commit is contained in:
1 parent
ed29f77fc2
commit
2b0c55f72e
6 files changed
+48
-8
No files matched your search
@@ -475,6 +475,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
|
||||
val bridge = PadBridge(File(LinuxRuntime.sessionRoot(this), "dev/input"))
|
||||
bridge.setSelectSteam(ControllerPrefs.read(this).selectSteam)
|
||||
bridge.setBuiltinPad(SessionState.mode != SessionService.MODE_STEAM || SessionPrefs.builtinPad(this))
|
||||
padBridge = bridge
|
||||
SessionState.padBridge = bridge
|
||||
if (Build.VERSION.SDK_INT >= 31) {
|
||||
@@ -2747,7 +2748,8 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
?.let { FileUtils.readString(it)?.trim()?.lowercase() }
|
||||
?: SessionPrefs.oscMode(this)
|
||||
val controls = onScreenControls ?: return
|
||||
if (pipUi || unfoldedPanel != null || pcKeyboardOpen) {
|
||||
if (pipUi || unfoldedPanel != null || pcKeyboardOpen ||
|
||||
(SessionState.mode == SessionService.MODE_STEAM && !SessionPrefs.builtinPad(this))) {
|
||||
onScreenButtonsVisible = false
|
||||
controls.releaseAll()
|
||||
controls.visibility = View.GONE
|
||||
|
||||
@@ -55,6 +55,7 @@ public final class PadBridge {
|
||||
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
private boolean open;
|
||||
private volatile boolean selectSteam;
|
||||
private volatile boolean builtinPad = true;
|
||||
private TouchRoute touchRoute;
|
||||
private final PadState routedTouch = new PadState();
|
||||
private boolean systemGuidePressed;
|
||||
@@ -110,6 +111,25 @@ public final class PadBridge {
|
||||
excluded = devices;
|
||||
}
|
||||
|
||||
public synchronized void setBuiltinPad(boolean on) {
|
||||
boolean changed = builtinPad != on;
|
||||
builtinPad = on;
|
||||
if (changed && !on) resetBuiltin();
|
||||
}
|
||||
|
||||
private void resetBuiltin() {
|
||||
routedTouch.clear();
|
||||
systemGuidePressed = false;
|
||||
systemQamPressed = false;
|
||||
qamTapPressed = false;
|
||||
qamChordActive = false;
|
||||
chordButtonPressed = false;
|
||||
qamChordGeneration++;
|
||||
chordHandler.removeCallbacksAndMessages(null);
|
||||
state.clear();
|
||||
publish();
|
||||
}
|
||||
|
||||
public synchronized boolean start() {
|
||||
if (!open) {
|
||||
open = writer.open();
|
||||
@@ -373,6 +393,7 @@ public final class PadBridge {
|
||||
}
|
||||
|
||||
public synchronized void applyTouch(java.util.function.Consumer<PadState> mutation) {
|
||||
if (!builtinPad) return;
|
||||
if (touchRoute != null && touchRoute.active()) {
|
||||
mutation.accept(routedTouch);
|
||||
touchRoute.accept(routedTouch);
|
||||
@@ -412,6 +433,7 @@ public final class PadBridge {
|
||||
}
|
||||
|
||||
public synchronized void setSystemButtons(boolean guidePressed, boolean qamPressed) {
|
||||
if (!builtinPad) return;
|
||||
if (systemGuidePressed == guidePressed && systemQamPressed == qamPressed) return;
|
||||
boolean qamStarted = qamPressed && !systemQamPressed;
|
||||
systemGuidePressed = guidePressed;
|
||||
@@ -443,6 +465,7 @@ public final class PadBridge {
|
||||
}
|
||||
|
||||
public synchronized void triggerQam() {
|
||||
if (!builtinPad) return;
|
||||
if (!nativeQam()) {
|
||||
startChord(PadState.A);
|
||||
return;
|
||||
@@ -461,6 +484,7 @@ public final class PadBridge {
|
||||
}
|
||||
|
||||
public synchronized void triggerSteamKeyboard() {
|
||||
if (!builtinPad) return;
|
||||
startChord(PadState.X);
|
||||
}
|
||||
|
||||
@@ -632,6 +656,7 @@ public final class PadBridge {
|
||||
}
|
||||
|
||||
private void publish() {
|
||||
if (!builtinPad && !open && owners[0] == NO_CONTROLLER && partners[0] == NO_CONTROLLER) return;
|
||||
if (!open && !start()) {
|
||||
statDropped++;
|
||||
return;
|
||||
|
||||
@@ -28,6 +28,7 @@ object SessionPrefs {
|
||||
const val CONTROLLER_STEAM = "steamcontroller"
|
||||
const val CONTROLLER_DS4 = "dualshock4"
|
||||
const val CONTROLLER_DUALSENSE = "dualsense"
|
||||
const val CONTROLLER_NONE = "none"
|
||||
const val OSC_AUTO = "auto"
|
||||
const val OSC_ALWAYS = "always"
|
||||
const val OSC_STEAM_QAM = "steam-qam"
|
||||
@@ -458,6 +459,8 @@ object SessionPrefs {
|
||||
fun steamController(context: Context): String =
|
||||
prefs(context).getString("steamController", CONTROLLER_DECK) ?: CONTROLLER_DECK
|
||||
fun setSteamController(context: Context, id: String) { prefs(context).edit().putString("steamController", id).apply() }
|
||||
|
||||
fun builtinPad(context: Context): Boolean = steamController(context) != CONTROLLER_NONE
|
||||
fun padType(id: String): Int = when (id) {
|
||||
CONTROLLER_STEAM -> com.droiddeck.launcher.input.FakeInputWriter.PAD_TYPE_STEAM
|
||||
CONTROLLER_XBOX360 -> com.droiddeck.launcher.input.FakeInputWriter.PAD_TYPE_XBOX
|
||||
|
||||
@@ -709,17 +709,21 @@ class SessionService : Service() {
|
||||
|
||||
private fun addControllerEnvironment(guest: MutableList<String>, fakeInputDir: File, sessionDir: File) {
|
||||
FakeInputWriter.prepareRingSlots(fakeInputDir, 4)
|
||||
val builtinPad = SessionPrefs.builtinPad(this)
|
||||
val hiddenPad = SessionState.mode == MODE_STEAM && !builtinPad
|
||||
fakeInputDir.listFiles()?.forEach { file ->
|
||||
val node = Regex("event(\\d+)").matchEntire(file.name)?.groupValues?.get(1)?.toIntOrNull()
|
||||
if (file.name.startsWith(".uinput-") || (node != null && node >= FIRST_VIRTUAL_PAD)) file.delete()
|
||||
if (file.name.startsWith(".uinput-") || (node != null && node >= FIRST_VIRTUAL_PAD) ||
|
||||
(hiddenPad && node == 0)) file.delete()
|
||||
}
|
||||
guest.add("FAKE_EVDEV_DIR=" + fakeInputDir.path)
|
||||
val rings = FakeInputWriter.getRingEnv(fakeInputDir)
|
||||
if (!rings.isNullOrEmpty()) guest.add("FAKE_EVDEV_MEMFD_PATHS=$rings")
|
||||
val presented = if (hiddenPad) rings?.split(';')?.filterNot { it.startsWith("0=") }?.joinToString(";") else rings
|
||||
if (!presented.isNullOrEmpty()) guest.add("FAKE_EVDEV_MEMFD_PATHS=$presented")
|
||||
guest.add("FAKE_EVDEV_IDENTITY=xbox360")
|
||||
guest.add("FAKE_EVDEV_VIBRATION=1")
|
||||
val uinput = !File(Environment.getExternalStorageDirectory(), NO_UINPUT_SWITCH).exists()
|
||||
val wantsDeck = uinput && SessionState.mode == MODE_STEAM &&
|
||||
val wantsDeck = uinput && builtinPad && SessionState.mode == MODE_STEAM &&
|
||||
SessionState.steamUi != "desktop" &&
|
||||
!File(Environment.getExternalStorageDirectory(), NO_DECK_PAD_SWITCH).exists()
|
||||
val wantsTouch = wantsDeck && !File(Environment.getExternalStorageDirectory(), NO_STEAM_TOUCH_SWITCH).exists()
|
||||
@@ -1740,7 +1744,9 @@ class SessionService : Service() {
|
||||
pads.add(String.format(java.util.Locale.ROOT, "\"%s\" (%04x:%04x)", d.name, d.vendorId, d.productId))
|
||||
}
|
||||
Log.i(TAG, "controllers at start: " + (if (pads.isEmpty()) "none" else pads.joinToString(", ")) +
|
||||
"; presented to the guest as " + if (SessionState.deckPad) "switchable, starting as " + SessionPrefs.steamController(this) else "an Xbox 360 controller")
|
||||
"; presented to the guest as " + if (SessionState.deckPad) "switchable, starting as " + SessionPrefs.steamController(this)
|
||||
else if (SessionState.mode == MODE_STEAM && !SessionPrefs.builtinPad(this)) "one per connected controller, no built-in pad"
|
||||
else "an Xbox 360 controller")
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -276,8 +276,10 @@ fun ModeSheetRows(s: ModeSettings, a: ModeSettingsActions, tab: String, extras:
|
||||
SessionPrefs.CONTROLLER_DS4 to stringResource(R.string.mode_controller_ds4),
|
||||
SessionPrefs.CONTROLLER_DUALSENSE to stringResource(R.string.mode_controller_dualsense),
|
||||
SessionPrefs.CONTROLLER_XBOX360 to stringResource(R.string.mode_controller_x360),
|
||||
SessionPrefs.CONTROLLER_NONE to stringResource(R.string.second_mode_none),
|
||||
), s.steamController,
|
||||
note = stringResource(R.string.mode_controller_note),
|
||||
note = if (s.steamController == SessionPrefs.CONTROLLER_NONE) stringResource(R.string.common_applies_next_session)
|
||||
else stringResource(R.string.mode_controller_note),
|
||||
onPick = a.onSteamController,
|
||||
)
|
||||
if (steam && s.unfoldedControls != null) ToggleRow(
|
||||
|
||||
@@ -82,9 +82,11 @@ internal class SecondScreenControls(
|
||||
keyboardHost = null
|
||||
closeTerminal()
|
||||
root.removeAllViews()
|
||||
if (currentMode == SecondScreenMode.NONE) return
|
||||
val mode = if (currentMode == SecondScreenMode.DECK_CONTROLS && !SessionState.deckPad) SecondScreenMode.NONE
|
||||
else currentMode
|
||||
if (mode == SecondScreenMode.NONE) return
|
||||
|
||||
when (currentMode) {
|
||||
when (mode) {
|
||||
SecondScreenMode.KEYBOARD_TRACKPAD -> renderKeyboardAndTrackpad()
|
||||
SecondScreenMode.TERMINAL -> renderTerminal()
|
||||
SecondScreenMode.DECK_CONTROLS -> root.addView(DeckControlsPanel(context, onClose, onSteamMenu, onQam, pad), weightParams())
|
||||
|
||||
Reference in new issue
Block a user