diff --git a/app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt b/app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt
index 2c2cf65ce..9897aa91d 100644
--- a/app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt
+++ b/app/src/main/java/app/gamenative/ui/component/dialog/ControllerTab.kt
@@ -53,11 +53,13 @@ fun ControllerTabContent(state: ContainerConfigState, default: Boolean) {
SettingsSwitch(
colors = settingsTileColorsAlt(),
title = { Text(text = stringResource(R.string.disable_mouse_input)) },
+ subtitle = { Text(text = stringResource(R.string.disable_mouse_input_description)) },
state = config.disableMouseInput,
onCheckedChange = { state.config.value = config.copy(disableMouseInput = it) },
)
SettingsSwitch(
colors = settingsTileColorsAlt(),
+ enabled = !config.disableMouseInput,
title = { Text(text = stringResource(R.string.touchscreen_mode)) },
subtitle = { Text(text = stringResource(R.string.touchscreen_mode_description)) },
state = config.touchscreenMode,
diff --git a/app/src/main/java/app/gamenative/ui/screen/xserver/PhysicalControllerHandler.kt b/app/src/main/java/app/gamenative/ui/screen/xserver/PhysicalControllerHandler.kt
index 036e5fb7b..fb1aeb877 100644
--- a/app/src/main/java/app/gamenative/ui/screen/xserver/PhysicalControllerHandler.kt
+++ b/app/src/main/java/app/gamenative/ui/screen/xserver/PhysicalControllerHandler.kt
@@ -150,7 +150,10 @@ class PhysicalControllerHandler(
val cursorSpeed = profile?.cursorSpeed ?: 1f
val deltaX = (mouseMoveOffset.x * 10 * cursorSpeed).toInt()
val deltaY = (mouseMoveOffset.y * 10 * cursorSpeed).toInt()
- xServer?.injectPointerMoveDelta(deltaX, deltaY)
+ xServer?.let {
+ if (!it.renderer.isCursorVisible) it.renderer.setCursorVisible(true)
+ it.injectPointerMoveDelta(deltaX, deltaY)
+ }
}
}, 0, 1000 / 60)
}
diff --git a/app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt b/app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
index df2ae38d9..24db2dda1 100644
--- a/app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
+++ b/app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
@@ -807,7 +807,7 @@ fun XServerScreen(
}
override fun onUpdateWindowContent(window: Window) {
if (!xServerState.value.winStarted && window.isApplicationWindow()) {
- if (!container.isDisableMouseInput && !container.isTouchscreenMode) renderer?.setCursorVisible(true)
+ if (!container.isDisableMouseInput) renderer?.setCursorVisible(true)
xServerState.value.winStarted = true
}
if (window.id == frameRatingWindowId) {
diff --git a/app/src/main/java/com/winlator/inputcontrols/TouchMouse.java b/app/src/main/java/com/winlator/inputcontrols/TouchMouse.java
index 2253e3b02..fa6f5557b 100644
--- a/app/src/main/java/com/winlator/inputcontrols/TouchMouse.java
+++ b/app/src/main/java/com/winlator/inputcontrols/TouchMouse.java
@@ -304,6 +304,10 @@ public boolean onExternalMouseEvent(MotionEvent event) {
boolean handled = false;
// if (event.isFromSource(InputDevice.SOURCE_MOUSE)) {
if (isMouseDevice(event.getDevice())) {
+ // show cursor on external mouse event
+ if (!xServer.getRenderer().isCursorVisible()) {
+ xServer.getRenderer().setCursorVisible(true);
+ }
int actionButton = event.getActionButton();
switch (event.getAction()) {
case MotionEvent.ACTION_BUTTON_PRESS:
diff --git a/app/src/main/java/com/winlator/widget/InputControlsView.java b/app/src/main/java/com/winlator/widget/InputControlsView.java
index 15ae1d5a8..81b4efa4d 100644
--- a/app/src/main/java/com/winlator/widget/InputControlsView.java
+++ b/app/src/main/java/com/winlator/widget/InputControlsView.java
@@ -288,6 +288,8 @@ private void createMouseMoveTimer() {
mouseMoveTimer.schedule(new TimerTask() {
@Override
public void run() {
+ // show cursor when on-screen control simulates mouse
+ if (!xServer.getRenderer().isCursorVisible()) xServer.getRenderer().setCursorVisible(true);
xServer.injectPointerMoveDelta((int)(mouseMoveOffset.x * 10 * cursorSpeed), (int)(mouseMoveOffset.y * 10 * cursorSpeed));
}
}, 0, 1000 / 60);
diff --git a/app/src/main/java/com/winlator/widget/TouchpadView.java b/app/src/main/java/com/winlator/widget/TouchpadView.java
index 06666e3ba..7cc79fd26 100644
--- a/app/src/main/java/com/winlator/widget/TouchpadView.java
+++ b/app/src/main/java/com/winlator/widget/TouchpadView.java
@@ -180,6 +180,10 @@ public boolean onTouchEvent(MotionEvent event) {
&& !event.isFromSource(InputDevice.SOURCE_MOUSE)) {
return true; // consume without generating mouse events
}
+ // hide cursor on touch in touchscreen mode, it reappears on external mouse event
+ if (isTouchscreenMode && !event.isFromSource(InputDevice.SOURCE_MOUSE) && xServer.getRenderer().isCursorVisible()) {
+ xServer.getRenderer().setCursorVisible(false);
+ }
if (toolType == MotionEvent.TOOL_TYPE_STYLUS) {
return handleStylusEvent(event);
} else if (isTouchscreenMode) {
@@ -602,6 +606,11 @@ public void setMoveCursorToTouchpoint(boolean moveCursorToTouchpoint) {
}
public boolean onExternalMouseEvent(MotionEvent event) {
+ // show cursor on external mouse event
+ if (event.isFromSource(InputDevice.SOURCE_MOUSE)
+ && !xServer.getRenderer().isCursorVisible()) {
+ xServer.getRenderer().setCursorVisible(true);
+ }
// one-shot: capture external mouse on first event, don't re-capture after user release
if (capturePointerOnExternalMouse && !pointerCaptureRequested) {
pointerCaptureRequested = true;
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index bddc95a38..a41d4f2bf 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -559,7 +559,8 @@
Enable XInput API
Enable DirectInput API
DirectInput Mapper Type
- Disable Mouse Input
+ Disable Touchscreen
+ Prevent touch from generating mouse events. External mouse and controller still work.
Touchscreen Mode
Direct touch-to-cursor movement (ON) vs touchpad-style relative movement (OFF)
External Display Input