fix: add the touch emulation method for Android TV

This commit is contained in:
albexk 2024-11-24 21:18:35 +03:00
parent 392cacaabc
commit 2987e03a86
5 changed files with 63 additions and 0 deletions

View file

@ -23,9 +23,12 @@ import android.os.Looper
import android.os.Message import android.os.Message
import android.os.Messenger import android.os.Messenger
import android.os.ParcelFileDescriptor import android.os.ParcelFileDescriptor
import android.os.SystemClock
import android.provider.OpenableColumns import android.provider.OpenableColumns
import android.provider.Settings import android.provider.Settings
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager.LayoutParams import android.view.WindowManager.LayoutParams
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import android.widget.Toast import android.widget.Toast
@ -800,6 +803,50 @@ class AmneziaActivity : QtActivity() {
} }
} }
// method to workaround Qt's problem with calling the keyboard on TVs
@Suppress("unused")
fun sendTouch(x: Float, y: Float) {
Log.v(TAG, "Send touch: $x, $y")
blockingCall {
findQtWindow(window.decorView)?.let {
Log.v(TAG, "Send touch to $it")
it.dispatchTouchEvent(createEvent(x, y, SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN))
it.dispatchTouchEvent(createEvent(x, y, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP))
}
}
}
private fun findQtWindow(view: View): View? {
Log.v(TAG, "findQtWindow: process $view")
if (view::class.simpleName == "QtWindow") return view
else if (view is ViewGroup) {
for (i in 0 until view.childCount) {
val result = findQtWindow(view.getChildAt(i))
if (result != null) return result
}
return null
} else return null
}
private fun createEvent(x: Float, y: Float, eventTime: Long, action: Int): MotionEvent =
MotionEvent.obtain(
eventTime,
eventTime,
action,
1,
arrayOf(MotionEvent.PointerProperties().apply {
id = 0
toolType = MotionEvent.TOOL_TYPE_FINGER
}),
arrayOf(MotionEvent.PointerCoords().apply {
this.x = x
this.y = y
pressure = 1f
size = 1f
}),
0, 0, 1.0f, 1.0f, 0, 0, 0,0
)
// workaround for a bug in Qt that causes the mouse click event not to be handled // workaround for a bug in Qt that causes the mouse click event not to be handled
// also disable right-click, as it causes the application to crash // also disable right-click, as it causes the application to crash
private var lastButtonState = 0 private var lastButtonState = 0
@ -849,6 +896,7 @@ class AmneziaActivity : QtActivity() {
} }
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean { override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
Log.v(TAG, "dispatchTouch: $ev")
if (ev != null && ev.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) { if (ev != null && ev.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
return handleMouseEvent(ev) { super.dispatchTouchEvent(it) } return handleMouseEvent(ev) { super.dispatchTouchEvent(it) }
} }

View file

@ -304,6 +304,11 @@ bool AndroidController::requestAuthentication()
return result; return result;
} }
void AndroidController::sendTouch(float x, float y)
{
callActivityMethod("sendTouch", "(FF)V", x, y);
}
// Moving log processing to the Android side // Moving log processing to the Android side
jclass AndroidController::log; jclass AndroidController::log;
jmethodID AndroidController::logDebug; jmethodID AndroidController::logDebug;

View file

@ -51,6 +51,7 @@ public:
bool isNotificationPermissionGranted(); bool isNotificationPermissionGranted();
void requestNotificationPermission(); void requestNotificationPermission();
bool requestAuthentication(); bool requestAuthentication();
void sendTouch(float x, float y);
static bool initLogging(); static bool initLogging();
static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message); static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message);

View file

@ -159,3 +159,10 @@ bool SystemController::isAuthenticated()
return true; return true;
#endif #endif
} }
void SystemController::sendTouch(float x, float y)
{
#ifdef Q_OS_ANDROID
AndroidController::instance()->sendTouch(x, y);
#endif
}

View file

@ -22,6 +22,8 @@ public slots:
void setQmlRoot(QObject *qmlRoot); void setQmlRoot(QObject *qmlRoot);
bool isAuthenticated(); bool isAuthenticated();
void sendTouch(float x, float y);
signals: signals:
void fileDialogClosed(const bool isAccepted); void fileDialogClosed(const bool isAccepted);