mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Support scrolling in Magic Leap Servo
This commit is contained in:
parent
95bfaa0a77
commit
3970c4ffbe
3 changed files with 101 additions and 16 deletions
|
@ -33,8 +33,12 @@ use servo::gl::Gl;
|
||||||
use servo::gl::GlesFns;
|
use servo::gl::GlesFns;
|
||||||
use servo::msg::constellation_msg::TraversalDirection;
|
use servo::msg::constellation_msg::TraversalDirection;
|
||||||
use servo::script_traits::MouseButton;
|
use servo::script_traits::MouseButton;
|
||||||
|
use servo::script_traits::TouchEventType;
|
||||||
use servo::servo_url::ServoUrl;
|
use servo::servo_url::ServoUrl;
|
||||||
|
use servo::webrender_api::DevicePixel;
|
||||||
use servo::webrender_api::DevicePoint;
|
use servo::webrender_api::DevicePoint;
|
||||||
|
use servo::webrender_api::LayoutPixel;
|
||||||
|
use servo::webrender_api::ScrollLocation;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
@ -113,6 +117,8 @@ pub unsafe extern "C" fn init_servo(ctxt: EGLContext,
|
||||||
app: app,
|
app: app,
|
||||||
browser_id: browser_id,
|
browser_id: browser_id,
|
||||||
history_update: history_update,
|
history_update: history_update,
|
||||||
|
scroll_state: ScrollState::TriggerUp,
|
||||||
|
scroll_scale: TypedScale::new(SCROLL_SCALE / hidpi),
|
||||||
servo: servo,
|
servo: servo,
|
||||||
});
|
});
|
||||||
Box::into_raw(result)
|
Box::into_raw(result)
|
||||||
|
@ -176,17 +182,84 @@ pub unsafe extern "C" fn heartbeat_servo(servo: *mut ServoInstance) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some magic numbers.
|
||||||
|
|
||||||
|
// How far does the cursor have to move for it to count as a drag rather than a click?
|
||||||
|
// (In device pixels squared, to avoid taking a sqrt when calculating move distance.)
|
||||||
|
const DRAG_CUTOFF_SQUARED: f32 = 100.0;
|
||||||
|
|
||||||
|
// How much should we scale scrolling by?
|
||||||
|
const SCROLL_SCALE: f32 = 3.0;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn cursor_servo(servo: *mut ServoInstance, x: f32, y: f32, trigger: bool) {
|
pub unsafe extern "C" fn move_servo(servo: *mut ServoInstance, x: f32, y: f32) {
|
||||||
|
// Servo's cursor was moved
|
||||||
|
if let Some(servo) = servo.as_mut() {
|
||||||
|
let point = DevicePoint::new(x, y);
|
||||||
|
let (new_state, window_event) = match servo.scroll_state {
|
||||||
|
ScrollState::TriggerUp => (
|
||||||
|
ScrollState::TriggerUp,
|
||||||
|
WindowEvent::MouseWindowMoveEventClass(point),
|
||||||
|
),
|
||||||
|
ScrollState::TriggerDown(start) if (start - point).square_length() < DRAG_CUTOFF_SQUARED => return,
|
||||||
|
ScrollState::TriggerDown(start) => (
|
||||||
|
ScrollState::TriggerDragging(start, point),
|
||||||
|
WindowEvent::Scroll(
|
||||||
|
ScrollLocation::Delta((point - start) * servo.scroll_scale),
|
||||||
|
start.to_i32(),
|
||||||
|
TouchEventType::Down
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ScrollState::TriggerDragging(start, prev) => (
|
||||||
|
ScrollState::TriggerDragging(start, point),
|
||||||
|
WindowEvent::Scroll(
|
||||||
|
ScrollLocation::Delta((point - prev) * servo.scroll_scale),
|
||||||
|
start.to_i32(),
|
||||||
|
TouchEventType::Move
|
||||||
|
),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
servo.scroll_state = new_state;
|
||||||
|
servo.servo.handle_events(vec![window_event]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn trigger_servo(servo: *mut ServoInstance, x: f32, y: f32, down: bool) {
|
||||||
// Servo was triggered
|
// Servo was triggered
|
||||||
if let Some(servo) = servo.as_mut() {
|
if let Some(servo) = servo.as_mut() {
|
||||||
let point = DevicePoint::new(x, y);
|
let point = DevicePoint::new(x, y);
|
||||||
let window_event = if trigger {
|
let (new_state, window_events) = match servo.scroll_state {
|
||||||
WindowEvent::MouseWindowEventClass(MouseWindowEvent::Click(MouseButton::Left, point))
|
ScrollState::TriggerUp if down => (
|
||||||
} else {
|
ScrollState::TriggerDown(point),
|
||||||
WindowEvent::MouseWindowMoveEventClass(point)
|
vec![
|
||||||
|
WindowEvent::MouseWindowEventClass(MouseWindowEvent::MouseDown(MouseButton::Left, point)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ScrollState::TriggerDown(start) if !down => (
|
||||||
|
ScrollState::TriggerUp,
|
||||||
|
vec![
|
||||||
|
WindowEvent::MouseWindowEventClass(MouseWindowEvent::MouseUp(MouseButton::Left, start)),
|
||||||
|
WindowEvent::MouseWindowEventClass(MouseWindowEvent::Click(MouseButton::Left, start)),
|
||||||
|
WindowEvent::MouseWindowMoveEventClass(point),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
ScrollState::TriggerDragging(start, prev) if !down => (
|
||||||
|
ScrollState::TriggerUp,
|
||||||
|
vec![
|
||||||
|
WindowEvent::Scroll(
|
||||||
|
ScrollLocation::Delta((point - prev) * servo.scroll_scale),
|
||||||
|
start.to_i32(),
|
||||||
|
TouchEventType::Up
|
||||||
|
),
|
||||||
|
WindowEvent::MouseWindowEventClass(MouseWindowEvent::MouseUp(MouseButton::Left, point)),
|
||||||
|
WindowEvent::MouseWindowMoveEventClass(point),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
_ => return,
|
||||||
};
|
};
|
||||||
servo.servo.handle_events(vec![window_event]);
|
servo.scroll_state = new_state;
|
||||||
|
servo.servo.handle_events(window_events);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,6 +307,8 @@ pub struct ServoInstance {
|
||||||
browser_id: BrowserId,
|
browser_id: BrowserId,
|
||||||
history_update: MLHistoryUpdate,
|
history_update: MLHistoryUpdate,
|
||||||
servo: Servo<WindowInstance>,
|
servo: Servo<WindowInstance>,
|
||||||
|
scroll_state: ScrollState,
|
||||||
|
scroll_scale: TypedScale<f32, DevicePixel, LayoutPixel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WindowInstance {
|
struct WindowInstance {
|
||||||
|
@ -246,6 +321,13 @@ struct WindowInstance {
|
||||||
hidpi: f32,
|
hidpi: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
enum ScrollState {
|
||||||
|
TriggerUp,
|
||||||
|
TriggerDown(DevicePoint),
|
||||||
|
TriggerDragging(DevicePoint, DevicePoint),
|
||||||
|
}
|
||||||
|
|
||||||
impl WindowMethods for WindowInstance {
|
impl WindowMethods for WindowInstance {
|
||||||
fn present(&self) {
|
fn present(&self) {
|
||||||
SwapBuffers(self.disp, self.surf);
|
SwapBuffers(self.disp, self.surf);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <lumin/LandscapeApp.h>
|
#include <lumin/LandscapeApp.h>
|
||||||
#include <lumin/Prism.h>
|
#include <lumin/Prism.h>
|
||||||
#include <lumin/event/ServerEvent.h>
|
#include <lumin/event/ServerEvent.h>
|
||||||
|
#include <lumin/event/GestureInputEventData.h>
|
||||||
#include <lumin/event/KeyInputEventData.h>
|
#include <lumin/event/KeyInputEventData.h>
|
||||||
#include <lumin/event/ControlTouchPadInputEventData.h>
|
#include <lumin/event/ControlTouchPadInputEventData.h>
|
||||||
#include <lumin/node/QuadNode.h>
|
#include <lumin/node/QuadNode.h>
|
||||||
|
@ -100,8 +101,8 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual bool eventListener(lumin::ServerEvent* event) override;
|
virtual bool eventListener(lumin::ServerEvent* event) override;
|
||||||
bool touchpadEventListener(lumin::ControlTouchPadInputEventData* event);
|
bool touchpadEventListener(lumin::ControlTouchPadInputEventData* event);
|
||||||
bool keyEventListener(lumin::KeyInputEventData* event);
|
|
||||||
void urlBarEventListener();
|
void urlBarEventListener();
|
||||||
|
bool gestureEventListener(lumin::GestureInputEventData* event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current cursor position, with respect to the viewport.
|
* Get the current cursor position, with respect to the viewport.
|
||||||
|
|
|
@ -45,7 +45,8 @@ extern "C" ServoInstance* init_servo(EGLContext, EGLSurface, EGLDisplay,
|
||||||
Servo2D*, MLLogger, MLHistoryUpdate,
|
Servo2D*, MLLogger, MLHistoryUpdate,
|
||||||
const char* url, int width, int height, float hidpi);
|
const char* url, int width, int height, float hidpi);
|
||||||
extern "C" void heartbeat_servo(ServoInstance*);
|
extern "C" void heartbeat_servo(ServoInstance*);
|
||||||
extern "C" void cursor_servo(ServoInstance*, float x, float y, bool triggered);
|
extern "C" void trigger_servo(ServoInstance*, float x, float y, bool down);
|
||||||
|
extern "C" void move_servo(ServoInstance*, float x, float y);
|
||||||
extern "C" void traverse_servo(ServoInstance*, int delta);
|
extern "C" void traverse_servo(ServoInstance*, int delta);
|
||||||
extern "C" void navigate_servo(ServoInstance*, const char* text);
|
extern "C" void navigate_servo(ServoInstance*, const char* text);
|
||||||
extern "C" void discard_servo(ServoInstance*);
|
extern "C" void discard_servo(ServoInstance*);
|
||||||
|
@ -220,8 +221,8 @@ bool Servo2D::eventListener(lumin::ServerEvent* event) {
|
||||||
switch (event->getServerEventType()) {
|
switch (event->getServerEventType()) {
|
||||||
case lumin::ServerEventType::kControlTouchPadInputEvent:
|
case lumin::ServerEventType::kControlTouchPadInputEvent:
|
||||||
return touchpadEventListener(static_cast<lumin::ControlTouchPadInputEventData*>(event));
|
return touchpadEventListener(static_cast<lumin::ControlTouchPadInputEventData*>(event));
|
||||||
case lumin::ServerEventType::kKeyInputEvent:
|
case lumin::ServerEventType::kGestureInputEvent:
|
||||||
return keyEventListener(static_cast<lumin::KeyInputEventData*>(event));
|
return gestureEventListener(static_cast<lumin::GestureInputEventData*>(event));
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -257,14 +258,15 @@ bool Servo2D::touchpadEventListener(lumin::ControlTouchPadInputEventData* event)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inform Servo of the trigger
|
// Inform Servo of the move
|
||||||
cursor_servo(servo_, pos.x, pos.y, false);
|
move_servo(servo_, pos.x, pos.y);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Servo2D::keyEventListener(lumin::KeyInputEventData* event) {
|
bool Servo2D::gestureEventListener(lumin::GestureInputEventData* event) {
|
||||||
// Only respond to trigger keys
|
// Only respond to trigger up or down
|
||||||
if (event->keyCode() != lumin::input::KeyCodes::AKEYCODE_EX_TRIGGER) {
|
lumin::input::GestureType typ = event->getGesture();
|
||||||
|
if (typ != lumin::input::GestureType::TriggerDown && typ != lumin::input::GestureType::TriggerUp) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +282,7 @@ bool Servo2D::keyEventListener(lumin::KeyInputEventData* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inform Servo of the trigger
|
// Inform Servo of the trigger
|
||||||
cursor_servo(servo_, pos.x, pos.y, true);
|
trigger_servo(servo_, pos.x, pos.y, typ == lumin::input::GestureType::TriggerDown);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue