mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Update to winit 0.24.
Co-authored-by: Josh Matthews <josh@joshmatthews.net> Co-authored-by: Paulo E. Castro <pecastro@wormholenet.com>
This commit is contained in:
parent
970ab0348f
commit
10231573be
18 changed files with 695 additions and 543 deletions
598
Cargo.lock
generated
598
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -40,8 +40,8 @@ sparkle = "0.1.25"
|
||||||
style = { path = "../style" }
|
style = { path = "../style" }
|
||||||
style_traits = { path = "../style_traits" }
|
style_traits = { path = "../style_traits" }
|
||||||
# NOTE: the sm-angle feature only enables angle on windows, not other platforms!
|
# NOTE: the sm-angle feature only enables angle on windows, not other platforms!
|
||||||
surfman = { version = "0.3", features = ["sm-angle","sm-angle-default"] }
|
surfman = { version = "0.4", features = ["sm-angle","sm-angle-default"] }
|
||||||
surfman-chains = "0.5"
|
surfman-chains = "0.6"
|
||||||
surfman-chains-api = "0.2"
|
surfman-chains-api = "0.2"
|
||||||
time = { version = "0.1.0", optional = true }
|
time = { version = "0.1.0", optional = true }
|
||||||
webrender = { git = "https://github.com/servo/webrender" }
|
webrender = { git = "https://github.com/servo/webrender" }
|
||||||
|
|
|
@ -78,7 +78,7 @@ servo_url = { path = "../url" }
|
||||||
sparkle = "0.1"
|
sparkle = "0.1"
|
||||||
style = { path = "../style", features = ["servo"] }
|
style = { path = "../style", features = ["servo"] }
|
||||||
style_traits = { path = "../style_traits", features = ["servo"] }
|
style_traits = { path = "../style_traits", features = ["servo"] }
|
||||||
surfman = "0.3"
|
surfman = "0.4"
|
||||||
webdriver_server = { path = "../webdriver_server", optional = true }
|
webdriver_server = { path = "../webdriver_server", optional = true }
|
||||||
webgpu = { path = "../webgpu" }
|
webgpu = { path = "../webgpu" }
|
||||||
webrender = { git = "https://github.com/servo/webrender" }
|
webrender = { git = "https://github.com/servo/webrender" }
|
||||||
|
|
|
@ -12,6 +12,6 @@ path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
euclid = "0.20"
|
euclid = "0.20"
|
||||||
surfman = "0.3"
|
surfman = "0.4"
|
||||||
surfman-chains = "0.5"
|
surfman-chains = "0.6"
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,8 @@ libservo = { path = "../../components/servo" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
servo-media = { git = "https://github.com/servo/media" }
|
servo-media = { git = "https://github.com/servo/media" }
|
||||||
sparkle = "0.1"
|
sparkle = "0.1"
|
||||||
surfman = "0.3"
|
surfman = "0.4"
|
||||||
surfman-chains = "0.5"
|
surfman-chains = "0.6"
|
||||||
surfman-chains-api = "0.2"
|
surfman-chains-api = "0.2"
|
||||||
webxr = { git = "https://github.com/servo/webxr", features = ["glwindow"] }
|
webxr = { git = "https://github.com/servo/webxr", features = ["glwindow"] }
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,9 @@ impl ServoThread {
|
||||||
ServoWebSrcMsg::GetSwapChain(sender) => self.send_swap_chain(sender),
|
ServoWebSrcMsg::GetSwapChain(sender) => self.send_swap_chain(sender),
|
||||||
ServoWebSrcMsg::SetSwapChain(swap_chain) => self.swap_chain = Some(swap_chain.0),
|
ServoWebSrcMsg::SetSwapChain(swap_chain) => self.swap_chain = Some(swap_chain.0),
|
||||||
ServoWebSrcMsg::Resize(size) => self.resize(size),
|
ServoWebSrcMsg::Resize(size) => self.resize(size),
|
||||||
ServoWebSrcMsg::Heartbeat => self.servo.handle_events(vec![]),
|
ServoWebSrcMsg::Heartbeat => {
|
||||||
|
self.servo.handle_events(vec![]);
|
||||||
|
}
|
||||||
ServoWebSrcMsg::Stop => break,
|
ServoWebSrcMsg::Stop => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ ipc-channel = "0.14"
|
||||||
libservo = { path = "../../../components/servo" }
|
libservo = { path = "../../../components/servo" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
servo-media = { git = "https://github.com/servo/media" }
|
servo-media = { git = "https://github.com/servo/media" }
|
||||||
surfman = { version = "0.3", features = ["sm-angle-default"] }
|
surfman = { version = "0.4", features = ["sm-angle-default"] }
|
||||||
webxr = { git = "https://github.com/servo/webxr"}
|
webxr = { git = "https://github.com/servo/webxr"}
|
||||||
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ env_logger = "0.8"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
simpleservo = { path = "../api" }
|
simpleservo = { path = "../api" }
|
||||||
surfman = "0.3"
|
surfman = "0.4"
|
||||||
keyboard-types = "0.5"
|
keyboard-types = "0.5"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
|
|
@ -57,10 +57,10 @@ libservo = { path = "../../components/servo" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
servo-media = { git = "https://github.com/servo/media" }
|
servo-media = { git = "https://github.com/servo/media" }
|
||||||
shellwords = "1.0.0"
|
shellwords = "1.0.0"
|
||||||
surfman = { version = "0.3", features = ["sm-winit", "sm-x11"] }
|
surfman = { version = "0.4", features = ["sm-winit", "sm-x11"] }
|
||||||
tinyfiledialogs = "3.0"
|
tinyfiledialogs = "3.0"
|
||||||
webxr = { git = "https://github.com/servo/webxr", features = ["ipc", "glwindow", "headless"] }
|
webxr = { git = "https://github.com/servo/webxr", features = ["ipc", "glwindow", "headless"] }
|
||||||
winit = "0.19"
|
winit = "0.24"
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies]
|
[target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies]
|
||||||
image = "0.23"
|
image = "0.23"
|
||||||
|
|
|
@ -6,9 +6,11 @@
|
||||||
|
|
||||||
use crate::browser::Browser;
|
use crate::browser::Browser;
|
||||||
use crate::embedder::EmbedderCallbacks;
|
use crate::embedder::EmbedderCallbacks;
|
||||||
use crate::events_loop::EventsLoop;
|
use crate::events_loop::{EventsLoop, ServoEvent};
|
||||||
use crate::window_trait::WindowPortsMethods;
|
use crate::window_trait::WindowPortsMethods;
|
||||||
use crate::{headed_window, headless_window};
|
use crate::{headed_window, headless_window};
|
||||||
|
use winit::window::WindowId;
|
||||||
|
use winit::event_loop::EventLoopWindowTarget;
|
||||||
use servo::compositing::windowing::WindowEvent;
|
use servo::compositing::windowing::WindowEvent;
|
||||||
use servo::config::opts::{self, parse_url_or_filename};
|
use servo::config::opts::{self, parse_url_or_filename};
|
||||||
use servo::servo_config::pref;
|
use servo::servo_config::pref;
|
||||||
|
@ -20,15 +22,13 @@ use std::env;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use webxr::glwindow::GlWindowDiscovery;
|
use webxr::glwindow::GlWindowDiscovery;
|
||||||
use winit::WindowId;
|
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
pub static WINDOWS: RefCell<HashMap<WindowId, Rc<dyn WindowPortsMethods>>> = RefCell::new(HashMap::new());
|
pub static WINDOWS: RefCell<HashMap<WindowId, Rc<dyn WindowPortsMethods>>> = RefCell::new(HashMap::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
events_loop: Rc<RefCell<EventsLoop>>,
|
servo: Option<Servo<dyn WindowPortsMethods>>,
|
||||||
servo: RefCell<Servo<dyn WindowPortsMethods>>,
|
|
||||||
browser: RefCell<Browser<dyn WindowPortsMethods>>,
|
browser: RefCell<Browser<dyn WindowPortsMethods>>,
|
||||||
event_queue: RefCell<Vec<WindowEvent>>,
|
event_queue: RefCell<Vec<WindowEvent>>,
|
||||||
suspended: Cell<bool>,
|
suspended: Cell<bool>,
|
||||||
|
@ -48,49 +48,96 @@ impl App {
|
||||||
} else {
|
} else {
|
||||||
Rc::new(headed_window::Window::new(
|
Rc::new(headed_window::Window::new(
|
||||||
opts::get().initial_window_size,
|
opts::get().initial_window_size,
|
||||||
events_loop.clone(),
|
&events_loop,
|
||||||
no_native_titlebar,
|
no_native_titlebar,
|
||||||
device_pixels_per_px,
|
device_pixels_per_px,
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
let xr_discovery = if pref!(dom.webxr.glwindow.enabled) {
|
|
||||||
let window = window.clone();
|
|
||||||
let surfman = window.webrender_surfman();
|
|
||||||
let events_loop = events_loop.clone();
|
|
||||||
let factory = Box::new(move || Ok(window.new_glwindow(&*events_loop.borrow())));
|
|
||||||
Some(GlWindowDiscovery::new(
|
|
||||||
surfman.connection(),
|
|
||||||
surfman.adapter(),
|
|
||||||
surfman.context_attributes(),
|
|
||||||
factory,
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implements embedder methods, used by libservo and constellation.
|
|
||||||
let embedder = Box::new(EmbedderCallbacks::new(events_loop.clone(), xr_discovery));
|
|
||||||
|
|
||||||
// Handle browser state.
|
// Handle browser state.
|
||||||
let browser = Browser::new(window.clone());
|
let browser = Browser::new(window.clone());
|
||||||
|
|
||||||
let mut servo = Servo::new(embedder, window.clone(), user_agent);
|
let mut app = App {
|
||||||
let browser_id = BrowserId::new();
|
|
||||||
servo.handle_events(vec![WindowEvent::NewBrowser(get_default_url(), browser_id)]);
|
|
||||||
servo.setup_logging();
|
|
||||||
|
|
||||||
register_window(window);
|
|
||||||
|
|
||||||
let app = App {
|
|
||||||
event_queue: RefCell::new(vec![]),
|
event_queue: RefCell::new(vec![]),
|
||||||
events_loop,
|
|
||||||
browser: RefCell::new(browser),
|
browser: RefCell::new(browser),
|
||||||
servo: RefCell::new(servo),
|
servo: None,
|
||||||
suspended: Cell::new(false),
|
suspended: Cell::new(false),
|
||||||
};
|
};
|
||||||
|
|
||||||
app.run_loop();
|
let ev_waker = events_loop.create_event_loop_waker();
|
||||||
|
events_loop.run_forever(move |e, w, control_flow| {
|
||||||
|
if let winit::event::Event::NewEvents(winit::event::StartCause::Init) = e {
|
||||||
|
let surfman = window.webrender_surfman();
|
||||||
|
|
||||||
|
let xr_discovery = if pref!(dom.webxr.glwindow.enabled) {
|
||||||
|
let window = window.clone();
|
||||||
|
// This should be safe because run_forever does, in fact,
|
||||||
|
// run forever. The event loop window target doesn't get
|
||||||
|
// moved, and does outlast this closure, and we won't
|
||||||
|
// ever try to make use of it once shutdown begins and
|
||||||
|
// it stops being valid.
|
||||||
|
let w = unsafe {
|
||||||
|
std::mem::transmute::<
|
||||||
|
&EventLoopWindowTarget<ServoEvent>,
|
||||||
|
&'static EventLoopWindowTarget<ServoEvent>
|
||||||
|
>(w.unwrap())
|
||||||
|
};
|
||||||
|
let factory = Box::new(move || Ok(window.new_glwindow(w)));
|
||||||
|
Some(GlWindowDiscovery::new(
|
||||||
|
surfman.connection(),
|
||||||
|
surfman.adapter(),
|
||||||
|
surfman.context_attributes(),
|
||||||
|
factory,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let window = window.clone();
|
||||||
|
// Implements embedder methods, used by libservo and constellation.
|
||||||
|
let embedder = Box::new(EmbedderCallbacks::new(
|
||||||
|
ev_waker.clone(),
|
||||||
|
xr_discovery,
|
||||||
|
));
|
||||||
|
|
||||||
|
let mut servo = Servo::new(embedder, window.clone(), user_agent.clone());
|
||||||
|
let browser_id = BrowserId::new();
|
||||||
|
servo.handle_events(vec![WindowEvent::NewBrowser(get_default_url(), browser_id)]);
|
||||||
|
servo.setup_logging();
|
||||||
|
|
||||||
|
register_window(window.clone());
|
||||||
|
app.servo = Some(servo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If self.servo is None here, it means that we're in the process of shutting down,
|
||||||
|
// let's ignore events.
|
||||||
|
if app.servo.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the event
|
||||||
|
app.winit_event_to_servo_event(e);
|
||||||
|
|
||||||
|
let animating = WINDOWS.with(|windows| {
|
||||||
|
windows
|
||||||
|
.borrow()
|
||||||
|
.iter()
|
||||||
|
.any(|(_, window)| window.is_animating())
|
||||||
|
});
|
||||||
|
|
||||||
|
// Block until the window gets an event
|
||||||
|
if !animating || app.suspended.get() {
|
||||||
|
*control_flow = winit::event_loop::ControlFlow::Wait;
|
||||||
|
} else {
|
||||||
|
*control_flow = winit::event_loop::ControlFlow::Poll;
|
||||||
|
}
|
||||||
|
|
||||||
|
let stop = app.handle_events();
|
||||||
|
if stop {
|
||||||
|
*control_flow = winit::event_loop::ControlFlow::Exit;
|
||||||
|
app.servo.take().unwrap().deinit();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_events(&self) -> Vec<WindowEvent> {
|
fn get_events(&self) -> Vec<WindowEvent> {
|
||||||
|
@ -98,87 +145,50 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function decides whether the event should be handled during `run_forever`.
|
// This function decides whether the event should be handled during `run_forever`.
|
||||||
fn winit_event_to_servo_event(&self, event: winit::Event) -> winit::ControlFlow {
|
fn winit_event_to_servo_event(&self, event: winit::event::Event<ServoEvent>) {
|
||||||
match event {
|
match event {
|
||||||
// App level events
|
// App level events
|
||||||
winit::Event::Suspended(suspended) => {
|
winit::event::Event::Suspended => {
|
||||||
self.suspended.set(suspended);
|
self.suspended.set(true);
|
||||||
if !suspended {
|
|
||||||
self.event_queue.borrow_mut().push(WindowEvent::Idle);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
winit::Event::Awakened => {
|
winit::event::Event::Resumed => {
|
||||||
|
self.suspended.set(false);
|
||||||
|
self.event_queue.borrow_mut().push(WindowEvent::Idle);
|
||||||
|
},
|
||||||
|
winit::event::Event::UserEvent(_) => {
|
||||||
|
self.event_queue.borrow_mut().push(WindowEvent::Idle);
|
||||||
|
},
|
||||||
|
winit::event::Event::DeviceEvent { .. } => {},
|
||||||
|
|
||||||
|
winit::event::Event::RedrawRequested(_) => {
|
||||||
self.event_queue.borrow_mut().push(WindowEvent::Idle);
|
self.event_queue.borrow_mut().push(WindowEvent::Idle);
|
||||||
},
|
},
|
||||||
winit::Event::DeviceEvent { .. } => {},
|
|
||||||
|
|
||||||
// Window level events
|
// Window level events
|
||||||
winit::Event::WindowEvent {
|
winit::event::Event::WindowEvent {
|
||||||
window_id, event, ..
|
window_id, event, ..
|
||||||
} => {
|
} => {
|
||||||
return WINDOWS.with(|windows| {
|
return WINDOWS.with(|windows| {
|
||||||
match windows.borrow().get(&window_id) {
|
match windows.borrow().get(&window_id) {
|
||||||
None => {
|
None => {
|
||||||
warn!("Got an event from unknown window");
|
warn!("Got an event from unknown window");
|
||||||
winit::ControlFlow::Break
|
|
||||||
},
|
},
|
||||||
Some(window) => {
|
Some(window) => {
|
||||||
// Resize events need to be handled during run_forever
|
|
||||||
let cont = if let winit::WindowEvent::Resized(_) = event {
|
|
||||||
winit::ControlFlow::Continue
|
|
||||||
} else {
|
|
||||||
winit::ControlFlow::Break
|
|
||||||
};
|
|
||||||
window.winit_event_to_servo_event(event);
|
window.winit_event_to_servo_event(event);
|
||||||
return cont;
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
winit::event::Event::LoopDestroyed |
|
||||||
|
winit::event::Event::NewEvents(..) |
|
||||||
|
winit::event::Event::MainEventsCleared |
|
||||||
|
winit::event::Event::RedrawEventsCleared => {},
|
||||||
}
|
}
|
||||||
winit::ControlFlow::Break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_loop(self) {
|
fn handle_events(&mut self) -> bool {
|
||||||
loop {
|
|
||||||
let animating = WINDOWS.with(|windows| {
|
|
||||||
windows
|
|
||||||
.borrow()
|
|
||||||
.iter()
|
|
||||||
.any(|(_, window)| window.is_animating())
|
|
||||||
});
|
|
||||||
if !animating || self.suspended.get() {
|
|
||||||
// If there's no animations running then we block on the window event loop.
|
|
||||||
self.events_loop.borrow_mut().run_forever(|e| {
|
|
||||||
let cont = self.winit_event_to_servo_event(e);
|
|
||||||
if cont == winit::ControlFlow::Continue {
|
|
||||||
// Note we need to be careful to make sure that any events
|
|
||||||
// that are handled during run_forever aren't re-entrant,
|
|
||||||
// since we are handling them while holding onto a mutable borrow
|
|
||||||
// of the events loop
|
|
||||||
self.handle_events();
|
|
||||||
}
|
|
||||||
cont
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Grab any other events that may have happened
|
|
||||||
self.events_loop.borrow_mut().poll_events(|e| {
|
|
||||||
self.winit_event_to_servo_event(e);
|
|
||||||
});
|
|
||||||
// If animations are running, we block on compositing
|
|
||||||
// (self.handle_events() ends up calling swap_buffers)
|
|
||||||
let stop = self.handle_events();
|
|
||||||
if stop {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.servo.into_inner().deinit()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_events(&self) -> bool {
|
|
||||||
let mut browser = self.browser.borrow_mut();
|
let mut browser = self.browser.borrow_mut();
|
||||||
let mut servo = self.servo.borrow_mut();
|
|
||||||
|
|
||||||
// FIXME:
|
// FIXME:
|
||||||
// As of now, we support only one browser (self.browser)
|
// As of now, we support only one browser (self.browser)
|
||||||
|
@ -203,21 +213,21 @@ impl App {
|
||||||
|
|
||||||
browser.handle_window_events(app_events);
|
browser.handle_window_events(app_events);
|
||||||
|
|
||||||
let mut servo_events = servo.get_events();
|
let mut servo_events = self.servo.as_mut().unwrap().get_events();
|
||||||
loop {
|
loop {
|
||||||
browser.handle_servo_events(servo_events);
|
browser.handle_servo_events(servo_events);
|
||||||
servo.handle_events(browser.get_events());
|
self.servo.as_mut().unwrap().handle_events(browser.get_events());
|
||||||
if browser.shutdown_requested() {
|
if browser.shutdown_requested() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
servo_events = servo.get_events();
|
servo_events = self.servo.as_mut().unwrap().get_events();
|
||||||
if servo_events.is_empty() {
|
if servo_events.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if need_resize {
|
if need_resize {
|
||||||
servo.repaint_synchronously();
|
self.servo.as_mut().unwrap().repaint_synchronously();
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,26 +4,23 @@
|
||||||
|
|
||||||
//! Implements the global methods required by Servo (not window/gl/compositor related).
|
//! Implements the global methods required by Servo (not window/gl/compositor related).
|
||||||
|
|
||||||
use crate::events_loop::EventsLoop;
|
|
||||||
use servo::compositing::windowing::EmbedderMethods;
|
use servo::compositing::windowing::EmbedderMethods;
|
||||||
use servo::embedder_traits::{EmbedderProxy, EventLoopWaker};
|
use servo::embedder_traits::{EmbedderProxy, EventLoopWaker};
|
||||||
use servo::servo_config::pref;
|
use servo::servo_config::pref;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use webxr::glwindow::GlWindowDiscovery;
|
use webxr::glwindow::GlWindowDiscovery;
|
||||||
|
|
||||||
pub struct EmbedderCallbacks {
|
pub struct EmbedderCallbacks {
|
||||||
events_loop: Rc<RefCell<EventsLoop>>,
|
event_loop_waker: Box<dyn EventLoopWaker>,
|
||||||
xr_discovery: Option<GlWindowDiscovery>,
|
xr_discovery: Option<GlWindowDiscovery>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EmbedderCallbacks {
|
impl EmbedderCallbacks {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
events_loop: Rc<RefCell<EventsLoop>>,
|
event_loop_waker: Box<dyn EventLoopWaker>,
|
||||||
xr_discovery: Option<GlWindowDiscovery>,
|
xr_discovery: Option<GlWindowDiscovery>,
|
||||||
) -> EmbedderCallbacks {
|
) -> EmbedderCallbacks {
|
||||||
EmbedderCallbacks {
|
EmbedderCallbacks {
|
||||||
events_loop,
|
event_loop_waker,
|
||||||
xr_discovery,
|
xr_discovery,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +28,7 @@ impl EmbedderCallbacks {
|
||||||
|
|
||||||
impl EmbedderMethods for EmbedderCallbacks {
|
impl EmbedderMethods for EmbedderCallbacks {
|
||||||
fn create_event_loop_waker(&mut self) -> Box<dyn EventLoopWaker> {
|
fn create_event_loop_waker(&mut self) -> Box<dyn EventLoopWaker> {
|
||||||
self.events_loop.borrow().create_event_loop_waker()
|
self.event_loop_waker.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_webxr(
|
fn register_webxr(
|
||||||
|
|
|
@ -5,16 +5,19 @@
|
||||||
//! An event loop implementation that works in headless mode.
|
//! An event loop implementation that works in headless mode.
|
||||||
|
|
||||||
use servo::embedder_traits::EventLoopWaker;
|
use servo::embedder_traits::EventLoopWaker;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::sync::{Arc, Condvar, Mutex};
|
use std::sync::{Arc, Condvar, Mutex};
|
||||||
use std::time;
|
use std::time;
|
||||||
use winit;
|
use winit;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ServoEvent {
|
||||||
|
Awakened,
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
enum EventLoop {
|
enum EventLoop {
|
||||||
/// A real Winit windowing event loop.
|
/// A real Winit windowing event loop.
|
||||||
Winit(Option<winit::EventsLoop>),
|
Winit(Option<winit::event_loop::EventLoop<ServoEvent>>),
|
||||||
/// A fake event loop which contains a signalling flag used to ensure
|
/// A fake event loop which contains a signalling flag used to ensure
|
||||||
/// that pending events get processed in a timely fashion, and a condition
|
/// that pending events get processed in a timely fashion, and a condition
|
||||||
/// variable to allow waiting on that flag changing state.
|
/// variable to allow waiting on that flag changing state.
|
||||||
|
@ -27,19 +30,16 @@ impl EventsLoop {
|
||||||
// Ideally, we could use the winit event loop in both modes,
|
// Ideally, we could use the winit event loop in both modes,
|
||||||
// but on Linux, the event loop requires a X11 server.
|
// but on Linux, the event loop requires a X11 server.
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
pub fn new(_headless: bool) -> Rc<RefCell<EventsLoop>> {
|
pub fn new(_headless: bool) -> EventsLoop {
|
||||||
Rc::new(RefCell::new(EventsLoop(EventLoop::Winit(Some(
|
EventsLoop(EventLoop::Winit(Some(winit::event_loop::EventLoop::with_user_event())))
|
||||||
winit::EventsLoop::new(),
|
|
||||||
)))))
|
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub fn new(headless: bool) -> Rc<RefCell<EventsLoop>> {
|
pub fn new(headless: bool) -> EventsLoop {
|
||||||
let events_loop = if headless {
|
EventsLoop(if headless {
|
||||||
EventLoop::Headless(Arc::new((Mutex::new(false), Condvar::new())))
|
EventLoop::Headless(Arc::new((Mutex::new(false), Condvar::new())))
|
||||||
} else {
|
} else {
|
||||||
EventLoop::Winit(Some(winit::EventsLoop::new()))
|
EventLoop::Winit(Some(winit::event_loop::EventLoop::with_user_event()))
|
||||||
};
|
})
|
||||||
Rc::new(RefCell::new(EventsLoop(events_loop)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ impl EventsLoop {
|
||||||
EventLoop::Headless(ref data) => Box::new(HeadlessEventLoopWaker(data.clone())),
|
EventLoop::Headless(ref data) => Box::new(HeadlessEventLoopWaker(data.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn as_winit(&self) -> &winit::EventsLoop {
|
pub fn as_winit(&self) -> &winit::event_loop::EventLoop<ServoEvent> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
EventLoop::Winit(Some(ref event_loop)) => event_loop,
|
EventLoop::Winit(Some(ref event_loop)) => event_loop,
|
||||||
EventLoop::Winit(None) | EventLoop::Headless(..) => {
|
EventLoop::Winit(None) | EventLoop::Headless(..) => {
|
||||||
|
@ -64,49 +64,41 @@ impl EventsLoop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_events<F>(&mut self, callback: F)
|
pub fn run_forever<F: 'static>(self, mut callback: F)
|
||||||
where
|
where F: FnMut(
|
||||||
F: FnMut(winit::Event),
|
winit::event::Event<ServoEvent>,
|
||||||
{
|
Option<&winit::event_loop::EventLoopWindowTarget<ServoEvent>>,
|
||||||
|
&mut winit::event_loop::ControlFlow
|
||||||
|
) {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
EventLoop::Winit(Some(ref mut events_loop)) => events_loop.poll_events(callback),
|
EventLoop::Winit(events_loop) => {
|
||||||
EventLoop::Winit(None) => (),
|
|
||||||
EventLoop::Headless(ref data) => {
|
|
||||||
// This is subtle - the use of the event loop in App::run_loop
|
|
||||||
// optionally calls run_forever, then always calls poll_events.
|
|
||||||
// If our signalling flag is true before we call run_forever,
|
|
||||||
// we don't want to reset it before poll_events is called or
|
|
||||||
// we'll end up sleeping even though there are events waiting
|
|
||||||
// to be handled. We compromise by only resetting the flag here
|
|
||||||
// in poll_events, so that both poll_events and run_forever can
|
|
||||||
// check it first and avoid sleeping unnecessarily.
|
|
||||||
self.sleep(&data.0, &data.1);
|
|
||||||
*data.0.lock().unwrap() = false;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn run_forever<F>(&mut self, mut callback: F)
|
|
||||||
where
|
|
||||||
F: FnMut(winit::Event) -> winit::ControlFlow,
|
|
||||||
{
|
|
||||||
match self.0 {
|
|
||||||
EventLoop::Winit(ref mut events_loop) => {
|
|
||||||
let events_loop = events_loop
|
let events_loop = events_loop
|
||||||
.as_mut()
|
|
||||||
.expect("Can't run an unavailable event loop.");
|
.expect("Can't run an unavailable event loop.");
|
||||||
events_loop.run_forever(callback);
|
events_loop.run(move |e, window_target, ref mut control_flow| {
|
||||||
},
|
callback(e, Some(window_target), control_flow)
|
||||||
|
});
|
||||||
|
}
|
||||||
EventLoop::Headless(ref data) => {
|
EventLoop::Headless(ref data) => {
|
||||||
let &(ref flag, ref condvar) = &**data;
|
let &(ref flag, ref condvar) = &**data;
|
||||||
while !*flag.lock().unwrap() {
|
loop {
|
||||||
self.sleep(flag, condvar);
|
self.sleep(flag, condvar);
|
||||||
if callback(winit::Event::Awakened) == winit::ControlFlow::Break {
|
let mut control_flow = winit::event_loop::ControlFlow::Poll;
|
||||||
|
|
||||||
|
callback(
|
||||||
|
winit::event::Event::<ServoEvent>::UserEvent(ServoEvent::Awakened),
|
||||||
|
None,
|
||||||
|
&mut control_flow
|
||||||
|
);
|
||||||
|
if control_flow != winit::event_loop::ControlFlow::Poll {
|
||||||
|
*flag.lock().unwrap() = false;
|
||||||
|
} else if control_flow == winit::event_loop::ControlFlow::Exit {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sleep(&self, lock: &Mutex<bool>, condvar: &Condvar) {
|
fn sleep(&self, lock: &Mutex<bool>, condvar: &Condvar) {
|
||||||
// To avoid sleeping when we should be processing events, do two things:
|
// To avoid sleeping when we should be processing events, do two things:
|
||||||
// * before sleeping, check whether our signalling flag has been set
|
// * before sleeping, check whether our signalling flag has been set
|
||||||
|
@ -123,18 +115,18 @@ impl EventsLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HeadedEventLoopWaker {
|
struct HeadedEventLoopWaker {
|
||||||
proxy: Arc<winit::EventsLoopProxy>,
|
proxy: Arc<Mutex<winit::event_loop::EventLoopProxy<ServoEvent>>>,
|
||||||
}
|
}
|
||||||
impl HeadedEventLoopWaker {
|
impl HeadedEventLoopWaker {
|
||||||
fn new(events_loop: &winit::EventsLoop) -> HeadedEventLoopWaker {
|
fn new(events_loop: &winit::event_loop::EventLoop<ServoEvent>) -> HeadedEventLoopWaker {
|
||||||
let proxy = Arc::new(events_loop.create_proxy());
|
let proxy = Arc::new(Mutex::new(events_loop.create_proxy()));
|
||||||
HeadedEventLoopWaker { proxy }
|
HeadedEventLoopWaker { proxy }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl EventLoopWaker for HeadedEventLoopWaker {
|
impl EventLoopWaker for HeadedEventLoopWaker {
|
||||||
fn wake(&self) {
|
fn wake(&self) {
|
||||||
// kick the OS event loop awake.
|
// Kick the OS event loop awake.
|
||||||
if let Err(err) = self.proxy.wakeup() {
|
if let Err(err) = self.proxy.lock().unwrap().send_event(ServoEvent::Awakened) {
|
||||||
warn!("Failed to wake up event loop ({}).", err);
|
warn!("Failed to wake up event loop ({}).", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,18 @@
|
||||||
|
|
||||||
//! A winit window implementation.
|
//! A winit window implementation.
|
||||||
|
|
||||||
use crate::events_loop::EventsLoop;
|
use crate::events_loop::{EventsLoop, ServoEvent};
|
||||||
use crate::keyutils::keyboard_event_from_winit;
|
use crate::keyutils::keyboard_event_from_winit;
|
||||||
use crate::window_trait::{WindowPortsMethods, LINE_HEIGHT};
|
use crate::window_trait::{WindowPortsMethods, LINE_HEIGHT};
|
||||||
use euclid::{Angle, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector2D, Vector3D};
|
use euclid::{
|
||||||
|
Angle, Point2D, Rotation3D, Scale, Size2D, UnknownUnit,
|
||||||
|
Vector2D, Vector3D,
|
||||||
|
};
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
use winit::platform::macos::{ActivationPolicy, WindowBuilderExtMacOS};
|
||||||
|
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||||
|
use winit::window::Icon;
|
||||||
|
use winit::event::{ElementState, KeyboardInput, MouseButton, MouseScrollDelta, TouchPhase, VirtualKeyCode};
|
||||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||||
use image;
|
use image;
|
||||||
use keyboard_types::{Key, KeyState, KeyboardEvent};
|
use keyboard_types::{Key, KeyState, KeyboardEvent};
|
||||||
|
@ -39,17 +47,11 @@ use surfman::GLVersion;
|
||||||
use surfman::SurfaceType;
|
use surfman::SurfaceType;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use winapi;
|
use winapi;
|
||||||
use winit::dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
use winit::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
||||||
#[cfg(target_os = "macos")]
|
use winit::event::ModifiersState;
|
||||||
use winit::os::macos::{ActivationPolicy, WindowBuilderExt};
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
|
||||||
use winit::Icon;
|
|
||||||
use winit::{
|
|
||||||
ElementState, KeyboardInput, MouseButton, MouseScrollDelta, TouchPhase, VirtualKeyCode,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn builder_with_platform_options(mut builder: winit::WindowBuilder) -> winit::WindowBuilder {
|
fn builder_with_platform_options(mut builder: winit::window::WindowBuilder) -> winit::window::WindowBuilder {
|
||||||
if opts::get().output_file.is_some() {
|
if opts::get().output_file.is_some() {
|
||||||
// Prevent the window from showing in Dock.app, stealing focus,
|
// Prevent the window from showing in Dock.app, stealing focus,
|
||||||
// when generating an output file.
|
// when generating an output file.
|
||||||
|
@ -59,18 +61,18 @@ fn builder_with_platform_options(mut builder: winit::WindowBuilder) -> winit::Wi
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
fn builder_with_platform_options(builder: winit::WindowBuilder) -> winit::WindowBuilder {
|
fn builder_with_platform_options(builder: winit::window::WindowBuilder) -> winit::window::WindowBuilder {
|
||||||
builder
|
builder
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
winit_window: winit::Window,
|
winit_window: winit::window::Window,
|
||||||
webrender_surfman: WebrenderSurfman,
|
webrender_surfman: WebrenderSurfman,
|
||||||
screen_size: Size2D<u32, DeviceIndependentPixel>,
|
screen_size: Size2D<u32, DeviceIndependentPixel>,
|
||||||
inner_size: Cell<Size2D<u32, DeviceIndependentPixel>>,
|
inner_size: Cell<Size2D<u32, DeviceIndependentPixel>>,
|
||||||
mouse_down_button: Cell<Option<winit::MouseButton>>,
|
mouse_down_button: Cell<Option<winit::event::MouseButton>>,
|
||||||
mouse_down_point: Cell<Point2D<i32, DevicePixel>>,
|
mouse_down_point: Cell<Point2D<i32, DevicePixel>>,
|
||||||
primary_monitor: winit::MonitorId,
|
primary_monitor: winit::monitor::MonitorHandle,
|
||||||
event_queue: RefCell<Vec<WindowEvent>>,
|
event_queue: RefCell<Vec<WindowEvent>>,
|
||||||
mouse_pos: Cell<Point2D<i32, DevicePixel>>,
|
mouse_pos: Cell<Point2D<i32, DevicePixel>>,
|
||||||
last_pressed: Cell<Option<(KeyboardEvent, Option<VirtualKeyCode>)>>,
|
last_pressed: Cell<Option<(KeyboardEvent, Option<VirtualKeyCode>)>>,
|
||||||
|
@ -81,6 +83,7 @@ pub struct Window {
|
||||||
fullscreen: Cell<bool>,
|
fullscreen: Cell<bool>,
|
||||||
device_pixels_per_px: Option<f32>,
|
device_pixels_per_px: Option<f32>,
|
||||||
xr_window_poses: RefCell<Vec<Rc<XRWindowPose>>>,
|
xr_window_poses: RefCell<Vec<Rc<XRWindowPose>>>,
|
||||||
|
modifiers_state: Cell<ModifiersState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
@ -98,7 +101,7 @@ fn window_creation_scale_factor() -> Scale<f32, DeviceIndependentPixel, DevicePi
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
win_size: Size2D<u32, DeviceIndependentPixel>,
|
win_size: Size2D<u32, DeviceIndependentPixel>,
|
||||||
events_loop: Rc<RefCell<EventsLoop>>,
|
events_loop: &EventsLoop,
|
||||||
no_native_titlebar: bool,
|
no_native_titlebar: bool,
|
||||||
device_pixels_per_px: Option<f32>,
|
device_pixels_per_px: Option<f32>,
|
||||||
) -> Window {
|
) -> Window {
|
||||||
|
@ -114,19 +117,16 @@ impl Window {
|
||||||
let width = win_size.to_untyped().width;
|
let width = win_size.to_untyped().width;
|
||||||
let height = win_size.to_untyped().height;
|
let height = win_size.to_untyped().height;
|
||||||
|
|
||||||
let mut window_builder = winit::WindowBuilder::new()
|
let mut window_builder = winit::window::WindowBuilder::new()
|
||||||
.with_title("Servo".to_string())
|
.with_title("Servo".to_string())
|
||||||
.with_decorations(!no_native_titlebar)
|
.with_decorations(!no_native_titlebar)
|
||||||
.with_transparency(no_native_titlebar)
|
.with_transparent(no_native_titlebar)
|
||||||
.with_dimensions(LogicalSize::new(width as f64, height as f64))
|
.with_inner_size(PhysicalSize::new(width as f64, height as f64))
|
||||||
.with_visibility(visible)
|
.with_visible(visible);
|
||||||
.with_multitouch();
|
|
||||||
|
|
||||||
window_builder = builder_with_platform_options(window_builder);
|
window_builder = builder_with_platform_options(window_builder);
|
||||||
|
|
||||||
let winit_window = window_builder
|
let winit_window = window_builder.build(events_loop.as_winit()).expect("Failed to create window.");
|
||||||
.build(events_loop.borrow().as_winit())
|
|
||||||
.expect("Failed to create window.");
|
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||||
{
|
{
|
||||||
|
@ -134,21 +134,16 @@ impl Window {
|
||||||
winit_window.set_window_icon(Some(load_icon(icon_bytes)));
|
winit_window.set_window_icon(Some(load_icon(icon_bytes)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let primary_monitor = events_loop.borrow().as_winit().get_primary_monitor();
|
let primary_monitor = events_loop.as_winit().available_monitors().nth(0).expect("No monitor detected");
|
||||||
|
|
||||||
let PhysicalSize {
|
let PhysicalSize {
|
||||||
width: screen_width,
|
width: screen_width,
|
||||||
height: screen_height,
|
height: screen_height,
|
||||||
} = primary_monitor.get_dimensions();
|
} = primary_monitor.clone().size();
|
||||||
let screen_size = Size2D::new(screen_width as u32, screen_height as u32);
|
let screen_size = Size2D::new(screen_width as u32, screen_height as u32);
|
||||||
// TODO(ajeffrey): can this fail?
|
let PhysicalSize { width, height } = winit_window.inner_size();
|
||||||
let LogicalSize { width, height } = winit_window
|
|
||||||
.get_inner_size()
|
|
||||||
.expect("Failed to get window inner size.");
|
|
||||||
let inner_size = Size2D::new(width as u32, height as u32);
|
let inner_size = Size2D::new(width as u32, height as u32);
|
||||||
|
|
||||||
winit_window.show();
|
|
||||||
|
|
||||||
// Initialize surfman
|
// Initialize surfman
|
||||||
let connection =
|
let connection =
|
||||||
Connection::from_winit_window(&winit_window).expect("Failed to create connection");
|
Connection::from_winit_window(&winit_window).expect("Failed to create connection");
|
||||||
|
@ -179,6 +174,7 @@ impl Window {
|
||||||
screen_size,
|
screen_size,
|
||||||
device_pixels_per_px,
|
device_pixels_per_px,
|
||||||
xr_window_poses: RefCell::new(vec![]),
|
xr_window_poses: RefCell::new(vec![]),
|
||||||
|
modifiers_state: Cell::new(ModifiersState::empty()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +223,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_keyboard_input(&self, input: KeyboardInput) {
|
fn handle_keyboard_input(&self, input: KeyboardInput) {
|
||||||
let mut event = keyboard_event_from_winit(input);
|
let mut event = keyboard_event_from_winit(input, self.modifiers_state.get());
|
||||||
trace!("handling {:?}", event);
|
trace!("handling {:?}", event);
|
||||||
if event.state == KeyState::Down && event.key == Key::Unidentified {
|
if event.state == KeyState::Down && event.key == Key::Unidentified {
|
||||||
// If pressed and probably printable, we expect a ReceivedCharacter event.
|
// If pressed and probably printable, we expect a ReceivedCharacter event.
|
||||||
|
@ -247,7 +243,7 @@ impl Window {
|
||||||
self.last_pressed.set(None);
|
self.last_pressed.set(None);
|
||||||
let xr_poses = self.xr_window_poses.borrow();
|
let xr_poses = self.xr_window_poses.borrow();
|
||||||
for xr_window_pose in &*xr_poses {
|
for xr_window_pose in &*xr_poses {
|
||||||
xr_window_pose.handle_xr_rotation(&input);
|
xr_window_pose.handle_xr_rotation(&input, self.modifiers_state.get());
|
||||||
}
|
}
|
||||||
self.event_queue
|
self.event_queue
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -258,17 +254,17 @@ impl Window {
|
||||||
/// Helper function to handle a click
|
/// Helper function to handle a click
|
||||||
fn handle_mouse(
|
fn handle_mouse(
|
||||||
&self,
|
&self,
|
||||||
button: winit::MouseButton,
|
button: winit::event::MouseButton,
|
||||||
action: winit::ElementState,
|
action: winit::event::ElementState,
|
||||||
coords: Point2D<i32, DevicePixel>,
|
coords: Point2D<i32, DevicePixel>,
|
||||||
) {
|
) {
|
||||||
use servo::script_traits::MouseButton;
|
use servo::script_traits::MouseButton;
|
||||||
|
|
||||||
let max_pixel_dist = 10.0 * self.servo_hidpi_factor().get();
|
let max_pixel_dist = 10.0 * self.servo_hidpi_factor().get();
|
||||||
let mouse_button = match &button {
|
let mouse_button = match &button {
|
||||||
winit::MouseButton::Left => MouseButton::Left,
|
winit::event::MouseButton::Left => MouseButton::Left,
|
||||||
winit::MouseButton::Right => MouseButton::Right,
|
winit::event::MouseButton::Right => MouseButton::Right,
|
||||||
winit::MouseButton::Middle => MouseButton::Middle,
|
winit::event::MouseButton::Middle => MouseButton::Middle,
|
||||||
_ => MouseButton::Left,
|
_ => MouseButton::Left,
|
||||||
};
|
};
|
||||||
let event = match action {
|
let event = match action {
|
||||||
|
@ -305,7 +301,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn device_hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
fn device_hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||||
Scale::new(self.winit_window.get_hidpi_factor() as f32)
|
Scale::new(self.winit_window.scale_factor() as f32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn servo_hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
fn servo_hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
|
||||||
|
@ -332,8 +328,7 @@ impl WindowPortsMethods for Window {
|
||||||
let dpr = self.servo_hidpi_factor();
|
let dpr = self.servo_hidpi_factor();
|
||||||
let size = self
|
let size = self
|
||||||
.winit_window
|
.winit_window
|
||||||
.get_inner_size()
|
.inner_size();
|
||||||
.expect("Failed to get window inner size.");
|
|
||||||
size.height as f32 * dpr.get()
|
size.height as f32 * dpr.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,24 +337,23 @@ impl WindowPortsMethods for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_inner_size(&self, size: DeviceIntSize) {
|
fn set_inner_size(&self, size: DeviceIntSize) {
|
||||||
let size = size.to_f32() / self.device_hidpi_factor();
|
|
||||||
self.winit_window
|
self.winit_window
|
||||||
.set_inner_size(LogicalSize::new(size.width.into(), size.height.into()))
|
.set_inner_size::<PhysicalSize<i32>>(PhysicalSize::new(size.width.into(), size.height.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_position(&self, point: DeviceIntPoint) {
|
fn set_position(&self, point: DeviceIntPoint) {
|
||||||
let point = point.to_f32() / self.device_hidpi_factor();
|
|
||||||
self.winit_window
|
self.winit_window
|
||||||
.set_position(LogicalPosition::new(point.x.into(), point.y.into()))
|
.set_outer_position::<PhysicalPosition<i32>>(PhysicalPosition::new(point.x.into(), point.y.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_fullscreen(&self, state: bool) {
|
fn set_fullscreen(&self, state: bool) {
|
||||||
if self.fullscreen.get() != state {
|
if self.fullscreen.get() != state {
|
||||||
self.winit_window.set_fullscreen(if state {
|
self.winit_window
|
||||||
Some(self.primary_monitor.clone())
|
.set_fullscreen(
|
||||||
} else {
|
if state {
|
||||||
None
|
Some(winit::window::Fullscreen::Borderless(Some(self.primary_monitor.clone())))
|
||||||
});
|
} else { None }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
self.fullscreen.set(state);
|
self.fullscreen.set(state);
|
||||||
}
|
}
|
||||||
|
@ -369,68 +363,68 @@ impl WindowPortsMethods for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_cursor(&self, cursor: Cursor) {
|
fn set_cursor(&self, cursor: Cursor) {
|
||||||
use winit::MouseCursor;
|
use winit::window::CursorIcon;
|
||||||
|
|
||||||
let winit_cursor = match cursor {
|
let winit_cursor = match cursor {
|
||||||
Cursor::Default => MouseCursor::Default,
|
Cursor::Default => CursorIcon::Default,
|
||||||
Cursor::Pointer => MouseCursor::Hand,
|
Cursor::Pointer => CursorIcon::Hand,
|
||||||
Cursor::ContextMenu => MouseCursor::ContextMenu,
|
Cursor::ContextMenu => CursorIcon::ContextMenu,
|
||||||
Cursor::Help => MouseCursor::Help,
|
Cursor::Help => CursorIcon::Help,
|
||||||
Cursor::Progress => MouseCursor::Progress,
|
Cursor::Progress => CursorIcon::Progress,
|
||||||
Cursor::Wait => MouseCursor::Wait,
|
Cursor::Wait => CursorIcon::Wait,
|
||||||
Cursor::Cell => MouseCursor::Cell,
|
Cursor::Cell => CursorIcon::Cell,
|
||||||
Cursor::Crosshair => MouseCursor::Crosshair,
|
Cursor::Crosshair => CursorIcon::Crosshair,
|
||||||
Cursor::Text => MouseCursor::Text,
|
Cursor::Text => CursorIcon::Text,
|
||||||
Cursor::VerticalText => MouseCursor::VerticalText,
|
Cursor::VerticalText => CursorIcon::VerticalText,
|
||||||
Cursor::Alias => MouseCursor::Alias,
|
Cursor::Alias => CursorIcon::Alias,
|
||||||
Cursor::Copy => MouseCursor::Copy,
|
Cursor::Copy => CursorIcon::Copy,
|
||||||
Cursor::Move => MouseCursor::Move,
|
Cursor::Move => CursorIcon::Move,
|
||||||
Cursor::NoDrop => MouseCursor::NoDrop,
|
Cursor::NoDrop => CursorIcon::NoDrop,
|
||||||
Cursor::NotAllowed => MouseCursor::NotAllowed,
|
Cursor::NotAllowed => CursorIcon::NotAllowed,
|
||||||
Cursor::Grab => MouseCursor::Grab,
|
Cursor::Grab => CursorIcon::Grab,
|
||||||
Cursor::Grabbing => MouseCursor::Grabbing,
|
Cursor::Grabbing => CursorIcon::Grabbing,
|
||||||
Cursor::EResize => MouseCursor::EResize,
|
Cursor::EResize => CursorIcon::EResize,
|
||||||
Cursor::NResize => MouseCursor::NResize,
|
Cursor::NResize => CursorIcon::NResize,
|
||||||
Cursor::NeResize => MouseCursor::NeResize,
|
Cursor::NeResize => CursorIcon::NeResize,
|
||||||
Cursor::NwResize => MouseCursor::NwResize,
|
Cursor::NwResize => CursorIcon::NwResize,
|
||||||
Cursor::SResize => MouseCursor::SResize,
|
Cursor::SResize => CursorIcon::SResize,
|
||||||
Cursor::SeResize => MouseCursor::SeResize,
|
Cursor::SeResize => CursorIcon::SeResize,
|
||||||
Cursor::SwResize => MouseCursor::SwResize,
|
Cursor::SwResize => CursorIcon::SwResize,
|
||||||
Cursor::WResize => MouseCursor::WResize,
|
Cursor::WResize => CursorIcon::WResize,
|
||||||
Cursor::EwResize => MouseCursor::EwResize,
|
Cursor::EwResize => CursorIcon::EwResize,
|
||||||
Cursor::NsResize => MouseCursor::NsResize,
|
Cursor::NsResize => CursorIcon::NsResize,
|
||||||
Cursor::NeswResize => MouseCursor::NeswResize,
|
Cursor::NeswResize => CursorIcon::NeswResize,
|
||||||
Cursor::NwseResize => MouseCursor::NwseResize,
|
Cursor::NwseResize => CursorIcon::NwseResize,
|
||||||
Cursor::ColResize => MouseCursor::ColResize,
|
Cursor::ColResize => CursorIcon::ColResize,
|
||||||
Cursor::RowResize => MouseCursor::RowResize,
|
Cursor::RowResize => CursorIcon::RowResize,
|
||||||
Cursor::AllScroll => MouseCursor::AllScroll,
|
Cursor::AllScroll => CursorIcon::AllScroll,
|
||||||
Cursor::ZoomIn => MouseCursor::ZoomIn,
|
Cursor::ZoomIn => CursorIcon::ZoomIn,
|
||||||
Cursor::ZoomOut => MouseCursor::ZoomOut,
|
Cursor::ZoomOut => CursorIcon::ZoomOut,
|
||||||
_ => MouseCursor::Default,
|
_ => CursorIcon::Default,
|
||||||
};
|
};
|
||||||
self.winit_window.set_cursor(winit_cursor);
|
self.winit_window.set_cursor_icon(winit_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_animating(&self) -> bool {
|
fn is_animating(&self) -> bool {
|
||||||
self.animation_state.get() == AnimationState::Animating
|
self.animation_state.get() == AnimationState::Animating
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id(&self) -> winit::WindowId {
|
fn id(&self) -> winit::window::WindowId {
|
||||||
self.winit_window.id()
|
self.winit_window.id()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn winit_event_to_servo_event(&self, event: winit::WindowEvent) {
|
fn winit_event_to_servo_event(&self, event: winit::event::WindowEvent) {
|
||||||
match event {
|
match event {
|
||||||
winit::WindowEvent::ReceivedCharacter(ch) => self.handle_received_character(ch),
|
winit::event::WindowEvent::ReceivedCharacter(ch) => self.handle_received_character(ch),
|
||||||
winit::WindowEvent::KeyboardInput { input, .. } => self.handle_keyboard_input(input),
|
winit::event::WindowEvent::KeyboardInput { input, .. } => self.handle_keyboard_input(input),
|
||||||
winit::WindowEvent::MouseInput { state, button, .. } => {
|
winit::event::WindowEvent::ModifiersChanged(state) => self.modifiers_state.set(state),
|
||||||
|
winit::event::WindowEvent::MouseInput { state, button, .. } => {
|
||||||
if button == MouseButton::Left || button == MouseButton::Right {
|
if button == MouseButton::Left || button == MouseButton::Right {
|
||||||
self.handle_mouse(button, state, self.mouse_pos.get());
|
self.handle_mouse(button, state, self.mouse_pos.get());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
winit::WindowEvent::CursorMoved { position, .. } => {
|
winit::event::WindowEvent::CursorMoved { position, .. } => {
|
||||||
let pos = position.to_physical(self.device_hidpi_factor().get() as f64);
|
let (x, y): (i32, i32) = position.into();
|
||||||
let (x, y): (i32, i32) = pos.into();
|
|
||||||
self.mouse_pos.set(Point2D::new(x, y));
|
self.mouse_pos.set(Point2D::new(x, y));
|
||||||
self.event_queue
|
self.event_queue
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -438,15 +432,15 @@ impl WindowPortsMethods for Window {
|
||||||
x as f32, y as f32,
|
x as f32, y as f32,
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
winit::WindowEvent::MouseWheel { delta, phase, .. } => {
|
winit::event::WindowEvent::MouseWheel { delta, phase, .. } => {
|
||||||
let (mut dx, mut dy, mode) = match delta {
|
let (mut dx, mut dy, mode) = match delta {
|
||||||
MouseScrollDelta::LineDelta(dx, dy) => {
|
MouseScrollDelta::LineDelta(dx, dy) => {
|
||||||
(dx as f64, (dy * LINE_HEIGHT) as f64, WheelMode::DeltaLine)
|
(dx as f64, (dy * LINE_HEIGHT) as f64, WheelMode::DeltaLine)
|
||||||
},
|
},
|
||||||
MouseScrollDelta::PixelDelta(position) => {
|
MouseScrollDelta::PixelDelta(position) => {
|
||||||
let position =
|
let position: LogicalPosition<f64> =
|
||||||
position.to_physical(self.device_hidpi_factor().get() as f64);
|
position.to_logical(self.device_hidpi_factor().get() as f64);
|
||||||
(position.x as f64, position.y as f64, WheelMode::DeltaPixel)
|
(position.x, position.y, WheelMode::DeltaPixel)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -478,30 +472,24 @@ impl WindowPortsMethods for Window {
|
||||||
self.event_queue.borrow_mut().push(wheel_event);
|
self.event_queue.borrow_mut().push(wheel_event);
|
||||||
self.event_queue.borrow_mut().push(scroll_event);
|
self.event_queue.borrow_mut().push(scroll_event);
|
||||||
},
|
},
|
||||||
winit::WindowEvent::Touch(touch) => {
|
winit::event::WindowEvent::Touch(touch) => {
|
||||||
use servo::script_traits::TouchId;
|
use servo::script_traits::TouchId;
|
||||||
|
|
||||||
let phase = winit_phase_to_touch_event_type(touch.phase);
|
let phase = winit_phase_to_touch_event_type(touch.phase);
|
||||||
let id = TouchId(touch.id as i32);
|
let id = TouchId(touch.id as i32);
|
||||||
let position = touch
|
let position = touch.location;
|
||||||
.location
|
|
||||||
.to_physical(self.device_hidpi_factor().get() as f64);
|
|
||||||
let point = Point2D::new(position.x as f32, position.y as f32);
|
let point = Point2D::new(position.x as f32, position.y as f32);
|
||||||
self.event_queue
|
self.event_queue
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.push(WindowEvent::Touch(phase, id, point));
|
.push(WindowEvent::Touch(phase, id, point));
|
||||||
},
|
},
|
||||||
winit::WindowEvent::Refresh => {
|
winit::event::WindowEvent::CloseRequested => {
|
||||||
self.event_queue.borrow_mut().push(WindowEvent::Refresh);
|
|
||||||
},
|
|
||||||
winit::WindowEvent::CloseRequested => {
|
|
||||||
self.event_queue.borrow_mut().push(WindowEvent::Quit);
|
self.event_queue.borrow_mut().push(WindowEvent::Quit);
|
||||||
},
|
},
|
||||||
winit::WindowEvent::Resized(size) => {
|
winit::event::WindowEvent::Resized(physical_size) => {
|
||||||
let (width, height) = size.into();
|
let (width, height) = physical_size.into();
|
||||||
let new_size = Size2D::new(width, height);
|
let new_size = Size2D::new(width, height);
|
||||||
if self.inner_size.get() != new_size {
|
if self.inner_size.get() != new_size {
|
||||||
let physical_size = size.to_physical(self.device_hidpi_factor().get() as f64);
|
|
||||||
let physical_size = Size2D::new(physical_size.width, physical_size.height);
|
let physical_size = Size2D::new(physical_size.width, physical_size.height);
|
||||||
self.webrender_surfman
|
self.webrender_surfman
|
||||||
.resize(physical_size.to_i32())
|
.resize(physical_size.to_i32())
|
||||||
|
@ -514,21 +502,20 @@ impl WindowPortsMethods for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_glwindow(&self, events_loop: &EventsLoop) -> Box<dyn webxr::glwindow::GlWindow> {
|
fn new_glwindow(
|
||||||
let size = self
|
&self,
|
||||||
.winit_window
|
event_loop: &winit::event_loop::EventLoopWindowTarget<ServoEvent>
|
||||||
.get_outer_size()
|
) -> Box<dyn webxr::glwindow::GlWindow> {
|
||||||
.expect("Failed to get window outer size");
|
let size = self.winit_window.outer_size();
|
||||||
|
|
||||||
let mut window_builder = winit::WindowBuilder::new()
|
let mut window_builder = winit::window::WindowBuilder::new()
|
||||||
.with_title("Servo XR".to_string())
|
.with_title("Servo XR".to_string())
|
||||||
.with_dimensions(size)
|
.with_inner_size(size)
|
||||||
.with_visibility(true);
|
.with_visible(true);
|
||||||
|
|
||||||
window_builder = builder_with_platform_options(window_builder);
|
window_builder = builder_with_platform_options(window_builder);
|
||||||
|
|
||||||
let winit_window = window_builder
|
let winit_window = window_builder.build(event_loop)
|
||||||
.build(events_loop.as_winit())
|
|
||||||
.expect("Failed to create window.");
|
.expect("Failed to create window.");
|
||||||
|
|
||||||
let pose = Rc::new(XRWindowPose {
|
let pose = Rc::new(XRWindowPose {
|
||||||
|
@ -542,24 +529,23 @@ impl WindowPortsMethods for Window {
|
||||||
|
|
||||||
impl WindowMethods for Window {
|
impl WindowMethods for Window {
|
||||||
fn get_coordinates(&self) -> EmbedderCoordinates {
|
fn get_coordinates(&self) -> EmbedderCoordinates {
|
||||||
// TODO(ajeffrey): can this fail?
|
// Needed to convince the type system that winit's physical pixels
|
||||||
let dpr = self.device_hidpi_factor();
|
// are actually device pixels.
|
||||||
let LogicalSize { width, height } = self
|
let dpr: Scale<f32, DeviceIndependentPixel, DevicePixel> = Scale::new(1.0);
|
||||||
|
let PhysicalSize { width, height } = self
|
||||||
.winit_window
|
.winit_window
|
||||||
.get_outer_size()
|
.outer_size();
|
||||||
.expect("Failed to get window outer size.");
|
let PhysicalPosition { x, y } = self
|
||||||
let LogicalPosition { x, y } = self
|
|
||||||
.winit_window
|
.winit_window
|
||||||
.get_position()
|
.outer_position()
|
||||||
.unwrap_or(LogicalPosition::new(0., 0.));
|
.unwrap_or(PhysicalPosition::new(0, 0));
|
||||||
let win_size = (Size2D::new(width as f32, height as f32) * dpr).to_i32();
|
let win_size = (Size2D::new(width as f32, height as f32) * dpr).to_i32();
|
||||||
let win_origin = (Point2D::new(x as f32, y as f32) * dpr).to_i32();
|
let win_origin = (Point2D::new(x as f32, y as f32) * dpr).to_i32();
|
||||||
let screen = (self.screen_size.to_f32() * dpr).to_i32();
|
let screen = (self.screen_size.to_f32() * dpr).to_i32();
|
||||||
|
|
||||||
let LogicalSize { width, height } = self
|
let PhysicalSize { width, height } = self
|
||||||
.winit_window
|
.winit_window
|
||||||
.get_inner_size()
|
.inner_size();
|
||||||
.expect("Failed to get window inner size.");
|
|
||||||
let inner_size = (Size2D::new(width as f32, height as f32) * dpr).to_i32();
|
let inner_size = (Size2D::new(width as f32, height as f32) * dpr).to_i32();
|
||||||
let viewport = DeviceIntRect::new(Point2D::zero(), inner_size);
|
let viewport = DeviceIntRect::new(Point2D::zero(), inner_size);
|
||||||
let framebuffer = DeviceIntSize::from_untyped(viewport.size.to_untyped());
|
let framebuffer = DeviceIntSize::from_untyped(viewport.size.to_untyped());
|
||||||
|
@ -684,7 +670,7 @@ fn load_icon(icon_bytes: &[u8]) -> Icon {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XRWindow {
|
struct XRWindow {
|
||||||
winit_window: winit::Window,
|
winit_window: winit::window::Window,
|
||||||
pose: Rc<XRWindowPose>,
|
pose: Rc<XRWindowPose>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,8 +743,8 @@ impl XRWindowPose {
|
||||||
self.xr_translation.set(vec);
|
self.xr_translation.set(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_xr_rotation(&self, input: &KeyboardInput) {
|
fn handle_xr_rotation(&self, input: &KeyboardInput, modifiers: ModifiersState) {
|
||||||
if input.state != winit::ElementState::Pressed {
|
if input.state != winit::event::ElementState::Pressed {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut x = 0.0;
|
let mut x = 0.0;
|
||||||
|
@ -770,7 +756,7 @@ impl XRWindowPose {
|
||||||
Some(VirtualKeyCode::Right) => y = -1.0,
|
Some(VirtualKeyCode::Right) => y = -1.0,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
if input.modifiers.shift {
|
if modifiers.shift() {
|
||||||
x = 10.0 * x;
|
x = 10.0 * x;
|
||||||
y = 10.0 * y;
|
y = 10.0 * y;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//! A headless window implementation.
|
//! A headless window implementation.
|
||||||
|
|
||||||
use crate::events_loop::EventsLoop;
|
use crate::events_loop::ServoEvent;
|
||||||
use crate::window_trait::WindowPortsMethods;
|
use crate::window_trait::WindowPortsMethods;
|
||||||
use euclid::{Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D};
|
use euclid::{Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D};
|
||||||
use servo::compositing::windowing::{AnimationState, WindowEvent};
|
use servo::compositing::windowing::{AnimationState, WindowEvent};
|
||||||
|
@ -71,8 +71,8 @@ impl WindowPortsMethods for Window {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id(&self) -> winit::WindowId {
|
fn id(&self) -> winit::window::WindowId {
|
||||||
unsafe { winit::WindowId::dummy() }
|
unsafe { winit::window::WindowId::dummy() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn page_height(&self) -> f32 {
|
fn page_height(&self) -> f32 {
|
||||||
|
@ -98,11 +98,14 @@ impl WindowPortsMethods for Window {
|
||||||
self.animation_state.get() == AnimationState::Animating
|
self.animation_state.get() == AnimationState::Animating
|
||||||
}
|
}
|
||||||
|
|
||||||
fn winit_event_to_servo_event(&self, _event: winit::WindowEvent) {
|
fn winit_event_to_servo_event(&self, _event: winit::event::WindowEvent) {
|
||||||
// Not expecting any winit events.
|
// Not expecting any winit events.
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_glwindow(&self, _events_loop: &EventsLoop) -> Box<dyn webxr::glwindow::GlWindow> {
|
fn new_glwindow(
|
||||||
|
&self,
|
||||||
|
_events_loop: &winit::event_loop::EventLoopWindowTarget<ServoEvent>
|
||||||
|
) -> Box<dyn webxr::glwindow::GlWindow> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use winit::event::{ElementState, KeyboardInput, ModifiersState, VirtualKeyCode};
|
||||||
use keyboard_types::{Code, Key, KeyState, KeyboardEvent, Location, Modifiers};
|
use keyboard_types::{Code, Key, KeyState, KeyboardEvent, Location, Modifiers};
|
||||||
use winit::{ElementState, KeyboardInput, ModifiersState, VirtualKeyCode};
|
|
||||||
|
|
||||||
// Some shortcuts use Cmd on Mac and Control on other systems.
|
// Some shortcuts use Cmd on Mac and Control on other systems.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
@ -18,7 +18,7 @@ pub const CMD_OR_ALT: Modifiers = Modifiers::META;
|
||||||
pub const CMD_OR_ALT: Modifiers = Modifiers::ALT;
|
pub const CMD_OR_ALT: Modifiers = Modifiers::ALT;
|
||||||
|
|
||||||
fn get_servo_key_from_winit_key(key: Option<VirtualKeyCode>) -> Key {
|
fn get_servo_key_from_winit_key(key: Option<VirtualKeyCode>) -> Key {
|
||||||
use winit::VirtualKeyCode::*;
|
use winit::event::VirtualKeyCode::*;
|
||||||
// TODO: figure out how to map NavigateForward, NavigateBackward
|
// TODO: figure out how to map NavigateForward, NavigateBackward
|
||||||
// TODO: map the remaining keys if possible
|
// TODO: map the remaining keys if possible
|
||||||
let key = if let Some(key) = key {
|
let key = if let Some(key) = key {
|
||||||
|
@ -127,7 +127,7 @@ fn get_servo_key_from_winit_key(key: Option<VirtualKeyCode>) -> Key {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_servo_location_from_winit_key(key: Option<VirtualKeyCode>) -> Location {
|
fn get_servo_location_from_winit_key(key: Option<VirtualKeyCode>) -> Location {
|
||||||
use winit::VirtualKeyCode::*;
|
use winit::event::VirtualKeyCode::*;
|
||||||
// TODO: add more numpad keys
|
// TODO: add more numpad keys
|
||||||
let key = if let Some(key) = key {
|
let key = if let Some(key) = key {
|
||||||
key
|
key
|
||||||
|
@ -243,14 +243,14 @@ fn get_servo_code_from_scancode(_scancode: u32) -> Code {
|
||||||
|
|
||||||
fn get_modifiers(mods: ModifiersState) -> Modifiers {
|
fn get_modifiers(mods: ModifiersState) -> Modifiers {
|
||||||
let mut modifiers = Modifiers::empty();
|
let mut modifiers = Modifiers::empty();
|
||||||
modifiers.set(Modifiers::CONTROL, mods.ctrl);
|
modifiers.set(Modifiers::CONTROL, mods.ctrl());
|
||||||
modifiers.set(Modifiers::SHIFT, mods.shift);
|
modifiers.set(Modifiers::SHIFT, mods.shift());
|
||||||
modifiers.set(Modifiers::ALT, mods.alt);
|
modifiers.set(Modifiers::ALT, mods.alt());
|
||||||
modifiers.set(Modifiers::META, mods.logo);
|
modifiers.set(Modifiers::META, mods.logo());
|
||||||
modifiers
|
modifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keyboard_event_from_winit(input: KeyboardInput) -> KeyboardEvent {
|
pub fn keyboard_event_from_winit(input: KeyboardInput, state: ModifiersState) -> KeyboardEvent {
|
||||||
info!("winit keyboard input: {:?}", input);
|
info!("winit keyboard input: {:?}", input);
|
||||||
KeyboardEvent {
|
KeyboardEvent {
|
||||||
state: match input.state {
|
state: match input.state {
|
||||||
|
@ -260,7 +260,7 @@ pub fn keyboard_event_from_winit(input: KeyboardInput) -> KeyboardEvent {
|
||||||
key: get_servo_key_from_winit_key(input.virtual_keycode),
|
key: get_servo_key_from_winit_key(input.virtual_keycode),
|
||||||
code: get_servo_code_from_scancode(input.scancode),
|
code: get_servo_code_from_scancode(input.scancode),
|
||||||
location: get_servo_location_from_winit_key(input.virtual_keycode),
|
location: get_servo_location_from_winit_key(input.virtual_keycode),
|
||||||
modifiers: get_modifiers(input.modifiers),
|
modifiers: get_modifiers(state),
|
||||||
repeat: false,
|
repeat: false,
|
||||||
is_composing: false,
|
is_composing: false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//! Definition of Window.
|
//! Definition of Window.
|
||||||
//! Implemented by headless and headed windows.
|
//! Implemented by headless and headed windows.
|
||||||
|
|
||||||
use crate::events_loop::EventsLoop;
|
use crate::events_loop::ServoEvent;
|
||||||
use servo::compositing::windowing::{WindowEvent, WindowMethods};
|
use servo::compositing::windowing::{WindowEvent, WindowMethods};
|
||||||
use servo::embedder_traits::Cursor;
|
use servo::embedder_traits::Cursor;
|
||||||
use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize};
|
use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize};
|
||||||
|
@ -16,16 +16,19 @@ pub const LINE_HEIGHT: f32 = 38.0;
|
||||||
|
|
||||||
pub trait WindowPortsMethods: WindowMethods {
|
pub trait WindowPortsMethods: WindowMethods {
|
||||||
fn get_events(&self) -> Vec<WindowEvent>;
|
fn get_events(&self) -> Vec<WindowEvent>;
|
||||||
fn id(&self) -> winit::WindowId;
|
fn id(&self) -> winit::window::WindowId;
|
||||||
fn has_events(&self) -> bool;
|
fn has_events(&self) -> bool;
|
||||||
fn page_height(&self) -> f32;
|
fn page_height(&self) -> f32;
|
||||||
fn get_fullscreen(&self) -> bool;
|
fn get_fullscreen(&self) -> bool;
|
||||||
fn winit_event_to_servo_event(&self, event: winit::WindowEvent);
|
fn winit_event_to_servo_event(&self, event: winit::event::WindowEvent);
|
||||||
fn is_animating(&self) -> bool;
|
fn is_animating(&self) -> bool;
|
||||||
fn set_title(&self, _title: &str) {}
|
fn set_title(&self, _title: &str) {}
|
||||||
fn set_inner_size(&self, _size: DeviceIntSize) {}
|
fn set_inner_size(&self, _size: DeviceIntSize) {}
|
||||||
fn set_position(&self, _point: DeviceIntPoint) {}
|
fn set_position(&self, _point: DeviceIntPoint) {}
|
||||||
fn set_fullscreen(&self, _state: bool) {}
|
fn set_fullscreen(&self, _state: bool) {}
|
||||||
fn set_cursor(&self, _cursor: Cursor) {}
|
fn set_cursor(&self, _cursor: Cursor) {}
|
||||||
fn new_glwindow(&self, events_loop: &EventsLoop) -> Box<dyn webxr::glwindow::GlWindow>;
|
fn new_glwindow(
|
||||||
|
&self,
|
||||||
|
events_loop: &winit::event_loop::EventLoopWindowTarget<ServoEvent>
|
||||||
|
) -> Box<dyn webxr::glwindow::GlWindow>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,17 +67,18 @@ packages = [
|
||||||
# Lots of crates to update.
|
# Lots of crates to update.
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
|
||||||
# https://github.com/servo/servo/issues/24421
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-xid",
|
|
||||||
|
|
||||||
# https://github.com/servo/servo/pull/25518
|
# https://github.com/servo/servo/pull/25518
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"core-graphics",
|
"core-graphics",
|
||||||
"lyon_geom",
|
"lyon_geom",
|
||||||
|
|
||||||
|
# https://github.com/servo/servo/pull/28236
|
||||||
|
"dlib",
|
||||||
|
"nix",
|
||||||
|
"nom",
|
||||||
|
"strsim",
|
||||||
|
|
||||||
# Duplicated by webrender debugger via ws
|
# Duplicated by webrender debugger via ws
|
||||||
"digest",
|
"digest",
|
||||||
"generic-array",
|
"generic-array",
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flexible-order.html]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue