diff --git a/ports/libmlservo/src/lib.rs b/ports/libmlservo/src/lib.rs index cd7d0d501fa..32371c823d9 100644 --- a/ports/libmlservo/src/lib.rs +++ b/ports/libmlservo/src/lib.rs @@ -278,7 +278,7 @@ pub unsafe extern "C" fn trigger_servo(servo: *mut ServoInstance, x: f32, y: f32 ScrollState::TriggerDown(start) if !down => { servo.scroll_state = ScrollState::TriggerUp; let _ = call(|s| s.mouse_up(start.x, start.y, MouseButton::Left)); - let _ = call(|s| s.click(start.x, start.y)); + let _ = call(|s| s.click(start.x as f32, start.y as f32)); let _ = call(|s| s.move_mouse(start.x, start.y)); }, ScrollState::TriggerDragging(start, prev) if !down => { diff --git a/ports/libsimpleservo/capi/src/lib.rs b/ports/libsimpleservo/capi/src/lib.rs index a7e5b039bc8..fe48d038b71 100644 --- a/ports/libsimpleservo/capi/src/lib.rs +++ b/ports/libsimpleservo/capi/src/lib.rs @@ -15,7 +15,9 @@ use backtrace::Backtrace; #[cfg(not(target_os = "windows"))] use env_logger; use simpleservo::{self, gl_glue, ServoGlue, SERVO}; -use simpleservo::{Coordinates, EventLoopWaker, HostTrait, InitOptions, VRInitOptions}; +use simpleservo::{ + Coordinates, EventLoopWaker, HostTrait, InitOptions, MouseButton, VRInitOptions, +}; use std::ffi::{CStr, CString}; #[cfg(target_os = "windows")] use std::mem; @@ -227,6 +229,23 @@ pub struct CInitOptions { pub vslogger_mod_size: u32, } +#[repr(C)] +pub enum CMouseButton { + Left, + Right, + Middle, +} + +impl CMouseButton { + pub fn convert(&self) -> MouseButton { + match self { + CMouseButton::Left => MouseButton::Left, + CMouseButton::Right => MouseButton::Right, + CMouseButton::Middle => MouseButton::Middle, + } + } +} + /// The returned string is not freed. This will leak. #[no_mangle] pub extern "C" fn servo_version() -> *const c_char { @@ -529,10 +548,26 @@ pub extern "C" fn pinchzoom_end(factor: f32, x: i32, y: i32) { } #[no_mangle] -pub extern "C" fn click(x: i32, y: i32) { +pub extern "C" fn mouse_down(x: f32, y: f32, button: CMouseButton) { + catch_any_panic(|| { + debug!("mouse_down"); + call(|s| s.mouse_down(x, y, button.convert())); + }); +} + +#[no_mangle] +pub extern "C" fn mouse_up(x: f32, y: f32, button: CMouseButton) { + catch_any_panic(|| { + debug!("mouse_up"); + call(|s| s.mouse_up(x, y, button.convert())); + }); +} + +#[no_mangle] +pub extern "C" fn click(x: f32, y: f32) { catch_any_panic(|| { debug!("click"); - call(|s| s.click(x as f32, y as f32)); + call(|s| s.click(x, y)); }); } diff --git a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/JNIServo.java b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/JNIServo.java index 28d5b07b70b..7bfcf233d8d 100644 --- a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/JNIServo.java +++ b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/JNIServo.java @@ -64,7 +64,7 @@ public class JNIServo { public native void pinchZoomEnd(float factor, int x, int y); - public native void click(int x, int y); + public native void click(float x, float y); public static class ServoOptions { public String args; diff --git a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/Servo.java b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/Servo.java index e503293cac9..dac970d1acf 100644 --- a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/Servo.java +++ b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/Servo.java @@ -160,7 +160,7 @@ public class Servo { mRunCallback.inGLThread(() -> mJNI.pinchZoomEnd(factor, x, y)); } - public void click(int x, int y) { + public void click(float x, float y) { mRunCallback.inGLThread(() -> mJNI.click(x, y)); } diff --git a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoSurface.java b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoSurface.java index 93691f0fbae..80f897fa4b9 100644 --- a/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoSurface.java +++ b/support/android/apk/servoview/src/main/java/org/mozilla/servoview/ServoSurface.java @@ -134,7 +134,7 @@ public class ServoSurface { mServo.scrollEnd(dx, dy, x, y); } - public void click(int x, int y) { + public void click(float x, float y) { mServo.click(x, y); } diff --git a/support/hololens/ServoApp/DefaultUrl.h b/support/hololens/ServoApp/DefaultUrl.h index 359a7962dbd..43d11789cb7 100644 --- a/support/hololens/ServoApp/DefaultUrl.h +++ b/support/hololens/ServoApp/DefaultUrl.h @@ -1,3 +1,3 @@ #pragma once -#define DEFAULT_URL L"about:blank"; +#define DEFAULT_URL L"http://paulrouget.com/test/bbjs/basic/"; diff --git a/support/hololens/ServoApp/ServoControl/Servo.h b/support/hololens/ServoApp/ServoControl/Servo.h index 26e268bd7a7..8c968a71835 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.h +++ b/support/hololens/ServoApp/ServoControl/Servo.h @@ -47,13 +47,22 @@ public: ~Servo(); ServoDelegate &Delegate() { return mDelegate; } + typedef capi::CMouseButton MouseButton; + void PerformUpdates() { capi::perform_updates(); } void DeInit() { capi::deinit(); } void RequestShutdown() { capi::request_shutdown(); } void SetBatchMode(bool mode) { capi::set_batch_mode(mode); } void GoForward() { capi::go_forward(); } void GoBack() { capi::go_back(); } - void Click(float x, float y) { capi::click((int32_t)x, (int32_t)y); } + void Click(float x, float y) { capi::click(x, y); } + void MouseDown(float x, float y, capi::CMouseButton b) { + capi::mouse_down(x, y, b); + } + void MouseUp(float x, float y, capi::CMouseButton b) { + capi::mouse_up(x, y, b); + } + void Reload() { capi::reload(); } void Stop() { capi::stop(); } void LoadUri(hstring uri) { capi::load_uri(*hstring2char(uri)); } diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.cpp b/support/hololens/ServoApp/ServoControl/ServoControl.cpp index 1d409e86c95..6c6fa094dad 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.cpp +++ b/support/hololens/ServoApp/ServoControl/ServoControl.cpp @@ -36,8 +36,11 @@ void ServoControl::Shutdown() { void ServoControl::OnLoaded(IInspectable const &, RoutedEventArgs const &) { auto panel = Panel(); - panel.Tapped( - std::bind(&ServoControl::OnSurfaceClicked, this, _1, _2)); + panel.Tapped(std::bind(&ServoControl::OnSurfaceTapped, this, _1, _2)); + panel.PointerPressed( + std::bind(&ServoControl::OnSurfacePointerPressed, this, _1, _2)); + panel.PointerReleased( + std::bind(&ServoControl::OnSurfacePointerPressed, this, _1, _2)); panel.ManipulationStarted( [=](IInspectable const &, Input::ManipulationStartedRoutedEventArgs const &e) { @@ -93,8 +96,8 @@ void ServoControl::OnSurfaceManipulationDelta( e.Handled(true); } -void ServoControl::OnSurfaceClicked(IInspectable const &, - Input::TappedRoutedEventArgs const &e) { +void ServoControl::OnSurfaceTapped(IInspectable const &, + Input::TappedRoutedEventArgs const &e) { auto coords = e.GetPosition(Panel()); auto x = coords.X * mDPI; auto y = coords.Y * mDPI; @@ -102,6 +105,41 @@ void ServoControl::OnSurfaceClicked(IInspectable const &, e.Handled(true); } +void ServoControl::OnSurfacePointerPressed( + IInspectable const &, Input::PointerRoutedEventArgs const &e) { + if (e.Pointer().PointerDeviceType() == + Windows::Devices::Input::PointerDeviceType::Mouse) { + auto point = e.GetCurrentPoint(Panel()); + + auto x = point.Position().X * mDPI; + auto y = point.Position().Y * mDPI; + auto props = point.Properties(); + std::optional button = {}; + + if (props.IsLeftButtonPressed()) { + button = Servo::MouseButton::Left; + } else if (props.IsRightButtonPressed()) { + button = Servo::MouseButton::Right; + } else if (props.IsMiddleButtonPressed()) { + button = Servo::MouseButton::Middle; + } + + if (!button.has_value() && mPressedMouseButton.has_value()) { + auto releasedButton = *mPressedMouseButton; + mPressedMouseButton = {}; + RunOnGLThread([=] { mServo->MouseUp(x, y, releasedButton); }); + e.Handled(true); + } + + if (button.has_value()) { + RunOnGLThread([=] { mServo->MouseDown(x, y, *button); }); + e.Handled(true); + } + + mPressedMouseButton = button; + } +} + void ServoControl::OnSurfaceResized(IInspectable const &, SizeChangedEventArgs const &e) { auto size = e.NewSize(); diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.h b/support/hololens/ServoApp/ServoControl/ServoControl.h index 4baa861d463..aa58f2f6ee1 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.h +++ b/support/hololens/ServoApp/ServoControl/ServoControl.h @@ -119,9 +119,12 @@ private: } void - OnSurfaceClicked(IInspectable const &, + OnSurfaceTapped(IInspectable const &, Windows::UI::Xaml::Input::TappedRoutedEventArgs const &); + void OnSurfacePointerPressed(IInspectable const &, + Windows::UI::Xaml::Input::PointerRoutedEventArgs const &); + void OnSurfaceManipulationDelta( IInspectable const &, Windows::UI::Xaml::Input::ManipulationDeltaRoutedEventArgs const &); @@ -142,6 +145,8 @@ private: CONDITION_VARIABLE mGLCondVar; std::unique_ptr> mLoopTask; hstring mArgs; + + std::optional mPressedMouseButton = {}; }; } // namespace winrt::ServoApp::implementation