From 0b87d79eb59165638611e57dfb44b148ea1a6931 Mon Sep 17 00:00:00 2001 From: Fabian Vogt Date: Tue, 4 Feb 2025 21:06:55 +0100 Subject: [PATCH] [Android] Simple haptic feedback HapticFeedbackConstants.KEYBOARD_TAP on all keypress and touchpad down events triggered by QML. Fixes #115 --- core/os/os-android.cpp | 30 ++++++++++++++++++++++++++++++ core/os/os.h | 2 ++ qmlbridge.cpp | 10 ++++++++++ 3 files changed, 42 insertions(+) diff --git a/core/os/os-android.cpp b/core/os/os-android.cpp index 3d03318e..d7a4921e 100644 --- a/core/os/os-android.cpp +++ b/core/os/os-android.cpp @@ -155,3 +155,33 @@ char *android_basename(const char *path) return nullptr; } + +void androidVibrate() +{ + QAndroidJniEnvironment env; + + // Call activity.getWindow().getDecorView().perforHapticFeedback(KEYBOARD_TAP); + QAndroidJniObject window = QtAndroid::androidActivity() + .callObjectMethod("getWindow", "()Landroid/view/Window;"); + + QAndroidJniObject decorView = window.callObjectMethod("getDecorView", "()Landroid/view/View;"); + + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + bool success = decorView.callMethod("performHapticFeedback", "(I)Z", 3); // HapticFeedbackConstants.KEYBOARD_TAP + + if (env->ExceptionCheck()) + { + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + if (!success) + qInfo() << "Haptic feedback failed"; +} diff --git a/core/os/os.h b/core/os/os.h index 703f512c..a5bf3445 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -25,6 +25,8 @@ FILE *fopen_utf8(const char *filename, const char *mode); #if defined(__ANDROID__) /* Returns an allocated string or NULL on failure. */ char *android_basename(const char *path); +/* KEYBOARD_TAP vibration for the current View. */ +void androidVibrate(); #endif void *os_reserve(size_t size); diff --git a/qmlbridge.cpp b/qmlbridge.cpp index 2b916c31..184c08a3 100644 --- a/qmlbridge.cpp +++ b/qmlbridge.cpp @@ -256,6 +256,11 @@ void QMLBridge::setButtonState(int id, bool state) { int col = id % KEYPAD_COLS, row = id / KEYPAD_COLS; +#ifdef Q_OS_ANDROID + if (state) + androidVibrate(); +#endif + ::keypad_set_key(row, col, state); } @@ -263,6 +268,11 @@ void QMLBridge::setTouchpadState(qreal x, qreal y, bool contact, bool down) { ::touchpad_set_state(x, y, contact, down); +#ifdef Q_OS_ANDROID + if (down) + androidVibrate(); +#endif + touchpadStateChanged(); }