diff --git a/ports/cef/browser.rs b/ports/cef/browser.rs index 6903c63505d..5c7db34abba 100644 --- a/ports/cef/browser.rs +++ b/ports/cef/browser.rs @@ -18,6 +18,7 @@ use glutin_app; use libc::c_int; use std::cell::{Cell, RefCell, BorrowState}; use std::ptr; +use std::rc::Rc; use std::sync::atomic::{AtomicIsize, Ordering}; thread_local!(pub static ID_COUNTER: AtomicIsize = AtomicIsize::new(0)); @@ -87,6 +88,8 @@ pub struct ServoCefBrowser { pub host: CefBrowserHost, /// A reference to the browser client. pub client: CefClient, + /// the glutin window when using windowed rendering + pub window: Option>, /// Whether the on-created callback has fired yet. pub callback_executed: Cell, /// the display system window handle: only to be used with host.get_window_handle() @@ -102,11 +105,15 @@ impl ServoCefBrowser { let frame = ServoCefFrame::new().as_cef_interface(); let host = ServoCefBrowserHost::new(client.clone()).as_cef_interface(); let mut window_handle: cef_window_handle_t = get_null_window_handle(); + let mut glutin_window: Option> = None; let servo_browser = if window_info.windowless_rendering_enabled == 0 { - let glutin_window = glutin_app::create_window(window_info.parent_window as glutin_app::WindowID); - let servo_browser = Browser::new(Some(glutin_window.clone())); - window_handle = glutin_window.platform_window() as cef_window_handle_t; + glutin_window = Some(glutin_app::create_window(window_info.parent_window as glutin_app::WindowID)); + let servo_browser = Browser::new(glutin_window.clone()); + window_handle = match glutin_window { + Some(ref win) => win.platform_window() as cef_window_handle_t, + None => get_null_window_handle() + }; ServoBrowser::OnScreen(servo_browser) } else { ServoBrowser::Invalid @@ -120,6 +127,7 @@ impl ServoCefBrowser { frame: frame, host: host, client: client, + window: glutin_window, callback_executed: Cell::new(false), servo_browser: RefCell::new(servo_browser), message_queue: RefCell::new(vec!()), @@ -139,9 +147,9 @@ pub trait ServoCefBrowserExtensions { impl ServoCefBrowserExtensions for CefBrowser { fn init(&self, window_info: &cef_window_info_t) { if window_info.windowless_rendering_enabled != 0 { - let window = window::Window::new(); - let servo_browser = Browser::new(Some(window.clone())); + let window = window::Window::new(window_info.width, window_info.height); window.set_browser(self.clone()); + let servo_browser = Browser::new(Some(window.clone())); *self.downcast().servo_browser.borrow_mut() = ServoBrowser::OffScreen(servo_browser); } diff --git a/ports/cef/window.rs b/ports/cef/window.rs index a8391c3dc37..328152f8067 100644 --- a/ports/cef/window.rs +++ b/ports/cef/window.rs @@ -43,6 +43,7 @@ pub static mut DISPLAY: *mut c_void = 0 as *mut c_void; #[derive(Clone)] pub struct Window { cef_browser: RefCell>, + size: TypedSize2D } #[cfg(target_os="macos")] @@ -77,11 +78,12 @@ fn load_gl() { impl Window { /// Creates a new window. - pub fn new() -> Rc { + pub fn new(width: u32, height: u32) -> Rc { load_gl(); Rc::new(Window { cef_browser: RefCell::new(None), + size: TypedSize2D(width, height) }) } @@ -166,14 +168,36 @@ impl WindowMethods for Window { fn framebuffer_size(&self) -> TypedSize2D { let browser = self.cef_browser.borrow(); match *browser { - None => TypedSize2D(400, 300), + None => self.size, Some(ref browser) => { - let mut rect = cef_rect_t::zero(); - browser.get_host() - .get_client() - .get_render_handler() - .get_backing_rect((*browser).clone(), &mut rect); - TypedSize2D(rect.width as u32, rect.height as u32) + if browser.downcast().callback_executed.get() != true { + self.size + } else { + let mut rect = cef_rect_t::zero(); + rect.width = self.size.width.get() as i32; + rect.height = self.size.height.get() as i32; + if cfg!(target_os="macos") { + // osx relies on virtual pixel scaling to provide sizes different from actual + // pixel size on screen. other platforms are just 1.0 unless the desktop/toolkit says otherwise + if check_ptr_exist!(browser.get_host().get_client(), get_render_handler) && + check_ptr_exist!(browser.get_host().get_client().get_render_handler(), get_backing_rect) { + browser.get_host() + .get_client() + .get_render_handler() + .get_backing_rect((*browser).clone(), &mut rect); + } + } else { + if check_ptr_exist!(browser.get_host().get_client(), get_render_handler) && + check_ptr_exist!(browser.get_host().get_client().get_render_handler(), get_view_rect) { + browser.get_host() + .get_client() + .get_render_handler() + .get_view_rect((*browser).clone(), &mut rect); + } + } + + TypedSize2D(rect.width as u32, rect.height as u32) + } } } }