Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UWP: better mouse interaction support #24547

Merged
merged 1 commit into from Oct 29, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -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 => {
@@ -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));
});
}

@@ -64,7 +64,7 @@

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;
@@ -160,7 +160,7 @@ public void pinchZoomEnd(float factor, int x, int y) {
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));
}

@@ -134,7 +134,7 @@ public void scrollEnd(int dx, int dy, int x, int y) {
mServo.scrollEnd(dx, dy, x, y);
}

public void click(int x, int y) {
public void click(float x, float y) {
mServo.click(x, y);
}

@@ -1,3 +1,3 @@
#pragma once

#define DEFAULT_URL L"about:blank";
#define DEFAULT_URL L"http://paulrouget.com/test/bbjs/basic/";
@@ -47,13 +47,22 @@ class Servo {
~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)); }
@@ -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,15 +96,50 @@ 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;
RunOnGLThread([=] { mServo->Click(x, y); });
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<Servo::MouseButton> 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();
@@ -119,9 +119,12 @@ struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
}

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 @@ struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
CONDITION_VARIABLE mGLCondVar;
std::unique_ptr<Concurrency::task<void>> mLoopTask;
hstring mArgs;

std::optional<servo::Servo::MouseButton> mPressedMouseButton = {};
};
} // namespace winrt::ServoApp::implementation

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.