feat: Gyro mouse aiming#875
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds gyro-based mouse aiming: quick-menu action/item, controller UI for selecting gyro sensitivity, persisted per-container sensitivity, a GyroAimingHelper sensor bridge, TouchpadView integration to inject deltas, XServerScreen wiring for toggles and persistence, and localized strings across many locales. Changes
Sequence DiagramsequenceDiagram
participant User
participant UI as QuickMenu UI
participant XServer as XServerScreen
participant Container as Container
participant TPView as TouchpadView
participant Gyro as GyroAimingHelper
participant Sensor as Gyro Sensor
User->>UI: toggle "Gyro Aiming"
UI->>XServer: dispatch QuickMenuAction.GYRO_AIMING
XServer->>Container: saveData(gyroAiming=true)
XServer->>TPView: setGyroAimingEnabled(true)
TPView->>Gyro: create & start()
Gyro->>Sensor: registerListener()
Sensor-->>Gyro: onSensorChanged(event)
Gyro->>Gyro: compute & accumulate deltas
Gyro-->>TPView: onMouseDelta(dx,dy)
TPView->>XServer: injectRelativeMouseMovement(dx,dy)
XServer-->>User: cursor moves
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
c09b277 to
7ace2fc
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
app/src/main/java/com/winlator/container/ContainerData.kt (1)
221-221: Clamp restoredgyroSensitivityto the same supported bounds.
Line 221 restores the value but does not enforce the[0.25f, 2f]range used elsewhere, so malformed saved state can leak invalid values into runtime state.♻️ Proposed fix
- gyroSensitivity = (savedMap["gyroSensitivity"] as? Float) ?: (savedMap["gyroSensitivity"] as? Double)?.toFloat() ?: 1f, + gyroSensitivity = + ( + (savedMap["gyroSensitivity"] as? Float) + ?: (savedMap["gyroSensitivity"] as? Double)?.toFloat() + ?: 1f + ).coerceIn(0.25f, 2f),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/winlator/container/ContainerData.kt` at line 221, Restore gyroSensitivity from savedMap but clamp it into the supported bounds [0.25f, 2f]; locate the assignment that reads gyroSensitivity = (savedMap["gyroSensitivity"] as? Float) ?: (savedMap["gyroSensitivity"] as? Double)?.toFloat() ?: 1f and wrap the parsed value with a clamp (e.g., use Kotlin's coerceIn on the parsed Float) so any malformed or out-of-range saved values are constrained to 0.25f..2f before storing in the ContainerData.gyroSensitivity field.app/src/main/java/app/gamenative/ui/component/QuickMenu.kt (1)
590-593: Make active rows use active text color as well.At Line 590-593, active-but-not-focused items keep default label color, which makes active state less consistent than the icon treatment.
🎨 Suggested tweak
Text( text = stringResource(item.labelResId), style = MaterialTheme.typography.bodyLarge, color = when { !isEnabled -> MaterialTheme.colorScheme.onSurface.copy(alpha = disabledAlpha) - isFocused -> accentColor + isFocused || isActive -> accentColor else -> MaterialTheme.colorScheme.onSurface }, modifier = Modifier.weight(1f) )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/app/gamenative/ui/component/QuickMenu.kt` around lines 590 - 593, The text color assignment for rows is missing the active-but-not-focused case; in the color = when { ... } block currently checking isEnabled and isFocused, add a branch that returns accentColor for the active/selected state (e.g., check your active flag such as isActive or isSelected) so active rows use accentColor like the icon does; keep the disabledAlpha branch and the fallback to MaterialTheme.colorScheme.onSurface unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt`:
- Around line 977-978: The gyro is enabled via
PluviaApp.touchpadView?.setGyroAimingEnabled(...) before the X server WinHandler
is assigned (getxServer().winHandler = WinHandler(...)), risking a callback
calling xServer.getWinHandler().mouseEvent(...) when null; move the WinHandler
initialization (the getxServer().winHandler = WinHandler(...) call) to occur
before calling PluviaApp.touchpadView?.setGyroAimingEnabled(...) so the handler
is always assigned before gyro callbacks can run, ensuring
TouchpadView.setGyroAimingEnabled() cannot trigger mouseEvent on a null handler.
In `@app/src/main/java/com/winlator/widget/GyroAimingHelper.java`:
- Around line 71-80: stop() currently only unregisters the sensor but does not
cancel already posted main-thread callbacks, so queued runnables can still
execute and move the cursor after disable; update stop() in GyroAimingHelper to
(1) set running = false, (2) remove any pending callbacks from the main thread
handler (e.g., call mainHandler.removeCallbacks(someRunnable) and/or
mainHandler.removeCallbacksAndMessages(null)), and (3) ensure the runnable(s)
that update cursor check the running flag at the start and return early if
false; apply the same cancellation/check to the other stop/pause block
referenced around lines 123-126 so no queued deltas execute after stop().
- Around line 125-126: The per-sample debug log call Timber.d("GyroAiming: delta
dx=%d dy=%d", fix, fiy) inside the gyro delta emitter in GyroAimingHelper is on
the input hot path and must be removed or gated; either delete the call or
replace it with a cheap sampling guard (e.g., only log when a lightweight
counter % N == 0 or when BuildConfig.DEBUG is true) so that the high-frequency
lambda/callback that emits deltas doesn't log every event and flood/slow the
system.
In `@app/src/main/java/com/winlator/widget/TouchpadView.java`:
- Around line 1310-1345: The field gyroAimingEnabled is set to true before
actually starting the gyro helper so isGyroAimingEnabled() can report true even
if start() fails; change setGyroAimingEnabled(boolean) so you only mark
gyroAimingEnabled = true after a successful gyroAimingHelper.start() (or catch
failures from start() and revert gyroAimingEnabled to false and log the error),
and/or make isGyroAimingEnabled() return the real running state by checking
gyroAimingHelper != null && gyroAimingHelper.isRunning() (or add an isRunning()
on GyroAimingHelper) instead of relying solely on the boolean flag. Ensure to
update references to gyroAimingEnabled/gyroAimingHelper in setGyroSensitivity
and shutdown paths accordingly.
---
Nitpick comments:
In `@app/src/main/java/app/gamenative/ui/component/QuickMenu.kt`:
- Around line 590-593: The text color assignment for rows is missing the
active-but-not-focused case; in the color = when { ... } block currently
checking isEnabled and isFocused, add a branch that returns accentColor for the
active/selected state (e.g., check your active flag such as isActive or
isSelected) so active rows use accentColor like the icon does; keep the
disabledAlpha branch and the fallback to MaterialTheme.colorScheme.onSurface
unchanged.
In `@app/src/main/java/com/winlator/container/ContainerData.kt`:
- Line 221: Restore gyroSensitivity from savedMap but clamp it into the
supported bounds [0.25f, 2f]; locate the assignment that reads gyroSensitivity =
(savedMap["gyroSensitivity"] as? Float) ?: (savedMap["gyroSensitivity"] as?
Double)?.toFloat() ?: 1f and wrap the parsed value with a clamp (e.g., use
Kotlin's coerceIn on the parsed Float) so any malformed or out-of-range saved
values are constrained to 0.25f..2f before storing in the
ContainerData.gyroSensitivity field.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 773fdc2c-3cf9-4363-91fd-9664358f2dc9
📒 Files selected for processing (22)
app/src/main/java/app/gamenative/ui/component/QuickMenu.ktapp/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.ktapp/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.ktapp/src/main/java/app/gamenative/utils/ContainerUtils.ktapp/src/main/java/com/winlator/container/ContainerData.ktapp/src/main/java/com/winlator/widget/GyroAimingHelper.javaapp/src/main/java/com/winlator/widget/TouchpadView.javaapp/src/main/java/com/winlator/winhandler/WinHandler.javaapp/src/main/res/values-da/strings.xmlapp/src/main/res/values-de/strings.xmlapp/src/main/res/values-es/strings.xmlapp/src/main/res/values-fr/strings.xmlapp/src/main/res/values-it/strings.xmlapp/src/main/res/values-ko/strings.xmlapp/src/main/res/values-pl/strings.xmlapp/src/main/res/values-pt-rBR/strings.xmlapp/src/main/res/values-ro/strings.xmlapp/src/main/res/values-ru/strings.xmlapp/src/main/res/values-uk/strings.xmlapp/src/main/res/values-zh-rCN/strings.xmlapp/src/main/res/values-zh-rTW/strings.xmlapp/src/main/res/values/strings.xml
💤 Files with no reviewable changes (1)
- app/src/main/java/com/winlator/winhandler/WinHandler.java
There was a problem hiding this comment.
2 issues found across 22 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="app/src/main/java/com/winlator/widget/GyroAimingHelper.java">
<violation number="1" location="app/src/main/java/com/winlator/widget/GyroAimingHelper.java:104">
P2: Gyroscope axes are not remapped for device orientation, causing inverted/swapped controls when device orientation differs from natural orientation</violation>
</file>
<file name="app/src/main/java/com/winlator/widget/TouchpadView.java">
<violation number="1" location="app/src/main/java/com/winlator/widget/TouchpadView.java:1317">
P2: Race condition: gyro callback lacks gyroAimingEnabled guard, allowing queued sensor events to inject mouse movement after feature is disabled</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
phobos665
left a comment
There was a problem hiding this comment.
Overall it seems pretty sensible.
Does it work seemlessly also with gamepad inputs at the same time?
That depends on how a game registers gamepads. |
7ace2fc to
0374434
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt (1)
1357-1358:⚠️ Potential issue | 🟠 MajorInitialize
WinHandlerbefore enabling gyro callbacks.Line 1358 enables gyro aiming before
winHandleris assigned at Line 1380, leaving a small callback window with unsafe ordering.🔧 Proposed fix
- PluviaApp.touchpadView?.setGyroSensitivity(container.getExtra("gyroSensitivity", "1").toFloatOrNull()?.coerceIn(0.25f, 2f) ?: 1f) - PluviaApp.touchpadView?.setGyroAimingEnabled(container.getExtra("gyroAiming", "false") == "true") + PluviaApp.touchpadView?.setGyroSensitivity( + container.getExtra("gyroSensitivity", "1").toFloatOrNull()?.coerceIn(0.25f, 2f) ?: 1f + ) @@ getxServer().winHandler = WinHandler(getxServer(), this) + PluviaApp.touchpadView?.setGyroAimingEnabled(container.getExtra("gyroAiming", "false") == "true")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt` around lines 1357 - 1358, The gyro aiming is enabled via PluviaApp.touchpadView.setGyroAimingEnabled(...) before winHandler is assigned, creating a race; move the initialization/assignment of winHandler (the variable or property named winHandler in XServerScreen) to occur before calling setGyroAimingEnabled and setGyroSensitivity, or defer enabling gyro callbacks until after winHandler is fully constructed/assigned (e.g., check winHandler != null or call an initialization method on winHandler first). Update the code paths around the calls to PluviaApp.touchpadView.setGyroSensitivity(...) and PluviaApp.touchpadView.setGyroAimingEnabled(...) so they execute only after the winHandler assignment is complete.
🧹 Nitpick comments (1)
app/src/main/java/com/winlator/container/ContainerData.kt (1)
221-221: Clamp restored sensitivity to the supported runtime range.Line 221 restores numeric types safely, but it can still accept out-of-range values from stale/corrupt state. Clamping here keeps behavior consistent with the rest of the gyro settings flow.
♻️ Proposed hardening
- gyroSensitivity = (savedMap["gyroSensitivity"] as? Float) ?: (savedMap["gyroSensitivity"] as? Double)?.toFloat() ?: 1f, + gyroSensitivity = ( + (savedMap["gyroSensitivity"] as? Float) + ?: (savedMap["gyroSensitivity"] as? Double)?.toFloat() + ?: 1f + ).coerceIn(0.25f, 2f),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/winlator/container/ContainerData.kt` at line 221, The restored gyroSensitivity value in ContainerData (gyroSensitivity property) should be clamped to the supported runtime range to avoid accepting stale/corrupt out-of-range values; replace the current restore expression with one that computes the Float as now (using the savedMap cast chain) and then calls .coerceIn(GYRO_SENSITIVITY_MIN, GYRO_SENSITIVITY_MAX), adding GYRO_SENSITIVITY_MIN and GYRO_SENSITIVITY_MAX constants (e.g., in ContainerData companion object or an existing config place) if they don't exist so the value is constrained to the same runtime limits used elsewhere in the gyro settings flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/main/java/com/winlator/widget/GyroAimingHelper.java`:
- Around line 71-73: The code sets the field running = true before confirming
sensor registration; change the start logic in GyroAimingHelper (the running
field and isRunning()) to first call sensorManager.registerListener(this, gyro,
SENSOR_DELAY_US), capture its boolean result, and only set running = true when
registration returns true; if registration fails, leave running false and log an
error via Timber (including gyro.getName()) and return/throw as appropriate so
callers can retry or handle failure.
---
Duplicate comments:
In `@app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt`:
- Around line 1357-1358: The gyro aiming is enabled via
PluviaApp.touchpadView.setGyroAimingEnabled(...) before winHandler is assigned,
creating a race; move the initialization/assignment of winHandler (the variable
or property named winHandler in XServerScreen) to occur before calling
setGyroAimingEnabled and setGyroSensitivity, or defer enabling gyro callbacks
until after winHandler is fully constructed/assigned (e.g., check winHandler !=
null or call an initialization method on winHandler first). Update the code
paths around the calls to PluviaApp.touchpadView.setGyroSensitivity(...) and
PluviaApp.touchpadView.setGyroAimingEnabled(...) so they execute only after the
winHandler assignment is complete.
---
Nitpick comments:
In `@app/src/main/java/com/winlator/container/ContainerData.kt`:
- Line 221: The restored gyroSensitivity value in ContainerData (gyroSensitivity
property) should be clamped to the supported runtime range to avoid accepting
stale/corrupt out-of-range values; replace the current restore expression with
one that computes the Float as now (using the savedMap cast chain) and then
calls .coerceIn(GYRO_SENSITIVITY_MIN, GYRO_SENSITIVITY_MAX), adding
GYRO_SENSITIVITY_MIN and GYRO_SENSITIVITY_MAX constants (e.g., in ContainerData
companion object or an existing config place) if they don't exist so the value
is constrained to the same runtime limits used elsewhere in the gyro settings
flow.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7ebdac61-1e72-4def-b169-c94a06764858
📒 Files selected for processing (21)
app/src/main/java/app/gamenative/ui/component/QuickMenu.ktapp/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.ktapp/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.ktapp/src/main/java/app/gamenative/utils/ContainerUtils.ktapp/src/main/java/com/winlator/container/ContainerData.ktapp/src/main/java/com/winlator/widget/GyroAimingHelper.javaapp/src/main/java/com/winlator/widget/TouchpadView.javaapp/src/main/res/values-da/strings.xmlapp/src/main/res/values-de/strings.xmlapp/src/main/res/values-es/strings.xmlapp/src/main/res/values-fr/strings.xmlapp/src/main/res/values-it/strings.xmlapp/src/main/res/values-ko/strings.xmlapp/src/main/res/values-pl/strings.xmlapp/src/main/res/values-pt-rBR/strings.xmlapp/src/main/res/values-ro/strings.xmlapp/src/main/res/values-ru/strings.xmlapp/src/main/res/values-uk/strings.xmlapp/src/main/res/values-zh-rCN/strings.xmlapp/src/main/res/values-zh-rTW/strings.xmlapp/src/main/res/values/strings.xml
✅ Files skipped from review due to trivial changes (13)
- app/src/main/res/values-es/strings.xml
- app/src/main/res/values-ru/strings.xml
- app/src/main/res/values-da/strings.xml
- app/src/main/res/values/strings.xml
- app/src/main/res/values-ro/strings.xml
- app/src/main/res/values-fr/strings.xml
- app/src/main/res/values-pl/strings.xml
- app/src/main/res/values-ko/strings.xml
- app/src/main/res/values-pt-rBR/strings.xml
- app/src/main/res/values-zh-rTW/strings.xml
- app/src/main/res/values-zh-rCN/strings.xml
- app/src/main/res/values-uk/strings.xml
- app/src/main/res/values-it/strings.xml
🚧 Files skipped from review as they are similar to previous changes (2)
- app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt
- app/src/main/java/com/winlator/widget/TouchpadView.java
0374434 to
95a08a2
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (2)
app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt (1)
4-8: Remove unused imports.The imports
padding,Modifier, anddp(lines 4, 6–7) are unused in this file. Onlyabsfrom line 8 is used in the gyro sensitivity calculation on line 111.Proposed cleanup
import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp import kotlin.math.abs🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt` around lines 4 - 8, In ControllerTab.kt the imports androidx.compose.foundation.layout.padding, androidx.compose.ui.Modifier, and androidx.compose.ui.unit.dp are unused and should be removed; keep kotlin.math.abs which is used by the gyro sensitivity calculation in the ControllerTab implementation (the code computing gyro sensitivity uses abs). Remove the three unused import lines to clean up the file and avoid unused-import warnings.app/src/main/java/com/winlator/widget/GyroAimingHelper.java (1)
80-91: Makestop()fully idempotent for partial-start states.At Line 81, early return skips cleanup when
runningis false. If startup partially initialized fields before failing,stop()won’t clear them. Consider always clearing callbacks/references and only gating unregister by prior running state.♻️ Proposed refactor
public void stop() { - if (!running) return; - running = false; + final boolean wasRunning = running; + running = false; mainHandler.removeCallbacksAndMessages(null); - if (sensorManager != null && gyro != null) { + if (wasRunning && sensorManager != null && gyro != null) { sensorManager.unregisterListener(this, gyro); } sensorManager = null; displayManager = null; gyro = null; Timber.d("GyroAiming: stopped"); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/com/winlator/widget/GyroAimingHelper.java` around lines 80 - 91, Make stop() fully idempotent: capture current running state (e.g., boolean wasRunning = running), then immediately set running = false; always call mainHandler.removeCallbacksAndMessages(null) and clear displayManager/sensorManager/gyro references to null; only call sensorManager.unregisterListener(this, gyro) when wasRunning is true and sensorManager != null and gyro != null to avoid attempting unregister for partial-start states; keep the final Timber.d("GyroAiming: stopped") log.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt`:
- Around line 4-8: In ControllerTab.kt the imports
androidx.compose.foundation.layout.padding, androidx.compose.ui.Modifier, and
androidx.compose.ui.unit.dp are unused and should be removed; keep
kotlin.math.abs which is used by the gyro sensitivity calculation in the
ControllerTab implementation (the code computing gyro sensitivity uses abs).
Remove the three unused import lines to clean up the file and avoid
unused-import warnings.
In `@app/src/main/java/com/winlator/widget/GyroAimingHelper.java`:
- Around line 80-91: Make stop() fully idempotent: capture current running state
(e.g., boolean wasRunning = running), then immediately set running = false;
always call mainHandler.removeCallbacksAndMessages(null) and clear
displayManager/sensorManager/gyro references to null; only call
sensorManager.unregisterListener(this, gyro) when wasRunning is true and
sensorManager != null and gyro != null to avoid attempting unregister for
partial-start states; keep the final Timber.d("GyroAiming: stopped") log.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5abd9d90-32ac-446e-96c9-4b1a6166410a
📒 Files selected for processing (21)
app/src/main/java/app/gamenative/ui/component/QuickMenu.ktapp/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.ktapp/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.ktapp/src/main/java/app/gamenative/utils/ContainerUtils.ktapp/src/main/java/com/winlator/container/ContainerData.ktapp/src/main/java/com/winlator/widget/GyroAimingHelper.javaapp/src/main/java/com/winlator/widget/TouchpadView.javaapp/src/main/res/values-da/strings.xmlapp/src/main/res/values-de/strings.xmlapp/src/main/res/values-es/strings.xmlapp/src/main/res/values-fr/strings.xmlapp/src/main/res/values-it/strings.xmlapp/src/main/res/values-ko/strings.xmlapp/src/main/res/values-pl/strings.xmlapp/src/main/res/values-pt-rBR/strings.xmlapp/src/main/res/values-ro/strings.xmlapp/src/main/res/values-ru/strings.xmlapp/src/main/res/values-uk/strings.xmlapp/src/main/res/values-zh-rCN/strings.xmlapp/src/main/res/values-zh-rTW/strings.xmlapp/src/main/res/values/strings.xml
✅ Files skipped from review due to trivial changes (11)
- app/src/main/res/values-uk/strings.xml
- app/src/main/res/values-es/strings.xml
- app/src/main/res/values-ro/strings.xml
- app/src/main/res/values-fr/strings.xml
- app/src/main/res/values/strings.xml
- app/src/main/res/values-de/strings.xml
- app/src/main/res/values-pt-rBR/strings.xml
- app/src/main/res/values-ko/strings.xml
- app/src/main/res/values-it/strings.xml
- app/src/main/res/values-zh-rTW/strings.xml
- app/src/main/res/values-ru/strings.xml
🚧 Files skipped from review as they are similar to previous changes (7)
- app/src/main/java/app/gamenative/ui/component/QuickMenu.kt
- app/src/main/java/com/winlator/container/ContainerData.kt
- app/src/main/res/values-pl/strings.xml
- app/src/main/res/values-zh-rCN/strings.xml
- app/src/main/res/values-da/strings.xml
- app/src/main/java/com/winlator/widget/TouchpadView.java
- app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
1ff1e57 to
52d2ac1
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt (1)
112-112: Prefer locale-aware percent formatting for dropdown labels.
"${(it * 100).toInt()}%"is readable, but using locale-aware formatting will better support non-English numeral/percent conventions.Suggested refactor
+import java.text.NumberFormat ... + val percentFormatter = remember { NumberFormat.getPercentInstance().apply { maximumFractionDigits = 0 } } ... - items = GYRO_SENSITIVITY_VALUES.map { "${(it * 100).toInt()}%" }, + items = GYRO_SENSITIVITY_VALUES.map { percentFormatter.format(it.toDouble()) },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt` at line 112, Replace the manual string interpolation for dropdown labels with a locale-aware percent formatter: create a NumberFormat via NumberFormat.getPercentInstance(Locale.getDefault()) (optionally set maximum/minimum fraction digits to 0) and use it to format each value in GYRO_SENSITIVITY_VALUES when assigning items (the mapping that currently uses "${(it * 100).toInt()}%").
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt`:
- Line 112: Replace the manual string interpolation for dropdown labels with a
locale-aware percent formatter: create a NumberFormat via
NumberFormat.getPercentInstance(Locale.getDefault()) (optionally set
maximum/minimum fraction digits to 0) and use it to format each value in
GYRO_SENSITIVITY_VALUES when assigning items (the mapping that currently uses
"${(it * 100).toInt()}%").
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 953e9836-9162-4812-a00e-7022272127a0
📒 Files selected for processing (21)
app/src/main/java/app/gamenative/ui/component/QuickMenu.ktapp/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.ktapp/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.ktapp/src/main/java/app/gamenative/utils/ContainerUtils.ktapp/src/main/java/com/winlator/container/ContainerData.ktapp/src/main/java/com/winlator/widget/GyroAimingHelper.javaapp/src/main/java/com/winlator/widget/TouchpadView.javaapp/src/main/res/values-da/strings.xmlapp/src/main/res/values-de/strings.xmlapp/src/main/res/values-es/strings.xmlapp/src/main/res/values-fr/strings.xmlapp/src/main/res/values-it/strings.xmlapp/src/main/res/values-ko/strings.xmlapp/src/main/res/values-pl/strings.xmlapp/src/main/res/values-pt-rBR/strings.xmlapp/src/main/res/values-ro/strings.xmlapp/src/main/res/values-ru/strings.xmlapp/src/main/res/values-uk/strings.xmlapp/src/main/res/values-zh-rCN/strings.xmlapp/src/main/res/values-zh-rTW/strings.xmlapp/src/main/res/values/strings.xml
✅ Files skipped from review due to trivial changes (15)
- app/src/main/java/app/gamenative/ui/component/QuickMenu.kt
- app/src/main/res/values-pt-rBR/strings.xml
- app/src/main/res/values-ro/strings.xml
- app/src/main/res/values/strings.xml
- app/src/main/res/values-ru/strings.xml
- app/src/main/res/values-da/strings.xml
- app/src/main/res/values-it/strings.xml
- app/src/main/res/values-fr/strings.xml
- app/src/main/res/values-zh-rCN/strings.xml
- app/src/main/res/values-es/strings.xml
- app/src/main/res/values-zh-rTW/strings.xml
- app/src/main/res/values-ko/strings.xml
- app/src/main/res/values-de/strings.xml
- app/src/main/java/com/winlator/widget/TouchpadView.java
- app/src/main/java/com/winlator/widget/GyroAimingHelper.java
🚧 Files skipped from review as they are similar to previous changes (5)
- app/src/main/java/com/winlator/container/ContainerData.kt
- app/src/main/res/values-pl/strings.xml
- app/src/main/java/app/gamenative/utils/ContainerUtils.kt
- app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
- app/src/main/res/values-uk/strings.xml
52d2ac1 to
fa25b83
Compare
|
Drafting this again since I might have a nicer solution that works with controllers. So more of a gamenative focused solution. |
|
Closed in favour of #1173 |
Currently only supports mouse. Controller is a pain in the ass. So let's just start with this.
Summary by cubic
Adds gyroscope-powered mouse aiming with a Quick Menu toggle and a per-container sensitivity (25%–200%) applied on launch. Localizes the new UI and highlights the toggle in the Quick Menu.
gyro_aiming_toggled.GyroAimingHelperconverts gyro data to relative mouse deltas with sensitivity scaling, per-frame clamping, rotation handling, and sub-pixel accumulation; integrated intoTouchpadView(enable/disable and sensitivity), works in relative and desktop pointer modes, auto-stops on detach, and initialized byXServerScreenon start.Written for commit fa25b83. Summary will update on new commits.
Summary by CodeRabbit
New Features
Localization