mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-12 03:21:08 +00:00
fix(input): make a hardware mouse and keyboard work like a PC (#2053)
* feat(gamescope): a three way switch for relative mouse motion Games that confine the cursor and warp it back to read movement never reach the nested hints rule, so their aim stays bounded by the screen. The convar defaults to 0 and leaves that rule alone; 1 forces relative motion for the focused game, 2 keeps the pointer absolute even when the rule would apply. (cherry picked from commitdb3d7555e0) * feat(input): the session carries a relative mouse mode per game Reads the mode from the game's gesture config, hands it to gamescope as gamescope_relative_mouse, and pushes a change to the running session through gamescopectl. (cherry picked from commite350d88464) * feat(drawer): the relative mouse switch is a three way choice Auto leaves it to the game, on forces relative motion, off keeps the pointer absolute. Named in all 32 locales so none of the three falls back to English. (cherry picked from commite96a187e02) * fix(input): follow the focused game's relative mouse mode Switching to a game whose saved mode differs left the session on the previous game's mode, since only the drawer state was refreshed. The requests also ran on a thread per selection, so two quick picks could reach gamescope out of order. (cherry picked from commit7ff8c5d568) * fix(input): retry the relative mouse mode gamescope did not take The drawer state moved before the request ran, so a failed request left the two out of step and the next focus change skipped the resend. (cherry picked from commitcf0f82d8cd) * fix(input): the relative mouse mode tracks the latest choice The guest agent answers ok when it handled the exec, so a failing gamescopectl was recorded as applied. Reconcile the newest desired mode on the worker thread after each request, and only mark applied when the command really exited zero. (cherry picked from commit5f5e3bd52e) * gamescope: a hidden cursor under any pointer constraint is relative Games that hide the cursor and confine the pointer had no lock hint, so the nested pointer stayed absolute and the camera froze. * Treat a hardware mouse as a real mouse in sessions A mouse now moves the guest pointer by relative motion for the whole session through pointer capture, so it no longer stops at screen edges or reaches system gestures. Its cursor stays visible in every touch mode, follows the game showing or hiding it, and clicks no longer press on-screen controls. * gamescope: use the mouse test release * Direct touch turns the camera while a game holds the pointer A swipe in direct touch now sends relative motion when a game has the pointer locked, including when the lock starts during the swipe, as when a game hides the cursor while a button is held. * Address review findings on mouse and touch input Keep touchpad taps on on-screen controls, cancel a pending long press during a locked swipe, let the three-finger gesture cancel a locked swipe, refresh capture when the output changes, and use the menu's key for the relative mouse setting. * Keep locked touches inside the game picture and free the mouse in touch editors * End touch editor ownership when the editor goes away * Bring the mouse cursor back when a touch editor closes * Release a pointer lock at the game's pointer * gamescope: use the pointer position test release * Fit the X screen to a fullscreen window larger than it * gamescope: use the X screen fit test release * Return the X screen when no game window has focus * gamescope: use the X screen return test release * ci: avoid redundant gamescope builds * fix: hardware mouse in Desktop and pointer warping games KWin nested on the host only reads relative motion while its own pointer lock is on, so a program that locked the pointer in Desktop (Blender orbit and pan) stopped receiving motion. A captured hardware mouse now turns that lock on, and a real Right Ctrl no longer toggles it. Gamescope follows a game's pointer warps instead of overriding them, and absolute motion also sends raw motion. Also retries relative mouse requests, tidies the unplug path, passes side buttons and fits a second oversized window correctly. * chore: use the gamescope build with patch 0131 * fix: Desktop mouse lock keeps retrying after early attempts fail * fix: hold the key that turns on the Desktop mouse lock KWin ignores a press and release delivered together. * fix: gamescope enters warp following sooner and keeps steady motion * chore: use gamescope p26 * Capture system keys in a focused session and keep the first Desktop mouse motion in place * Use the p27 gamescope build * Update the system keys row test * Recognise a captured mouse so the Desktop grab can start * Keep touch warps out of relative motion * Send Esc from keyboards that report it as Back * Use the p28 gamescope build * Release captured keys on pause, forward motion during a grab and wait for a pending screen fit * Use the p29 gamescope build * fix(input): keep held system keys consumed until they are released Copy each captured key event, since the service owns the original only for the callback, and consume the physical release of a key already released to the guest. Use the published gamescope p20. * fix(input): capture a system key only from its first press --------- Co-authored-by: kingokksa <kingokksa@qq.com> Co-authored-by: maxjivi05 <6025299+maxjivi05@users.noreply.github.com>
This commit is contained in:
56 files changed
+1210
-212
No files matched your search
@@ -19,7 +19,7 @@ permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: gamescope-${{ github.event_name }}-${{ github.ref }}-${{ inputs.tag || 'artifact' }}
|
||||
group: ${{ inputs.tag && format('gamescope-tag-{0}', inputs.tag) || format('gamescope-{0}-{1}', github.event_name, github.ref) }}
|
||||
cancel-in-progress: ${{ github.event_name == 'push' }}
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -324,11 +324,8 @@ class FrontEndActivity : ComponentActivity() {
|
||||
SteamIntegration.Feature.HOME -> if (HomeApp.isDefault(this)) HomeApp.openSystemHomeSettings(this) else offerHomeScreen()
|
||||
SteamIntegration.Feature.SHORTCUTS -> {
|
||||
if (!integrationState.shortcuts) shortcutsTried = true
|
||||
if (!HomeApp.isDefault(this)) configureIntegration(SteamIntegration.Feature.HOME)
|
||||
else {
|
||||
SteamIntegration.setShortcutsListed(this, true)
|
||||
integrationSettings(SteamIntegration.shortcutSettings(this), android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS)
|
||||
}
|
||||
SteamIntegration.setShortcutsListed(this, true)
|
||||
integrationSettings(SteamIntegration.shortcutSettings(this), android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,6 +224,8 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
private var steamImportAsk by mutableStateOf<com.droiddeck.launcher.session.SteamImportPrompt.Ask?>(null)
|
||||
private var steamImportAnswered: String? = null
|
||||
private var directHoldBehavior by mutableStateOf(com.droiddeck.launcher.input.TouchGestureConfig.MOUSE_BEHAVIOR_CLICK)
|
||||
private var relativeMouseMode by mutableIntStateOf(0)
|
||||
@Volatile private var appliedRelativeMouseMode: Int? = null
|
||||
private var screenKeyPickerOpen by mutableStateOf(false)
|
||||
private var screenKeyBind: List<Int>? = null
|
||||
private var screenKeyDir: Int? = null
|
||||
@@ -257,20 +259,29 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
private val cursorPosBuf = IntArray(2)
|
||||
private var cursorSerial = 0
|
||||
private var clientHidesCursor = false
|
||||
private var mouseOwnsCursor = false
|
||||
private var pointerLocked = false
|
||||
private var desktopGrabTapAt = 0L
|
||||
private var desktopGrabTaps = 0
|
||||
private var desktopMousePlaced = false
|
||||
private val pointerLockListener = WaylandCompositor.PointerLockListener { locked, _, _ ->
|
||||
uiHandler.post {
|
||||
if (pointerLocked == locked) return@post
|
||||
gesturePointerReady = false
|
||||
pointerLocked = locked
|
||||
Log.i(TAG, "pointer lock " + if (locked) "taken by a program" else "released")
|
||||
if (locked) openEvdevMouse() else closeEvdevMouse()
|
||||
if (locked) desktopGrabTaps = 0
|
||||
if (programLocksPointer()) openEvdevMouse() else closeEvdevMouse()
|
||||
padMouseCheckedAt = 0L
|
||||
if (::padMouse.isInitialized) padMouseMode()
|
||||
if (locked && ::touchpad.isInitialized) {
|
||||
drawnRect()?.let { touchpad.place(it.centerX(), it.centerY()) }
|
||||
cursorVisible = false
|
||||
}
|
||||
if (!locked && mouseOwnsCursor) {
|
||||
uiHandler.removeCallbacks(cursorResync)
|
||||
uiHandler.post(cursorResync)
|
||||
}
|
||||
updatePointerCapture()
|
||||
}
|
||||
}
|
||||
@@ -283,6 +294,13 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
override fun run() {
|
||||
if (syncClientCursor() && clientHidesCursor) {
|
||||
cursorVisible = false
|
||||
if (!mouseOwnsCursor) return
|
||||
}
|
||||
if (mouseOwnsCursor) {
|
||||
if (pointerLocked) return
|
||||
alignCursorToGuest()
|
||||
if (!clientHidesCursor) cursorVisible = true
|
||||
uiHandler.postDelayed(this, 60)
|
||||
return
|
||||
}
|
||||
if (touchDrivesPointer()) return
|
||||
@@ -564,6 +582,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
override fun onInputDeviceRemoved(deviceId: Int) {
|
||||
physicalShortcuts.onDeviceRemoved(deviceId)
|
||||
Log.i(TAG, "input device $deviceId disconnected")
|
||||
dropMouseCursor()
|
||||
backQamInput.onDeviceRemoved(deviceId)
|
||||
joyConVr?.refresh()
|
||||
padBridge?.onDeviceRemoved(deviceId)
|
||||
@@ -644,6 +663,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
override fun dispatchPointerCaptureChanged(hasCapture: Boolean) {
|
||||
super.dispatchPointerCaptureChanged(hasCapture)
|
||||
Log.i(TAG, "pointer capture " + if (hasCapture) "on" else "off")
|
||||
if (!hasCapture) uiHandler.postDelayed(::updatePointerCapture, 250)
|
||||
}
|
||||
}
|
||||
sessionRoot = root
|
||||
@@ -681,6 +701,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
bridge.setOnPlayerInput {
|
||||
lastPadInputMs = android.os.SystemClock.uptimeMillis()
|
||||
uiHandler.removeCallbacks(cursorHide)
|
||||
mouseOwnsCursor = false
|
||||
cursorVisible = false
|
||||
}
|
||||
onScreenControls = OnScreenControls(this, bridge, onKeyboard = ::togglePcKeyboard).also { controls ->
|
||||
@@ -700,7 +721,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
}
|
||||
keys.onAdd = { screenKeyPickerOpen = true }
|
||||
keys.onSelect = { codes -> screenKeyEdit = screenKeys?.stateOf(codes) }
|
||||
keys.onEditingChanged = { if (!it) screenKeyEdit = null }
|
||||
keys.onEditingChanged = { touchEditorChanged(); if (!it) screenKeyEdit = null }
|
||||
keys.steamStyle = { steamTouchControls?.style }
|
||||
keys.visibility = if (screenKeysShown) View.VISIBLE else View.GONE
|
||||
root.addView(keys)
|
||||
@@ -1316,7 +1337,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
onEvdevMouse = { on ->
|
||||
SessionPrefs.setEvdevMouse(this@SessionActivity, on)
|
||||
evdevMouseOn = on
|
||||
if (on) { if (pointerLocked) openEvdevMouse() } else releaseEvdevMouse()
|
||||
if (on) { if (programLocksPointer()) openEvdevMouse() } else releaseEvdevMouse()
|
||||
},
|
||||
directCursor = directCursorOn,
|
||||
onDirectCursor = { on ->
|
||||
@@ -1354,7 +1375,14 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
com.droiddeck.launcher.input.GesturePrefs.save(this@SessionActivity, gestureGame, base.copy(directHoldBehavior = value))
|
||||
refreshGestureConfig()
|
||||
},
|
||||
onScreenKeys = { drawerOpen = false; screenKeys?.startEditing() },
|
||||
relativeMouseMode = relativeMouseMode,
|
||||
onRelativeMouseMode = { mode ->
|
||||
val base = com.droiddeck.launcher.input.GesturePrefs.read(this@SessionActivity, gestureGame)
|
||||
com.droiddeck.launcher.input.GesturePrefs.save(this@SessionActivity, gestureGame, base.copy(relativeMouseMode = mode))
|
||||
relativeMouseMode = mode
|
||||
setRelativeMouse(mode)
|
||||
},
|
||||
onScreenKeys = { if (screenKeysShown) { drawerOpen = false; screenKeys?.startEditing() } },
|
||||
screenKeysShown = screenKeysShown,
|
||||
onScreenKeysShown = { shown ->
|
||||
screenKeysShown = shown
|
||||
@@ -2647,7 +2675,9 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
if (joyConVr?.onKeyEvent(event) == true) return true
|
||||
if (fromController && event.keyCode != KeyEvent.KEYCODE_BACK && padMouseMode() && padMouse.onKey(event)) return true
|
||||
if (event.keyCode != KeyEvent.KEYCODE_BACK && padBridge?.onKeyEvent(event) == true) return true
|
||||
if (CompositorHost.isStarted && event.keyCode != KeyEvent.KEYCODE_BACK && !fromController) {
|
||||
val keyboardKey = event.keyCode != KeyEvent.KEYCODE_BACK ||
|
||||
com.droiddeck.launcher.input.GuestKeys.isKeyboardEscape(event.keyCode, event.scanCode)
|
||||
if (CompositorHost.isStarted && keyboardKey && !fromController) {
|
||||
val down = event.action == KeyEvent.ACTION_DOWN
|
||||
if (down && event.repeatCount > 0) return true
|
||||
if (com.droiddeck.launcher.input.GuestKeys.send(event, ::sendGuestKey)) return true
|
||||
@@ -2694,6 +2724,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
if (event.isFromSource(android.view.InputDevice.SOURCE_MOUSE) && !drawerOpen) {
|
||||
if (appUiOwnsPointer()) {
|
||||
if (super.dispatchGenericMotionEvent(event)) return true
|
||||
if (touchEditorOpen) return false
|
||||
if (onMouse(event)) return true
|
||||
return false
|
||||
}
|
||||
@@ -2847,9 +2878,48 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
private fun layoutNames(): List<String> =
|
||||
com.droiddeck.launcher.input.ControllerPrefs.screenLayouts(this).keys.sorted()
|
||||
|
||||
private val relativeMouseRequests = java.util.concurrent.Executors.newSingleThreadExecutor { runnable ->
|
||||
Thread(runnable, "relative-mouse").apply { isDaemon = true }
|
||||
}
|
||||
@Volatile private var desiredRelativeMouseMode = 0
|
||||
|
||||
@Volatile private var relativeMouseRetries = 0
|
||||
|
||||
private fun setRelativeMouse(mode: Int) {
|
||||
desiredRelativeMouseMode = mode
|
||||
relativeMouseRetries = 0
|
||||
requestRelativeMouse()
|
||||
}
|
||||
|
||||
private fun requestRelativeMouse() {
|
||||
runCatching { relativeMouseRequests.execute { applyRelativeMouse() } }
|
||||
}
|
||||
|
||||
private fun applyRelativeMouse() {
|
||||
val mode = desiredRelativeMouseMode
|
||||
if (appliedRelativeMouseMode == mode) return
|
||||
val request = org.json.JSONObject()
|
||||
.put("kind", "exec")
|
||||
.put("argv", org.json.JSONArray(listOf("gamescopectl", "relative_mouse", mode.toString())))
|
||||
.put("timeout", 5.0)
|
||||
val result = runCatching { AgentGuest.call(this, request, 8_000, trusted = true) }
|
||||
val answer = result.getOrNull()
|
||||
val applied = answer?.optBoolean("ok") == true
|
||||
&& answer.optInt("exitCode", -1) == 0
|
||||
&& !answer.optBoolean("timedOut")
|
||||
if (applied) appliedRelativeMouseMode = mode
|
||||
else {
|
||||
Log.w(TAG, "gamescope did not take relative mouse $mode: ${result.exceptionOrNull() ?: answer}")
|
||||
if (relativeMouseRetries++ < RELATIVE_MOUSE_MAX_RETRIES) uiHandler.postDelayed({ requestRelativeMouse() }, 2_000)
|
||||
}
|
||||
if (desiredRelativeMouseMode != mode) requestRelativeMouse()
|
||||
}
|
||||
|
||||
private fun refreshGestureConfig() {
|
||||
gestureConfig = com.droiddeck.launcher.input.GesturePrefs.read(this, gestureGame)
|
||||
directHoldBehavior = gestureConfig.directHoldBehavior
|
||||
relativeMouseMode = gestureConfig.relativeMouseMode
|
||||
setRelativeMouse(relativeMouseMode)
|
||||
gestureTouchStreamGate.reset()
|
||||
if (::touchscreenGestures.isInitialized) touchscreenGestures.configure(gestureConfig)
|
||||
if (::directTouchHold.isInitialized) directTouchHold.configure(gestureConfig)
|
||||
@@ -3018,26 +3088,38 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
cursorVisible = false
|
||||
}
|
||||
|
||||
private fun movePointer(x: Float, y: Float) {
|
||||
private fun movePointer(x: Float, y: Float, fromMouse: Boolean = false) {
|
||||
val rect = drawnRect() ?: return
|
||||
val cx = x.coerceIn(rect.left, rect.right)
|
||||
val cy = y.coerceIn(rect.top, rect.bottom)
|
||||
WaylandCompositor.nativeSendPointer(1, InputSpace.x(cx, outputView().width), InputSpace.y(cy, outputView().height))
|
||||
showCursor(cx, cy)
|
||||
showCursor(cx, cy, fromMouse)
|
||||
}
|
||||
|
||||
private fun showCursor(x: Float, y: Float) {
|
||||
private fun moveCapturedMouse(dx: Float, dy: Float) {
|
||||
val rect = drawnRect() ?: return
|
||||
val scale = sceneScale(rect)
|
||||
WaylandCompositor.sendPointerDelta(dx, dy)
|
||||
showCursor(
|
||||
(cursorPos.x + dx / scale).coerceIn(rect.left, rect.right),
|
||||
(cursorPos.y + dy / scale).coerceIn(rect.top, rect.bottom),
|
||||
fromMouse = true,
|
||||
)
|
||||
}
|
||||
|
||||
private fun showCursor(x: Float, y: Float, fromMouse: Boolean = false) {
|
||||
cursorPos = androidx.compose.ui.geometry.Offset(x, y)
|
||||
syncClientCursor()
|
||||
mouseOwnsCursor = fromMouse
|
||||
uiHandler.removeCallbacks(cursorResync)
|
||||
cursorResyncIdle = 0
|
||||
if (!touchDrivesPointer()) uiHandler.postDelayed(cursorResync, 60)
|
||||
if (fromMouse || !touchDrivesPointer()) uiHandler.postDelayed(cursorResync, 60)
|
||||
if (clientHidesCursor) { cursorVisible = false; return }
|
||||
if (directTouchCursorHidden()) { cursorVisible = false; return }
|
||||
if (!fromMouse && directTouchCursorHidden()) { cursorVisible = false; return }
|
||||
if (android.os.SystemClock.uptimeMillis() - lastPadInputMs < CURSOR_PAD_HOLD_MS) return
|
||||
cursorVisible = true
|
||||
uiHandler.removeCallbacks(cursorHide)
|
||||
if (SessionState.mode == SessionService.MODE_STEAM && SessionState.steamUi != "desktop") uiHandler.postDelayed(cursorHide, 2500)
|
||||
if (!fromMouse && SessionState.mode == SessionService.MODE_STEAM && SessionState.steamUi != "desktop") uiHandler.postDelayed(cursorHide, 2500)
|
||||
}
|
||||
|
||||
private fun touchDrivesPointer(): Boolean =
|
||||
@@ -3562,6 +3644,11 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
}
|
||||
|
||||
private var ignoreGameTouch = false
|
||||
private var lockedTouchTurns = false
|
||||
private var touchEditorOpen by mutableStateOf(false)
|
||||
private var lockedSwipeUsed = false
|
||||
private var lockedSwipeX = 0f
|
||||
private var lockedSwipeY = 0f
|
||||
private var dismissTouch = false
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
@@ -3604,11 +3691,15 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
}
|
||||
com.droiddeck.launcher.input.TouchRouter.Route.SCROLL -> scrollTouch.onTouch(event)
|
||||
else -> {
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
||||
val inPicture = drawnRect()?.let { !topPictureMapped || it.contains(event.x, event.y) } ?: false
|
||||
lockedTouchTurns = programLocksPointer() && inPicture && route != com.droiddeck.launcher.input.TouchRouter.Route.TOUCHPAD
|
||||
}
|
||||
if (com.droiddeck.launcher.input.TouchRouter.steamKeyboardZone(snapshot)) {
|
||||
val wasActive = threeFingerTap.active
|
||||
if (threeFingerTap.onTouch(event)) padBridge?.triggerSteamKeyboard()
|
||||
if (threeFingerTap.active && !wasActive) {
|
||||
if (route == com.droiddeck.launcher.input.TouchRouter.Route.TOUCHPAD) touchpad.cancel()
|
||||
if (route == com.droiddeck.launcher.input.TouchRouter.Route.TOUCHPAD || lockedTouchTurns) touchpad.cancel()
|
||||
else {
|
||||
directTouchHold.cancel()
|
||||
WaylandCompositor.nativeSendTouch(3, -1, 0, 0)
|
||||
@@ -3616,7 +3707,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
}
|
||||
if (threeFingerTap.active || wasActive) return true
|
||||
}
|
||||
if (route == com.droiddeck.launcher.input.TouchRouter.Route.TOUCHPAD) {
|
||||
if (route == com.droiddeck.launcher.input.TouchRouter.Route.TOUCHPAD || lockedTouchTurns) {
|
||||
val rect = drawnRect() ?: return false
|
||||
if (touchpad.bounds != rect) {
|
||||
val fresh = touchpad.bounds.width() <= 1f
|
||||
@@ -3668,8 +3759,25 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
}
|
||||
|
||||
private fun forwardTouch(event: MotionEvent, rect: android.graphics.RectF): Boolean {
|
||||
val swipeX = lockedSwipeX
|
||||
val swipeY = lockedSwipeY
|
||||
lockedSwipeX = event.x
|
||||
lockedSwipeY = event.y
|
||||
if ((event.actionMasked == MotionEvent.ACTION_UP || event.actionMasked == MotionEvent.ACTION_CANCEL) && lockedSwipeUsed) {
|
||||
lockedSwipeUsed = false
|
||||
directTouchHold.cancel()
|
||||
return true
|
||||
}
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) lockedSwipeUsed = false
|
||||
if (programLocksPointer() && event.actionMasked == MotionEvent.ACTION_MOVE) {
|
||||
lockedSwipeUsed = true
|
||||
directTouchHold.cancelPendingHold()
|
||||
val scale = sceneScale(rect)
|
||||
sendSceneDelta((event.x - swipeX) * scale, (event.y - swipeY) * scale)
|
||||
return true
|
||||
}
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
||||
showCursor(event.x.coerceIn(rect.left, rect.right), event.y.coerceIn(rect.top, rect.bottom))
|
||||
if (!pointerLocked) showCursor(event.x.coerceIn(rect.left, rect.right), event.y.coerceIn(rect.top, rect.bottom))
|
||||
if (WaylandCompositor.nativeFocusTakesTouch()) {
|
||||
listOf(PointerGestures.BTN_LEFT, PointerGestures.BTN_RIGHT, PointerGestures.BTN_MIDDLE).forEach {
|
||||
WaylandCompositor.nativeSendSceneInput(3, it, 0)
|
||||
@@ -3683,12 +3791,14 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
private fun onMouse(event: MotionEvent): Boolean {
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_HOVER_MOVE, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_HOVER_ENTER ->
|
||||
if (evdevMouseActive) sendMouseDelta(event.x, event.y) else movePointer(event.x, event.y)
|
||||
if (evdevMouseActive) sendMouseDelta(event.x, event.y) else movePointer(event.x, event.y, fromMouse = true)
|
||||
MotionEvent.ACTION_BUTTON_PRESS, MotionEvent.ACTION_BUTTON_RELEASE -> {
|
||||
if (evdevMouseActive) sendMouseDelta(event.x, event.y) else movePointer(event.x, event.y)
|
||||
if (evdevMouseActive) sendMouseDelta(event.x, event.y) else movePointer(event.x, event.y, fromMouse = true)
|
||||
val button = when (event.actionButton) {
|
||||
MotionEvent.BUTTON_SECONDARY -> PointerGestures.BTN_RIGHT
|
||||
MotionEvent.BUTTON_TERTIARY -> PointerGestures.BTN_MIDDLE
|
||||
MotionEvent.BUTTON_BACK -> BTN_SIDE
|
||||
MotionEvent.BUTTON_FORWARD -> BTN_EXTRA
|
||||
else -> PointerGestures.BTN_LEFT
|
||||
}
|
||||
sendSceneButton(button, event.actionMasked == MotionEvent.ACTION_BUTTON_PRESS)
|
||||
@@ -3703,23 +3813,79 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun mouseAttached(): Boolean = InputDevice.getDeviceIds().any { id ->
|
||||
private fun isHardwareMouse(d: InputDevice?): Boolean =
|
||||
d != null && !d.isVirtual && (d.supportsSource(InputDevice.SOURCE_MOUSE) || d.supportsSource(InputDevice.SOURCE_MOUSE_RELATIVE))
|
||||
|
||||
private fun mouseAttached(): Boolean = InputDevice.getDeviceIds().any { isHardwareMouse(InputDevice.getDevice(it)) }
|
||||
|
||||
private fun relativeMouseAttached(): Boolean = !isInMultiWindowMode && !glassesOutputActive && InputDevice.getDeviceIds().any { id ->
|
||||
val d = InputDevice.getDevice(id)
|
||||
d != null && !d.isVirtual && d.supportsSource(InputDevice.SOURCE_MOUSE)
|
||||
isHardwareMouse(d) && d?.supportsSource(InputDevice.SOURCE_TOUCHPAD) != true
|
||||
}
|
||||
|
||||
private fun updatePointerCapture() {
|
||||
if (!::surfaceView.isInitialized) return
|
||||
val view = window.decorView
|
||||
val want = pointerLocked && resumed && hasWindowFocus() && !drawerOpen && !pcKeyboardOpen && !achievementsOpen && !pipUi && !bottomOutputActive && mouseAttached()
|
||||
val want = (pointerLocked || relativeMouseAttached()) && resumed && hasWindowFocus() && !drawerOpen && !pcKeyboardOpen && !achievementsOpen && !pipUi && !bottomOutputActive && !touchEditorOpen && mouseAttached()
|
||||
releaseDesktopMouseGrab()
|
||||
if (want == view.hasPointerCapture()) return
|
||||
if (want) view.requestPointerCapture() else view.releasePointerCapture()
|
||||
}
|
||||
|
||||
private fun programLocksPointer(): Boolean =
|
||||
pointerLocked && SessionState.mode != SessionService.MODE_DESKTOP
|
||||
|
||||
private fun desktopMouseGrabAllowed(): Boolean =
|
||||
SessionState.mode == SessionService.MODE_DESKTOP && relativeMouseAttached() && !bottomOutputActive
|
||||
|
||||
private fun tapDesktopGrabKey() {
|
||||
val now = android.os.SystemClock.uptimeMillis()
|
||||
if (now - desktopGrabTapAt < DESKTOP_GRAB_TAP_MS) return
|
||||
desktopGrabTapAt = now
|
||||
desktopGrabTaps++
|
||||
WaylandCompositor.nativeSendKey(KEY_RIGHTCTRL, 1)
|
||||
uiHandler.postDelayed({ WaylandCompositor.nativeSendKey(KEY_RIGHTCTRL, 0) }, DESKTOP_GRAB_KEY_HOLD_MS)
|
||||
}
|
||||
|
||||
private fun grabDesktopMouse() {
|
||||
if (!desktopMouseGrabAllowed()) return
|
||||
if (desktopGrabTaps >= DESKTOP_GRAB_MAX_TAPS) {
|
||||
if (android.os.SystemClock.uptimeMillis() - desktopGrabTapAt < DESKTOP_GRAB_RETRY_MS) return
|
||||
desktopGrabTaps = 0
|
||||
}
|
||||
if (!desktopMousePlaced) {
|
||||
desktopMousePlaced = true
|
||||
drawnRect()?.let { movePointer(it.centerX(), it.centerY()) }
|
||||
}
|
||||
tapDesktopGrabKey()
|
||||
}
|
||||
|
||||
private fun releaseDesktopMouseGrab() {
|
||||
if (pointerLocked && SessionState.mode == SessionService.MODE_DESKTOP && !desktopMouseGrabAllowed()) tapDesktopGrabKey()
|
||||
}
|
||||
|
||||
private fun dropMouseCursor() {
|
||||
if (!mouseOwnsCursor || mouseAttached()) return
|
||||
mouseOwnsCursor = false
|
||||
uiHandler.removeCallbacks(cursorResync)
|
||||
cursorVisible = false
|
||||
}
|
||||
|
||||
override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean, newConfig: android.content.res.Configuration) {
|
||||
super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig)
|
||||
updatePointerCapture()
|
||||
}
|
||||
|
||||
private var platformPointerShown: Boolean? = null
|
||||
|
||||
private fun touchEditorChanged() {
|
||||
touchEditorOpen = screenKeys?.isEditing == true || steamTouchControls?.isEditing == true
|
||||
updatePointerCapture()
|
||||
applyPlatformPointer(appUiOwnsPointer())
|
||||
}
|
||||
|
||||
private fun appUiOwnsPointer(): Boolean =
|
||||
drawerOpen || pcKeyboardOpen || achievementsOpen || pipUi || glassesOutputActive || bottomOutputActive
|
||||
drawerOpen || pcKeyboardOpen || achievementsOpen || pipUi || glassesOutputActive || bottomOutputActive || touchEditorOpen
|
||||
|
||||
private fun applyPlatformPointer(shown: Boolean) {
|
||||
if (!::sessionRoot.isInitialized || !::surfaceView.isInitialized) return
|
||||
@@ -3732,7 +3898,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
}
|
||||
|
||||
private fun onCapturedPointer(event: MotionEvent): Boolean {
|
||||
if (!pointerLocked || !event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)) return false
|
||||
if (!event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)) return false
|
||||
notePress(event)
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
@@ -3742,7 +3908,11 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
dx += event.getHistoricalX(i)
|
||||
dy += event.getHistoricalY(i)
|
||||
}
|
||||
sendSceneDelta(dx, dy)
|
||||
if (pointerLocked) sendSceneDelta(dx, dy)
|
||||
else {
|
||||
grabDesktopMouse()
|
||||
moveCapturedMouse(dx, dy)
|
||||
}
|
||||
}
|
||||
MotionEvent.ACTION_BUTTON_PRESS, MotionEvent.ACTION_BUTTON_RELEASE -> {
|
||||
val button = when (event.actionButton) {
|
||||
@@ -3773,6 +3943,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
val device = com.droiddeck.launcher.input.SteamTouchDevice.current ?: return null
|
||||
steamTouchControls?.let { view ->
|
||||
if (view.device === device) return view
|
||||
view.cancelEditing()
|
||||
view.releaseAll()
|
||||
(view.parent as? android.view.ViewGroup)?.removeView(view)
|
||||
steamTouchControls = null
|
||||
@@ -3781,6 +3952,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
val view = com.droiddeck.launcher.input.SteamTouchControls(this, device,
|
||||
onMenu = { drawerOpen = true }, onKeyboard = ::togglePcKeyboard)
|
||||
view.visibility = View.GONE
|
||||
view.onEditingChanged = { touchEditorChanged() }
|
||||
view.onOptions = { options ->
|
||||
steamTouchOptions = options
|
||||
applyTouchRouting()
|
||||
@@ -3827,7 +3999,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
onScreenButtonsVisible = false
|
||||
controls.releaseAll()
|
||||
controls.visibility = View.GONE
|
||||
steamTouchControls?.let { it.releaseAll(); it.visibility = View.GONE }
|
||||
steamTouchControls?.let { it.cancelEditing(); it.releaseAll(); it.visibility = View.GONE }
|
||||
com.droiddeck.launcher.input.SteamTouchDevice.current?.plugged = false
|
||||
screenKeys?.followSteam = false
|
||||
applyTouchRouting()
|
||||
@@ -3841,7 +4013,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
uiHandler.postDelayed(steamTouchRetry, 1000)
|
||||
}
|
||||
if (steam == null) {
|
||||
steamTouchControls?.let { it.releaseAll(); it.visibility = View.GONE }
|
||||
steamTouchControls?.let { it.cancelEditing(); it.releaseAll(); it.visibility = View.GONE }
|
||||
com.droiddeck.launcher.input.SteamTouchDevice.current?.plugged = false
|
||||
applyTouchRouting()
|
||||
}
|
||||
@@ -3860,7 +4032,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
if (steam != null) {
|
||||
screenKeys?.followSteam = drawn
|
||||
if (controls.visibility == View.VISIBLE) { controls.releaseAll(); controls.visibility = View.GONE }
|
||||
if (!drawn) steam.releaseAll()
|
||||
if (!drawn) { steam.cancelEditing(); steam.releaseAll() }
|
||||
steam.visibility = if (drawn) View.VISIBLE else View.GONE
|
||||
com.droiddeck.launcher.input.SteamTouchDevice.current?.plugged = show
|
||||
applyTouchRouting()
|
||||
@@ -3935,8 +4107,9 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
private fun keyboardCoversPad() =
|
||||
SessionState.mode == SessionService.MODE_STEAM && AgentGuest.steamKeyboard
|
||||
|
||||
private fun sendGuestKey(code: Int, down: Boolean) {
|
||||
private fun sendGuestKey(key: Int, down: Boolean) {
|
||||
if (down && pipUi) return
|
||||
val code = if (key == KEY_RIGHTCTRL && SessionState.mode == SessionService.MODE_DESKTOP) KEY_LEFTCTRL else key
|
||||
if (down) guestKeysDown.add(code) else guestKeysDown.remove(code)
|
||||
if (down || code !in gestureKeysDown) WaylandCompositor.nativeSendKey(code, if (down) 1 else 0)
|
||||
}
|
||||
@@ -4135,6 +4308,9 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
com.droiddeck.launcher.input.SystemKeyCapture.attach(this, { hasWindowFocus() && !appUiOwnsPointer() && CompositorHost.isStarted }) { event ->
|
||||
com.droiddeck.launcher.input.GuestKeys.send(event, ::sendGuestKey)
|
||||
}
|
||||
if (refreshActivityDisplayId() && started) {
|
||||
SessionService.setActivityDisplay(this, sessionActivityDisplayId)
|
||||
}
|
||||
@@ -4178,6 +4354,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
com.droiddeck.launcher.input.SystemKeyCapture.detach(this)
|
||||
com.droiddeck.launcher.input.HomeButtonShortcuts.detach(this)
|
||||
if (runtimeRemovalBlocked) { super.onPause(); return }
|
||||
physicalShortcuts.clear()
|
||||
@@ -4420,6 +4597,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
if (holder !== outputHolder()) return
|
||||
glassesOutputActive = glassesScreen?.holder === holder
|
||||
bottomOutputActive = bottomGame?.holder === holder
|
||||
updatePointerCapture()
|
||||
if (bottomOutputActive) bottomRecoveries = 0
|
||||
if (CompositorHost.isStarted) WaylandCompositor.nativeSetCursorComposite(glassesOutputActive || bottomOutputActive)
|
||||
surfaceView.visibility = if (glassesOutputActive || bottomOutputActive) View.INVISIBLE else View.VISIBLE
|
||||
@@ -4794,6 +4972,7 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
|
||||
override fun onDestroy() {
|
||||
com.droiddeck.launcher.input.HomeButtonShortcuts.detach(this)
|
||||
relativeMouseRequests.shutdownNow()
|
||||
backQamInput.cancel()
|
||||
steamVrRecovery.close()
|
||||
uiHandler.removeCallbacks(steamTouchRetry)
|
||||
@@ -4908,6 +5087,14 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
|
||||
private const val PAD_SCROLL_HEIGHTS_PER_S = 3f
|
||||
private const val AXIS_UNITS_PER_PIXEL = 3f
|
||||
private const val KEY_LEFTCTRL = 29
|
||||
private const val KEY_RIGHTCTRL = 97
|
||||
private const val BTN_SIDE = 0x113
|
||||
private const val BTN_EXTRA = 0x114
|
||||
private const val DESKTOP_GRAB_TAP_MS = 500L
|
||||
private const val DESKTOP_GRAB_MAX_TAPS = 8
|
||||
private const val DESKTOP_GRAB_RETRY_MS = 30_000L
|
||||
private const val DESKTOP_GRAB_KEY_HOLD_MS = 40L
|
||||
private const val RELATIVE_MOUSE_MAX_RETRIES = 5
|
||||
private const val DRAWER_HAT_THRESHOLD = 0.5f
|
||||
private const val DRAWER_STICK_ENTER_THRESHOLD = 0.55f
|
||||
private const val DRAWER_STICK_EXIT_THRESHOLD = 0.35f
|
||||
|
||||
@@ -66,6 +66,10 @@ class DirectTouchHold(
|
||||
held = false
|
||||
}
|
||||
|
||||
fun cancelPendingHold() {
|
||||
handler.removeCallbacks(hold)
|
||||
}
|
||||
|
||||
fun onTouch(event: MotionEvent): Boolean {
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
||||
if (liftPending) {
|
||||
|
||||
@@ -7,7 +7,7 @@ object GuestKeys {
|
||||
fun send(event: KeyEvent, sendKey: (code: Int, down: Boolean) -> Unit): Boolean {
|
||||
val down = event.action == KeyEvent.ACTION_DOWN
|
||||
if (!down && event.action != KeyEvent.ACTION_UP) return false
|
||||
var evdev = EvdevKeys.fromKeyCode(event.keyCode)
|
||||
var evdev = if (isKeyboardEscape(event.keyCode, event.scanCode)) KEY_ESC else EvdevKeys.fromKeyCode(event.keyCode)
|
||||
val ch = event.unicodeChar
|
||||
val plain = if (ch > 0) EvdevKeys.unshiftedChar(ch) else 0
|
||||
if (evdev <= 0 && ch > 0) {
|
||||
@@ -27,5 +27,9 @@ object GuestKeys {
|
||||
return true
|
||||
}
|
||||
|
||||
fun isKeyboardEscape(keyCode: Int, scanCode: Int): Boolean =
|
||||
keyCode == KeyEvent.KEYCODE_BACK && scanCode == KEY_ESC
|
||||
|
||||
private const val KEY_ESC = 1
|
||||
private const val KEY_LEFTSHIFT = 42
|
||||
}
|
||||
@@ -45,6 +45,62 @@ object HomeButtonShortcuts {
|
||||
fun onDeviceRemoved(device: Int) = input.onDeviceRemoved(device)
|
||||
}
|
||||
|
||||
object SystemKeyCapture {
|
||||
private var owner: Any? = null
|
||||
private var active: () -> Boolean = { false }
|
||||
private var send: (KeyEvent) -> Unit = {}
|
||||
private val held = HashMap<Pair<Int, Int>, KeyEvent>()
|
||||
private val releasing = HashSet<Pair<Int, Int>>()
|
||||
internal var isKeyboard: (KeyEvent) -> Boolean = ::fromKeyboard
|
||||
|
||||
fun attach(owner: Any, active: () -> Boolean, send: (KeyEvent) -> Unit) {
|
||||
this.owner = owner
|
||||
this.active = active
|
||||
this.send = send
|
||||
}
|
||||
|
||||
fun detach(owner: Any) {
|
||||
if (this.owner !== owner) return
|
||||
held.values.forEach { send(KeyEvent.changeAction(it, KeyEvent.ACTION_UP)) }
|
||||
releasing += held.keys
|
||||
held.clear()
|
||||
this.owner = null
|
||||
active = { false }
|
||||
send = {}
|
||||
}
|
||||
|
||||
internal fun captures(keyCode: Int, metaState: Int): Boolean = when {
|
||||
keyCode == KeyEvent.KEYCODE_META_LEFT || keyCode == KeyEvent.KEYCODE_META_RIGHT -> true
|
||||
metaState and KeyEvent.META_META_ON != 0 -> true
|
||||
metaState and KeyEvent.META_ALT_ON != 0 -> keyCode == KeyEvent.KEYCODE_TAB || keyCode == KeyEvent.KEYCODE_ESCAPE
|
||||
else -> false
|
||||
}
|
||||
|
||||
private fun fromKeyboard(event: KeyEvent): Boolean =
|
||||
event.device?.let { !it.isVirtual && it.keyboardType == android.view.InputDevice.KEYBOARD_TYPE_ALPHABETIC } == true
|
||||
|
||||
fun onKeyEvent(event: KeyEvent): Boolean {
|
||||
val key = event.deviceId to event.keyCode
|
||||
if (event.action == KeyEvent.ACTION_DOWN && event.repeatCount == 0) {
|
||||
releasing -= key
|
||||
} else if (key in releasing) {
|
||||
if (event.action == KeyEvent.ACTION_UP) releasing -= key
|
||||
return true
|
||||
}
|
||||
val taken = when (event.action) {
|
||||
KeyEvent.ACTION_DOWN -> {
|
||||
val take = key in held || (event.repeatCount == 0 && active() && isKeyboard(event) && captures(event.keyCode, event.metaState))
|
||||
if (take) held[key] = KeyEvent(event)
|
||||
take
|
||||
}
|
||||
KeyEvent.ACTION_UP -> held.remove(key) != null
|
||||
else -> false
|
||||
}
|
||||
if (taken) send(event)
|
||||
return taken
|
||||
}
|
||||
}
|
||||
|
||||
class HomeButtonService : AccessibilityService(), InputManager.InputDeviceListener {
|
||||
private var bottomScreen: BottomScreenWatch? = null
|
||||
|
||||
@@ -58,7 +114,8 @@ class HomeButtonService : AccessibilityService(), InputManager.InputDeviceListen
|
||||
bottomScreen = null
|
||||
}
|
||||
|
||||
override fun onKeyEvent(event: KeyEvent) = HomeButtonShortcuts.onKeyEvent(this, event)
|
||||
override fun onKeyEvent(event: KeyEvent) =
|
||||
SystemKeyCapture.onKeyEvent(event) || HomeButtonShortcuts.onKeyEvent(this, event)
|
||||
override fun onAccessibilityEvent(event: AccessibilityEvent?) { event?.let { bottomScreen?.onEvent(it) } }
|
||||
override fun onInterrupt() { HomeButtonShortcuts.release() }
|
||||
override fun onInputDeviceAdded(deviceId: Int) {}
|
||||
|
||||
@@ -519,6 +519,7 @@ class OnScreenControls(
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
if (editing) return onEditTouch(event)
|
||||
if (event.getToolType(event.actionIndex) == MotionEvent.TOOL_TYPE_MOUSE) return false
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN -> {
|
||||
val index = event.actionIndex
|
||||
|
||||
@@ -56,6 +56,7 @@ class ScreenKeys(context: Context, private val sendKey: (Int, Boolean) -> Unit)
|
||||
private var guideY = -1f
|
||||
private val addPress = Runnable { addX = pressX; addY = pressY; onAdd?.invoke() }
|
||||
private var editing = false
|
||||
val isEditing get() = editing
|
||||
private var selected: Entry? = null
|
||||
private var dragX = 0f
|
||||
private var dragY = 0f
|
||||
@@ -811,6 +812,7 @@ class ScreenKeys(context: Context, private val sendKey: (Int, Boolean) -> Unit)
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean = if (editing) editTouch(event) else playTouch(event)
|
||||
|
||||
private fun playTouch(event: MotionEvent): Boolean {
|
||||
if (event.getToolType(event.actionIndex) == MotionEvent.TOOL_TYPE_MOUSE) return false
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN -> {
|
||||
val index = event.actionIndex
|
||||
|
||||
@@ -107,6 +107,7 @@ class SteamTouchControls(
|
||||
var onTouchMiss: ((MotionEvent) -> Unit)? = null
|
||||
|
||||
private var editing = false
|
||||
var onEditingChanged: ((Boolean) -> Unit)? = null
|
||||
private var editElements: MutableList<Element> = mutableListOf()
|
||||
private var hidden: MutableList<Element> = mutableListOf()
|
||||
private var selected = -1
|
||||
@@ -617,6 +618,7 @@ class SteamTouchControls(
|
||||
}
|
||||
return true
|
||||
}
|
||||
if (event.getToolType(event.actionIndex) == MotionEvent.TOOL_TYPE_MOUSE) return false
|
||||
val index = event.actionIndex
|
||||
lastTouchMs = android.os.SystemClock.uptimeMillis()
|
||||
if (faded) { faded = false; invalidate() }
|
||||
@@ -705,6 +707,7 @@ class SteamTouchControls(
|
||||
fun startEditing() {
|
||||
releaseAll()
|
||||
editing = true
|
||||
onEditingChanged?.invoke(true)
|
||||
editSets.clear()
|
||||
selected = -1
|
||||
pendingBindings.clear()
|
||||
@@ -755,8 +758,13 @@ class SteamTouchControls(
|
||||
actionSet = saved
|
||||
}
|
||||
|
||||
fun cancelEditing() {
|
||||
if (editing) stopEditing()
|
||||
}
|
||||
|
||||
private fun stopEditing() {
|
||||
editing = false
|
||||
onEditingChanged?.invoke(false)
|
||||
trayOpen = false
|
||||
trayDrag = null
|
||||
selected = -1
|
||||
|
||||
@@ -39,6 +39,7 @@ data class TouchGestureConfig(
|
||||
val showGestureDebugOverlay: Boolean = false,
|
||||
val gestureThreshold: Int = DEFAULT_GESTURE_THRESHOLD,
|
||||
val mouseDragMovementMode: String = MOUSE_DRAG_MOVEMENT_DIRECT,
|
||||
val relativeMouseMode: Int = RELATIVE_MOUSE_AUTO,
|
||||
) {
|
||||
|
||||
fun toJson(): String {
|
||||
@@ -75,6 +76,7 @@ data class TouchGestureConfig(
|
||||
put(KEY_SHOW_GESTURE_DEBUG_OVERLAY, showGestureDebugOverlay)
|
||||
put(KEY_GESTURE_THRESHOLD, gestureThreshold)
|
||||
put(KEY_MOUSE_DRAG_MOVEMENT_MODE, mouseDragMovementMode)
|
||||
put(KEY_RELATIVE_MOUSE_MODE, relativeMouseMode)
|
||||
}.toString()
|
||||
}
|
||||
|
||||
@@ -91,6 +93,10 @@ data class TouchGestureConfig(
|
||||
|
||||
const val MOUSE_DRAG_MOVEMENT_DIRECT = "direct"
|
||||
const val MOUSE_DRAG_MOVEMENT_RELATIVE = "relative"
|
||||
|
||||
const val RELATIVE_MOUSE_AUTO = 0
|
||||
const val RELATIVE_MOUSE_ON = 1
|
||||
const val RELATIVE_MOUSE_OFF = 2
|
||||
const val ACTION_SHOW_KEYBOARD = "show_keyboard"
|
||||
const val ACTION_KEY_ESC = "key_ESC"
|
||||
const val ACTION_KEY_TILDE = "key_TILDE"
|
||||
@@ -114,6 +120,7 @@ data class TouchGestureConfig(
|
||||
private const val KEY_LONG_PRESS_MOUSE_BEHAVIOR = "longPressMouseBehavior"
|
||||
private const val KEY_LONG_PRESS_DELAY = "longPressDelay"
|
||||
private const val KEY_DIRECT_HOLD_BEHAVIOR = "directHoldBehavior"
|
||||
private const val KEY_RELATIVE_MOUSE_MODE = "relativeMouseMode"
|
||||
private const val KEY_DOUBLE_TAP_ENABLED = "doubleTapEnabled"
|
||||
private const val KEY_DOUBLE_TAP_DELAY = "doubleTapDelay"
|
||||
private const val KEY_TWO_FINGER_DRAG_ENABLED = "twoFingerDragEnabled"
|
||||
@@ -191,6 +198,7 @@ data class TouchGestureConfig(
|
||||
mouseDragMovementMode = normalizeMouseDragMovementMode(
|
||||
obj.optString(KEY_MOUSE_DRAG_MOVEMENT_MODE, MOUSE_DRAG_MOVEMENT_DIRECT),
|
||||
),
|
||||
relativeMouseMode = normalizeRelativeMouseMode(obj.optInt(KEY_RELATIVE_MOUSE_MODE, RELATIVE_MOUSE_AUTO)),
|
||||
)
|
||||
} catch (_: Exception) {
|
||||
fallbackDefaults()
|
||||
@@ -205,6 +213,10 @@ data class TouchGestureConfig(
|
||||
return if (value == MOUSE_BEHAVIOR_CLICK) MOUSE_BEHAVIOR_CLICK else MOUSE_BEHAVIOR_HOLD
|
||||
}
|
||||
|
||||
private fun normalizeRelativeMouseMode(mode: Int): Int {
|
||||
return if (mode in RELATIVE_MOUSE_AUTO..RELATIVE_MOUSE_OFF) mode else RELATIVE_MOUSE_AUTO
|
||||
}
|
||||
|
||||
private fun normalizeMouseDragMovementMode(mode: String?): String {
|
||||
return if (mode == MOUSE_DRAG_MOVEMENT_RELATIVE) {
|
||||
MOUSE_DRAG_MOVEMENT_RELATIVE
|
||||
|
||||
@@ -775,6 +775,12 @@ class SessionService : Service() {
|
||||
return sessionDir
|
||||
}
|
||||
|
||||
private fun relativeMouseForSession(): Int {
|
||||
val game = if (SessionState.mode == MODE_RUN) SessionState.program?.let { "program:$it" }
|
||||
else SessionState.gameId?.toLongOrNull()?.toString()
|
||||
return com.droiddeck.launcher.input.GesturePrefs.read(this, game).relativeMouseMode
|
||||
}
|
||||
|
||||
private fun addClientEnvironment(guest: MutableList<String>, steamHere: Boolean, agentEnvironment: List<String>) {
|
||||
guest.add("/usr/bin/env")
|
||||
guest.add("-i")
|
||||
@@ -846,6 +852,7 @@ class SessionService : Service() {
|
||||
guest.add("BL_FSYNC_FIRST=" + (if (SessionPrefs.fsyncFirst(this)) "1" else "0"))
|
||||
guest.add("BL_GAMESCOPE_REALTIME=" + (if (SessionPrefs.gamescopeRealtime(this)) "1" else "0"))
|
||||
if (SessionPrefs.cursorComposite(this)) guest.add("BL_CURSOR_COMPOSITE=1")
|
||||
relativeMouseForSession().takeIf { it != 0 }?.let { guest.add("gamescope_relative_mouse=$it") }
|
||||
if (com.droiddeck.launcher.core.ZramSupport.supported()) {
|
||||
guest.add("BL_ZRAM=1")
|
||||
if (steamHere) SessionPrefs.ramCapMb(this).takeIf { it > 0 }?.let { guest.add("BL_RAM_CAP_MB=$it") }
|
||||
|
||||
@@ -282,6 +282,8 @@ class DrawerActions(
|
||||
val onLowLatency: (Boolean) -> Unit = {},
|
||||
val evdevMouse: Boolean = false,
|
||||
val onEvdevMouse: (Boolean) -> Unit = {},
|
||||
val relativeMouseMode: Int = 0,
|
||||
val onRelativeMouseMode: (Int) -> Unit = {},
|
||||
val directCursor: Boolean = false,
|
||||
val onDirectCursor: (Boolean) -> Unit = {},
|
||||
val onTouch: (String) -> Unit,
|
||||
@@ -599,6 +601,8 @@ internal fun SessionDrawer(open: Boolean, requestedPage: SessionDrawerPage, cont
|
||||
ChoiceRow(host, "touch", stringResource(R.string.mode_touch), null,
|
||||
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_GESTURES to stringResource(R.string.mode_touch_gestures), SessionPrefs.TOUCH_OFF to stringResource(R.string.widgets_off)),
|
||||
a.touchMode, chipModifier = focus.track(page, "touch"), onPick = a.onTouch)
|
||||
if (a.touchActive == SessionPrefs.TOUCH_PAD)
|
||||
RelativeMouseRow(host, a, focus.track(page, "relative-mouse"))
|
||||
if (a.touchActive == SessionPrefs.TOUCH_DIRECT)
|
||||
ToggleRow(host, "direct-cursor", stringResource(R.string.drawer_direct_cursor),
|
||||
null, a.directCursor,
|
||||
@@ -620,7 +624,7 @@ internal fun SessionDrawer(open: Boolean, requestedPage: SessionDrawerPage, cont
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
||||
) {
|
||||
SecondaryButton(stringResource(R.string.ctrl_edit),
|
||||
SecondaryButton(stringResource(R.string.ctrl_edit), enabled = a.screenKeysShown,
|
||||
modifier = focus.track(page, "screen-keys"), onClick = a.onScreenKeys)
|
||||
a.onScreenLayouts?.let { open ->
|
||||
SecondaryButton(stringResource(R.string.screen_key_layout),
|
||||
@@ -679,6 +683,8 @@ internal fun SessionDrawer(open: Boolean, requestedPage: SessionDrawerPage, cont
|
||||
ToggleRow(host, "evdev-mouse", stringResource(R.string.drawer_evdev_mouse),
|
||||
null, a.evdevMouse,
|
||||
chipModifier = focus.track(page, "evdev-mouse"), onChange = a.onEvdevMouse)
|
||||
if (a.touchActive != SessionPrefs.TOUCH_PAD)
|
||||
RelativeMouseRow(host, a, focus.track(page, "relative-mouse"))
|
||||
}
|
||||
SettingsGroup(stringResource(R.string.drawer_keyboard)) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth().padding(8.dp)) {
|
||||
@@ -1197,6 +1203,15 @@ private fun SecondScreenGroup(host: MenuHost, a: DrawerActions, track: (String)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RelativeMouseRow(host: MenuHost, a: DrawerActions, modifier: Modifier) {
|
||||
ChoiceRow(host, "relative-mouse", stringResource(R.string.drawer_relative_mouse), null,
|
||||
listOf(com.droiddeck.launcher.input.TouchGestureConfig.RELATIVE_MOUSE_AUTO to stringResource(R.string.drawer_relative_mouse_auto),
|
||||
com.droiddeck.launcher.input.TouchGestureConfig.RELATIVE_MOUSE_ON to stringResource(R.string.drawer_relative_mouse_on),
|
||||
com.droiddeck.launcher.input.TouchGestureConfig.RELATIVE_MOUSE_OFF to stringResource(R.string.drawer_relative_mouse_off)),
|
||||
a.relativeMouseMode, chipModifier = modifier, onPick = a.onRelativeMouseMode)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DrawerFexPresetRow(host: MenuHost, a: DrawerActions, modifier: Modifier) {
|
||||
val appId = a.selectedGameProfileId
|
||||
|
||||
@@ -60,7 +60,7 @@ internal fun SteamIntegration.State.enabled(feature: Feature) = when (feature) {
|
||||
Feature.WIFI -> wifi && locationPermission && locationOn
|
||||
Feature.BRIGHTNESS -> brightness
|
||||
Feature.HOME -> home
|
||||
Feature.SHORTCUTS -> home && shortcuts
|
||||
Feature.SHORTCUTS -> shortcuts
|
||||
}
|
||||
|
||||
internal fun SteamIntegration.State.enabledCount() = Feature.entries.count { enabled(it) }
|
||||
@@ -105,14 +105,12 @@ private fun IntegrationRow(
|
||||
val bg by animateColorAsState(if (flash) pal.signal.copy(alpha = 0.12f) else Color.Transparent, Motion.tw(400), label = "integrationFlash")
|
||||
val wifiLocationOff = feature == Feature.WIFI && state.wifi && state.locationPermission && !state.locationOn
|
||||
val wifiDenied = feature == Feature.WIFI && !state.locationPermission && state.locationBlocked
|
||||
val needsHome = feature == Feature.SHORTCUTS && !state.home
|
||||
val restricted = feature == Feature.SHORTCUTS && !needsHome && !state.shortcuts && state.shortcutsRestricted
|
||||
val maybeRestricted = feature == Feature.SHORTCUTS && !needsHome && !state.shortcuts && !restricted && state.shortcutsTried &&
|
||||
val restricted = feature == Feature.SHORTCUTS && !state.shortcuts && state.shortcutsRestricted
|
||||
val maybeRestricted = feature == Feature.SHORTCUTS && !state.shortcuts && !restricted && state.shortcutsTried &&
|
||||
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU
|
||||
val hint = stringResource(when {
|
||||
wifiLocationOff -> R.string.integration_wifi_location_off
|
||||
wifiDenied -> R.string.integration_wifi_denied
|
||||
needsHome -> R.string.integration_shortcuts_needs_home
|
||||
restricted -> R.string.integration_shortcuts_restricted
|
||||
maybeRestricted -> R.string.integration_shortcuts_maybe_restricted
|
||||
feature == Feature.WIFI -> if (on) R.string.integration_wifi_on else R.string.integration_wifi_hint
|
||||
@@ -141,7 +139,7 @@ private fun IntegrationRow(
|
||||
restricted || maybeRestricted -> SecondaryButton(stringResource(R.string.integration_app_info), compact = true, onClick = onAppInfo)
|
||||
}
|
||||
val checked = if (feature == Feature.WIFI) state.wifi && state.locationPermission else on
|
||||
ToggleSwitch(checked, enabled = !needsHome && !restricted, label = stringResource(featureTitle(feature)),
|
||||
ToggleSwitch(checked, enabled = !restricted, label = stringResource(featureTitle(feature)),
|
||||
modifier = Modifier.testTag("integration-action-${feature.name.lowercase()}")) { onFeature(feature) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -755,6 +755,10 @@
|
||||
<string name="drawer_low_latency_touch">لمس بزمن استجابة منخفض</string>
|
||||
<string name="drawer_low_latency_touch_hint">تتجاوز اللمسات تجميع الإطارات، فيعمل اللمس في Steam بمعدل 1000 هرتز. استهلاك معالج أعلى قليلًا.</string>
|
||||
<string name="drawer_evdev_mouse">قناة فأرة خام</string>
|
||||
<string name="drawer_relative_mouse">فأرة نسبية</string>
|
||||
<string name="drawer_relative_mouse_auto">تلقائي</string>
|
||||
<string name="drawer_relative_mouse_on">تشغيل</string>
|
||||
<string name="drawer_relative_mouse_off">إيقاف</string>
|
||||
<string name="drawer_direct_cursor">المؤشر</string>
|
||||
<string name="drawer_pc_keyboard">لوحة مفاتيح الكمبيوتر</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3658,19 +3662,18 @@
|
||||
<string name="integration_wifi">أسماء شبكات Wi-Fi</string>
|
||||
<string name="integration_brightness">السطوع</string>
|
||||
<string name="integration_home">DroidDeck كشاشة رئيسية</string>
|
||||
<string name="integration_shortcuts">اختصارات زر الشاشة الرئيسية</string>
|
||||
<string name="integration_shortcuts">مفاتيح النظام</string>
|
||||
<string name="integration_wifi_hint">إظهار الشبكات في Steam · يتطلب الوصول إلى الموقع الجغرافي، دون تتبّع أبدًا</string>
|
||||
<string name="integration_wifi_on">تظهر الشبكات في Steam</string>
|
||||
<string name="integration_wifi_location_off">الموقع الجغرافي متوقف</string>
|
||||
<string name="integration_wifi_denied">رُفض الوصول إلى الموقع الجغرافي · اسمح به في معلومات التطبيق</string>
|
||||
<string name="integration_brightness_hint">شريط التمرير في Steam يضبط سطوع الشاشة</string>
|
||||
<string name="integration_home_hint">زر الشاشة الرئيسية يفتح قائمة Steam أثناء الجلسة</string>
|
||||
<string name="integration_shortcuts_hint">اضغط مطوّلًا على زر الشاشة الرئيسية لاختصارات Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">يتطلب DroidDeck كشاشة رئيسية</string>
|
||||
<string name="integration_shortcuts_hint">يبقى Alt+Tab ومفتاح Win وزر الرئيسية داخل الجلسة</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">غير متاح في Android؟ معلومات التطبيق → ⋮ → السماح بالإعدادات المحظورة</string>
|
||||
<string name="integration_shortcuts_restricted">محظور من Android · معلومات التطبيق → ⋮ → السماح بالإعدادات المحظورة</string>
|
||||
<string name="integration_shortcuts_service">زر الشاشة الرئيسية في DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">يمرّر ضغطات زر الشاشة الرئيسية إلى Steam Guide عندما تكون جلسة Steam في المقدمة ويكون DroidDeck تطبيق الشاشة الرئيسية الافتراضي. لا يقرأ محتوى الشاشة.</string>
|
||||
<string name="integration_shortcuts_service">مفاتيح نظام DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">إبقاء Alt+Tab ومفتاح Win وزر الرئيسية داخل جلسة DroidDeck النشطة بدلاً من Android.</string>
|
||||
<string name="integration_brightness_needed">فعّل «السطوع» من الإعداد → تكامل Steam</string>
|
||||
<string name="setup_gpu_bridge_off">جسر Mali: متوقف</string>
|
||||
<string name="setup_gpu_bridge_on">جسر Mali: يعمل</string>
|
||||
|
||||
@@ -773,6 +773,10 @@
|
||||
<string name="drawer_low_latency_touch">Táctil de baja latencia</string>
|
||||
<string name="drawer_low_latency_touch_hint">Los toques omiten la agrupación de fotogramas; los controles táctiles de Steam van a 1000 Hz. Usa algo más de CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Canal de ratón sin procesar</string>
|
||||
<string name="drawer_relative_mouse">Ratón relativo</string>
|
||||
<string name="drawer_relative_mouse_auto">Automático</string>
|
||||
<string name="drawer_relative_mouse_on">Activado</string>
|
||||
<string name="drawer_relative_mouse_off">Desactivado</string>
|
||||
<string name="drawer_direct_cursor">Cursor</string>
|
||||
<string name="drawer_pc_keyboard">Teclado de PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3523,19 +3527,18 @@
|
||||
<string name="integration_wifi">Nombres de Wi-Fi</string>
|
||||
<string name="integration_brightness">Brillo</string>
|
||||
<string name="integration_home">DroidDeck como inicio</string>
|
||||
<string name="integration_shortcuts">Atajos del botón de inicio</string>
|
||||
<string name="integration_shortcuts">Teclas del sistema</string>
|
||||
<string name="integration_wifi_hint">Muestra las redes en Steam · requiere acceso a la ubicación, nunca se rastrea</string>
|
||||
<string name="integration_wifi_on">Las redes se muestran en Steam</string>
|
||||
<string name="integration_wifi_location_off">La ubicación está desactivada</string>
|
||||
<string name="integration_wifi_denied">Ubicación denegada · permítela en Información de la app</string>
|
||||
<string name="integration_brightness_hint">El control deslizante de Steam ajusta el brillo de la pantalla</string>
|
||||
<string name="integration_home_hint">Inicio abre el menú de Steam en una sesión</string>
|
||||
<string name="integration_shortcuts_hint">Mantén Inicio para las combinaciones de Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Requiere DroidDeck como inicio</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, la tecla Win y el botón Inicio se quedan en la sesión</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">¿Aparece en gris en Android? Información de la app → ⋮ → Permitir configuración restringida</string>
|
||||
<string name="integration_shortcuts_restricted">Bloqueado por Android · Información de la app → ⋮ → Permitir configuración restringida</string>
|
||||
<string name="integration_shortcuts_service">Botón de inicio de DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Pasa las pulsaciones del botón de inicio a Steam Guide mientras una sesión de Steam está en primer plano y DroidDeck es la app de inicio predeterminada. No lee el contenido de la pantalla.</string>
|
||||
<string name="integration_shortcuts_service">Teclas del sistema de DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Mantiene Alt+Tab, la tecla Win y el botón Inicio dentro de una sesión activa de DroidDeck en lugar de Android.</string>
|
||||
<string name="integration_brightness_needed">Activa Brillo en Configuración → Integración con Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Puente Mali: desactivado</string>
|
||||
<string name="setup_gpu_bridge_on">Puente Mali: activado</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">Докосване с ниско закъснение</string>
|
||||
<string name="drawer_low_latency_touch_hint">Докосванията пропускат групирането на кадри; управлението с докосване в Steam работи при 1000 Hz. Малко повече CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Суров канал за мишка</string>
|
||||
<string name="drawer_relative_mouse">Относителна мишка</string>
|
||||
<string name="drawer_relative_mouse_auto">Автоматично</string>
|
||||
<string name="drawer_relative_mouse_on">Включено</string>
|
||||
<string name="drawer_relative_mouse_off">Изключено</string>
|
||||
<string name="drawer_direct_cursor">Курсор</string>
|
||||
<string name="drawer_pc_keyboard">Клавиатура за компютър</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Имена на Wi-Fi</string>
|
||||
<string name="integration_brightness">Яркост</string>
|
||||
<string name="integration_home">DroidDeck като начален екран</string>
|
||||
<string name="integration_shortcuts">Преки пътища с бутона за начален екран</string>
|
||||
<string name="integration_shortcuts">Системни клавиши</string>
|
||||
<string name="integration_wifi_hint">Показване на мрежите в Steam · изисква достъп до местоположението, никога не се проследява</string>
|
||||
<string name="integration_wifi_on">Мрежите се показват в Steam</string>
|
||||
<string name="integration_wifi_location_off">Местоположението е изключено</string>
|
||||
<string name="integration_wifi_denied">Местоположението е отказано · разрешете го в „Информация за приложението“</string>
|
||||
<string name="integration_brightness_hint">Плъзгачът на Steam задава яркостта на екрана</string>
|
||||
<string name="integration_home_hint">Бутонът за начален екран отваря менюто на Steam в сесия</string>
|
||||
<string name="integration_shortcuts_hint">Задръжте бутона за начален екран за комбинации със Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Изисква DroidDeck като начален екран</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, клавишът Win и бутонът Начало остават в сесията</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Неактивно в Android? Информация за приложението → ⋮ → Разрешаване на ограничените настройки</string>
|
||||
<string name="integration_shortcuts_restricted">Блокирано от Android · Информация за приложението → ⋮ → Разрешаване на ограничените настройки</string>
|
||||
<string name="integration_shortcuts_service">Бутон за начален екран на DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Предава натисканията на бутона за начален екран към Steam Guide, докато сесия на Steam е на фокус и DroidDeck е приложението за начален екран по подразбиране. Не чете съдържанието на екрана.</string>
|
||||
<string name="integration_shortcuts_service">Системни клавиши на DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Задържа Alt+Tab, клавиша Win и бутона Начало в активната сесия на DroidDeck вместо в Android.</string>
|
||||
<string name="integration_brightness_needed">Включете „Яркост“ в Настройка → Интеграция със Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Mali мост: изкл.</string>
|
||||
<string name="setup_gpu_bridge_on">Mali мост: вкл.</string>
|
||||
|
||||
@@ -751,6 +751,10 @@
|
||||
<string name="drawer_low_latency_touch">Dotek s nízkým zpožděním</string>
|
||||
<string name="drawer_low_latency_touch_hint">Doteky přeskakují dávkování snímků, takže ovládání dotykem ve Steamu běží na 1000 Hz. O něco víc CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Surový kanál myši</string>
|
||||
<string name="drawer_relative_mouse">Relativní myš</string>
|
||||
<string name="drawer_relative_mouse_auto">Automaticky</string>
|
||||
<string name="drawer_relative_mouse_on">Zapnuto</string>
|
||||
<string name="drawer_relative_mouse_off">Vypnuto</string>
|
||||
<string name="drawer_direct_cursor">Kurzor</string>
|
||||
<string name="drawer_pc_keyboard">Klávesnice PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3586,19 +3590,18 @@
|
||||
<string name="integration_wifi">Názvy Wi-Fi</string>
|
||||
<string name="integration_brightness">Jas</string>
|
||||
<string name="integration_home">DroidDeck jako domovská obrazovka</string>
|
||||
<string name="integration_shortcuts">Zkratky tlačítka Domů</string>
|
||||
<string name="integration_shortcuts">Systémové klávesy</string>
|
||||
<string name="integration_wifi_hint">Zobrazit sítě ve Steamu · vyžaduje přístup k poloze, nikdy se nesleduje</string>
|
||||
<string name="integration_wifi_on">Sítě se zobrazují ve Steamu</string>
|
||||
<string name="integration_wifi_location_off">Poloha je vypnutá</string>
|
||||
<string name="integration_wifi_denied">Poloha zamítnuta · povolte ji v Informacích o aplikaci</string>
|
||||
<string name="integration_brightness_hint">Posuvník Steamu nastavuje jas obrazovky</string>
|
||||
<string name="integration_home_hint">Tlačítko Domů v relaci otevře nabídku Steam</string>
|
||||
<string name="integration_shortcuts_hint">Podržte Domů pro kombinace Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Vyžaduje DroidDeck jako domovskou obrazovku</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, klávesa Win a tlačítko Domů zůstanou v relaci</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">V Androidu zašedlé? Informace o aplikaci → ⋮ → Povolit omezená nastavení</string>
|
||||
<string name="integration_shortcuts_restricted">Blokováno Androidem · Informace o aplikaci → ⋮ → Povolit omezená nastavení</string>
|
||||
<string name="integration_shortcuts_service">Tlačítko Domů pro DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Předává stisky tlačítka Domů do Steam Guide, když je aktivní relace Steamu a DroidDeck je výchozí aplikací domovské obrazovky. Nečte obsah obrazovky.</string>
|
||||
<string name="integration_shortcuts_service">Systémové klávesy DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Ponechá Alt+Tab, klávesu Win a tlačítko Domů v aktivní relaci DroidDeck místo Androidu.</string>
|
||||
<string name="integration_brightness_needed">Zapněte Jas v Příprava → Integrace se Steamem</string>
|
||||
<string name="setup_gpu_bridge_off">Most Mali: vypnuto</string>
|
||||
<string name="setup_gpu_bridge_on">Most Mali: zapnuto</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">Berøring med lav forsinkelse</string>
|
||||
<string name="drawer_low_latency_touch_hint">Berøringer springer billedsamling over; Steams berøringsstyring kører ved 1000 Hz. Lidt mere CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Rå musekanal</string>
|
||||
<string name="drawer_relative_mouse">Relativ mus</string>
|
||||
<string name="drawer_relative_mouse_auto">Automatisk</string>
|
||||
<string name="drawer_relative_mouse_on">Til</string>
|
||||
<string name="drawer_relative_mouse_off">Fra</string>
|
||||
<string name="drawer_direct_cursor">Markør</string>
|
||||
<string name="drawer_pc_keyboard">PC-tastatur</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Wi-Fi-navne</string>
|
||||
<string name="integration_brightness">Lysstyrke</string>
|
||||
<string name="integration_home">DroidDeck som startskærm</string>
|
||||
<string name="integration_shortcuts">Genveje til Hjem-knappen</string>
|
||||
<string name="integration_shortcuts">Systemtaster</string>
|
||||
<string name="integration_wifi_hint">Vis netværk i Steam · kræver placeringsadgang, spores aldrig</string>
|
||||
<string name="integration_wifi_on">Netværk vises i Steam</string>
|
||||
<string name="integration_wifi_location_off">Placering er slået fra</string>
|
||||
<string name="integration_wifi_denied">Placering afvist · tillad den i Appinfo</string>
|
||||
<string name="integration_brightness_hint">Steams skyder indstiller skærmens lysstyrke</string>
|
||||
<string name="integration_home_hint">Hjem åbner Steam-menuen i en session</string>
|
||||
<string name="integration_shortcuts_hint">Hold Hjem nede for Steam Guide-kombinationer</string>
|
||||
<string name="integration_shortcuts_needs_home">Kræver DroidDeck som startskærm</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, Win-tasten og Hjem-knappen bliver i sessionen</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Nedtonet i Android? Appinfo → ⋮ → Tillad begrænsede indstillinger</string>
|
||||
<string name="integration_shortcuts_restricted">Blokeret af Android · Appinfo → ⋮ → Tillad begrænsede indstillinger</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck Hjem-knap</string>
|
||||
<string name="integration_shortcuts_service_description">Sender tryk på Hjem-knappen til Steam Guide, mens en Steam-session er i fokus, og DroidDeck er standardstartskærmen. Læser ikke skærmindhold.</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck-systemtaster</string>
|
||||
<string name="integration_shortcuts_service_description">Holder Alt+Tab, Win-tasten og Hjem-knappen i en aktiv DroidDeck-session i stedet for Android.</string>
|
||||
<string name="integration_brightness_needed">Slå Lysstyrke til under Opsætning → Steam-integration</string>
|
||||
<string name="setup_gpu_bridge_off">Mali-bro: fra</string>
|
||||
<string name="setup_gpu_bridge_on">Mali-bro: til</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">Touch mit geringer Latenz</string>
|
||||
<string name="drawer_low_latency_touch_hint">Touch überspringt das Zusammenfassen von Frames, Steam-Touch meldet mit 1000 Hz. Die CPU-Last ist etwas höher.</string>
|
||||
<string name="drawer_evdev_mouse">Roher Mauskanal</string>
|
||||
<string name="drawer_relative_mouse">Relative Maus</string>
|
||||
<string name="drawer_relative_mouse_auto">Automatisch</string>
|
||||
<string name="drawer_relative_mouse_on">An</string>
|
||||
<string name="drawer_relative_mouse_off">Aus</string>
|
||||
<string name="drawer_direct_cursor">Zeiger</string>
|
||||
<string name="drawer_pc_keyboard">PC-Tastatur</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Wi-Fi-Namen</string>
|
||||
<string name="integration_brightness">Helligkeit</string>
|
||||
<string name="integration_home">DroidDeck als Startbildschirm</string>
|
||||
<string name="integration_shortcuts">Kürzel der Home-Taste</string>
|
||||
<string name="integration_shortcuts">Systemtasten</string>
|
||||
<string name="integration_wifi_hint">Netzwerke in Steam anzeigen · braucht Standortzugriff, kein Tracking</string>
|
||||
<string name="integration_wifi_on">Netzwerke werden in Steam angezeigt</string>
|
||||
<string name="integration_wifi_location_off">Standort ist aus</string>
|
||||
<string name="integration_wifi_denied">Standort verweigert · erlaube ihn in App-Info</string>
|
||||
<string name="integration_brightness_hint">Steams Regler stellt die Bildschirmhelligkeit ein</string>
|
||||
<string name="integration_home_hint">Home öffnet in einer Sitzung das Steam-Menü</string>
|
||||
<string name="integration_shortcuts_hint">Home halten für Steam-Guide-Tastenkombinationen</string>
|
||||
<string name="integration_shortcuts_needs_home">Benötigt DroidDeck als Startbildschirm</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, Win-Taste und Home-Taste bleiben in der Sitzung</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">In Android ausgegraut? App-Info → ⋮ → Eingeschränkte Einstellungen zulassen</string>
|
||||
<string name="integration_shortcuts_restricted">Von Android blockiert · App-Info → ⋮ → Eingeschränkte Einstellungen zulassen</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck-Home-Taste</string>
|
||||
<string name="integration_shortcuts_service_description">Leitet Drücke der Home-Taste an Steam Guide weiter, während eine Steam-Sitzung im Fokus ist und DroidDeck die Standard-Startbildschirm-App ist. Liest keine Bildschirminhalte.</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck-Systemtasten</string>
|
||||
<string name="integration_shortcuts_service_description">Hält Alt+Tab, die Win-Taste und die Home-Taste in einer aktiven DroidDeck-Sitzung statt bei Android.</string>
|
||||
<string name="integration_brightness_needed">Aktiviere Helligkeit unter Einrichtung → Steam-Integration</string>
|
||||
<string name="setup_gpu_bridge_off">Mali-Brücke: aus</string>
|
||||
<string name="setup_gpu_bridge_on">Mali-Brücke: an</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">Αφή χαμηλής καθυστέρησης</string>
|
||||
<string name="drawer_low_latency_touch_hint">Οι αφές παρακάμπτουν την ομαδοποίηση καρέ, οπότε ο χειρισμός αφής του Steam τρέχει στα 1000 Hz. Λίγο περισσότερο CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Ακατέργαστο κανάλι ποντικιού</string>
|
||||
<string name="drawer_relative_mouse">Σχετικό ποντίκι</string>
|
||||
<string name="drawer_relative_mouse_auto">Αυτόματα</string>
|
||||
<string name="drawer_relative_mouse_on">Ενεργό</string>
|
||||
<string name="drawer_relative_mouse_off">Ανενεργό</string>
|
||||
<string name="drawer_direct_cursor">Δείκτης</string>
|
||||
<string name="drawer_pc_keyboard">Πληκτρολόγιο PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Ονόματα Wi-Fi</string>
|
||||
<string name="integration_brightness">Φωτεινότητα</string>
|
||||
<string name="integration_home">DroidDeck ως Αρχική</string>
|
||||
<string name="integration_shortcuts">Συντομεύσεις κουμπιού Αρχικής</string>
|
||||
<string name="integration_shortcuts">Πλήκτρα συστήματος</string>
|
||||
<string name="integration_wifi_hint">Εμφάνιση δικτύων στο Steam · χρειάζεται πρόσβαση στην Τοποθεσία, χωρίς ποτέ παρακολούθηση</string>
|
||||
<string name="integration_wifi_on">Τα δίκτυα εμφανίζονται στο Steam</string>
|
||||
<string name="integration_wifi_location_off">Η Τοποθεσία είναι απενεργοποιημένη</string>
|
||||
<string name="integration_wifi_denied">Η Τοποθεσία απορρίφθηκε · επιτρέψτε την στις Πληροφορίες εφαρμογής</string>
|
||||
<string name="integration_brightness_hint">Το ρυθμιστικό του Steam ορίζει τη φωτεινότητα οθόνης</string>
|
||||
<string name="integration_home_hint">Η Αρχική ανοίγει το μενού Steam σε συνεδρία</string>
|
||||
<string name="integration_shortcuts_hint">Κρατήστε πατημένη την Αρχική για συνδυασμούς Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Απαιτεί το DroidDeck ως Αρχική</string>
|
||||
<string name="integration_shortcuts_hint">Τα Alt+Tab, Win και Αρχική μένουν στη συνεδρία</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Γκρίζο στο Android; Πληροφορίες εφαρμογής → ⋮ → Να επιτρέπονται οι περιορισμένες ρυθμίσεις</string>
|
||||
<string name="integration_shortcuts_restricted">Αποκλείεται από το Android · Πληροφορίες εφαρμογής → ⋮ → Να επιτρέπονται οι περιορισμένες ρυθμίσεις</string>
|
||||
<string name="integration_shortcuts_service">Κουμπί Αρχικής DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Μεταβιβάζει τα πατήματα του κουμπιού Αρχικής στο Steam Guide όσο μια συνεδρία Steam είναι εστιασμένη και το DroidDeck είναι η προεπιλεγμένη εφαρμογή Αρχικής. Δεν διαβάζει το περιεχόμενο της οθόνης.</string>
|
||||
<string name="integration_shortcuts_service">Πλήκτρα συστήματος DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Διατηρεί τα Alt+Tab, το πλήκτρο Win και το κουμπί Αρχικής στην ενεργή συνεδρία DroidDeck αντί για το Android.</string>
|
||||
<string name="integration_brightness_needed">Ενεργοποιήστε τη Φωτεινότητα στη Ρύθμιση → Ενσωμάτωση Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Γέφυρα Mali: ανενεργή</string>
|
||||
<string name="setup_gpu_bridge_on">Γέφυρα Mali: ενεργή</string>
|
||||
|
||||
@@ -749,6 +749,10 @@
|
||||
<string name="drawer_low_latency_touch">Táctil de baja latencia</string>
|
||||
<string name="drawer_low_latency_touch_hint">Los toques omiten la agrupación de fotogramas; los controles táctiles de Steam van a 1000 Hz. Usa algo más de CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Canal de ratón sin procesar</string>
|
||||
<string name="drawer_relative_mouse">Ratón relativo</string>
|
||||
<string name="drawer_relative_mouse_auto">Automático</string>
|
||||
<string name="drawer_relative_mouse_on">Activado</string>
|
||||
<string name="drawer_relative_mouse_off">Desactivado</string>
|
||||
<string name="drawer_direct_cursor">Cursor</string>
|
||||
<string name="drawer_pc_keyboard">Teclado de PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3550,19 +3554,18 @@
|
||||
<string name="integration_wifi">Nombres de Wi-Fi</string>
|
||||
<string name="integration_brightness">Brillo</string>
|
||||
<string name="integration_home">DroidDeck como inicio</string>
|
||||
<string name="integration_shortcuts">Atajos del botón de inicio</string>
|
||||
<string name="integration_shortcuts">Teclas del sistema</string>
|
||||
<string name="integration_wifi_hint">Muestra las redes en Steam · requiere acceso a la ubicación, nunca se rastrea</string>
|
||||
<string name="integration_wifi_on">Las redes se muestran en Steam</string>
|
||||
<string name="integration_wifi_location_off">La ubicación está desactivada</string>
|
||||
<string name="integration_wifi_denied">Ubicación denegada · permítela en Información de la aplicación</string>
|
||||
<string name="integration_brightness_hint">El control deslizante de Steam ajusta el brillo de la pantalla</string>
|
||||
<string name="integration_home_hint">Inicio abre el menú de Steam en una sesión</string>
|
||||
<string name="integration_shortcuts_hint">Mantén Inicio para las combinaciones de Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Requiere DroidDeck como inicio</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, la tecla Win y el botón Inicio se quedan en la sesión</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">¿Aparece en gris en Android? Información de la aplicación → ⋮ → Permitir ajustes restringidos</string>
|
||||
<string name="integration_shortcuts_restricted">Bloqueado por Android · Información de la aplicación → ⋮ → Permitir ajustes restringidos</string>
|
||||
<string name="integration_shortcuts_service">Botón de inicio de DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Pasa las pulsaciones del botón de inicio a Steam Guide mientras una sesión de Steam está en primer plano y DroidDeck es la app de inicio predeterminada. No lee el contenido de la pantalla.</string>
|
||||
<string name="integration_shortcuts_service">Teclas del sistema de DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Mantiene Alt+Tab, la tecla Win y el botón Inicio en una sesión activa de DroidDeck en lugar de Android.</string>
|
||||
<string name="integration_brightness_needed">Activa Brillo en Configuración → Integración con Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Puente Mali: desactivado</string>
|
||||
<string name="setup_gpu_bridge_on">Puente Mali: activado</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">Matalan viiveen kosketus</string>
|
||||
<string name="drawer_low_latency_touch_hint">Kosketukset ohittavat ruutujen niputuksen, joten Steamin kosketusohjaus toimii 1000 Hz:llä. Hieman enemmän CPU:ta.</string>
|
||||
<string name="drawer_evdev_mouse">Raaka hiirikanava</string>
|
||||
<string name="drawer_relative_mouse">Suhteellinen hiiri</string>
|
||||
<string name="drawer_relative_mouse_auto">Automaattinen</string>
|
||||
<string name="drawer_relative_mouse_on">Päällä</string>
|
||||
<string name="drawer_relative_mouse_off">Pois</string>
|
||||
<string name="drawer_direct_cursor">Osoitin</string>
|
||||
<string name="drawer_pc_keyboard">PC-näppäimistö</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Wi-Fi-nimet</string>
|
||||
<string name="integration_brightness">Kirkkaus</string>
|
||||
<string name="integration_home">DroidDeck aloitusnäyttönä</string>
|
||||
<string name="integration_shortcuts">Koti-painikkeen pikakomennot</string>
|
||||
<string name="integration_shortcuts">Järjestelmänäppäimet</string>
|
||||
<string name="integration_wifi_hint">Näytä verkot Steamissa · vaatii sijaintiluvan, ei koskaan seurata</string>
|
||||
<string name="integration_wifi_on">Verkot näkyvät Steamissa</string>
|
||||
<string name="integration_wifi_location_off">Sijainti on pois päältä</string>
|
||||
<string name="integration_wifi_denied">Sijainti estetty · salli se Sovelluksen tiedoissa</string>
|
||||
<string name="integration_brightness_hint">Steamin liukusäädin säätää näytön kirkkautta</string>
|
||||
<string name="integration_home_hint">Koti avaa Steam-valikon istunnossa</string>
|
||||
<string name="integration_shortcuts_hint">Pidä Koti-painiketta Steam Guide -yhdistelmiä varten</string>
|
||||
<string name="integration_shortcuts_needs_home">Vaatii DroidDeckin aloitusnäytöksi</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, Win-näppäin ja Koti-painike pysyvät istunnossa</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Harmaana Androidissa? Sovelluksen tiedot → ⋮ → Salli rajoitetut asetukset</string>
|
||||
<string name="integration_shortcuts_restricted">Androidin estämä · Sovelluksen tiedot → ⋮ → Salli rajoitetut asetukset</string>
|
||||
<string name="integration_shortcuts_service">DroidDeckin Koti-painike</string>
|
||||
<string name="integration_shortcuts_service_description">Välittää Koti-painikkeen painallukset Steam Guidelle, kun Steam-istunto on aktiivinen ja DroidDeck on oletusaloitusnäyttösovellus. Ei lue näytön sisältöä.</string>
|
||||
<string name="integration_shortcuts_service">DroidDeckin järjestelmänäppäimet</string>
|
||||
<string name="integration_shortcuts_service_description">Pitää Alt+Tabin, Win-näppäimen ja Koti-painikkeen aktiivisessa DroidDeck-istunnossa Androidin sijaan.</string>
|
||||
<string name="integration_brightness_needed">Ota Kirkkaus käyttöön kohdassa Käyttöönotto → Steam-integraatio</string>
|
||||
<string name="setup_gpu_bridge_off">Mali-silta: pois</string>
|
||||
<string name="setup_gpu_bridge_on">Mali-silta: päällä</string>
|
||||
|
||||
@@ -749,6 +749,10 @@
|
||||
<string name="drawer_low_latency_touch">Tactile à faible latence</string>
|
||||
<string name="drawer_low_latency_touch_hint">Les touchers ignorent le regroupement d\'images ; les commandes tactiles Steam passent à 1000 Hz. Un peu plus de CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Canal souris brut</string>
|
||||
<string name="drawer_relative_mouse">Souris relative</string>
|
||||
<string name="drawer_relative_mouse_auto">Automatique</string>
|
||||
<string name="drawer_relative_mouse_on">Activé</string>
|
||||
<string name="drawer_relative_mouse_off">Désactivé</string>
|
||||
<string name="drawer_direct_cursor">Curseur</string>
|
||||
<string name="drawer_pc_keyboard">Clavier PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3550,19 +3554,18 @@
|
||||
<string name="integration_wifi">Noms des réseaux Wi-Fi</string>
|
||||
<string name="integration_brightness">Luminosité</string>
|
||||
<string name="integration_home">DroidDeck comme écran d\'accueil</string>
|
||||
<string name="integration_shortcuts">Raccourcis du bouton Accueil</string>
|
||||
<string name="integration_shortcuts">Touches système</string>
|
||||
<string name="integration_wifi_hint">Afficher les réseaux dans Steam · nécessite l\'accès à la position, jamais suivie</string>
|
||||
<string name="integration_wifi_on">Les réseaux s\'affichent dans Steam</string>
|
||||
<string name="integration_wifi_location_off">La localisation est désactivée</string>
|
||||
<string name="integration_wifi_denied">Position refusée · autorisez-la dans Infos sur l\'appli</string>
|
||||
<string name="integration_brightness_hint">Le curseur de Steam règle la luminosité de l\'écran</string>
|
||||
<string name="integration_home_hint">Accueil ouvre le menu Steam pendant une session</string>
|
||||
<string name="integration_shortcuts_hint">Maintenez Accueil pour les combinaisons Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Nécessite DroidDeck comme écran d\'accueil</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, la touche Win et le bouton Accueil restent dans la session</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Grisé dans Android ? Infos sur l\'appli → ⋮ → Autoriser les paramètres restreints</string>
|
||||
<string name="integration_shortcuts_restricted">Bloqué par Android · Infos sur l\'appli → ⋮ → Autoriser les paramètres restreints</string>
|
||||
<string name="integration_shortcuts_service">Bouton Accueil DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Transmet les appuis sur le bouton Accueil à Steam Guide lorsqu\'une session Steam est au premier plan et que DroidDeck est l\'application d\'écran d\'accueil par défaut. Ne lit pas le contenu de l\'écran.</string>
|
||||
<string name="integration_shortcuts_service">Touches système DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Garde Alt+Tab, la touche Win et le bouton Accueil dans une session DroidDeck active plutôt que dans Android.</string>
|
||||
<string name="integration_brightness_needed">Activez Luminosité dans Paramètres → Intégration Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Pont Mali : désactivé</string>
|
||||
<string name="setup_gpu_bridge_on">Pont Mali : activé</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">कम लेटेंसी टच</string>
|
||||
<string name="drawer_low_latency_touch_hint">टच फ़्रेम बैचिंग छोड़ देते हैं, इसलिए Steam का टच कंट्रोल 1000 Hz पर चलता है। थोड़ा ज़्यादा CPU।</string>
|
||||
<string name="drawer_evdev_mouse">रॉ माउस चैनल</string>
|
||||
<string name="drawer_relative_mouse">सापेक्ष माउस</string>
|
||||
<string name="drawer_relative_mouse_auto">स्वचालित</string>
|
||||
<string name="drawer_relative_mouse_on">चालू</string>
|
||||
<string name="drawer_relative_mouse_off">बंद</string>
|
||||
<string name="drawer_direct_cursor">कर्सर</string>
|
||||
<string name="drawer_pc_keyboard">पीसी कीबोर्ड</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Wi-Fi नाम</string>
|
||||
<string name="integration_brightness">ब्राइटनेस</string>
|
||||
<string name="integration_home">DroidDeck होम के रूप में</string>
|
||||
<string name="integration_shortcuts">होम बटन शॉर्टकट</string>
|
||||
<string name="integration_shortcuts">सिस्टम कुंजियाँ</string>
|
||||
<string name="integration_wifi_hint">Steam में नेटवर्क दिखाएं · लोकेशन ऐक्सेस चाहिए, कभी ट्रैक नहीं किया जाता</string>
|
||||
<string name="integration_wifi_on">नेटवर्क Steam में दिखते हैं</string>
|
||||
<string name="integration_wifi_location_off">लोकेशन बंद है</string>
|
||||
<string name="integration_wifi_denied">लोकेशन अस्वीकार · ऐप्लिकेशन की जानकारी में इसकी अनुमति दें</string>
|
||||
<string name="integration_brightness_hint">Steam का स्लाइडर स्क्रीन ब्राइटनेस सेट करता है</string>
|
||||
<string name="integration_home_hint">सेशन में होम, Steam मेनू खोलता है</string>
|
||||
<string name="integration_shortcuts_hint">Steam Guide कॉर्ड के लिए होम दबाए रखें</string>
|
||||
<string name="integration_shortcuts_needs_home">DroidDeck को होम के रूप में होना चाहिए</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, Win कुंजी और होम बटन सत्र में ही रहते हैं</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Android में धूसर है? ऐप्लिकेशन की जानकारी → ⋮ → प्रतिबंधित सेटिंग की अनुमति दें</string>
|
||||
<string name="integration_shortcuts_restricted">Android ने ब्लॉक किया · ऐप्लिकेशन की जानकारी → ⋮ → प्रतिबंधित सेटिंग की अनुमति दें</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck होम बटन</string>
|
||||
<string name="integration_shortcuts_service_description">जब Steam सेशन फ़ोकस में हो और DroidDeck डिफ़ॉल्ट होम ऐप हो, तब होम बटन दबाने को Steam Guide तक भेजता है। स्क्रीन की सामग्री नहीं पढ़ता।</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck सिस्टम कुंजियाँ</string>
|
||||
<string name="integration_shortcuts_service_description">Alt+Tab, Win कुंजी और होम बटन को Android के बजाय सक्रिय DroidDeck सत्र में रखता है।</string>
|
||||
<string name="integration_brightness_needed">Setup → Steam इंटीग्रेशन में ब्राइटनेस चालू करें</string>
|
||||
<string name="setup_gpu_bridge_off">Mali ब्रिज: बंद</string>
|
||||
<string name="setup_gpu_bridge_on">Mali ब्रिज: चालू</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">Alacsony késleltetésű érintés</string>
|
||||
<string name="drawer_low_latency_touch_hint">Az érintések kihagyják a képkockák kötegelését, így a Steam érintésvezérlése 1000 Hz-en fut. Kicsit több CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Nyers egércsatorna</string>
|
||||
<string name="drawer_relative_mouse">Relatív egér</string>
|
||||
<string name="drawer_relative_mouse_auto">Automatikus</string>
|
||||
<string name="drawer_relative_mouse_on">Be</string>
|
||||
<string name="drawer_relative_mouse_off">Ki</string>
|
||||
<string name="drawer_direct_cursor">Kurzor</string>
|
||||
<string name="drawer_pc_keyboard">PC-billentyűzet</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Wi-Fi-nevek</string>
|
||||
<string name="integration_brightness">Fényerő</string>
|
||||
<string name="integration_home">DroidDeck kezdőképernyőként</string>
|
||||
<string name="integration_shortcuts">Kezdőképernyő gomb parancsikonjai</string>
|
||||
<string name="integration_shortcuts">Rendszerbillentyűk</string>
|
||||
<string name="integration_wifi_hint">Hálózatok megjelenítése a Steamben · helyhozzáférést igényel, követés nélkül</string>
|
||||
<string name="integration_wifi_on">A hálózatok megjelennek a Steamben</string>
|
||||
<string name="integration_wifi_location_off">A hely ki van kapcsolva</string>
|
||||
<string name="integration_wifi_denied">Hely megtagadva · engedélyezze az Alkalmazásinformációban</string>
|
||||
<string name="integration_brightness_hint">A Steam csúszkája állítja a képernyő fényerejét</string>
|
||||
<string name="integration_home_hint">A Kezdőképernyő gomb megnyitja a Steam menüt egy munkamenetben</string>
|
||||
<string name="integration_shortcuts_hint">Tartsa lenyomva a Kezdőképernyő gombot a Steam Guide-kombinációkhoz</string>
|
||||
<string name="integration_shortcuts_needs_home">A DroidDecknek kell kezdőképernyőnek lennie</string>
|
||||
<string name="integration_shortcuts_hint">Az Alt+Tab, a Win billentyű és a Kezdőlap gomb a munkamenetben marad</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Szürke az Androidban? Alkalmazásinformáció → ⋮ → Korlátozott beállítások engedélyezése</string>
|
||||
<string name="integration_shortcuts_restricted">Az Android letiltotta · Alkalmazásinformáció → ⋮ → Korlátozott beállítások engedélyezése</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck Kezdőképernyő gomb</string>
|
||||
<string name="integration_shortcuts_service_description">A Kezdőképernyő gomb lenyomásait továbbítja a Steam Guide-nak, amíg egy Steam-munkamenet van fókuszban, és a DroidDeck az alapértelmezett kezdőképernyő alkalmazás. Nem olvassa a képernyő tartalmát.</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck rendszerbillentyűk</string>
|
||||
<string name="integration_shortcuts_service_description">Az Alt+Tab, a Win billentyű és a Kezdőlap gomb az aktív DroidDeck-munkamenetben marad az Android helyett.</string>
|
||||
<string name="integration_brightness_needed">Kapcsolja be a Fényerőt itt: Beállítás → Steam-integráció</string>
|
||||
<string name="setup_gpu_bridge_off">Mali híd: ki</string>
|
||||
<string name="setup_gpu_bridge_on">Mali híd: be</string>
|
||||
|
||||
@@ -745,6 +745,10 @@
|
||||
<string name="drawer_low_latency_touch">Sentuh latensi rendah</string>
|
||||
<string name="drawer_low_latency_touch_hint">Sentuhan melewati pengelompokan frame, jadi kontrol sentuh Steam berjalan pada 1000 Hz. Sedikit lebih banyak CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Kanal mouse mentah</string>
|
||||
<string name="drawer_relative_mouse">Mouse relatif</string>
|
||||
<string name="drawer_relative_mouse_auto">Otomatis</string>
|
||||
<string name="drawer_relative_mouse_on">Aktif</string>
|
||||
<string name="drawer_relative_mouse_off">Nonaktif</string>
|
||||
<string name="drawer_direct_cursor">Kursor</string>
|
||||
<string name="drawer_pc_keyboard">Keyboard PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3487,19 +3491,18 @@
|
||||
<string name="integration_wifi">Nama Wi-Fi</string>
|
||||
<string name="integration_brightness">Kecerahan</string>
|
||||
<string name="integration_home">DroidDeck sebagai Beranda</string>
|
||||
<string name="integration_shortcuts">Pintasan tombol Home</string>
|
||||
<string name="integration_shortcuts">Tombol sistem</string>
|
||||
<string name="integration_wifi_hint">Tampilkan jaringan di Steam · memerlukan akses Lokasi, tidak pernah dilacak</string>
|
||||
<string name="integration_wifi_on">Jaringan tampil di Steam</string>
|
||||
<string name="integration_wifi_location_off">Lokasi nonaktif</string>
|
||||
<string name="integration_wifi_denied">Lokasi ditolak · izinkan di Info aplikasi</string>
|
||||
<string name="integration_brightness_hint">Penggeser Steam mengatur kecerahan layar</string>
|
||||
<string name="integration_home_hint">Home membuka menu Steam dalam sesi</string>
|
||||
<string name="integration_shortcuts_hint">Tahan Home untuk kombinasi Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Memerlukan DroidDeck sebagai Beranda</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, tombol Win, dan tombol Beranda tetap di sesi</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Berwarna abu-abu di Android? Info aplikasi → ⋮ → Izinkan setelan terbatas</string>
|
||||
<string name="integration_shortcuts_restricted">Diblokir oleh Android · Info aplikasi → ⋮ → Izinkan setelan terbatas</string>
|
||||
<string name="integration_shortcuts_service">Tombol Home DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Meneruskan tekanan tombol Home ke Steam Guide saat sesi Steam sedang aktif dan DroidDeck adalah aplikasi Beranda default. Tidak membaca konten layar.</string>
|
||||
<string name="integration_shortcuts_service">Tombol sistem DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Menjaga Alt+Tab, tombol Win, dan tombol Beranda tetap di sesi DroidDeck yang aktif, bukan di Android.</string>
|
||||
<string name="integration_brightness_needed">Aktifkan Kecerahan di Penyiapan → Integrasi Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Jembatan Mali: mati</string>
|
||||
<string name="setup_gpu_bridge_on">Jembatan Mali: nyala</string>
|
||||
|
||||
@@ -749,6 +749,10 @@
|
||||
<string name="drawer_low_latency_touch">Touch a bassa latenza</string>
|
||||
<string name="drawer_low_latency_touch_hint">I tocchi saltano il raggruppamento dei frame; i controlli touch di Steam passano a 1000 Hz. Un po\' più di CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Canale mouse grezzo</string>
|
||||
<string name="drawer_relative_mouse">Mouse relativo</string>
|
||||
<string name="drawer_relative_mouse_auto">Automatico</string>
|
||||
<string name="drawer_relative_mouse_on">Attivo</string>
|
||||
<string name="drawer_relative_mouse_off">Disattivato</string>
|
||||
<string name="drawer_direct_cursor">Cursore</string>
|
||||
<string name="drawer_pc_keyboard">Tastiera PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3550,19 +3554,18 @@
|
||||
<string name="integration_wifi">Nomi Wi-Fi</string>
|
||||
<string name="integration_brightness">Luminosità</string>
|
||||
<string name="integration_home">DroidDeck come Home</string>
|
||||
<string name="integration_shortcuts">Scorciatoie del tasto Home</string>
|
||||
<string name="integration_shortcuts">Tasti di sistema</string>
|
||||
<string name="integration_wifi_hint">Mostra le reti in Steam · richiede l\'accesso alla posizione, mai tracciata</string>
|
||||
<string name="integration_wifi_on">Le reti sono visibili in Steam</string>
|
||||
<string name="integration_wifi_location_off">La posizione è disattivata</string>
|
||||
<string name="integration_wifi_denied">Posizione negata · consentila in Informazioni app</string>
|
||||
<string name="integration_brightness_hint">Il cursore di Steam regola la luminosità dello schermo</string>
|
||||
<string name="integration_home_hint">Home apre il menu di Steam durante una sessione</string>
|
||||
<string name="integration_shortcuts_hint">Tieni premuto Home per le combinazioni di Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Richiede DroidDeck come Home</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, tasto Win e tasto Home restano nella sessione</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Disattivato in grigio su Android? Informazioni app → ⋮ → Consenti impostazioni con limitazioni</string>
|
||||
<string name="integration_shortcuts_restricted">Bloccato da Android · Informazioni app → ⋮ → Consenti impostazioni con limitazioni</string>
|
||||
<string name="integration_shortcuts_service">Tasto Home di DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Inoltra le pressioni del tasto Home a Steam Guide mentre una sessione Steam è in primo piano e DroidDeck è l\'app Home predefinita. Non legge il contenuto dello schermo.</string>
|
||||
<string name="integration_shortcuts_service">Tasti di sistema DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Mantiene Alt+Tab, il tasto Win e il tasto Home in una sessione DroidDeck attiva anziché in Android.</string>
|
||||
<string name="integration_brightness_needed">Attiva Luminosità in Configurazione → Integrazione con Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Ponte Mali: disattivato</string>
|
||||
<string name="setup_gpu_bridge_on">Ponte Mali: attivo</string>
|
||||
|
||||
@@ -745,6 +745,10 @@
|
||||
<string name="drawer_low_latency_touch">低遅延タッチ</string>
|
||||
<string name="drawer_low_latency_touch_hint">タッチはフレームの結合を省略し、Steam のタッチは 1000 Hz で報告されます。CPU 使用率がわずかに上がります。</string>
|
||||
<string name="drawer_evdev_mouse">生のマウス経路</string>
|
||||
<string name="drawer_relative_mouse">相対マウス</string>
|
||||
<string name="drawer_relative_mouse_auto">自動</string>
|
||||
<string name="drawer_relative_mouse_on">オン</string>
|
||||
<string name="drawer_relative_mouse_off">オフ</string>
|
||||
<string name="drawer_direct_cursor">カーソル</string>
|
||||
<string name="drawer_pc_keyboard">PCキーボード</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3487,19 +3491,18 @@
|
||||
<string name="integration_wifi">Wi-Fi名</string>
|
||||
<string name="integration_brightness">明るさ</string>
|
||||
<string name="integration_home">DroidDeckをホームに設定</string>
|
||||
<string name="integration_shortcuts">ホームボタンのショートカット</string>
|
||||
<string name="integration_shortcuts">システムキー</string>
|
||||
<string name="integration_wifi_hint">Steamにネットワークを表示 · 位置情報へのアクセスが必要ですが、追跡はしません</string>
|
||||
<string name="integration_wifi_on">Steamにネットワークが表示されます</string>
|
||||
<string name="integration_wifi_location_off">位置情報がオフです</string>
|
||||
<string name="integration_wifi_denied">位置情報が拒否されています · アプリ情報で許可してください</string>
|
||||
<string name="integration_brightness_hint">Steamのスライダーで画面の明るさを調整します</string>
|
||||
<string name="integration_home_hint">セッション中はホームでSteamメニューを開きます</string>
|
||||
<string name="integration_shortcuts_hint">ホームを長押しでSteamガイドの同時押し操作を使用</string>
|
||||
<string name="integration_shortcuts_needs_home">DroidDeckをホームに設定する必要があります</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab、Win キー、ホームボタンをセッション内で使えます</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Androidでグレー表示されていますか?アプリ情報 → ⋮ → 制限付き設定を許可</string>
|
||||
<string name="integration_shortcuts_restricted">Androidによってブロックされています · アプリ情報 → ⋮ → 制限付き設定を許可</string>
|
||||
<string name="integration_shortcuts_service">DroidDeckホームボタン</string>
|
||||
<string name="integration_shortcuts_service_description">Steamセッションがフォーカスされ、DroidDeckがデフォルトのホームアプリの場合に、ホームボタンの操作をSteamガイドに渡します。画面のコンテンツは読み取りません。</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck システムキー</string>
|
||||
<string name="integration_shortcuts_service_description">Alt+Tab、Win キー、ホームボタンを Android ではなく操作中の DroidDeck セッションで使えるようにします。</string>
|
||||
<string name="integration_brightness_needed">「セットアップ」→「Steam連携」で明るさをオンにしてください</string>
|
||||
<string name="setup_gpu_bridge_off">Mali ブリッジ: オフ</string>
|
||||
<string name="setup_gpu_bridge_on">Mali ブリッジ: オン</string>
|
||||
|
||||
@@ -745,6 +745,10 @@
|
||||
<string name="drawer_low_latency_touch">저지연 터치</string>
|
||||
<string name="drawer_low_latency_touch_hint">터치가 프레임 병합을 건너뛰고 Steam 터치가 1000 Hz로 보고됩니다. CPU 사용량이 약간 늘어납니다.</string>
|
||||
<string name="drawer_evdev_mouse">원시 마우스 채널</string>
|
||||
<string name="drawer_relative_mouse">상대 마우스</string>
|
||||
<string name="drawer_relative_mouse_auto">자동</string>
|
||||
<string name="drawer_relative_mouse_on">켜기</string>
|
||||
<string name="drawer_relative_mouse_off">끄기</string>
|
||||
<string name="drawer_direct_cursor">커서</string>
|
||||
<string name="drawer_pc_keyboard">PC 키보드</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3487,19 +3491,18 @@
|
||||
<string name="integration_wifi">Wi-Fi 이름</string>
|
||||
<string name="integration_brightness">밝기</string>
|
||||
<string name="integration_home">DroidDeck을 홈으로</string>
|
||||
<string name="integration_shortcuts">홈 버튼 단축키</string>
|
||||
<string name="integration_shortcuts">시스템 키</string>
|
||||
<string name="integration_wifi_hint">Steam에 네트워크 표시 · 위치 접근 권한 필요, 위치는 추적하지 않음</string>
|
||||
<string name="integration_wifi_on">Steam에 네트워크가 표시됨</string>
|
||||
<string name="integration_wifi_location_off">위치가 꺼져 있음</string>
|
||||
<string name="integration_wifi_denied">위치 거부됨 · 앱 정보에서 허용하세요</string>
|
||||
<string name="integration_brightness_hint">Steam 슬라이더로 화면 밝기 조절</string>
|
||||
<string name="integration_home_hint">세션 중 홈 버튼으로 Steam 메뉴 열기</string>
|
||||
<string name="integration_shortcuts_hint">홈 버튼을 길게 눌러 Steam Guide 조합 사용</string>
|
||||
<string name="integration_shortcuts_needs_home">DroidDeck을 홈으로 설정해야 함</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, Win 키, 홈 버튼이 세션 안에서 작동합니다</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Android에서 회색으로 표시되나요? 앱 정보 → ⋮ → 제한된 설정 허용</string>
|
||||
<string name="integration_shortcuts_restricted">Android에서 차단됨 · 앱 정보 → ⋮ → 제한된 설정 허용</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck 홈 버튼</string>
|
||||
<string name="integration_shortcuts_service_description">Steam 세션에 포커스가 있고 DroidDeck이 기본 홈 앱일 때 홈 버튼 입력을 Steam Guide로 전달합니다. 화면 콘텐츠는 읽지 않습니다.</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck 시스템 키</string>
|
||||
<string name="integration_shortcuts_service_description">Alt+Tab, Win 키, 홈 버튼을 Android 대신 사용 중인 DroidDeck 세션에서 작동하게 합니다.</string>
|
||||
<string name="integration_brightness_needed">설정 → Steam 연동에서 밝기를 켜세요</string>
|
||||
<string name="setup_gpu_bridge_off">Mali 브리지: 끔</string>
|
||||
<string name="setup_gpu_bridge_on">Mali 브리지: 켬</string>
|
||||
|
||||
@@ -745,6 +745,10 @@
|
||||
<string name="drawer_low_latency_touch">Sentuh kependaman rendah</string>
|
||||
<string name="drawer_low_latency_touch_hint">Sentuhan melangkau pengumpulan bingkai, jadi kawalan sentuh Steam berjalan pada 1000 Hz. Sedikit lebih banyak CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Saluran tetikus mentah</string>
|
||||
<string name="drawer_relative_mouse">Tetikus relatif</string>
|
||||
<string name="drawer_relative_mouse_auto">Automatik</string>
|
||||
<string name="drawer_relative_mouse_on">Hidup</string>
|
||||
<string name="drawer_relative_mouse_off">Mati</string>
|
||||
<string name="drawer_direct_cursor">Kursor</string>
|
||||
<string name="drawer_pc_keyboard">Papan kekunci PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3487,19 +3491,18 @@
|
||||
<string name="integration_wifi">Nama Wi-Fi</string>
|
||||
<string name="integration_brightness">Kecerahan</string>
|
||||
<string name="integration_home">DroidDeck sebagai Laman Utama</string>
|
||||
<string name="integration_shortcuts">Pintasan butang Laman Utama</string>
|
||||
<string name="integration_shortcuts">Kekunci sistem</string>
|
||||
<string name="integration_wifi_hint">Paparkan rangkaian dalam Steam · memerlukan akses Lokasi, tidak pernah dijejak</string>
|
||||
<string name="integration_wifi_on">Rangkaian dipaparkan dalam Steam</string>
|
||||
<string name="integration_wifi_location_off">Lokasi dimatikan</string>
|
||||
<string name="integration_wifi_denied">Lokasi ditolak · benarkannya dalam Maklumat apl</string>
|
||||
<string name="integration_brightness_hint">Peluncur Steam menetapkan kecerahan skrin</string>
|
||||
<string name="integration_home_hint">Laman Utama membuka menu Steam dalam sesi</string>
|
||||
<string name="integration_shortcuts_hint">Tahan Laman Utama untuk kord Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Memerlukan DroidDeck sebagai Laman Utama</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, kekunci Win dan butang Utama kekal dalam sesi</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Dikelabukan dalam Android? Maklumat apl → ⋮ → Benarkan tetapan terhad</string>
|
||||
<string name="integration_shortcuts_restricted">Disekat oleh Android · Maklumat apl → ⋮ → Benarkan tetapan terhad</string>
|
||||
<string name="integration_shortcuts_service">Butang Laman Utama DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Menghantar tekanan butang Laman Utama kepada Steam Guide semasa sesi Steam difokuskan dan DroidDeck ialah apl Laman Utama lalai. Tidak membaca kandungan skrin.</string>
|
||||
<string name="integration_shortcuts_service">Kekunci sistem DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Mengekalkan Alt+Tab, kekunci Win dan butang Utama dalam sesi DroidDeck yang aktif, bukan Android.</string>
|
||||
<string name="integration_brightness_needed">Hidupkan Kecerahan dalam Persediaan → Integrasi Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Jambatan Mali: mati</string>
|
||||
<string name="setup_gpu_bridge_on">Jambatan Mali: hidup</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">Berøring med lav forsinkelse</string>
|
||||
<string name="drawer_low_latency_touch_hint">Berøringer hopper over bildeinnsamling; Steams berøringsstyring går ved 1000 Hz. Litt mer CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Rå musekanal</string>
|
||||
<string name="drawer_relative_mouse">Relativ mus</string>
|
||||
<string name="drawer_relative_mouse_auto">Automatisk</string>
|
||||
<string name="drawer_relative_mouse_on">På</string>
|
||||
<string name="drawer_relative_mouse_off">Av</string>
|
||||
<string name="drawer_direct_cursor">Peker</string>
|
||||
<string name="drawer_pc_keyboard">PC-tastatur</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Wi-Fi-navn</string>
|
||||
<string name="integration_brightness">Lysstyrke</string>
|
||||
<string name="integration_home">DroidDeck som startskjerm</string>
|
||||
<string name="integration_shortcuts">Snarveier for Hjem-knappen</string>
|
||||
<string name="integration_shortcuts">Systemtaster</string>
|
||||
<string name="integration_wifi_hint">Vis nettverk i Steam · krever posisjonstilgang, spores aldri</string>
|
||||
<string name="integration_wifi_on">Nettverk vises i Steam</string>
|
||||
<string name="integration_wifi_location_off">Posisjon er av</string>
|
||||
<string name="integration_wifi_denied">Posisjon avslått · tillat den i Appinfo</string>
|
||||
<string name="integration_brightness_hint">Steams glidebryter styrer skjermens lysstyrke</string>
|
||||
<string name="integration_home_hint">Hjem åpner Steam-menyen i en sesjon</string>
|
||||
<string name="integration_shortcuts_hint">Hold Hjem for Steam Guide-kombinasjoner</string>
|
||||
<string name="integration_shortcuts_needs_home">Krever DroidDeck som startskjerm</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, Win-tasten og Hjem-knappen blir i økten</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Nedtonet i Android? Appinfo → ⋮ → Tillat begrensede innstillinger</string>
|
||||
<string name="integration_shortcuts_restricted">Blokkert av Android · Appinfo → ⋮ → Tillat begrensede innstillinger</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck Hjem-knapp</string>
|
||||
<string name="integration_shortcuts_service_description">Sender trykk på Hjem-knappen til Steam Guide mens en Steam-sesjon er i fokus og DroidDeck er standard startskjerm-app. Leser ikke skjerminnhold.</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck-systemtaster</string>
|
||||
<string name="integration_shortcuts_service_description">Holder Alt+Tab, Win-tasten og Hjem-knappen i en aktiv DroidDeck-økt i stedet for Android.</string>
|
||||
<string name="integration_brightness_needed">Slå på Lysstyrke i Oppsett → Steam-integrering</string>
|
||||
<string name="setup_gpu_bridge_off">Mali-bro: av</string>
|
||||
<string name="setup_gpu_bridge_on">Mali-bro: på</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">Aanraking met lage latentie</string>
|
||||
<string name="drawer_low_latency_touch_hint">Aanrakingen slaan framebundeling over; Steam-aanraakbediening op 1000 Hz. Iets meer CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Ruw muiskanaal</string>
|
||||
<string name="drawer_relative_mouse">Relatieve muis</string>
|
||||
<string name="drawer_relative_mouse_auto">Automatisch</string>
|
||||
<string name="drawer_relative_mouse_on">Aan</string>
|
||||
<string name="drawer_relative_mouse_off">Uit</string>
|
||||
<string name="drawer_direct_cursor">Cursor</string>
|
||||
<string name="drawer_pc_keyboard">Pc-toetsenbord</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Wi-Fi-namen</string>
|
||||
<string name="integration_brightness">Helderheid</string>
|
||||
<string name="integration_home">DroidDeck als startscherm</string>
|
||||
<string name="integration_shortcuts">Sneltoetsen voor de startknop</string>
|
||||
<string name="integration_shortcuts">Systeemtoetsen</string>
|
||||
<string name="integration_wifi_hint">Netwerken tonen in Steam · vereist locatietoegang, nooit gevolgd</string>
|
||||
<string name="integration_wifi_on">Netwerken worden getoond in Steam</string>
|
||||
<string name="integration_wifi_location_off">Locatie staat uit</string>
|
||||
<string name="integration_wifi_denied">Locatie geweigerd · sta het toe in App-info</string>
|
||||
<string name="integration_brightness_hint">De schuifregelaar van Steam stelt de schermhelderheid in</string>
|
||||
<string name="integration_home_hint">Home opent het Steam-menu in een sessie</string>
|
||||
<string name="integration_shortcuts_hint">Houd Home ingedrukt voor Steam Guide-combinaties</string>
|
||||
<string name="integration_shortcuts_needs_home">Vereist DroidDeck als startscherm</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, Win-toets en Home-knop blijven in de sessie</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Grijs in Android? App-info → ⋮ → Beperkte instellingen toestaan</string>
|
||||
<string name="integration_shortcuts_restricted">Geblokkeerd door Android · App-info → ⋮ → Beperkte instellingen toestaan</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck-startknop</string>
|
||||
<string name="integration_shortcuts_service_description">Geeft drukken op de startknop door aan Steam Guide terwijl een Steam-sessie actief is en DroidDeck de standaard startscherm-app is. Leest geen scherminhoud.</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck-systeemtoetsen</string>
|
||||
<string name="integration_shortcuts_service_description">Houdt Alt+Tab, de Win-toets en de Home-knop in een actieve DroidDeck-sessie in plaats van Android.</string>
|
||||
<string name="integration_brightness_needed">Zet Helderheid aan in Installatie → Steam-integratie</string>
|
||||
<string name="setup_gpu_bridge_off">Mali-brug: uit</string>
|
||||
<string name="setup_gpu_bridge_on">Mali-brug: aan</string>
|
||||
|
||||
@@ -751,6 +751,10 @@
|
||||
<string name="drawer_low_latency_touch">Dotyk o niskim opóźnieniu</string>
|
||||
<string name="drawer_low_latency_touch_hint">Dotknięcia pomijają łączenie klatek; sterowanie dotykiem Steam działa z 1000 Hz. Nieco więcej CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Surowy kanał myszy</string>
|
||||
<string name="drawer_relative_mouse">Mysz względna</string>
|
||||
<string name="drawer_relative_mouse_auto">Automatycznie</string>
|
||||
<string name="drawer_relative_mouse_on">Włączone</string>
|
||||
<string name="drawer_relative_mouse_off">Wyłączone</string>
|
||||
<string name="drawer_direct_cursor">Kursor</string>
|
||||
<string name="drawer_pc_keyboard">Klawiatura PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3586,19 +3590,18 @@
|
||||
<string name="integration_wifi">Nazwy Wi-Fi</string>
|
||||
<string name="integration_brightness">Jasność</string>
|
||||
<string name="integration_home">DroidDeck jako ekran główny</string>
|
||||
<string name="integration_shortcuts">Skróty przycisku ekranu głównego</string>
|
||||
<string name="integration_shortcuts">Klawisze systemowe</string>
|
||||
<string name="integration_wifi_hint">Pokazuj sieci w Steam · wymaga dostępu do lokalizacji, nigdy nie jest śledzona</string>
|
||||
<string name="integration_wifi_on">Sieci są widoczne w Steam</string>
|
||||
<string name="integration_wifi_location_off">Lokalizacja jest wyłączona</string>
|
||||
<string name="integration_wifi_denied">Odmówiono dostępu do lokalizacji · zezwól w Informacjach o aplikacji</string>
|
||||
<string name="integration_brightness_hint">Suwak Steam ustawia jasność ekranu</string>
|
||||
<string name="integration_home_hint">Przycisk ekranu głównego otwiera menu Steam w sesji</string>
|
||||
<string name="integration_shortcuts_hint">Przytrzymaj przycisk ekranu głównego, aby użyć skrótów Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Wymaga DroidDeck jako ekranu głównego</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, klawisz Win i przycisk Home pozostają w sesji</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Wyszarzone w Androidzie? Informacje o aplikacji → ⋮ → Zezwól na ustawienia z ograniczeniami</string>
|
||||
<string name="integration_shortcuts_restricted">Zablokowane przez Androida · Informacje o aplikacji → ⋮ → Zezwól na ustawienia z ograniczeniami</string>
|
||||
<string name="integration_shortcuts_service">Przycisk ekranu głównego DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Przekazuje naciśnięcia przycisku ekranu głównego do Steam Guide, gdy aktywna jest sesja Steam, a DroidDeck jest domyślną aplikacją ekranu głównego. Nie odczytuje zawartości ekranu.</string>
|
||||
<string name="integration_shortcuts_service">Klawisze systemowe DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Zatrzymuje Alt+Tab, klawisz Win i przycisk Home w aktywnej sesji DroidDeck zamiast w Androidzie.</string>
|
||||
<string name="integration_brightness_needed">Włącz Jasność w Konfiguracja → Integracja ze Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Most Mali: wył.</string>
|
||||
<string name="setup_gpu_bridge_on">Most Mali: wł.</string>
|
||||
|
||||
@@ -749,6 +749,10 @@
|
||||
<string name="drawer_low_latency_touch">Toque de baixa latência</string>
|
||||
<string name="drawer_low_latency_touch_hint">Os toques ignoram o agrupamento de fotogramas; os controlos táteis do Steam passam a 1000 Hz. Um pouco mais de CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Canal de rato em bruto</string>
|
||||
<string name="drawer_relative_mouse">Rato relativo</string>
|
||||
<string name="drawer_relative_mouse_auto">Automático</string>
|
||||
<string name="drawer_relative_mouse_on">Ativado</string>
|
||||
<string name="drawer_relative_mouse_off">Desativado</string>
|
||||
<string name="drawer_direct_cursor">Cursor</string>
|
||||
<string name="drawer_pc_keyboard">Teclado de PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3550,19 +3554,18 @@
|
||||
<string name="integration_wifi">Nomes de Wi-Fi</string>
|
||||
<string name="integration_brightness">Brilho</string>
|
||||
<string name="integration_home">DroidDeck como página inicial</string>
|
||||
<string name="integration_shortcuts">Atalhos do botão Página inicial</string>
|
||||
<string name="integration_shortcuts">Teclas do sistema</string>
|
||||
<string name="integration_wifi_hint">Mostra redes no Steam · requer acesso à localização, nunca monitorizada</string>
|
||||
<string name="integration_wifi_on">As redes aparecem no Steam</string>
|
||||
<string name="integration_wifi_location_off">A localização está desativada</string>
|
||||
<string name="integration_wifi_denied">Localização recusada · permita-a em Informações da aplicação</string>
|
||||
<string name="integration_brightness_hint">O controlo de deslize do Steam ajusta o brilho do ecrã</string>
|
||||
<string name="integration_home_hint">Página inicial abre o menu do Steam numa sessão</string>
|
||||
<string name="integration_shortcuts_hint">Mantenha Página inicial premido para combinações do botão Guide do Steam</string>
|
||||
<string name="integration_shortcuts_needs_home">Requer o DroidDeck como página inicial</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, tecla Win e botão Início ficam na sessão</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Desativado a cinzento no Android? Informações da aplicação → ⋮ → Permitir definições restritas</string>
|
||||
<string name="integration_shortcuts_restricted">Bloqueado pelo Android · Informações da aplicação → ⋮ → Permitir definições restritas</string>
|
||||
<string name="integration_shortcuts_service">Botão Página inicial do DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Envia os toques no botão Página inicial para o Guide do Steam enquanto uma sessão do Steam está em foco e o DroidDeck é a app de página inicial predefinida. Não lê o conteúdo do ecrã.</string>
|
||||
<string name="integration_shortcuts_service">Teclas do sistema DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Mantém Alt+Tab, a tecla Win e o botão Início numa sessão ativa do DroidDeck em vez do Android.</string>
|
||||
<string name="integration_brightness_needed">Ative Brilho em Configuração → Integração com o Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Ponte Mali: desligada</string>
|
||||
<string name="setup_gpu_bridge_on">Ponte Mali: ligada</string>
|
||||
|
||||
@@ -749,6 +749,10 @@
|
||||
<string name="drawer_low_latency_touch">Toque de baixa latência</string>
|
||||
<string name="drawer_low_latency_touch_hint">Os toques ignoram o agrupamento de quadros; os controles de toque da Steam vão a 1000 Hz. Um pouco mais de CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Canal de mouse bruto</string>
|
||||
<string name="drawer_relative_mouse">Mouse relativo</string>
|
||||
<string name="drawer_relative_mouse_auto">Automático</string>
|
||||
<string name="drawer_relative_mouse_on">Ativado</string>
|
||||
<string name="drawer_relative_mouse_off">Desativado</string>
|
||||
<string name="drawer_direct_cursor">Cursor</string>
|
||||
<string name="drawer_pc_keyboard">Teclado de PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3550,19 +3554,18 @@
|
||||
<string name="integration_wifi">Nomes de Wi-Fi</string>
|
||||
<string name="integration_brightness">Brilho</string>
|
||||
<string name="integration_home">DroidDeck como tela inicial</string>
|
||||
<string name="integration_shortcuts">Atalhos do botão Início</string>
|
||||
<string name="integration_shortcuts">Teclas do sistema</string>
|
||||
<string name="integration_wifi_hint">Mostra redes na Steam · requer acesso à localização, nunca rastreada</string>
|
||||
<string name="integration_wifi_on">As redes aparecem na Steam</string>
|
||||
<string name="integration_wifi_location_off">A localização está desativada</string>
|
||||
<string name="integration_wifi_denied">Localização negada · permita em Informações do app</string>
|
||||
<string name="integration_brightness_hint">O controle deslizante da Steam ajusta o brilho da tela</string>
|
||||
<string name="integration_home_hint">Início abre o menu Steam em uma sessão</string>
|
||||
<string name="integration_shortcuts_hint">Segure Início para combinações do botão Guide da Steam</string>
|
||||
<string name="integration_shortcuts_needs_home">Requer DroidDeck como tela inicial</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, tecla Win e botão Início ficam na sessão</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Esmaecido no Android? Informações do app → ⋮ → Permitir configurações restritas</string>
|
||||
<string name="integration_shortcuts_restricted">Bloqueado pelo Android · Informações do app → ⋮ → Permitir configurações restritas</string>
|
||||
<string name="integration_shortcuts_service">Botão Início do DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Repassa os toques no botão Início para o Guide da Steam enquanto uma sessão da Steam está em foco e o DroidDeck é o app de tela inicial padrão. Não lê o conteúdo da tela.</string>
|
||||
<string name="integration_shortcuts_service">Teclas do sistema DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Mantém Alt+Tab, a tecla Win e o botão Início em uma sessão ativa do DroidDeck em vez do Android.</string>
|
||||
<string name="integration_brightness_needed">Ative Brilho em Configuração → Integração com a Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Ponte Mali: desligada</string>
|
||||
<string name="setup_gpu_bridge_on">Ponte Mali: ligada</string>
|
||||
|
||||
@@ -749,6 +749,10 @@
|
||||
<string name="drawer_low_latency_touch">Atingere cu latență mică</string>
|
||||
<string name="drawer_low_latency_touch_hint">Atingerile sar peste gruparea cadrelor, deci controlul tactil Steam rulează la 1000 Hz. Consum CPU puțin mai mare.</string>
|
||||
<string name="drawer_evdev_mouse">Canal brut de mouse</string>
|
||||
<string name="drawer_relative_mouse">Mouse relativ</string>
|
||||
<string name="drawer_relative_mouse_auto">Automat</string>
|
||||
<string name="drawer_relative_mouse_on">Pornit</string>
|
||||
<string name="drawer_relative_mouse_off">Oprit</string>
|
||||
<string name="drawer_direct_cursor">Cursor</string>
|
||||
<string name="drawer_pc_keyboard">Tastatură de PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3550,19 +3554,18 @@
|
||||
<string name="integration_wifi">Nume Wi-Fi</string>
|
||||
<string name="integration_brightness">Luminozitate</string>
|
||||
<string name="integration_home">DroidDeck ca Acasă</string>
|
||||
<string name="integration_shortcuts">Comenzi rapide pentru butonul Acasă</string>
|
||||
<string name="integration_shortcuts">Taste de sistem</string>
|
||||
<string name="integration_wifi_hint">Afișează rețelele în Steam · necesită acces la locație, fără urmărire</string>
|
||||
<string name="integration_wifi_on">Rețelele apar în Steam</string>
|
||||
<string name="integration_wifi_location_off">Locația este dezactivată</string>
|
||||
<string name="integration_wifi_denied">Locație refuzată · permite-o în Informații despre aplicație</string>
|
||||
<string name="integration_brightness_hint">Glisorul din Steam setează luminozitatea ecranului</string>
|
||||
<string name="integration_home_hint">Acasă deschide meniul Steam într-o sesiune</string>
|
||||
<string name="integration_shortcuts_hint">Ține apăsat Acasă pentru combinațiile Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Necesită DroidDeck ca Acasă</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, tasta Win și butonul Acasă rămân în sesiune</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Inactiv în Android? Informații despre aplicație → ⋮ → Permite setările restricționate</string>
|
||||
<string name="integration_shortcuts_restricted">Blocat de Android · Informații despre aplicație → ⋮ → Permite setările restricționate</string>
|
||||
<string name="integration_shortcuts_service">Butonul Acasă DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Transmite apăsările butonului Acasă către Steam Guide cât timp o sesiune Steam este activă și DroidDeck este aplicația Acasă implicită. Nu citește conținutul ecranului.</string>
|
||||
<string name="integration_shortcuts_service">Taste de sistem DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Păstrează Alt+Tab, tasta Win și butonul Acasă într-o sesiune DroidDeck activă în loc de Android.</string>
|
||||
<string name="integration_brightness_needed">Activează Luminozitate în Configurare → Integrare Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Punte Mali: oprită</string>
|
||||
<string name="setup_gpu_bridge_on">Punte Mali: pornită</string>
|
||||
|
||||
@@ -751,6 +751,10 @@
|
||||
<string name="drawer_low_latency_touch">Сенсор с низкой задержкой</string>
|
||||
<string name="drawer_low_latency_touch_hint">Касания идут без объединения кадров; сенсорное управление Steam работает на 1000 Гц. Немного больше нагрузки на CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Сырой канал мыши</string>
|
||||
<string name="drawer_relative_mouse">Относительная мышь</string>
|
||||
<string name="drawer_relative_mouse_auto">Автоматически</string>
|
||||
<string name="drawer_relative_mouse_on">Включено</string>
|
||||
<string name="drawer_relative_mouse_off">Выключено</string>
|
||||
<string name="drawer_direct_cursor">Курсор</string>
|
||||
<string name="drawer_pc_keyboard">Клавиатура ПК</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3586,19 +3590,18 @@
|
||||
<string name="integration_wifi">Названия сетей Wi-Fi</string>
|
||||
<string name="integration_brightness">Яркость</string>
|
||||
<string name="integration_home">DroidDeck как главный экран</string>
|
||||
<string name="integration_shortcuts">Сочетания кнопки «Домой»</string>
|
||||
<string name="integration_shortcuts">Системные клавиши</string>
|
||||
<string name="integration_wifi_hint">Показывать сети в Steam · нужен доступ к местоположению, без отслеживания</string>
|
||||
<string name="integration_wifi_on">Сети отображаются в Steam</string>
|
||||
<string name="integration_wifi_location_off">Местоположение отключено</string>
|
||||
<string name="integration_wifi_denied">Доступ к местоположению запрещён · разрешите его в «О приложении»</string>
|
||||
<string name="integration_brightness_hint">Ползунок Steam задаёт яркость экрана</string>
|
||||
<string name="integration_home_hint">«Домой» открывает меню Steam в сессии</string>
|
||||
<string name="integration_shortcuts_hint">Удерживайте «Домой» для сочетаний Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Нужен DroidDeck как главный экран</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, клавиша Win и кнопка «Домой» работают в сеансе</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Неактивно в Android? «О приложении» → ⋮ → «Разрешить доступ к настройкам с ограниченным доступом»</string>
|
||||
<string name="integration_shortcuts_restricted">Заблокировано Android · «О приложении» → ⋮ → «Разрешить доступ к настройкам с ограниченным доступом»</string>
|
||||
<string name="integration_shortcuts_service">Кнопка «Домой» DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Передаёт нажатия кнопки «Домой» в Steam Guide, пока активна сессия Steam и DroidDeck является главным экраном по умолчанию. Не считывает содержимое экрана.</string>
|
||||
<string name="integration_shortcuts_service">Системные клавиши DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Оставляет Alt+Tab, клавишу Win и кнопку «Домой» в активном сеансе DroidDeck, а не в Android.</string>
|
||||
<string name="integration_brightness_needed">Включите «Яркость» в «Настройка → Интеграция со Steam»</string>
|
||||
<string name="setup_gpu_bridge_off">Мост Mali: выкл.</string>
|
||||
<string name="setup_gpu_bridge_on">Мост Mali: вкл.</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">Pekning med låg latens</string>
|
||||
<string name="drawer_low_latency_touch_hint">Pekningar hoppar över bildrutebatchning; Steams pekstyrning går i 1000 Hz. Något mer CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Rå muskanal</string>
|
||||
<string name="drawer_relative_mouse">Relativ mus</string>
|
||||
<string name="drawer_relative_mouse_auto">Automatiskt</string>
|
||||
<string name="drawer_relative_mouse_on">På</string>
|
||||
<string name="drawer_relative_mouse_off">Av</string>
|
||||
<string name="drawer_direct_cursor">Markör</string>
|
||||
<string name="drawer_pc_keyboard">PC-tangentbord</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Wi-Fi-namn</string>
|
||||
<string name="integration_brightness">Ljusstyrka</string>
|
||||
<string name="integration_home">DroidDeck som startskärm</string>
|
||||
<string name="integration_shortcuts">Genvägar för hemknappen</string>
|
||||
<string name="integration_shortcuts">Systemtangenter</string>
|
||||
<string name="integration_wifi_hint">Visa nätverk i Steam · kräver platsåtkomst, spåras aldrig</string>
|
||||
<string name="integration_wifi_on">Nätverk visas i Steam</string>
|
||||
<string name="integration_wifi_location_off">Plats är avstängd</string>
|
||||
<string name="integration_wifi_denied">Plats nekad · tillåt den i Appinfo</string>
|
||||
<string name="integration_brightness_hint">Steams reglage ställer in skärmens ljusstyrka</string>
|
||||
<string name="integration_home_hint">Hem öppnar Steam-menyn i en session</string>
|
||||
<string name="integration_shortcuts_hint">Håll Hem för Steam Guide-kombinationer</string>
|
||||
<string name="integration_shortcuts_needs_home">Kräver DroidDeck som startskärm</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, Win-tangenten och Hem-knappen stannar i sessionen</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Nedtonat i Android? Appinfo → ⋮ → Tillåt begränsade inställningar</string>
|
||||
<string name="integration_shortcuts_restricted">Blockerat av Android · Appinfo → ⋮ → Tillåt begränsade inställningar</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck hemknapp</string>
|
||||
<string name="integration_shortcuts_service_description">Skickar tryck på hemknappen till Steam Guide medan en Steam-session är i fokus och DroidDeck är standardappen för startskärmen. Läser inte skärminnehåll.</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck-systemtangenter</string>
|
||||
<string name="integration_shortcuts_service_description">Håller Alt+Tab, Win-tangenten och Hem-knappen i en aktiv DroidDeck-session i stället för Android.</string>
|
||||
<string name="integration_brightness_needed">Slå på Ljusstyrka under Konfiguration → Steam-integration</string>
|
||||
<string name="setup_gpu_bridge_off">Mali-brygga: av</string>
|
||||
<string name="setup_gpu_bridge_on">Mali-brygga: på</string>
|
||||
|
||||
@@ -745,6 +745,10 @@
|
||||
<string name="drawer_low_latency_touch">การสัมผัสความหน่วงต่ำ</string>
|
||||
<string name="drawer_low_latency_touch_hint">การสัมผัสข้ามการรวมเฟรม ทำให้ระบบสัมผัสของ Steam ทำงานที่ 1000 Hz ใช้ CPU เพิ่มขึ้นเล็กน้อย</string>
|
||||
<string name="drawer_evdev_mouse">ช่องเมาส์ดิบ</string>
|
||||
<string name="drawer_relative_mouse">เมาส์แบบสัมพัทธ์</string>
|
||||
<string name="drawer_relative_mouse_auto">อัตโนมัติ</string>
|
||||
<string name="drawer_relative_mouse_on">เปิด</string>
|
||||
<string name="drawer_relative_mouse_off">ปิด</string>
|
||||
<string name="drawer_direct_cursor">เคอร์เซอร์</string>
|
||||
<string name="drawer_pc_keyboard">แป้นพิมพ์พีซี</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3487,19 +3491,18 @@
|
||||
<string name="integration_wifi">ชื่อ Wi-Fi</string>
|
||||
<string name="integration_brightness">ความสว่าง</string>
|
||||
<string name="integration_home">DroidDeck เป็นหน้าหลัก</string>
|
||||
<string name="integration_shortcuts">ทางลัดปุ่มหน้าหลัก</string>
|
||||
<string name="integration_shortcuts">ปุ่มระบบ</string>
|
||||
<string name="integration_wifi_hint">แสดงเครือข่ายใน Steam · ต้องใช้สิทธิ์ตำแหน่ง ไม่มีการติดตาม</string>
|
||||
<string name="integration_wifi_on">เครือข่ายแสดงใน Steam</string>
|
||||
<string name="integration_wifi_location_off">ตำแหน่งปิดอยู่</string>
|
||||
<string name="integration_wifi_denied">ปฏิเสธตำแหน่ง · อนุญาตในข้อมูลแอป</string>
|
||||
<string name="integration_brightness_hint">แถบเลื่อนของ Steam ปรับความสว่างหน้าจอ</string>
|
||||
<string name="integration_home_hint">ปุ่มหน้าหลักเปิดเมนู Steam ในเซสชัน</string>
|
||||
<string name="integration_shortcuts_hint">กดปุ่มหน้าหลักค้างไว้เพื่อใช้คอร์ด Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">ต้องตั้ง DroidDeck เป็นหน้าหลัก</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab ปุ่ม Win และปุ่มโฮมทำงานในเซสชัน</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">เป็นสีเทาใน Android? ข้อมูลแอป → ⋮ → อนุญาตการตั้งค่าที่จำกัด</string>
|
||||
<string name="integration_shortcuts_restricted">ถูกบล็อกโดย Android · ข้อมูลแอป → ⋮ → อนุญาตการตั้งค่าที่จำกัด</string>
|
||||
<string name="integration_shortcuts_service">ปุ่มหน้าหลัก DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">ส่งการกดปุ่มหน้าหลักไปยัง Steam Guide ขณะเซสชัน Steam อยู่ในโฟกัสและ DroidDeck เป็นแอปหน้าหลักเริ่มต้น ไม่อ่านเนื้อหาบนหน้าจอ</string>
|
||||
<string name="integration_shortcuts_service">ปุ่มระบบของ DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">ให้ Alt+Tab ปุ่ม Win และปุ่มโฮมทำงานในเซสชัน DroidDeck ที่ใช้งานอยู่แทน Android</string>
|
||||
<string name="integration_brightness_needed">เปิดความสว่างในการตั้งค่า → การผสานรวม Steam</string>
|
||||
<string name="setup_gpu_bridge_off">บริดจ์ Mali: ปิด</string>
|
||||
<string name="setup_gpu_bridge_on">บริดจ์ Mali: เปิด</string>
|
||||
|
||||
@@ -747,6 +747,10 @@
|
||||
<string name="drawer_low_latency_touch">Düşük gecikmeli dokunma</string>
|
||||
<string name="drawer_low_latency_touch_hint">Dokunmalar kare gruplamasını atlar; Steam dokunmatik kontrolleri 1000 Hz çalışır. CPU kullanımı biraz artar.</string>
|
||||
<string name="drawer_evdev_mouse">Ham fare kanalı</string>
|
||||
<string name="drawer_relative_mouse">Göreli fare</string>
|
||||
<string name="drawer_relative_mouse_auto">Otomatik</string>
|
||||
<string name="drawer_relative_mouse_on">Açık</string>
|
||||
<string name="drawer_relative_mouse_off">Kapalı</string>
|
||||
<string name="drawer_direct_cursor">İmleç</string>
|
||||
<string name="drawer_pc_keyboard">PC klavyesi</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3514,19 +3518,18 @@
|
||||
<string name="integration_wifi">Wi-Fi adları</string>
|
||||
<string name="integration_brightness">Parlaklık</string>
|
||||
<string name="integration_home">Ana ekran olarak DroidDeck</string>
|
||||
<string name="integration_shortcuts">Ana ekran düğmesi kısayolları</string>
|
||||
<string name="integration_shortcuts">Sistem tuşları</string>
|
||||
<string name="integration_wifi_hint">Ağları Steam\'de göster · Konum erişimi gerekir, konum asla izlenmez</string>
|
||||
<string name="integration_wifi_on">Ağlar Steam\'de görünür</string>
|
||||
<string name="integration_wifi_location_off">Konum kapalı</string>
|
||||
<string name="integration_wifi_denied">Konum reddedildi · Uygulama bilgileri\'nden izin verin</string>
|
||||
<string name="integration_brightness_hint">Steam\'in kaydırıcısı ekran parlaklığını ayarlar</string>
|
||||
<string name="integration_home_hint">Ana ekran düğmesi oturumda Steam menüsünü açar</string>
|
||||
<string name="integration_shortcuts_hint">Steam Guide kombinasyonları için Ana ekran düğmesini basılı tutun</string>
|
||||
<string name="integration_shortcuts_needs_home">Ana ekran olarak DroidDeck gerekir</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, Win tuşu ve Ana Ekran düğmesi oturumda kalır</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Android\'de gri mi görünüyor? Uygulama bilgileri → ⋮ → Kısıtlanmış ayarlara izin ver</string>
|
||||
<string name="integration_shortcuts_restricted">Android tarafından engellendi · Uygulama bilgileri → ⋮ → Kısıtlanmış ayarlara izin ver</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck Ana ekran düğmesi</string>
|
||||
<string name="integration_shortcuts_service_description">Bir Steam oturumu odaktayken ve DroidDeck varsayılan Ana ekran uygulamasıyken Ana ekran düğmesine basışları Steam Guide\'a iletir. Ekran içeriğini okumaz.</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck sistem tuşları</string>
|
||||
<string name="integration_shortcuts_service_description">Alt+Tab, Win tuşu ve Ana Ekran düğmesini Android yerine etkin DroidDeck oturumunda tutar.</string>
|
||||
<string name="integration_brightness_needed">Kurulum → Steam entegrasyonu bölümünde Parlaklık\'ı açın</string>
|
||||
<string name="setup_gpu_bridge_off">Mali köprüsü: kapalı</string>
|
||||
<string name="setup_gpu_bridge_on">Mali köprüsü: açık</string>
|
||||
|
||||
@@ -751,6 +751,10 @@
|
||||
<string name="drawer_low_latency_touch">Дотик із низькою затримкою</string>
|
||||
<string name="drawer_low_latency_touch_hint">Дотики обходять групування кадрів, тож сенсорне керування Steam працює на 1000 Hz. Трохи більше навантаження на CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Сирий канал миші</string>
|
||||
<string name="drawer_relative_mouse">Відносна миша</string>
|
||||
<string name="drawer_relative_mouse_auto">Автоматично</string>
|
||||
<string name="drawer_relative_mouse_on">Увімкнено</string>
|
||||
<string name="drawer_relative_mouse_off">Вимкнено</string>
|
||||
<string name="drawer_direct_cursor">Курсор</string>
|
||||
<string name="drawer_pc_keyboard">Клавіатура ПК</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3586,19 +3590,18 @@
|
||||
<string name="integration_wifi">Назви мереж Wi-Fi</string>
|
||||
<string name="integration_brightness">Яскравість</string>
|
||||
<string name="integration_home">DroidDeck як головний екран</string>
|
||||
<string name="integration_shortcuts">Комбінації кнопки «Додому»</string>
|
||||
<string name="integration_shortcuts">Системні клавіші</string>
|
||||
<string name="integration_wifi_hint">Показувати мережі в Steam · потрібен доступ до місцезнаходження, без стеження</string>
|
||||
<string name="integration_wifi_on">Мережі відображаються в Steam</string>
|
||||
<string name="integration_wifi_location_off">Місцезнаходження вимкнено</string>
|
||||
<string name="integration_wifi_denied">Доступ до місцезнаходження заборонено · дозвольте його в «Про додаток»</string>
|
||||
<string name="integration_brightness_hint">Повзунок Steam задає яскравість екрана</string>
|
||||
<string name="integration_home_hint">«Додому» відкриває меню Steam у сеансі</string>
|
||||
<string name="integration_shortcuts_hint">Утримуйте «Додому» для комбінацій Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Потрібен DroidDeck як головний екран</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, клавіша Win і кнопка «Додому» працюють у сеансі</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Неактивно в Android? «Про додаток» → ⋮ → «Дозволити обмежені налаштування»</string>
|
||||
<string name="integration_shortcuts_restricted">Заблоковано Android · «Про додаток» → ⋮ → «Дозволити обмежені налаштування»</string>
|
||||
<string name="integration_shortcuts_service">Кнопка «Додому» DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Передає натискання кнопки «Додому» в Steam Guide, поки активний сеанс Steam і DroidDeck є типовим головним екраном. Не зчитує вміст екрана.</string>
|
||||
<string name="integration_shortcuts_service">Системні клавіші DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Залишає Alt+Tab, клавішу Win і кнопку «Додому» в активному сеансі DroidDeck, а не в Android.</string>
|
||||
<string name="integration_brightness_needed">Увімкніть «Яскравість» у «Налаштування → Інтеграція зі Steam»</string>
|
||||
<string name="setup_gpu_bridge_off">Міст Mali: вимк.</string>
|
||||
<string name="setup_gpu_bridge_on">Міст Mali: увімк.</string>
|
||||
|
||||
@@ -745,6 +745,10 @@
|
||||
<string name="drawer_low_latency_touch">Cảm ứng độ trễ thấp</string>
|
||||
<string name="drawer_low_latency_touch_hint">Cảm ứng bỏ qua việc gộp khung hình, nên điều khiển cảm ứng của Steam chạy ở 1000 Hz. Tốn thêm một chút CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Kênh chuột thô</string>
|
||||
<string name="drawer_relative_mouse">Chuột tương đối</string>
|
||||
<string name="drawer_relative_mouse_auto">Tự động</string>
|
||||
<string name="drawer_relative_mouse_on">Bật</string>
|
||||
<string name="drawer_relative_mouse_off">Tắt</string>
|
||||
<string name="drawer_direct_cursor">Con trỏ</string>
|
||||
<string name="drawer_pc_keyboard">Bàn phím PC</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3487,19 +3491,18 @@
|
||||
<string name="integration_wifi">Tên Wi-Fi</string>
|
||||
<string name="integration_brightness">Độ sáng</string>
|
||||
<string name="integration_home">DroidDeck làm màn hình chính</string>
|
||||
<string name="integration_shortcuts">Phím tắt nút Home</string>
|
||||
<string name="integration_shortcuts">Phím hệ thống</string>
|
||||
<string name="integration_wifi_hint">Hiện mạng trong Steam · cần quyền Vị trí, không bao giờ theo dõi</string>
|
||||
<string name="integration_wifi_on">Mạng hiện trong Steam</string>
|
||||
<string name="integration_wifi_location_off">Vị trí đang tắt</string>
|
||||
<string name="integration_wifi_denied">Vị trí bị từ chối · hãy cho phép trong Thông tin ứng dụng</string>
|
||||
<string name="integration_brightness_hint">Thanh trượt của Steam đặt độ sáng màn hình</string>
|
||||
<string name="integration_home_hint">Home mở menu Steam trong phiên</string>
|
||||
<string name="integration_shortcuts_hint">Giữ Home để dùng tổ hợp Steam Guide</string>
|
||||
<string name="integration_shortcuts_needs_home">Cần DroidDeck làm màn hình chính</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, phím Win và nút Trang chủ giữ trong phiên</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Bị làm mờ trong Android? Thông tin ứng dụng → ⋮ → Cho phép chế độ cài đặt bị hạn chế</string>
|
||||
<string name="integration_shortcuts_restricted">Bị Android chặn · Thông tin ứng dụng → ⋮ → Cho phép chế độ cài đặt bị hạn chế</string>
|
||||
<string name="integration_shortcuts_service">Nút Home DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Chuyển các lần nhấn nút Home đến Steam Guide khi phiên Steam đang được chọn và DroidDeck là ứng dụng màn hình chính mặc định. Không đọc nội dung màn hình.</string>
|
||||
<string name="integration_shortcuts_service">Phím hệ thống DroidDeck</string>
|
||||
<string name="integration_shortcuts_service_description">Giữ Alt+Tab, phím Win và nút Trang chủ trong phiên DroidDeck đang dùng thay vì Android.</string>
|
||||
<string name="integration_brightness_needed">Bật Độ sáng trong Thiết lập → Tích hợp Steam</string>
|
||||
<string name="setup_gpu_bridge_off">Cầu Mali: tắt</string>
|
||||
<string name="setup_gpu_bridge_on">Cầu Mali: bật</string>
|
||||
|
||||
@@ -745,6 +745,10 @@
|
||||
<string name="drawer_low_latency_touch">低延迟触控</string>
|
||||
<string name="drawer_low_latency_touch_hint">触控跳过帧合并,Steam 触控以 1000 Hz 上报。CPU 占用略高。</string>
|
||||
<string name="drawer_evdev_mouse">原生鼠标通道</string>
|
||||
<string name="drawer_relative_mouse">相对鼠标</string>
|
||||
<string name="drawer_relative_mouse_auto">自动</string>
|
||||
<string name="drawer_relative_mouse_on">开</string>
|
||||
<string name="drawer_relative_mouse_off">关</string>
|
||||
<string name="drawer_direct_cursor">光标</string>
|
||||
<string name="drawer_pc_keyboard">PC 键盘</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3490,19 +3494,18 @@
|
||||
<string name="integration_wifi">Wi-Fi 名称</string>
|
||||
<string name="integration_brightness">亮度</string>
|
||||
<string name="integration_home">将 DroidDeck 设为主屏幕</string>
|
||||
<string name="integration_shortcuts">主屏幕按钮快捷键</string>
|
||||
<string name="integration_shortcuts">系统按键</string>
|
||||
<string name="integration_wifi_hint">在 Steam 中显示网络 · 需要位置信息权限,绝不跟踪</string>
|
||||
<string name="integration_wifi_on">网络会显示在 Steam 中</string>
|
||||
<string name="integration_wifi_location_off">位置信息已关闭</string>
|
||||
<string name="integration_wifi_denied">位置信息权限被拒绝 · 请在“应用信息”中允许</string>
|
||||
<string name="integration_brightness_hint">Steam 的滑块可调节屏幕亮度</string>
|
||||
<string name="integration_home_hint">在会话中按主屏幕按钮会打开 Steam 菜单</string>
|
||||
<string name="integration_shortcuts_hint">按住主屏幕按钮使用 Steam Guide 按钮组合键</string>
|
||||
<string name="integration_shortcuts_needs_home">需要将 DroidDeck 设为主屏幕</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab、Win 键和主页键留在会话中</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">在 Android 中显示为灰色?应用信息 → ⋮ → 允许受限设置</string>
|
||||
<string name="integration_shortcuts_restricted">已被 Android 阻止 · 应用信息 → ⋮ → 允许受限设置</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck 主屏幕按钮</string>
|
||||
<string name="integration_shortcuts_service_description">当 Steam 会话处于焦点且 DroidDeck 为默认主屏幕应用时,将主屏幕按钮的按下操作传递给 Steam Guide 按钮。不会读取屏幕内容。</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck 系统按键</string>
|
||||
<string name="integration_shortcuts_service_description">让 Alt+Tab、Win 键和主页键在当前 DroidDeck 会话中生效,而不是交给 Android。</string>
|
||||
<string name="integration_brightness_needed">请在“配置”→“Steam 集成”中开启亮度</string>
|
||||
<string name="setup_bridge_dxvk">DXVK</string>
|
||||
<string name="setup_bridge_dxvk_auto">DXVK:自动</string>
|
||||
|
||||
@@ -745,6 +745,10 @@
|
||||
<string name="drawer_low_latency_touch">低延遲觸控</string>
|
||||
<string name="drawer_low_latency_touch_hint">觸控略過幀合併,Steam 觸控以 1000 Hz 回報。CPU 使用率略高。</string>
|
||||
<string name="drawer_evdev_mouse">原生滑鼠通道</string>
|
||||
<string name="drawer_relative_mouse">相對滑鼠</string>
|
||||
<string name="drawer_relative_mouse_auto">自動</string>
|
||||
<string name="drawer_relative_mouse_on">開</string>
|
||||
<string name="drawer_relative_mouse_off">關</string>
|
||||
<string name="drawer_direct_cursor">游標</string>
|
||||
<string name="drawer_pc_keyboard">電腦鍵盤</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3487,19 +3491,18 @@
|
||||
<string name="integration_wifi">Wi-Fi 名稱</string>
|
||||
<string name="integration_brightness">亮度</string>
|
||||
<string name="integration_home">將 DroidDeck 用作主畫面</string>
|
||||
<string name="integration_shortcuts">主畫面按鈕快速鍵</string>
|
||||
<string name="integration_shortcuts">系統按鍵</string>
|
||||
<string name="integration_wifi_hint">在 Steam 中顯示網絡 · 需要位置存取權,絕不追蹤</string>
|
||||
<string name="integration_wifi_on">網絡會顯示在 Steam 中</string>
|
||||
<string name="integration_wifi_location_off">位置資訊已關閉</string>
|
||||
<string name="integration_wifi_denied">位置存取遭拒 · 請在「應用程式資訊」中允許</string>
|
||||
<string name="integration_brightness_hint">Steam 的滑桿會設定螢幕亮度</string>
|
||||
<string name="integration_home_hint">在會話中,主畫面按鈕會開啟 Steam 選單</string>
|
||||
<string name="integration_shortcuts_hint">按住主畫面按鈕以使用 Steam Guide 組合鍵</string>
|
||||
<string name="integration_shortcuts_needs_home">需要將 DroidDeck 設為主畫面</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab、Win 鍵和主頁鍵留在工作階段中</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">在 Android 中呈灰色?應用程式資訊 → ⋮ → 允許受限制的設定</string>
|
||||
<string name="integration_shortcuts_restricted">已被 Android 封鎖 · 應用程式資訊 → ⋮ → 允許受限制的設定</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck 主畫面按鈕</string>
|
||||
<string name="integration_shortcuts_service_description">當 Steam 會話處於焦點且 DroidDeck 為預設主畫面應用程式時,將主畫面按鈕的按壓傳送給 Steam Guide。不會讀取螢幕內容。</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck 系統按鍵</string>
|
||||
<string name="integration_shortcuts_service_description">讓 Alt+Tab、Win 鍵和主頁鍵在目前的 DroidDeck 工作階段中生效,而不是交給 Android。</string>
|
||||
<string name="integration_brightness_needed">請在「初始設定 → Steam 整合」中開啟「亮度」</string>
|
||||
<string name="setup_bridge_dxvk">DXVK</string>
|
||||
<string name="setup_bridge_dxvk_auto">DXVK:自動</string>
|
||||
|
||||
@@ -745,6 +745,10 @@
|
||||
<string name="drawer_low_latency_touch">低延遲觸控</string>
|
||||
<string name="drawer_low_latency_touch_hint">觸控略過影格合併,Steam 觸控以 1000 Hz 回報。CPU 使用率略高。</string>
|
||||
<string name="drawer_evdev_mouse">原生滑鼠通道</string>
|
||||
<string name="drawer_relative_mouse">相對滑鼠</string>
|
||||
<string name="drawer_relative_mouse_auto">自動</string>
|
||||
<string name="drawer_relative_mouse_on">開</string>
|
||||
<string name="drawer_relative_mouse_off">關</string>
|
||||
<string name="drawer_direct_cursor">游標</string>
|
||||
<string name="drawer_pc_keyboard">電腦鍵盤</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3487,19 +3491,18 @@
|
||||
<string name="integration_wifi">Wi-Fi 名稱</string>
|
||||
<string name="integration_brightness">亮度</string>
|
||||
<string name="integration_home">將 DroidDeck 設為主畫面</string>
|
||||
<string name="integration_shortcuts">主畫面按鈕快速鍵</string>
|
||||
<string name="integration_shortcuts">系統按鍵</string>
|
||||
<string name="integration_wifi_hint">在 Steam 中顯示網路 · 需要位置存取權,絕不追蹤</string>
|
||||
<string name="integration_wifi_on">網路會顯示在 Steam 中</string>
|
||||
<string name="integration_wifi_location_off">位置資訊已關閉</string>
|
||||
<string name="integration_wifi_denied">位置存取遭拒 · 請在「應用程式資訊」中允許</string>
|
||||
<string name="integration_brightness_hint">Steam 的滑桿會設定螢幕亮度</string>
|
||||
<string name="integration_home_hint">在工作階段中,主畫面按鈕會開啟 Steam 選單</string>
|
||||
<string name="integration_shortcuts_hint">按住主畫面按鈕以使用 Steam Guide 組合鍵</string>
|
||||
<string name="integration_shortcuts_needs_home">需要將 DroidDeck 設為主畫面</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab、Win 鍵和主畫面鍵留在工作階段中</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">在 Android 中呈灰色?應用程式資訊 → ⋮ → 允許受限制的設定</string>
|
||||
<string name="integration_shortcuts_restricted">已被 Android 封鎖 · 應用程式資訊 → ⋮ → 允許受限制的設定</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck 主畫面按鈕</string>
|
||||
<string name="integration_shortcuts_service_description">當 Steam 工作階段處於焦點且 DroidDeck 為預設主畫面應用程式時,將主畫面按鈕的按壓傳送給 Steam Guide。不會讀取螢幕內容。</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck 系統按鍵</string>
|
||||
<string name="integration_shortcuts_service_description">讓 Alt+Tab、Win 鍵和主畫面鍵在目前的 DroidDeck 工作階段中生效,而不是交給 Android。</string>
|
||||
<string name="integration_brightness_needed">請在「初始設定 → Steam 整合」中開啟「亮度」</string>
|
||||
<string name="setup_bridge_dxvk">DXVK</string>
|
||||
<string name="setup_bridge_dxvk_auto">DXVK:自動</string>
|
||||
|
||||
@@ -815,6 +815,10 @@
|
||||
<string name="drawer_low_latency_touch">Low-latency touch</string>
|
||||
<string name="drawer_low_latency_touch_hint">Touches skip frame batching; Steam touch controls at 1000 Hz. Slightly more CPU.</string>
|
||||
<string name="drawer_evdev_mouse">Raw mouse channel</string>
|
||||
<string name="drawer_relative_mouse">Relative mouse</string>
|
||||
<string name="drawer_relative_mouse_auto">Auto</string>
|
||||
<string name="drawer_relative_mouse_on">On</string>
|
||||
<string name="drawer_relative_mouse_off">Off</string>
|
||||
<string name="drawer_direct_cursor">Cursor</string>
|
||||
<string name="drawer_pc_keyboard">PC keyboard</string>
|
||||
<string name="drawer_android_keyboard">Android</string>
|
||||
@@ -3693,19 +3697,18 @@
|
||||
<string name="integration_wifi">Wi-Fi names</string>
|
||||
<string name="integration_brightness">Brightness</string>
|
||||
<string name="integration_home">DroidDeck as Home</string>
|
||||
<string name="integration_shortcuts">Home button shortcuts</string>
|
||||
<string name="integration_shortcuts">System keys</string>
|
||||
<string name="integration_wifi_hint">Show networks in Steam · needs Location access, never tracked</string>
|
||||
<string name="integration_wifi_on">Networks show in Steam</string>
|
||||
<string name="integration_wifi_location_off">Location is off</string>
|
||||
<string name="integration_wifi_denied">Location denied · allow it in App info</string>
|
||||
<string name="integration_brightness_hint">Steam’s slider sets screen brightness</string>
|
||||
<string name="integration_home_hint">Home opens the Steam menu in a session</string>
|
||||
<string name="integration_shortcuts_hint">Hold Home for Steam Guide chords</string>
|
||||
<string name="integration_shortcuts_needs_home">Needs DroidDeck as Home</string>
|
||||
<string name="integration_shortcuts_hint">Alt+Tab, Win key and Home button stay in the session</string>
|
||||
<string name="integration_shortcuts_maybe_restricted">Greyed out in Android? App info → ⋮ → Allow restricted settings</string>
|
||||
<string name="integration_shortcuts_restricted">Blocked by Android · App info → ⋮ → Allow restricted settings</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck Home button</string>
|
||||
<string name="integration_shortcuts_service_description">Pass Home button presses to Steam Guide while a Steam session is focused and DroidDeck is the default Home app. Does not read screen content.</string>
|
||||
<string name="integration_shortcuts_service">DroidDeck system keys</string>
|
||||
<string name="integration_shortcuts_service_description">Keep Alt+Tab, the Win key and the Home button inside a focused DroidDeck session instead of Android.</string>
|
||||
<string name="integration_brightness_needed">Turn on Brightness in Setup → Steam integration</string>
|
||||
<string name="desktop_restore_title">Restoring your software</string>
|
||||
<string name="desktop_restore_body">Reinstalling the apps you added after a DroidDeck update.</string>
|
||||
|
||||
@@ -10,6 +10,13 @@ import org.robolectric.annotation.Config
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(sdk = [28], manifest = Config.NONE)
|
||||
class GesturePrefsTest {
|
||||
@Test fun relativeMouseModeSurvivesSerializationAndRejectsUnknownValues() {
|
||||
val on = TouchGestureConfig(relativeMouseMode = TouchGestureConfig.RELATIVE_MOUSE_ON)
|
||||
assertEquals(TouchGestureConfig.RELATIVE_MOUSE_ON, TouchGestureConfig.fromJson(on.toJson()).relativeMouseMode)
|
||||
assertEquals(TouchGestureConfig.RELATIVE_MOUSE_AUTO, TouchGestureConfig.fromJson("""{"relativeMouseMode":9}""").relativeMouseMode)
|
||||
assertEquals(TouchGestureConfig.RELATIVE_MOUSE_AUTO, TouchGestureConfig.fromJson("{}").relativeMouseMode)
|
||||
}
|
||||
|
||||
@Test fun removedOptionsAreIgnoredWhenLoadingExistingSettings() {
|
||||
val old = """{"holdMouseButtonWhileTouchingEnabled":true,"holdMouseButtonWhileTouchingAction":"right_click",
|
||||
"showClickHighlight":true,"showCursorInTouchscreenMode":true,"tapAction":"key_E","longPressDelay":650}"""
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.droiddeck.launcher.input
|
||||
|
||||
import android.view.KeyEvent
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
class SystemKeyCaptureTest {
|
||||
@Test fun systemCombinationsAreCaptured() {
|
||||
assertTrue(SystemKeyCapture.captures(KeyEvent.KEYCODE_META_LEFT, 0))
|
||||
assertTrue(SystemKeyCapture.captures(KeyEvent.KEYCODE_META_RIGHT, 0))
|
||||
assertTrue(SystemKeyCapture.captures(KeyEvent.KEYCODE_TAB, KeyEvent.META_ALT_ON or KeyEvent.META_ALT_LEFT_ON))
|
||||
assertTrue(SystemKeyCapture.captures(KeyEvent.KEYCODE_ESCAPE, KeyEvent.META_ALT_ON))
|
||||
assertTrue(SystemKeyCapture.captures(KeyEvent.KEYCODE_D, KeyEvent.META_META_ON))
|
||||
}
|
||||
|
||||
@Test fun onlyTheEscapeScanCodeTurnsBackIntoEscape() {
|
||||
assertTrue(GuestKeys.isKeyboardEscape(KeyEvent.KEYCODE_BACK, 1))
|
||||
assertFalse(GuestKeys.isKeyboardEscape(KeyEvent.KEYCODE_BACK, 158))
|
||||
assertFalse(GuestKeys.isKeyboardEscape(KeyEvent.KEYCODE_ESCAPE, 1))
|
||||
}
|
||||
|
||||
@Test fun ordinaryKeysStayWithTheNormalPath() {
|
||||
assertFalse(SystemKeyCapture.captures(KeyEvent.KEYCODE_TAB, 0))
|
||||
assertFalse(SystemKeyCapture.captures(KeyEvent.KEYCODE_A, 0))
|
||||
assertFalse(SystemKeyCapture.captures(KeyEvent.KEYCODE_F, KeyEvent.META_ALT_ON))
|
||||
assertFalse(SystemKeyCapture.captures(KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_ON))
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class SystemKeyCaptureHeldKeysTest {
|
||||
private val sent = mutableListOf<Int>()
|
||||
|
||||
private fun key(action: Int, repeat: Int = 0) =
|
||||
KeyEvent(0L, 0L, action, KeyEvent.KEYCODE_META_LEFT, repeat)
|
||||
|
||||
private fun attached(): Any = Any().also {
|
||||
SystemKeyCapture.isKeyboard = { true }
|
||||
SystemKeyCapture.attach(it, { true }) { event -> sent += event.action }
|
||||
}
|
||||
|
||||
@Test fun keyHeldThroughDetachIsReleasedOnceAndItsPhysicalReleaseIsConsumed() {
|
||||
val owner = attached()
|
||||
assertTrue(SystemKeyCapture.onKeyEvent(key(KeyEvent.ACTION_DOWN)))
|
||||
SystemKeyCapture.detach(owner)
|
||||
assertEquals(listOf(KeyEvent.ACTION_DOWN, KeyEvent.ACTION_UP), sent)
|
||||
assertTrue(SystemKeyCapture.onKeyEvent(key(KeyEvent.ACTION_DOWN, repeat = 1)))
|
||||
assertTrue(SystemKeyCapture.onKeyEvent(key(KeyEvent.ACTION_UP)))
|
||||
assertEquals(2, sent.size)
|
||||
assertFalse(SystemKeyCapture.onKeyEvent(key(KeyEvent.ACTION_UP)))
|
||||
}
|
||||
|
||||
@Test fun aKeyAlreadyHeldWhenCaptureStartsStaysWithAndroid() {
|
||||
val owner = attached()
|
||||
assertFalse(SystemKeyCapture.onKeyEvent(key(KeyEvent.ACTION_DOWN, repeat = 1)))
|
||||
assertFalse(SystemKeyCapture.onKeyEvent(key(KeyEvent.ACTION_UP)))
|
||||
SystemKeyCapture.detach(owner)
|
||||
assertEquals(0, sent.size)
|
||||
}
|
||||
|
||||
@Test fun newPressAfterDetachIsNotSwallowed() {
|
||||
val owner = attached()
|
||||
SystemKeyCapture.onKeyEvent(key(KeyEvent.ACTION_DOWN))
|
||||
SystemKeyCapture.detach(owner)
|
||||
assertFalse(SystemKeyCapture.onKeyEvent(key(KeyEvent.ACTION_DOWN)))
|
||||
}
|
||||
}
|
||||
@@ -53,11 +53,8 @@ class SteamIntegrationGroupTest {
|
||||
compose.onNodeWithText("3 of 4 on").assertExists()
|
||||
}
|
||||
|
||||
@Test fun shortcutsWaitForHome() {
|
||||
@Test fun shortcutsDoNotNeedHome() {
|
||||
show()
|
||||
compose.onNodeWithTag("integration-action-shortcuts").assertIsNotEnabled()
|
||||
compose.onNodeWithText("Needs DroidDeck as Home").assertExists()
|
||||
compose.runOnIdle { state.value = state.value.copy(home = true) }
|
||||
compose.onNodeWithTag("integration-action-shortcuts").assertIsEnabled()
|
||||
}
|
||||
|
||||
|
||||
@@ -225,3 +225,38 @@ PropertyNotify, and it listens for those from map on, so the style Wine sets bef
|
||||
was never known; `map_win` now reads it with the other properties, which the layered-launcher and
|
||||
Xalia rules rely on too. `tools/tests/test_gamescope_override_stacking.py` compiles the rule from
|
||||
this patch.
|
||||
|
||||
## 0127 steamcompmgr: a three way relative mouse switch
|
||||
|
||||
`relative_mouse` is read where the decision is made: 0 leaves it to the rule below, 1 forces relative
|
||||
motion for the focused game except Steam's own windows and composites the cursor, 2 never goes relative.
|
||||
For games that confine a visible cursor and warp it, which the automatic rule cannot see.
|
||||
|
||||
## 0128 steamcompmgr: a hidden cursor under any pointer constraint is relative
|
||||
|
||||
The rule only counted a lock with a cursor position hint. A game that hides the cursor and confines the
|
||||
pointer through a grab (Wine's ClipCursor) has a constraint with no hint, so the nested pointer stayed
|
||||
absolute, the constraint held the X pointer still and no raw motion was produced: the camera froze.
|
||||
|
||||
## 0129 steamcompmgr, wayland: release a pointer lock at the game's pointer
|
||||
|
||||
A game can move the X pointer while it holds the lock (Wine's ClipCursor recentres it), and the nested host
|
||||
never hears about it. On unlock the host's next absolute motion dropped the pointer back at its old position,
|
||||
often near a corner. The unlock now sends the X pointer as a cursor position hint and commits it first. A cursor
|
||||
forced On by `relative_mouse` also stays visible while idle, since the host cursor is hidden during the lock.
|
||||
|
||||
## 0130 steamcompmgr: fit the X screen to a larger fullscreen window
|
||||
|
||||
A game can open a fullscreen window larger than its X screen (Valheim at 1366x768 on 1280x720). The X server
|
||||
keeps the pointer inside the screen, so the outer part of the window could not be reached and motion past the
|
||||
edge had to be undone. The server's mode now follows such a window, and returns once the focused window fits,
|
||||
focus moves to Steam or no window has focus.
|
||||
|
||||
## 0131 steamcompmgr, wlserver: follow a game's pointer warps
|
||||
|
||||
Under a nested host the seat's absolute position came from the host, so a game that warped a visible X pointer
|
||||
to the screen centre read the distance back to the host's position on the next motion, and the view spun. When
|
||||
the X pointer stays far from the seat position while input moves, gamescope takes the host's lock and applies
|
||||
each frame's motion to the X pointer itself until the game stops warping. Absolute motion also sends relative
|
||||
motion, as a real compositor does, so XInput2 raw motion reaches games that read only that. A touch moves the
|
||||
pointer without relative motion, so tapping the screen does not turn the camera.
|
||||
@@ -0,0 +1,30 @@
|
||||
--- a/src/steamcompmgr.cpp
|
||||
+++ b/src/steamcompmgr.cpp
|
||||
@@ -3062,8 +3062,13 @@
|
||||
#endif
|
||||
|
||||
gamescope::ConVar<int> cv_cursor_composite{ "cursor_composite", 1, "0 = Never composite a cursor. 1 = Composite cursor when not nested. 2 = Always composite a cursor manually" };
|
||||
+static gamescope::ConVar<int> cv_relative_mouse( "relative_mouse", 0,
|
||||
+"0 = Leave it to the game and the nested hints. 1 = Send host pointer motion as relative movement, for games that confine the cursor and warp it back to read movement. 2 = Never go relative." );
|
||||
bool ShouldDrawCursor()
|
||||
{
|
||||
+ if ( cv_relative_mouse.Get() == 1 )
|
||||
+ return true;
|
||||
+
|
||||
global_focus_t *pFocus = GetCurrentFocus();
|
||||
gamescope::INestedHints *pNestedHints = pFocus ? pFocus->GetNestedHints() : nullptr;
|
||||
return gamescope::CursorShouldBeComposited( cv_cursor_composite.Get(), g_bForceRelativeMouse,
|
||||
@@ -10810,7 +10815,12 @@
|
||||
|
||||
const bool bExcludedAppId = uAppId && gamescope::Algorithm::Contains( s_uRelativeMouseFilteredAppids, uAppId );
|
||||
|
||||
- const bool bRelativeMouseMode = bImageEmpty && bHasPointerConstraint && !bExcludedAppId;
|
||||
+ const int nRelativeMouse = cv_relative_mouse.Get();
|
||||
+ const bool bForcedRelativeMouse = nRelativeMouse == 1 && !window_is_steam( pPaintFocus->inputFocusWindow );
|
||||
+
|
||||
+ const bool bRelativeMouseMode = nRelativeMouse == 2
|
||||
+ ? false
|
||||
+ : ( bForcedRelativeMouse || ( bImageEmpty && bHasPointerConstraint && !bExcludedAppId ) );
|
||||
|
||||
pPaintFocus->GetNestedHints()->SetRelativeMouseMode( bRelativeMouseMode );
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
--- a/src/steamcompmgr.cpp
|
||||
+++ b/src/steamcompmgr.cpp
|
||||
@@ -10804,7 +10804,8 @@
|
||||
( pPaintFocus->cursor && pPaintFocus->cursor->imageEmpty() ) &&
|
||||
( !window_is_steam( pPaintFocus->inputFocusWindow ) );
|
||||
|
||||
- const bool bHasPointerConstraint = pPaintFocus->cursor && pPaintFocus->cursor->IsConstrained();
|
||||
+ const bool bHasPointerConstraint = pPaintFocus->cursor &&
|
||||
+ ( pPaintFocus->cursor->IsConstrained() || wlserver.HasMouseConstraint() );
|
||||
|
||||
uint32_t uAppId = pPaintFocus->inputFocusWindow
|
||||
? pPaintFocus->inputFocusWindow->appID
|
||||
@@ -0,0 +1,145 @@
|
||||
diff --git a/src/Backends/WaylandBackend.cpp b/src/Backends/WaylandBackend.cpp
|
||||
index 953765a..572fb0e 100644
|
||||
--- a/src/Backends/WaylandBackend.cpp
|
||||
+++ b/src/Backends/WaylandBackend.cpp
|
||||
@@ -464,6 +464,7 @@ namespace gamescope
|
||||
|
||||
virtual void SetCursorImage( std::shared_ptr<INestedHints::CursorInfo> info ) override;
|
||||
virtual void SetRelativeMouseMode( bool bRelative ) override;
|
||||
+ virtual void SetCursorPositionHint( double flX, double flY ) override;
|
||||
virtual void SetVisible( bool bVisible ) override;
|
||||
virtual void SetTitle( std::shared_ptr<std::string> szTitle ) override;
|
||||
virtual void SetIcon( std::shared_ptr<std::vector<uint32_t>> uIconPixels ) override;
|
||||
@@ -719,6 +720,7 @@ namespace gamescope
|
||||
|
||||
void SetCursorImage( std::shared_ptr<INestedHints::CursorInfo> info );
|
||||
void SetRelativeMouseMode( wl_surface *pSurface, bool bRelative );
|
||||
+ void SetCursorPositionHint( wl_fixed_t fSurfaceX, wl_fixed_t fSurfaceY );
|
||||
void UpdateCursor();
|
||||
|
||||
friend CWaylandConnector;
|
||||
@@ -1270,6 +1272,16 @@ namespace gamescope
|
||||
// TODO: Do more tracking across multiple connectors, and activity here if we ever want to use this.
|
||||
m_pBackend->SetRelativeMouseMode( m_Planes[0].GetSurface(), bRelative );
|
||||
}
|
||||
+ void CWaylandConnector::SetCursorPositionHint( double flX, double flY )
|
||||
+ {
|
||||
+ auto oState = m_Planes[0].GetCurrentState();
|
||||
+ if ( !oState || !oState->uFractionalScale )
|
||||
+ return;
|
||||
+
|
||||
+ const double flSurfaceX = ( flX * g_nOutputWidth - oState->nDestX ) * 120.0 / oState->uFractionalScale;
|
||||
+ const double flSurfaceY = ( flY * g_nOutputHeight - oState->nDestY ) * 120.0 / oState->uFractionalScale;
|
||||
+ m_pBackend->SetCursorPositionHint( wl_fixed_from_double( flSurfaceX ), wl_fixed_from_double( flSurfaceY ) );
|
||||
+ }
|
||||
void CWaylandConnector::SetVisible( bool bVisible )
|
||||
{
|
||||
if ( m_bVisible == bVisible )
|
||||
@@ -2484,6 +2496,15 @@ namespace gamescope
|
||||
|
||||
UpdateCursor();
|
||||
}
|
||||
+ void CWaylandBackend::SetCursorPositionHint( wl_fixed_t fSurfaceX, wl_fixed_t fSurfaceY )
|
||||
+ {
|
||||
+ if ( !m_pLockedPointer )
|
||||
+ return;
|
||||
+
|
||||
+ zwp_locked_pointer_v1_set_cursor_position_hint( m_pLockedPointer, fSurfaceX, fSurfaceY );
|
||||
+ wl_surface_commit( m_pLockedSurface );
|
||||
+ }
|
||||
+
|
||||
void CWaylandBackend::SetRelativeMouseMode( wl_surface *pSurface, bool bRelative )
|
||||
{
|
||||
if ( !m_pPointer )
|
||||
diff --git a/src/backend.h b/src/backend.h
|
||||
index d264917..37b936e 100644
|
||||
--- a/src/backend.h
|
||||
+++ b/src/backend.h
|
||||
@@ -271,6 +271,7 @@ namespace gamescope
|
||||
|
||||
virtual void SetCursorImage( std::shared_ptr<CursorInfo> info ) = 0;
|
||||
virtual void SetRelativeMouseMode( bool bRelative ) = 0;
|
||||
+ virtual void SetCursorPositionHint( double flX, double flY ) {}
|
||||
virtual void SetVisible( bool bVisible ) = 0;
|
||||
virtual void SetTitle( std::shared_ptr<std::string> szTitle ) = 0;
|
||||
virtual void SetIcon( std::shared_ptr<std::vector<uint32_t>> uIconPixels ) = 0;
|
||||
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
||||
index f1346e5..2c92afe 100644
|
||||
--- a/src/steamcompmgr.cpp
|
||||
+++ b/src/steamcompmgr.cpp
|
||||
@@ -2078,6 +2078,18 @@ void MouseCursor::UpdatePosition()
|
||||
}
|
||||
}
|
||||
|
||||
+void MouseCursor::QueryRootPosition( int *pX, int *pY )
|
||||
+{
|
||||
+ Window root_ret, child_ret;
|
||||
+ int win_x = 0, win_y = 0;
|
||||
+ unsigned int mask;
|
||||
+ *pX = m_x;
|
||||
+ *pY = m_y;
|
||||
+ XQueryPointer( m_ctx->dpy, DefaultRootWindow( m_ctx->dpy ), &root_ret, &child_ret, pX, pY, &win_x, &win_y, &mask );
|
||||
+}
|
||||
+
|
||||
+static bool relative_mouse_forced();
|
||||
+
|
||||
void MouseCursor::checkSuspension()
|
||||
{
|
||||
getTexture();
|
||||
@@ -2085,7 +2097,12 @@ void MouseCursor::checkSuspension()
|
||||
if ( ShouldDrawCursor() )
|
||||
{
|
||||
const bool suspended = int64_t( get_time_in_nanos() ) - int64_t( wlserver.ulLastMovedCursorTime ) > int64_t( cursorHideTime );
|
||||
- if (!wlserver.bCursorHidden && suspended) {
|
||||
+ if ( relative_mouse_forced() && wlserver.bCursorHidden )
|
||||
+ {
|
||||
+ wlserver.bCursorHidden = false;
|
||||
+ hasRepaintNonBasePlane = true;
|
||||
+ }
|
||||
+ if (!wlserver.bCursorHidden && suspended && !relative_mouse_forced()) {
|
||||
wlserver.bCursorHidden = true;
|
||||
|
||||
steamcompmgr_win_t *window = m_ctx->focus.inputFocusWindow;
|
||||
@@ -3064,6 +3081,11 @@ static void paint_pipewire()
|
||||
gamescope::ConVar<int> cv_cursor_composite{ "cursor_composite", 1, "0 = Never composite a cursor. 1 = Composite cursor when not nested. 2 = Always composite a cursor manually" };
|
||||
static gamescope::ConVar<int> cv_relative_mouse( "relative_mouse", 0,
|
||||
"0 = Leave it to the game and the nested hints. 1 = Send host pointer motion as relative movement, for games that confine the cursor and warp it back to read movement. 2 = Never go relative." );
|
||||
+static bool relative_mouse_forced()
|
||||
+{
|
||||
+ return cv_relative_mouse.Get() == 1;
|
||||
+}
|
||||
+
|
||||
bool ShouldDrawCursor()
|
||||
{
|
||||
if ( cv_relative_mouse.Get() == 1 )
|
||||
@@ -10828,6 +10850,18 @@ steamcompmgr_main(int argc, char **argv)
|
||||
? false
|
||||
: ( bForcedRelativeMouse || ( bImageEmpty && bHasPointerConstraint && !bExcludedAppId ) );
|
||||
|
||||
+ static bool s_bRelativeMouseMode = false;
|
||||
+ if ( s_bRelativeMouseMode && !bRelativeMouseMode && pPaintFocus->cursor &&
|
||||
+ g_nOutputWidth && g_nOutputHeight && focusedWindowScaleX > 0.0f && focusedWindowScaleY > 0.0f )
|
||||
+ {
|
||||
+ int nRootX, nRootY;
|
||||
+ pPaintFocus->cursor->QueryRootPosition( &nRootX, &nRootY );
|
||||
+ pPaintFocus->GetNestedHints()->SetCursorPositionHint(
|
||||
+ ( nRootX / focusedWindowScaleX - focusedWindowOffsetX ) / g_nOutputWidth,
|
||||
+ ( nRootY / focusedWindowScaleY - focusedWindowOffsetY ) / g_nOutputHeight );
|
||||
+ }
|
||||
+ s_bRelativeMouseMode = bRelativeMouseMode;
|
||||
+
|
||||
pPaintFocus->GetNestedHints()->SetRelativeMouseMode( bRelativeMouseMode );
|
||||
}
|
||||
|
||||
diff --git a/src/steamcompmgr.hpp b/src/steamcompmgr.hpp
|
||||
index 7a7119f..ff54d8e 100644
|
||||
--- a/src/steamcompmgr.hpp
|
||||
+++ b/src/steamcompmgr.hpp
|
||||
@@ -85,6 +85,7 @@ public:
|
||||
}
|
||||
|
||||
void UpdatePosition();
|
||||
+ void QueryRootPosition( int *pX, int *pY );
|
||||
|
||||
bool isHidden() { return wlserver.bCursorHidden || m_imageEmpty; }
|
||||
bool imageEmpty() const { return m_imageEmpty; }
|
||||
@@ -0,0 +1,94 @@
|
||||
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
||||
index 2c92afe..17bae3a 100644
|
||||
--- a/src/steamcompmgr.cpp
|
||||
+++ b/src/steamcompmgr.cpp
|
||||
@@ -4662,6 +4662,49 @@ static void set_wm_state( xwayland_ctx_t *ctx, Window win, uint32_t state )
|
||||
sizeof(wmState) / sizeof(wmState[0]));
|
||||
}
|
||||
|
||||
+static void
|
||||
+fit_root_to_focus_window( xwayland_ctx_t *ctx )
|
||||
+{
|
||||
+ steamcompmgr_win_t *w = ctx->focus.focusWindow;
|
||||
+ const bool bGame = w && !window_is_steam( w );
|
||||
+ const int nWindowX = bGame ? w->xwayland().a.x : 0;
|
||||
+ const int nWindowY = bGame ? w->xwayland().a.y : 0;
|
||||
+ const int nWindowWidth = bGame ? w->xwayland().a.width : 0;
|
||||
+ const int nWindowHeight = bGame ? w->xwayland().a.height : 0;
|
||||
+ const int nBaseWidth = ctx->nFitRestoreWidth ? ctx->nFitRestoreWidth : ctx->root_width;
|
||||
+ const int nBaseHeight = ctx->nFitRestoreWidth ? ctx->nFitRestoreHeight : ctx->root_height;
|
||||
+ const bool bCoversBase = nWindowX == 0 && nWindowY == 0 && nWindowWidth >= nBaseWidth && nWindowHeight >= nBaseHeight;
|
||||
+ const bool bPlausible = nWindowWidth <= 8192 && nWindowHeight <= 8192;
|
||||
+
|
||||
+ int nWidth = 0;
|
||||
+ int nHeight = 0;
|
||||
+ if ( bGame && bCoversBase && bPlausible && ( nWindowWidth > nBaseWidth || nWindowHeight > nBaseHeight ) )
|
||||
+ {
|
||||
+ if ( !ctx->nFitRestoreWidth )
|
||||
+ {
|
||||
+ ctx->nFitRestoreWidth = ctx->root_width;
|
||||
+ ctx->nFitRestoreHeight = ctx->root_height;
|
||||
+ }
|
||||
+ nWidth = nWindowWidth;
|
||||
+ nHeight = nWindowHeight;
|
||||
+ }
|
||||
+ else if ( ctx->nFitRestoreWidth && nWindowWidth <= ctx->nFitRestoreWidth && nWindowHeight <= ctx->nFitRestoreHeight )
|
||||
+ {
|
||||
+ nWidth = ctx->nFitRestoreWidth;
|
||||
+ nHeight = ctx->nFitRestoreHeight;
|
||||
+ ctx->nFitRestoreWidth = 0;
|
||||
+ ctx->nFitRestoreHeight = 0;
|
||||
+ }
|
||||
+
|
||||
+ if ( !nWidth || ( nWidth == ctx->root_width && nHeight == ctx->root_height ) )
|
||||
+ return;
|
||||
+
|
||||
+ ctx->bFitPending = true;
|
||||
+ wlserver_lock();
|
||||
+ wlserver_set_xwayland_server_mode( ctx->xwayland_server->get_index(), nWidth, nHeight, g_nOutputRefresh );
|
||||
+ wlserver_unlock();
|
||||
+}
|
||||
+
|
||||
void xwayland_ctx_t::DetermineAndApplyFocus( const std::vector< steamcompmgr_win_t* > &vecPossibleFocusWindows )
|
||||
{
|
||||
xwayland_ctx_t *ctx = this;
|
||||
@@ -4736,6 +4779,8 @@ void xwayland_ctx_t::DetermineAndApplyFocus( const std::vector< steamcompmgr_win
|
||||
inputFocus = ctx->focus.focusWindow;
|
||||
}
|
||||
|
||||
+ fit_root_to_focus_window( ctx );
|
||||
+
|
||||
if ( ctx->focus.focusWindow )
|
||||
{
|
||||
if ( prevFocusWindow != ctx->focus.focusWindow )
|
||||
@@ -5001,7 +5046,7 @@ void xwayland_ctx_t::DetermineAndApplyFocus( const std::vector< steamcompmgr_win
|
||||
fs_width = ctx->root_width * steam_height_scale;
|
||||
}
|
||||
|
||||
- if ( w->GetGeometry().nWidth != fs_width || w->GetGeometry().nHeight != fs_height || globalScaleRatio != 1.0f )
|
||||
+ if ( !ctx->bFitPending && ( w->GetGeometry().nWidth != fs_width || w->GetGeometry().nHeight != fs_height || globalScaleRatio != 1.0f ) )
|
||||
XResizeWindow(ctx->dpy, ctx->focus.focusWindow->xwayland().id, fs_width, fs_height);
|
||||
}
|
||||
else
|
||||
@@ -6232,6 +6277,7 @@ configure_win(xwayland_ctx_t *ctx, XConfigureEvent *ce)
|
||||
{
|
||||
if (ce->window == ctx->root)
|
||||
{
|
||||
+ ctx->bFitPending = false;
|
||||
ctx->root_width = ce->width;
|
||||
ctx->root_height = ce->height;
|
||||
MakeFocusDirty();
|
||||
diff --git a/src/xwayland_ctx.hpp b/src/xwayland_ctx.hpp
|
||||
index 3a75650..15c2e6b 100644
|
||||
--- a/src/xwayland_ctx.hpp
|
||||
+++ b/src/xwayland_ctx.hpp
|
||||
@@ -87,6 +87,9 @@ struct xwayland_ctx_t final : public gamescope::IWaitable
|
||||
Window ourWindow;
|
||||
|
||||
focus_t focus;
|
||||
+ int nFitRestoreWidth = 0;
|
||||
+ int nFitRestoreHeight = 0;
|
||||
+ bool bFitPending = false;
|
||||
Window currentKeyboardFocusWindow;
|
||||
Window focusControlWindow;
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
||||
index 17bae3a..c468fb3 100644
|
||||
--- a/src/steamcompmgr.cpp
|
||||
+++ b/src/steamcompmgr.cpp
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "backend.h"
|
||||
#include "gamescope_shared.h"
|
||||
#include "xwayland_ctx.hpp"
|
||||
+#include <cmath>
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
@@ -2088,6 +2089,7 @@ void MouseCursor::QueryRootPosition( int *pX, int *pY )
|
||||
XQueryPointer( m_ctx->dpy, DefaultRootWindow( m_ctx->dpy ), &root_ret, &child_ret, pX, pY, &win_x, &win_y, &mask );
|
||||
}
|
||||
|
||||
+static bool s_bFollowClientPointer = false;
|
||||
static bool relative_mouse_forced();
|
||||
|
||||
void MouseCursor::checkSuspension()
|
||||
@@ -3083,12 +3085,89 @@ static gamescope::ConVar<int> cv_relative_mouse( "relative_mouse", 0,
|
||||
"0 = Leave it to the game and the nested hints. 1 = Send host pointer motion as relative movement, for games that confine the cursor and warp it back to read movement. 2 = Never go relative." );
|
||||
static bool relative_mouse_forced()
|
||||
{
|
||||
- return cv_relative_mouse.Get() == 1;
|
||||
+ return cv_relative_mouse.Get() == 1 || s_bFollowClientPointer;
|
||||
+}
|
||||
+
|
||||
+static void update_client_pointer_follow( global_focus_t *pFocus, bool bAllowed )
|
||||
+{
|
||||
+ static int s_nAwayFrames = 0;
|
||||
+ static int s_nQuietFrames = 0;
|
||||
+ static uint64_t s_ulLastAway = 0;
|
||||
+ static double s_flLastX = 0.0;
|
||||
+ static double s_flLastY = 0.0;
|
||||
+
|
||||
+ int nRootX = 0;
|
||||
+ int nRootY = 0;
|
||||
+ if ( bAllowed && pFocus->cursor )
|
||||
+ pFocus->cursor->QueryRootPosition( &nRootX, &nRootY );
|
||||
+ else
|
||||
+ bAllowed = false;
|
||||
+
|
||||
+ wlserver_lock();
|
||||
+ const double flX = wlserver.mouse_surface_cursorx;
|
||||
+ const double flY = wlserver.mouse_surface_cursory;
|
||||
+ if ( !bAllowed )
|
||||
+ {
|
||||
+ s_nAwayFrames = 0;
|
||||
+ s_bFollowClientPointer = false;
|
||||
+ wlserver.bFollowClientPointer = false;
|
||||
+ }
|
||||
+ else if ( !s_bFollowClientPointer )
|
||||
+ {
|
||||
+ const bool bMoved = flX != s_flLastX || flY != s_flLastY;
|
||||
+ if ( bMoved && ( std::abs( nRootX - flX ) > 48.0 || std::abs( nRootY - flY ) > 48.0 ) )
|
||||
+ {
|
||||
+ const uint64_t ulNow = get_time_in_nanos();
|
||||
+ if ( ulNow - s_ulLastAway > 500'000'000ul )
|
||||
+ s_nAwayFrames = 0;
|
||||
+ s_ulLastAway = ulNow;
|
||||
+ s_nAwayFrames++;
|
||||
+ }
|
||||
+
|
||||
+ if ( s_nAwayFrames >= 3 )
|
||||
+ {
|
||||
+ s_nAwayFrames = 0;
|
||||
+ s_nQuietFrames = 0;
|
||||
+ s_bFollowClientPointer = true;
|
||||
+ wlserver.bFollowClientPointer = true;
|
||||
+ wlserver.flFollowDX = 0.0;
|
||||
+ wlserver.flFollowDY = 0.0;
|
||||
+ wlserver_mousewarp( nRootX, nRootY, 0, true );
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ const bool bWarped = std::abs( nRootX - flX ) > 2.0 || std::abs( nRootY - flY ) > 2.0;
|
||||
+ const double flDX = std::trunc( wlserver.flFollowDX );
|
||||
+ const double flDY = std::trunc( wlserver.flFollowDY );
|
||||
+ if ( bWarped )
|
||||
+ s_nQuietFrames = 0;
|
||||
+ else if ( flDX != 0.0 || flDY != 0.0 )
|
||||
+ s_nQuietFrames++;
|
||||
+
|
||||
+ if ( flDX != 0.0 || flDY != 0.0 || bWarped )
|
||||
+ {
|
||||
+ wlserver.flFollowDX -= flDX;
|
||||
+ wlserver.flFollowDY -= flDY;
|
||||
+ wlserver_mousewarp( nRootX, nRootY, 0, true );
|
||||
+ if ( flDX != 0.0 || flDY != 0.0 )
|
||||
+ wlserver_mousewarp( nRootX + flDX, nRootY + flDY, 0, true );
|
||||
+ }
|
||||
+
|
||||
+ if ( s_nQuietFrames >= 60 )
|
||||
+ {
|
||||
+ s_bFollowClientPointer = false;
|
||||
+ wlserver.bFollowClientPointer = false;
|
||||
+ }
|
||||
+ }
|
||||
+ s_flLastX = wlserver.mouse_surface_cursorx;
|
||||
+ s_flLastY = wlserver.mouse_surface_cursory;
|
||||
+ wlserver_unlock();
|
||||
}
|
||||
|
||||
bool ShouldDrawCursor()
|
||||
{
|
||||
- if ( cv_relative_mouse.Get() == 1 )
|
||||
+ if ( relative_mouse_forced() )
|
||||
return true;
|
||||
|
||||
global_focus_t *pFocus = GetCurrentFocus();
|
||||
@@ -10892,9 +10971,15 @@ steamcompmgr_main(int argc, char **argv)
|
||||
const int nRelativeMouse = cv_relative_mouse.Get();
|
||||
const bool bForcedRelativeMouse = nRelativeMouse == 1 && !window_is_steam( pPaintFocus->inputFocusWindow );
|
||||
|
||||
+ if ( vblank )
|
||||
+ {
|
||||
+ update_client_pointer_follow( pPaintFocus,
|
||||
+ nRelativeMouse != 2 && !bExcludedAppId && !bHasPointerConstraint && !window_is_steam( pPaintFocus->inputFocusWindow ) );
|
||||
+ }
|
||||
+
|
||||
const bool bRelativeMouseMode = nRelativeMouse == 2
|
||||
? false
|
||||
- : ( bForcedRelativeMouse || ( bImageEmpty && bHasPointerConstraint && !bExcludedAppId ) );
|
||||
+ : ( bForcedRelativeMouse || s_bFollowClientPointer || ( bImageEmpty && bHasPointerConstraint && !bExcludedAppId ) );
|
||||
|
||||
static bool s_bRelativeMouseMode = false;
|
||||
if ( s_bRelativeMouseMode && !bRelativeMouseMode && pPaintFocus->cursor &&
|
||||
diff --git a/src/wlserver.cpp b/src/wlserver.cpp
|
||||
index 5733871..cc75f8a 100644
|
||||
--- a/src/wlserver.cpp
|
||||
+++ b/src/wlserver.cpp
|
||||
@@ -1,3 +1,4 @@
|
||||
+#include <cmath>
|
||||
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
@@ -3086,6 +3087,16 @@ void wlserver_mousemotion( double dx, double dy, uint32_t time )
|
||||
|
||||
wlserver_perform_rel_pointer_motion( dx, dy );
|
||||
|
||||
+ if ( wlserver.bFollowClientPointer )
|
||||
+ {
|
||||
+ wlserver.flFollowDX += dx;
|
||||
+ wlserver.flFollowDY += dy;
|
||||
+ wlserver.ulLastMovedCursorTime = get_time_in_nanos();
|
||||
+ wlserver.bCursorHidden = !wlserver.bCursorHasImage;
|
||||
+ wlr_seat_pointer_notify_frame( wlserver.wlr.seat );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if ( !wlserver_apply_constraint( &dx, &dy ) )
|
||||
{
|
||||
wlr_seat_pointer_notify_frame( wlserver.wlr.seat );
|
||||
@@ -3110,10 +3121,18 @@ void wlserver_mousemotion( double dx, double dy, uint32_t time )
|
||||
wlr_seat_pointer_notify_frame( wlserver.wlr.seat );
|
||||
}
|
||||
|
||||
-void wlserver_mousewarp( double x, double y, uint32_t time, bool bSynthetic )
|
||||
+void wlserver_mousewarp( double x, double y, uint32_t time, bool bSynthetic, bool bFromTouch )
|
||||
{
|
||||
assert( wlserver_is_lock_held() );
|
||||
|
||||
+ if ( !bSynthetic && wlserver.bFollowClientPointer )
|
||||
+ return;
|
||||
+
|
||||
+ const double flStepX = x - wlserver.mouse_surface_cursorx;
|
||||
+ const double flStepY = y - wlserver.mouse_surface_cursory;
|
||||
+ if ( !bSynthetic && !bFromTouch && ( flStepX != 0.0 || flStepY != 0.0 ) && std::abs( flStepX ) < 256.0 && std::abs( flStepY ) < 256.0 )
|
||||
+ wlserver_perform_rel_pointer_motion( flStepX, flStepY );
|
||||
+
|
||||
wlserver.mouse_surface_cursorx = x;
|
||||
wlserver.mouse_surface_cursory = y;
|
||||
|
||||
@@ -3304,7 +3323,7 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool
|
||||
{
|
||||
g_bPendingTouchMovement = true;
|
||||
|
||||
- wlserver_mousewarp( tx, ty, time, false );
|
||||
+ wlserver_mousewarp( tx, ty, time, false, !bAlwaysWarpCursor );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3352,7 +3371,7 @@ void wlserver_touchdown( double x, double y, int touch_id, uint32_t time, gamesc
|
||||
|
||||
if ( eMode != gamescope::TouchClickModes::Trackpad )
|
||||
{
|
||||
- wlserver_mousewarp( tx, ty, time, false );
|
||||
+ wlserver_mousewarp( tx, ty, time, false, true );
|
||||
}
|
||||
|
||||
uint32_t button = TouchClickModeToLinuxButton( eMode );
|
||||
diff --git a/src/wlserver.hpp b/src/wlserver.hpp
|
||||
index 79a0723..ca8d015 100644
|
||||
--- a/src/wlserver.hpp
|
||||
+++ b/src/wlserver.hpp
|
||||
@@ -168,6 +168,9 @@ struct wlserver_t {
|
||||
uint64_t ulLastMovedCursorTime = 0;
|
||||
bool bCursorHidden = true;
|
||||
bool bCursorHasImage = true;
|
||||
+ bool bFollowClientPointer = false;
|
||||
+ double flFollowDX = 0.0;
|
||||
+ double flFollowDY = 0.0;
|
||||
|
||||
bool button_held[ WLSERVER_BUTTON_COUNT ];
|
||||
std::set <uint32_t> touch_down_ids;
|
||||
@@ -271,7 +274,7 @@ void wlserver_clear_dropdowns();
|
||||
void wlserver_notify_dropdown( struct wlr_surface *wlrsurface, int nX, int nY );
|
||||
void wlserver_mousemotion( double x, double y, uint32_t time );
|
||||
void wlserver_mousehide();
|
||||
-void wlserver_mousewarp( double x, double y, uint32_t time, bool bSynthetic );
|
||||
+void wlserver_mousewarp( double x, double y, uint32_t time, bool bSynthetic, bool bFromTouch = false );
|
||||
void wlserver_mousebutton( int button, bool press, uint32_t time );
|
||||
void wlserver_mousewheel( double x, double y, uint32_t time );
|
||||
bool wlserver_input_held();
|
||||
@@ -1,3 +1,3 @@
|
||||
GAMESCOPE_REPO=Droid-Deck/DroidDeck-Components
|
||||
GAMESCOPE_TAG=gamescope-3.16.29-p19
|
||||
GAMESCOPE_SHA256=e7333c6a2b95708b199c2c5bd0973e3f0e711e2dc746950cc648c2515ea2926b
|
||||
GAMESCOPE_TAG=gamescope-3.16.29-p20
|
||||
GAMESCOPE_SHA256=30a94becf21f3de4d1d7239c47b5168aab973f4e95981402a550c228929ba827
|
||||
Reference in new issue
Block a user