Android: Pass touch events through as mouse events

This is probably not the best way of handling touch events, but at least
it allows the user to actually interact with the page!
This commit is contained in:
Alex Studer 2024-07-07 01:26:04 -04:00 committed by Andrew Kaster
parent feb7c0d950
commit e6432041b2
Notes: sideshowbarker 2024-07-17 06:33:00 +09:00
5 changed files with 71 additions and 0 deletions

View file

@ -103,6 +103,25 @@ void WebViewImplementationNative::set_device_pixel_ratio(float f)
client().async_set_device_pixels_per_css_pixel(0, m_device_pixel_ratio);
}
void WebViewImplementationNative::mouse_event(Web::MouseEvent::Type event_type, float x, float y, float raw_x, float raw_y)
{
Gfx::IntPoint position = { x, y };
Gfx::IntPoint screen_position = { raw_x, raw_y };
auto event = Web::MouseEvent {
event_type,
position.to_type<Web::DevicePixels>(),
screen_position.to_type<Web::DevicePixels>(),
Web::UIEvents::MouseButton::Primary,
Web::UIEvents::MouseButton::Primary,
Web::UIEvents::KeyModifier::Mod_None,
0,
0,
nullptr
};
enqueue_input_event(move(event));
}
NonnullRefPtr<WebView::WebContentClient> WebViewImplementationNative::bind_web_content_client()
{
JavaEnvironment env(global_vm);

View file

@ -29,6 +29,8 @@ public:
void set_viewport_geometry(int w, int h);
void set_device_pixel_ratio(float f);
void mouse_event(Web::MouseEvent::Type event_type, float x, float y, float raw_x, float raw_y);
static jclass global_class_reference;
static jmethodID bind_webcontent_method;
static jmethodID invalidate_layout_method;

View file

@ -93,3 +93,29 @@ Java_org_serenityos_ladybird_WebViewImplementation_nativeSetDevicePixelRatio(JNI
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
impl->set_device_pixel_ratio(ratio);
}
extern "C" JNIEXPORT void JNICALL
Java_org_serenityos_ladybird_WebViewImplementation_nativeMouseEvent(JNIEnv*, jobject /* thiz */, jlong instance, jint event_type, jfloat x, jfloat y, jfloat raw_x, jfloat raw_y)
{
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
Web::MouseEvent::Type web_event_type;
// These integers are defined in Android's MotionEvent.
// See https://developer.android.com/reference/android/view/MotionEvent#constants_1
if (event_type == 0) {
// MotionEvent.ACTION_DOWN
web_event_type = Web::MouseEvent::Type::MouseDown;
} else if (event_type == 1) {
// MotionEvent.ACTION_UP
web_event_type = Web::MouseEvent::Type::MouseUp;
} else if (event_type == 2) {
// MotionEvent.ACTION_MOVE
web_event_type = Web::MouseEvent::Type::MouseMove;
} else {
// Unknown event type, default to MouseUp
web_event_type = Web::MouseEvent::Type::MouseUp;
}
impl->mouse_event(web_event_type, x, y, raw_x, raw_y);
}

View file

@ -10,6 +10,7 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
// FIXME: This should (eventually) implement NestedScrollingChild3 and ScrollingView
@ -30,6 +31,23 @@ class WebView(context: Context, attributeSet: AttributeSet) : View(context, attr
viewImpl.loadURL(url)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
// The native side only supports down, move, and up events.
// So, ignore any other MotionEvents.
if (event.action != MotionEvent.ACTION_DOWN &&
event.action != MotionEvent.ACTION_MOVE &&
event.action != MotionEvent.ACTION_UP) {
return super.onTouchEvent(event);
}
// FIXME: We are passing these through as mouse events.
// We should really be handling them as touch events.
// (And we should handle scrolling - right now you have tap and drag the scrollbar!)
viewImpl.mouseEvent(event.action, event.x, event.y, event.rawX, event.rawY)
return true
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
contentBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)

View file

@ -11,6 +11,7 @@ import android.content.Intent
import android.content.ServiceConnection
import android.graphics.Bitmap
import android.util.Log
import android.view.MotionEvent
import android.view.View
import java.net.URL
@ -49,6 +50,10 @@ class WebViewImplementation(private val view: WebView) {
nativeSetDevicePixelRatio(nativeInstance, ratio)
}
fun mouseEvent(eventType: Int, x: Float, y: Float, rawX: Float, rawY: Float) {
nativeMouseEvent(nativeInstance, eventType, x, y, rawX, rawY)
}
// Functions called from native code
fun bindWebContentService(ipcFd: Int) {
val connector = LadybirdServiceConnection(ipcFd, resourceDir)
@ -82,6 +87,7 @@ class WebViewImplementation(private val view: WebView) {
private external fun nativeSetViewportGeometry(instance: Long, w: Int, h: Int)
private external fun nativeSetDevicePixelRatio(instance: Long, ratio: Float)
private external fun nativeLoadURL(instance: Long, url: String)
private external fun nativeMouseEvent(instance: Long, eventType: Int, x: Float, y: Float, rawX: Float, rawY: Float)
companion object {
/*