mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
auto merge of #4583 : glennw/servo/cef-tabs, r=pcwalton
This commit is contained in:
commit
9b6d979f19
4 changed files with 170 additions and 149 deletions
|
@ -3,9 +3,8 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use browser_host::{ServoCefBrowserHost, ServoCefBrowserHostExtensions};
|
use browser_host::{ServoCefBrowserHost, ServoCefBrowserHostExtensions};
|
||||||
use core::{mod, ServoCefGlobals, globals};
|
|
||||||
use eutil::Downcast;
|
use eutil::Downcast;
|
||||||
use frame::ServoCefFrame;
|
use frame::{ServoCefFrame, ServoCefFrameExtensions};
|
||||||
use interfaces::{CefBrowser, CefBrowserHost, CefClient, CefFrame, CefRequestContext};
|
use interfaces::{CefBrowser, CefBrowserHost, CefClient, CefFrame, CefRequestContext};
|
||||||
use interfaces::{cef_browser_t, cef_browser_host_t, cef_client_t, cef_frame_t};
|
use interfaces::{cef_browser_t, cef_browser_host_t, cef_client_t, cef_frame_t};
|
||||||
use interfaces::{cef_request_context_t};
|
use interfaces::{cef_request_context_t};
|
||||||
|
@ -19,18 +18,52 @@ use libc::c_int;
|
||||||
use servo_util::opts;
|
use servo_util::opts;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
|
||||||
|
thread_local!(pub static BROWSERS: RefCell<Vec<CefBrowser>> = RefCell::new(vec!()))
|
||||||
|
|
||||||
|
pub enum ServoBrowser {
|
||||||
|
Invalid,
|
||||||
|
OnScreen(Browser<glfw_app::window::Window>),
|
||||||
|
OffScreen(Browser<window::Window>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServoBrowser {
|
||||||
|
fn handle_event(&mut self, event: WindowEvent) {
|
||||||
|
match *self {
|
||||||
|
ServoBrowser::OnScreen(ref mut browser) => { browser.handle_event(event); }
|
||||||
|
ServoBrowser::OffScreen(ref mut browser) => { browser.handle_event(event); }
|
||||||
|
ServoBrowser::Invalid => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_title_for_main_frame(&self) {
|
||||||
|
match *self {
|
||||||
|
ServoBrowser::OnScreen(ref browser) => browser.get_title_for_main_frame(),
|
||||||
|
ServoBrowser::OffScreen(ref browser) => browser.get_title_for_main_frame(),
|
||||||
|
ServoBrowser::Invalid => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pinch_zoom_level(&self) -> f32 {
|
||||||
|
match *self {
|
||||||
|
ServoBrowser::OnScreen(ref browser) => browser.pinch_zoom_level(),
|
||||||
|
ServoBrowser::OffScreen(ref browser) => browser.pinch_zoom_level(),
|
||||||
|
ServoBrowser::Invalid => 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cef_class_impl! {
|
cef_class_impl! {
|
||||||
ServoCefBrowser : CefBrowser, cef_browser_t {
|
ServoCefBrowser : CefBrowser, cef_browser_t {
|
||||||
fn get_host(&this) -> *mut cef_browser_host_t {
|
fn get_host(&this) -> *mut cef_browser_host_t {
|
||||||
this.downcast().host.clone()
|
this.downcast().host.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn go_back(&_this) -> () {
|
fn go_back(&this) -> () {
|
||||||
core::send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Back));
|
this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Back));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn go_forward(&_this) -> () {
|
fn go_forward(&this) -> () {
|
||||||
core::send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Forward));
|
this.send_window_event(WindowEvent::Navigation(WindowNavigateMsg::Forward));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the main (top-level) frame for the browser window.
|
// Returns the main (top-level) frame for the browser window.
|
||||||
|
@ -49,53 +82,93 @@ pub struct ServoCefBrowser {
|
||||||
pub client: CefClient,
|
pub client: CefClient,
|
||||||
/// Whether the on-created callback has fired yet.
|
/// Whether the on-created callback has fired yet.
|
||||||
pub callback_executed: Cell<bool>,
|
pub callback_executed: Cell<bool>,
|
||||||
|
|
||||||
|
servo_browser: RefCell<ServoBrowser>,
|
||||||
|
message_queue: RefCell<Vec<WindowEvent>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServoCefBrowser {
|
impl ServoCefBrowser {
|
||||||
pub fn new(window_info: &cef_window_info_t, client: CefClient) -> ServoCefBrowser {
|
pub fn new(window_info: &cef_window_info_t, client: CefClient) -> ServoCefBrowser {
|
||||||
let frame = ServoCefFrame::new().as_cef_interface();
|
let frame = ServoCefFrame::new().as_cef_interface();
|
||||||
let host = ServoCefBrowserHost::new(client.clone()).as_cef_interface();
|
let host = ServoCefBrowserHost::new(client.clone()).as_cef_interface();
|
||||||
if window_info.windowless_rendering_enabled == 0 {
|
|
||||||
globals.with(|ref r| {
|
let servo_browser = if window_info.windowless_rendering_enabled == 0 {
|
||||||
let glfw_window = glfw_app::create_window();
|
let glfw_window = glfw_app::create_window();
|
||||||
*r.borrow_mut() = Some(ServoCefGlobals::OnScreenGlobals(
|
let servo_browser = Browser::new(Some(glfw_window.clone()));
|
||||||
RefCell::new(glfw_window.clone()),
|
ServoBrowser::OnScreen(servo_browser)
|
||||||
RefCell::new(Browser::new(Some(glfw_window)))));
|
} else {
|
||||||
});
|
ServoBrowser::Invalid
|
||||||
}
|
};
|
||||||
|
|
||||||
ServoCefBrowser {
|
ServoCefBrowser {
|
||||||
frame: frame,
|
frame: frame,
|
||||||
host: host,
|
host: host,
|
||||||
client: client,
|
client: client,
|
||||||
callback_executed: Cell::new(false),
|
callback_executed: Cell::new(false),
|
||||||
|
servo_browser: RefCell::new(servo_browser),
|
||||||
|
message_queue: RefCell::new(vec!()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ServoCefBrowserExtensions {
|
pub trait ServoCefBrowserExtensions {
|
||||||
fn init(&self, window_info: &cef_window_info_t);
|
fn init(&self, window_info: &cef_window_info_t);
|
||||||
|
fn send_window_event(&self, event: WindowEvent);
|
||||||
|
fn get_title_for_main_frame(&self);
|
||||||
|
fn pinch_zoom_level(&self) -> f32;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServoCefBrowserExtensions for CefBrowser {
|
impl ServoCefBrowserExtensions for CefBrowser {
|
||||||
fn init(&self, window_info: &cef_window_info_t) {
|
fn init(&self, window_info: &cef_window_info_t) {
|
||||||
if window_info.windowless_rendering_enabled != 0 {
|
if window_info.windowless_rendering_enabled != 0 {
|
||||||
globals.with(|ref r| {
|
|
||||||
let window = window::Window::new();
|
let window = window::Window::new();
|
||||||
let servo_browser = Browser::new(Some(window.clone()));
|
let servo_browser = Browser::new(Some(window.clone()));
|
||||||
window.set_browser(self.clone());
|
window.set_browser(self.clone());
|
||||||
|
*self.downcast().servo_browser.borrow_mut() = ServoBrowser::OffScreen(servo_browser);
|
||||||
*r.borrow_mut() = Some(ServoCefGlobals::OffScreenGlobals(
|
|
||||||
RefCell::new(window),
|
|
||||||
RefCell::new(servo_browser)));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.downcast().host.set_browser((*self).clone());
|
self.downcast().host.set_browser((*self).clone());
|
||||||
|
self.downcast().frame.set_browser((*self).clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_window_event(&self, event: WindowEvent) {
|
||||||
|
self.downcast().message_queue.borrow_mut().push(event);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match self.downcast().servo_browser.try_borrow_mut() {
|
||||||
|
None => {
|
||||||
|
// We're trying to send an event while processing another one. This will
|
||||||
|
// cause general badness, so queue up that event instead of immediately
|
||||||
|
// processing it.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
Some(ref mut browser) => {
|
||||||
|
let event = match self.downcast().message_queue.borrow_mut().pop() {
|
||||||
|
None => return,
|
||||||
|
Some(event) => event,
|
||||||
|
};
|
||||||
|
browser.handle_event(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_title_for_main_frame(&self) {
|
||||||
|
self.downcast().servo_browser.borrow().get_title_for_main_frame()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pinch_zoom_level(&self) -> f32 {
|
||||||
|
self.downcast().servo_browser.borrow().pinch_zoom_level()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local!(pub static GLOBAL_BROWSERS: RefCell<Vec<CefBrowser>> = RefCell::new(vec!()))
|
pub fn update() {
|
||||||
|
BROWSERS.with(|browsers| {
|
||||||
|
for browser in browsers.borrow().iter() {
|
||||||
|
browser.send_window_event(WindowEvent::Idle);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn browser_callback_after_created(browser: CefBrowser) {
|
pub fn browser_callback_after_created(browser: CefBrowser) {
|
||||||
if browser.downcast().client.is_null_cef_object() {
|
if browser.downcast().client.is_null_cef_object() {
|
||||||
|
@ -122,7 +195,9 @@ fn browser_host_create(window_info: &cef_window_info_t,
|
||||||
if callback_executed {
|
if callback_executed {
|
||||||
browser_callback_after_created(browser.clone());
|
browser_callback_after_created(browser.clone());
|
||||||
}
|
}
|
||||||
GLOBAL_BROWSERS.with(|ref r| r.borrow_mut().push(browser.clone()));
|
BROWSERS.with(|browsers| {
|
||||||
|
browsers.borrow_mut().push(browser.clone());
|
||||||
|
});
|
||||||
browser
|
browser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
* 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 http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use core;
|
|
||||||
use eutil::Downcast;
|
use eutil::Downcast;
|
||||||
use interfaces::{CefBrowser, CefBrowserHost, CefClient, cef_browser_host_t, cef_client_t};
|
use interfaces::{CefBrowser, CefBrowserHost, CefClient, cef_browser_host_t, cef_client_t};
|
||||||
use types::{cef_mouse_button_type_t, cef_mouse_event, cef_rect_t, cef_key_event};
|
use types::{cef_mouse_button_type_t, cef_mouse_event, cef_rect_t, cef_key_event};
|
||||||
use types::cef_key_event_type_t::{KEYEVENT_CHAR, KEYEVENT_KEYDOWN, KEYEVENT_KEYUP, KEYEVENT_RAWKEYDOWN};
|
use types::cef_key_event_type_t::{KEYEVENT_CHAR, KEYEVENT_KEYDOWN, KEYEVENT_KEYUP, KEYEVENT_RAWKEYDOWN};
|
||||||
|
use browser::ServoCefBrowserExtensions;
|
||||||
|
|
||||||
use compositing::windowing::{WindowEvent, MouseWindowEvent};
|
use compositing::windowing::{WindowEvent, MouseWindowEvent};
|
||||||
use geom::point::TypedPoint2D;
|
use geom::point::TypedPoint2D;
|
||||||
|
@ -34,11 +34,20 @@ cef_class_impl! {
|
||||||
.get_render_handler()
|
.get_render_handler()
|
||||||
.get_backing_rect(this.downcast().browser.borrow().clone().unwrap(), &mut rect);
|
.get_backing_rect(this.downcast().browser.borrow().clone().unwrap(), &mut rect);
|
||||||
let size = TypedSize2D(rect.width as uint, rect.height as uint);
|
let size = TypedSize2D(rect.width as uint, rect.height as uint);
|
||||||
core::send_window_event(WindowEvent::Resize(size));
|
this.downcast().send_window_event(WindowEvent::Resize(size));
|
||||||
core::repaint_synchronously();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_key_event(&_this, event: *const cef_key_event) -> () {
|
fn close_browser(&_this, _force: c_int) -> () {
|
||||||
|
// TODO: Clean shutdown.
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_focus_event(&this, focus: c_int) -> () {
|
||||||
|
if focus != 0 {
|
||||||
|
this.downcast().send_window_event(WindowEvent::Refresh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_key_event(&this, event: *const cef_key_event) -> () {
|
||||||
// FIXME(pcwalton): So awful. But it's nearly midnight here and I have to get
|
// FIXME(pcwalton): So awful. But it's nearly midnight here and I have to get
|
||||||
// Google working.
|
// Google working.
|
||||||
let event: &cef_key_event = event;
|
let event: &cef_key_event = event;
|
||||||
|
@ -88,10 +97,10 @@ cef_class_impl! {
|
||||||
KEYEVENT_KEYUP => KeyState::Released,
|
KEYEVENT_KEYUP => KeyState::Released,
|
||||||
};
|
};
|
||||||
let key_modifiers = KeyModifiers::empty(); // TODO(pcwalton)
|
let key_modifiers = KeyModifiers::empty(); // TODO(pcwalton)
|
||||||
core::send_window_event(WindowEvent::KeyEvent(key, key_state, key_modifiers))
|
this.downcast().send_window_event(WindowEvent::KeyEvent(key, key_state, key_modifiers))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_mouse_click_event(&_this,
|
fn send_mouse_click_event(&this,
|
||||||
event: *const cef_mouse_event,
|
event: *const cef_mouse_event,
|
||||||
mouse_button_type: cef_mouse_button_type_t,
|
mouse_button_type: cef_mouse_button_type_t,
|
||||||
mouse_up: c_int,
|
mouse_up: c_int,
|
||||||
|
@ -101,22 +110,22 @@ cef_class_impl! {
|
||||||
let button_type = mouse_button_type as uint;
|
let button_type = mouse_button_type as uint;
|
||||||
let point = TypedPoint2D((*event).x as f32, (*event).y as f32);
|
let point = TypedPoint2D((*event).x as f32, (*event).y as f32);
|
||||||
if mouse_up != 0 {
|
if mouse_up != 0 {
|
||||||
core::send_window_event(WindowEvent::MouseWindowEventClass(
|
this.downcast().send_window_event(WindowEvent::MouseWindowEventClass(
|
||||||
MouseWindowEvent::Click(button_type, point)))
|
MouseWindowEvent::Click(button_type, point)))
|
||||||
} else {
|
} else {
|
||||||
core::send_window_event(WindowEvent::MouseWindowEventClass(
|
this.downcast().send_window_event(WindowEvent::MouseWindowEventClass(
|
||||||
MouseWindowEvent::MouseUp(button_type, point)))
|
MouseWindowEvent::MouseUp(button_type, point)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_mouse_move_event(&_this, event: *const cef_mouse_event, _mouse_exited: c_int)
|
fn send_mouse_move_event(&this, event: *const cef_mouse_event, _mouse_exited: c_int)
|
||||||
-> () {
|
-> () {
|
||||||
let event: &cef_mouse_event = event;
|
let event: &cef_mouse_event = event;
|
||||||
let point = TypedPoint2D((*event).x as f32, (*event).y as f32);
|
let point = TypedPoint2D((*event).x as f32, (*event).y as f32);
|
||||||
core::send_window_event(WindowEvent::MouseWindowMoveEventClass(point))
|
this.downcast().send_window_event(WindowEvent::MouseWindowMoveEventClass(point))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_mouse_wheel_event(&_this,
|
fn send_mouse_wheel_event(&this,
|
||||||
event: *const cef_mouse_event,
|
event: *const cef_mouse_event,
|
||||||
delta_x: c_int,
|
delta_x: c_int,
|
||||||
delta_y: c_int)
|
delta_y: c_int)
|
||||||
|
@ -124,20 +133,20 @@ cef_class_impl! {
|
||||||
let event: &cef_mouse_event = event;
|
let event: &cef_mouse_event = event;
|
||||||
let delta = TypedPoint2D(delta_x as f32, delta_y as f32);
|
let delta = TypedPoint2D(delta_x as f32, delta_y as f32);
|
||||||
let origin = TypedPoint2D((*event).x as i32, (*event).y as i32);
|
let origin = TypedPoint2D((*event).x as i32, (*event).y as i32);
|
||||||
core::send_window_event(WindowEvent::Scroll(delta, origin))
|
this.downcast().send_window_event(WindowEvent::Scroll(delta, origin))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_zoom_level(&_this) -> c_double {
|
fn get_zoom_level(&this) -> c_double {
|
||||||
core::pinch_zoom_level() as c_double
|
this.downcast().pinch_zoom_level() as c_double
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_zoom_level(&this, new_zoom_level: c_double) -> () {
|
fn set_zoom_level(&this, new_zoom_level: c_double) -> () {
|
||||||
let old_zoom_level = this.get_zoom_level();
|
let old_zoom_level = this.get_zoom_level();
|
||||||
core::send_window_event(WindowEvent::PinchZoom((new_zoom_level / old_zoom_level) as f32))
|
this.downcast().send_window_event(WindowEvent::PinchZoom((new_zoom_level / old_zoom_level) as f32))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_compositing(&_this) -> () {
|
fn initialize_compositing(&this) -> () {
|
||||||
core::send_window_event(WindowEvent::InitializeCompositing);
|
this.downcast().send_window_event(WindowEvent::InitializeCompositing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,6 +158,14 @@ impl ServoCefBrowserHost {
|
||||||
client: client,
|
client: client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_window_event(&self, event: WindowEvent) {
|
||||||
|
self.browser.borrow_mut().as_mut().unwrap().send_window_event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pinch_zoom_level(&self) -> f32 {
|
||||||
|
self.browser.borrow_mut().as_mut().unwrap().pinch_zoom_level()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ServoCefBrowserHostExtensions {
|
pub trait ServoCefBrowserHostExtensions {
|
||||||
|
|
|
@ -5,36 +5,22 @@
|
||||||
use command_line::command_line_init;
|
use command_line::command_line_init;
|
||||||
use interfaces::cef_app_t;
|
use interfaces::cef_app_t;
|
||||||
use types::{cef_main_args_t, cef_settings_t};
|
use types::{cef_main_args_t, cef_settings_t};
|
||||||
use window;
|
|
||||||
|
|
||||||
use compositing::windowing::WindowEvent;
|
|
||||||
use geom::size::TypedSize2D;
|
use geom::size::TypedSize2D;
|
||||||
use glfw_app;
|
|
||||||
use libc::{c_char, c_int, c_void};
|
use libc::{c_char, c_int, c_void};
|
||||||
use servo::Browser;
|
use rustrt::local::Local;
|
||||||
|
use rustrt::task;
|
||||||
use servo_util::opts;
|
use servo_util::opts;
|
||||||
use servo_util::opts::RenderApi;
|
use servo_util::opts::RenderApi;
|
||||||
use std::c_str::CString;
|
use std::c_str::CString;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::rt;
|
use std::rt;
|
||||||
|
use browser;
|
||||||
|
|
||||||
const MAX_RENDERING_THREADS: uint = 128;
|
const MAX_RENDERING_THREADS: uint = 128;
|
||||||
|
|
||||||
// TODO(pcwalton): Get the home page via the CEF API.
|
// TODO(pcwalton): Get the home page via the CEF API.
|
||||||
static HOME_URL: &'static str = "http://s27.postimg.org/vqbtrolyr/servo.jpg";
|
static HOME_URL: &'static str = "http://s27.postimg.org/vqbtrolyr/servo.jpg";
|
||||||
|
|
||||||
// TODO(pcwalton): Support multiple windows.
|
|
||||||
pub enum ServoCefGlobals {
|
|
||||||
OnScreenGlobals(RefCell<Rc<glfw_app::window::Window>>,
|
|
||||||
RefCell<Browser<glfw_app::window::Window>>),
|
|
||||||
OffScreenGlobals(RefCell<Rc<window::Window>>, RefCell<Browser<window::Window>>),
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local!(pub static globals: Rc<RefCell<Option<ServoCefGlobals>>> = Rc::new(RefCell::new(None)))
|
|
||||||
|
|
||||||
thread_local!(pub static message_queue: Rc<RefCell<Vec<WindowEvent>>> = Rc::new(RefCell::new(vec!())))
|
|
||||||
|
|
||||||
static CEF_API_HASH_UNIVERSAL: &'static [u8] = b"8efd129f4afc344bd04b2feb7f73a149b6c4e27f\0";
|
static CEF_API_HASH_UNIVERSAL: &'static [u8] = b"8efd129f4afc344bd04b2feb7f73a149b6c4e27f\0";
|
||||||
#[cfg(target_os="windows")]
|
#[cfg(target_os="windows")]
|
||||||
static CEF_API_HASH_PLATFORM: &'static [u8] = b"5c7f3e50ff5265985d11dc1a466513e25748bedd\0";
|
static CEF_API_HASH_PLATFORM: &'static [u8] = b"5c7f3e50ff5265985d11dc1a466513e25748bedd\0";
|
||||||
|
@ -53,6 +39,11 @@ fn resources_path() -> Option<String> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_rust_task() {
|
||||||
|
let task = box task::Task::new(None, None);
|
||||||
|
Local::put(task);
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn cef_initialize(args: *const cef_main_args_t,
|
pub extern "C" fn cef_initialize(args: *const cef_main_args_t,
|
||||||
settings: *mut cef_settings_t,
|
settings: *mut cef_settings_t,
|
||||||
|
@ -77,6 +68,8 @@ pub extern "C" fn cef_initialize(args: *const cef_main_args_t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_rust_task();
|
||||||
|
|
||||||
let urls = vec![HOME_URL.into_string()];
|
let urls = vec![HOME_URL.into_string()];
|
||||||
opts::set_opts(opts::Opts {
|
opts::set_opts(opts::Opts {
|
||||||
urls: urls,
|
urls: urls,
|
||||||
|
@ -124,22 +117,17 @@ pub extern "C" fn cef_shutdown() {
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn cef_run_message_loop() {
|
pub extern "C" fn cef_run_message_loop() {
|
||||||
globals.with(|ref r| {
|
// GWTODO: Support blocking message loop
|
||||||
let mut the_globals = r.borrow_mut();
|
// again. Although, will it ever actually
|
||||||
match *the_globals.as_mut().unwrap() {
|
// be used or will everything use the
|
||||||
ServoCefGlobals::OnScreenGlobals(ref window, ref browser) => {
|
// cef_do_message_loop_work function below
|
||||||
while browser.borrow_mut().handle_event(window.borrow_mut().wait_events()) {}
|
// as our current miniservo apps do?
|
||||||
}
|
unimplemented!()
|
||||||
ServoCefGlobals::OffScreenGlobals(ref window, ref browser) => {
|
|
||||||
while browser.borrow_mut().handle_event(window.borrow_mut().wait_events()) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn cef_do_message_loop_work() {
|
pub extern "C" fn cef_do_message_loop_work() {
|
||||||
send_window_event(WindowEvent::Idle)
|
browser::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -154,79 +142,6 @@ pub extern "C" fn cef_execute_process(_args: *const cef_main_args_t,
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_window_event(event: WindowEvent) {
|
|
||||||
message_queue.with(|ref r| r.borrow_mut().push(event.clone()));
|
|
||||||
|
|
||||||
globals.with(|ref r| {
|
|
||||||
let mut the_globals = r.borrow_mut();
|
|
||||||
match &mut *the_globals {
|
|
||||||
&None => return,
|
|
||||||
&Some(ref mut the_globals) => loop {
|
|
||||||
match *the_globals {
|
|
||||||
ServoCefGlobals::OnScreenGlobals(_, ref browser) => {
|
|
||||||
match browser.try_borrow_mut() {
|
|
||||||
None => {
|
|
||||||
// We're trying to send an event while processing another one. This will
|
|
||||||
// cause general badness, so queue up that event instead of immediately
|
|
||||||
// processing it.
|
|
||||||
break
|
|
||||||
}
|
|
||||||
Some(ref mut browser) => {
|
|
||||||
let event = match message_queue.with(|ref r| r.borrow_mut().pop()) {
|
|
||||||
None => return,
|
|
||||||
Some(event) => event,
|
|
||||||
};
|
|
||||||
browser.handle_event(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ServoCefGlobals::OffScreenGlobals(_, ref browser) => {
|
|
||||||
match browser.try_borrow_mut() {
|
|
||||||
None => {
|
|
||||||
// We're trying to send an event while processing another one. This will
|
|
||||||
// cause general badness, so queue up that event instead of immediately
|
|
||||||
// processing it.
|
|
||||||
break
|
|
||||||
}
|
|
||||||
Some(ref mut browser) => {
|
|
||||||
let event = match message_queue.with(|ref r| r.borrow_mut().pop()) {
|
|
||||||
None => return,
|
|
||||||
Some(event) => event,
|
|
||||||
};
|
|
||||||
browser.handle_event(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! browser_method_delegate(
|
|
||||||
( $( fn $method:ident ( ) -> $return_type:ty ; )* ) => (
|
|
||||||
$(
|
|
||||||
pub fn $method() -> $return_type {
|
|
||||||
globals.with(|ref r| {
|
|
||||||
match r.borrow_mut().as_mut() {
|
|
||||||
None => panic!("{}: no globals created", stringify!($method)),
|
|
||||||
Some(&ServoCefGlobals::OnScreenGlobals(_, ref browser)) =>
|
|
||||||
browser.borrow_mut().$method(),
|
|
||||||
Some(&ServoCefGlobals::OffScreenGlobals(_, ref browser)) =>
|
|
||||||
browser.borrow_mut().$method(),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
browser_method_delegate! {
|
|
||||||
fn repaint_synchronously() -> ();
|
|
||||||
fn pinch_zoom_level() -> f32;
|
|
||||||
fn get_title_for_main_frame() -> ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn cef_api_hash(entry: c_int) -> *const c_char {
|
pub extern "C" fn cef_api_hash(entry: c_int) -> *const c_char {
|
||||||
if entry == 0 {
|
if entry == 0 {
|
||||||
|
|
|
@ -3,16 +3,19 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use eutil::Downcast;
|
use eutil::Downcast;
|
||||||
use interfaces::{CefFrame, CefStringVisitor, cef_frame_t, cef_string_visitor_t};
|
use interfaces::{CefBrowser, CefFrame, CefStringVisitor, cef_frame_t, cef_string_visitor_t};
|
||||||
use types::{cef_string_t, cef_string_userfree_t};
|
use types::{cef_string_t, cef_string_userfree_t};
|
||||||
|
use browser::ServoCefBrowserExtensions;
|
||||||
|
|
||||||
use core;
|
|
||||||
use compositing::windowing::WindowEvent;
|
use compositing::windowing::WindowEvent;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
pub struct ServoCefFrame {
|
pub struct ServoCefFrame {
|
||||||
pub title_visitor: RefCell<Option<CefStringVisitor>>,
|
pub title_visitor: RefCell<Option<CefStringVisitor>>,
|
||||||
pub url: RefCell<String>,
|
pub url: RefCell<String>,
|
||||||
|
|
||||||
|
/// A reference to the browser.
|
||||||
|
pub browser: RefCell<Option<CefBrowser>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServoCefFrame {
|
impl ServoCefFrame {
|
||||||
|
@ -20,6 +23,7 @@ impl ServoCefFrame {
|
||||||
ServoCefFrame {
|
ServoCefFrame {
|
||||||
title_visitor: RefCell::new(None),
|
title_visitor: RefCell::new(None),
|
||||||
url: RefCell::new(String::new()),
|
url: RefCell::new(String::new()),
|
||||||
|
browser: RefCell::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +33,8 @@ cef_class_impl! {
|
||||||
fn load_url(&this, url: *const cef_string_t) -> () {
|
fn load_url(&this, url: *const cef_string_t) -> () {
|
||||||
let this = this.downcast();
|
let this = this.downcast();
|
||||||
*this.url.borrow_mut() = String::from_utf16(url).unwrap();
|
*this.url.borrow_mut() = String::from_utf16(url).unwrap();
|
||||||
core::send_window_event(WindowEvent::LoadUrl(String::from_utf16(url).unwrap()));
|
let event = WindowEvent::LoadUrl(String::from_utf16(url).unwrap());
|
||||||
|
this.browser.borrow_mut().as_mut().unwrap().send_window_event(event);
|
||||||
}
|
}
|
||||||
fn get_url(&this) -> cef_string_userfree_t {
|
fn get_url(&this) -> cef_string_userfree_t {
|
||||||
let this = this.downcast();
|
let this = this.downcast();
|
||||||
|
@ -38,8 +43,17 @@ cef_class_impl! {
|
||||||
fn get_text(&this, visitor: *mut cef_string_visitor_t) -> () {
|
fn get_text(&this, visitor: *mut cef_string_visitor_t) -> () {
|
||||||
let this = this.downcast();
|
let this = this.downcast();
|
||||||
*this.title_visitor.borrow_mut() = Some(visitor);
|
*this.title_visitor.borrow_mut() = Some(visitor);
|
||||||
core::get_title_for_main_frame();
|
this.browser.borrow().as_ref().unwrap().get_title_for_main_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ServoCefFrameExtensions {
|
||||||
|
fn set_browser(&self, browser: CefBrowser);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServoCefFrameExtensions for CefFrame {
|
||||||
|
fn set_browser(&self, browser: CefBrowser) {
|
||||||
|
*self.downcast().browser.borrow_mut() = Some(browser)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue