mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
De @-mut windowing.
This commit is contained in:
parent
52b6993dc8
commit
bfa4226e8f
5 changed files with 145 additions and 127 deletions
|
@ -39,11 +39,12 @@ use servo_util::{time, url};
|
|||
use std::comm::Port;
|
||||
use std::num::Orderable;
|
||||
use std::path::Path;
|
||||
use std::rc::Rc;
|
||||
|
||||
|
||||
pub struct IOCompositor {
|
||||
/// The application window.
|
||||
window: @mut Window,
|
||||
window: Rc<Window>,
|
||||
|
||||
/// The port on which we receive messages.
|
||||
port: Port<Msg>,
|
||||
|
@ -115,14 +116,14 @@ impl IOCompositor {
|
|||
port: Port<Msg>,
|
||||
constellation_chan: ConstellationChan,
|
||||
profiler_chan: ProfilerChan) -> IOCompositor {
|
||||
let window: @mut Window = WindowMethods::new(app);
|
||||
let window: Rc<Window> = WindowMethods::new(app);
|
||||
|
||||
// Create an initial layer tree.
|
||||
//
|
||||
// TODO: There should be no initial layer tree until the renderer creates one from the display
|
||||
// list. This is only here because we don't have that logic in the renderer yet.
|
||||
let root_layer = @mut ContainerLayer();
|
||||
let window_size = window.size();
|
||||
let window_size = window.borrow().size();
|
||||
|
||||
IOCompositor {
|
||||
window: window,
|
||||
|
@ -181,7 +182,8 @@ impl IOCompositor {
|
|||
}
|
||||
|
||||
// Check for messages coming from the windowing system.
|
||||
self.handle_window_message(self.window.recv());
|
||||
let msg = self.window.borrow().recv();
|
||||
self.handle_window_message(msg);
|
||||
|
||||
// If asked to recomposite and renderer has run at least once
|
||||
if self.recomposite && self.composite_ready {
|
||||
|
@ -231,7 +233,7 @@ impl IOCompositor {
|
|||
}
|
||||
|
||||
(Some(ChangeReadyState(ready_state)), false) => {
|
||||
self.window.set_ready_state(ready_state);
|
||||
self.window.borrow().set_ready_state(ready_state);
|
||||
self.ready_state = ready_state;
|
||||
}
|
||||
|
||||
|
@ -293,7 +295,7 @@ impl IOCompositor {
|
|||
}
|
||||
|
||||
fn change_render_state(&mut self, render_state: RenderState) {
|
||||
self.window.set_render_state(render_state);
|
||||
self.window.borrow().set_render_state(render_state);
|
||||
if render_state == IdleRenderState {
|
||||
self.composite_ready = true;
|
||||
}
|
||||
|
@ -335,7 +337,7 @@ impl IOCompositor {
|
|||
self.compositor_layer = Some(layer);
|
||||
|
||||
// Initialize the new constellation channel by sending it the root window size.
|
||||
let window_size = self.window.size();
|
||||
let window_size = self.window.borrow().size();
|
||||
let window_size = Size2D(window_size.width as uint,
|
||||
window_size.height as uint);
|
||||
new_constellation_chan.send(ResizedWindowMsg(window_size));
|
||||
|
@ -660,7 +662,7 @@ impl IOCompositor {
|
|||
profile(time::CompositingCategory, self.profiler_chan.clone(), || {
|
||||
debug!("compositor: compositing");
|
||||
// Adjust the layer dimensions as necessary to correspond to the size of the window.
|
||||
self.scene.size = self.window.size();
|
||||
self.scene.size = self.window.borrow().size();
|
||||
// Render the scene.
|
||||
match self.compositor_layer {
|
||||
Some(ref mut layer) => {
|
||||
|
@ -709,7 +711,7 @@ impl IOCompositor {
|
|||
self.shutting_down = true;
|
||||
}
|
||||
|
||||
self.window.present();
|
||||
self.window.borrow().present();
|
||||
|
||||
let exit = self.opts.exit_after_load;
|
||||
if exit {
|
||||
|
|
|
@ -14,8 +14,11 @@ use windowing::{Forward, Back};
|
|||
use alert::{Alert, AlertMethods};
|
||||
use extra::time::Timespec;
|
||||
use extra::time;
|
||||
use std::cell::RefCell;
|
||||
use std::libc::{exit, c_int};
|
||||
use std::local_data;
|
||||
use std::rc::Rc;
|
||||
|
||||
use geom::point::Point2D;
|
||||
use geom::size::Size2D;
|
||||
use servo_msg::compositor_msg::{IdleRenderState, RenderState, RenderingRenderState};
|
||||
|
@ -86,60 +89,61 @@ macro_rules! glfw_callback(
|
|||
pub struct Window {
|
||||
glfw_window: glfw::Window,
|
||||
|
||||
event_queue: @mut ~[WindowEvent],
|
||||
event_queue: RefCell<~[WindowEvent]>,
|
||||
|
||||
drag_origin: Point2D<c_int>,
|
||||
|
||||
mouse_down_button: @mut Option<glfw::MouseButton>,
|
||||
mouse_down_point: @mut Point2D<c_int>,
|
||||
mouse_down_button: RefCell<Option<glfw::MouseButton>>,
|
||||
mouse_down_point: RefCell<Point2D<c_int>>,
|
||||
|
||||
ready_state: ReadyState,
|
||||
render_state: RenderState,
|
||||
ready_state: RefCell<ReadyState>,
|
||||
render_state: RefCell<RenderState>,
|
||||
|
||||
last_title_set_time: Timespec,
|
||||
last_title_set_time: RefCell<Timespec>,
|
||||
}
|
||||
|
||||
impl WindowMethods<Application> for Window {
|
||||
/// Creates a new window.
|
||||
fn new(_: &Application) -> @mut Window {
|
||||
fn new(_: &Application) -> Rc<Window> {
|
||||
// Create the GLFW window.
|
||||
let glfw_window = glfw::Window::create(800, 600, "Servo", glfw::Windowed)
|
||||
.expect("Failed to create GLFW window");
|
||||
glfw_window.make_context_current();
|
||||
|
||||
// Create our window object.
|
||||
let window = @mut Window {
|
||||
let window = Window {
|
||||
glfw_window: glfw_window,
|
||||
|
||||
event_queue: @mut ~[],
|
||||
event_queue: RefCell::new(~[]),
|
||||
|
||||
drag_origin: Point2D(0 as c_int, 0),
|
||||
|
||||
mouse_down_button: @mut None,
|
||||
mouse_down_point: @mut Point2D(0 as c_int, 0),
|
||||
mouse_down_button: RefCell::new(None),
|
||||
mouse_down_point: RefCell::new(Point2D(0 as c_int, 0)),
|
||||
|
||||
ready_state: Blank,
|
||||
render_state: IdleRenderState,
|
||||
ready_state: RefCell::new(Blank),
|
||||
render_state: RefCell::new(IdleRenderState),
|
||||
|
||||
last_title_set_time: Timespec::new(0, 0),
|
||||
last_title_set_time: RefCell::new(Timespec::new(0, 0)),
|
||||
};
|
||||
|
||||
install_local_window(window);
|
||||
|
||||
// Register event handlers.
|
||||
window.glfw_window.set_framebuffer_size_callback(
|
||||
glfw_callback!(glfw::FramebufferSizeCallback(_win: &glfw::Window, width: i32, height: i32) {
|
||||
local_window().event_queue.push(ResizeWindowEvent(width as uint, height as uint));
|
||||
let tmp = local_window();
|
||||
tmp.borrow().event_queue.with_mut(|queue| queue.push(ResizeWindowEvent(width as uint, height as uint)));
|
||||
}));
|
||||
window.glfw_window.set_refresh_callback(
|
||||
glfw_callback!(glfw::WindowRefreshCallback(_win: &glfw::Window) {
|
||||
local_window().event_queue.push(RefreshWindowEvent);
|
||||
let tmp = local_window();
|
||||
tmp.borrow().event_queue.with_mut(|queue| queue.push(RefreshWindowEvent));
|
||||
}));
|
||||
window.glfw_window.set_key_callback(
|
||||
glfw_callback!(glfw::KeyCallback(_win: &glfw::Window, key: glfw::Key, _scancode: c_int,
|
||||
action: glfw::Action, mods: glfw::Modifiers) {
|
||||
if action == glfw::Press {
|
||||
local_window().handle_key(key, mods)
|
||||
let tmp = local_window();
|
||||
tmp.borrow().handle_key(key, mods)
|
||||
}
|
||||
}));
|
||||
window.glfw_window.set_mouse_button_callback(
|
||||
|
@ -153,12 +157,14 @@ impl WindowMethods<Application> for Window {
|
|||
let x = x as f32 * hidpi;
|
||||
let y = y as f32 * hidpi;
|
||||
if button == glfw::MouseButtonLeft || button == glfw::MouseButtonRight {
|
||||
local_window().handle_mouse(button, action, x as i32, y as i32);
|
||||
let tmp = local_window();
|
||||
tmp.borrow().handle_mouse(button, action, x as i32, y as i32);
|
||||
}
|
||||
}));
|
||||
window.glfw_window.set_cursor_pos_callback(
|
||||
glfw_callback!(glfw::CursorPosCallback(_win: &glfw::Window, xpos: f64, ypos: f64) {
|
||||
local_window().event_queue.push(MouseWindowMoveEventClass(Point2D(xpos as f32, ypos as f32)));
|
||||
let tmp = local_window();
|
||||
tmp.borrow().event_queue.with_mut(|queue| queue.push(MouseWindowMoveEventClass(Point2D(xpos as f32, ypos as f32))));
|
||||
}));
|
||||
window.glfw_window.set_scroll_callback(
|
||||
glfw_callback!(glfw::ScrollCallback(win: &glfw::Window, xpos: f64, ypos: f64) {
|
||||
|
@ -173,10 +179,15 @@ impl WindowMethods<Application> for Window {
|
|||
let x = x as f32 * hidpi;
|
||||
let y = y as f32 * hidpi;
|
||||
|
||||
local_window().event_queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32)));
|
||||
let tmp = local_window();
|
||||
tmp.borrow().event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32))));
|
||||
}));
|
||||
|
||||
window
|
||||
let wrapped_window = Rc::from_send(window);
|
||||
|
||||
install_local_window(wrapped_window.clone());
|
||||
|
||||
wrapped_window
|
||||
}
|
||||
|
||||
/// Returns the size of the window.
|
||||
|
@ -186,45 +197,45 @@ impl WindowMethods<Application> for Window {
|
|||
}
|
||||
|
||||
/// Presents the window to the screen (perhaps by page flipping).
|
||||
fn present(&mut self) {
|
||||
fn present(&self) {
|
||||
self.glfw_window.swap_buffers();
|
||||
}
|
||||
|
||||
fn recv(@mut self) -> WindowEvent {
|
||||
if !self.event_queue.is_empty() {
|
||||
return self.event_queue.shift()
|
||||
fn recv(&self) -> WindowEvent {
|
||||
if !self.event_queue.with_mut(|queue| queue.is_empty()) {
|
||||
return self.event_queue.with_mut(|queue| queue.shift())
|
||||
}
|
||||
glfw::poll_events();
|
||||
|
||||
if self.glfw_window.should_close() {
|
||||
QuitWindowEvent
|
||||
} else if !self.event_queue.is_empty() {
|
||||
self.event_queue.shift()
|
||||
} else if !self.event_queue.with_mut(|queue| queue.is_empty()) {
|
||||
self.event_queue.with_mut(|queue| queue.shift())
|
||||
} else {
|
||||
IdleWindowEvent
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the ready state.
|
||||
fn set_ready_state(@mut self, ready_state: ReadyState) {
|
||||
self.ready_state = ready_state;
|
||||
fn set_ready_state(&self, ready_state: ReadyState) {
|
||||
self.ready_state.set(ready_state);
|
||||
self.update_window_title()
|
||||
}
|
||||
|
||||
/// Sets the render state.
|
||||
fn set_render_state(@mut self, render_state: RenderState) {
|
||||
if self.ready_state == FinishedLoading &&
|
||||
self.render_state == RenderingRenderState &&
|
||||
fn set_render_state(&self, render_state: RenderState) {
|
||||
if self.ready_state.get() == FinishedLoading &&
|
||||
self.render_state.get() == RenderingRenderState &&
|
||||
render_state == IdleRenderState {
|
||||
// page loaded
|
||||
self.event_queue.push(FinishedWindowEvent);
|
||||
self.event_queue.with_mut(|queue| queue.push(FinishedWindowEvent));
|
||||
}
|
||||
|
||||
self.render_state = render_state;
|
||||
self.render_state.set(render_state);
|
||||
self.update_window_title()
|
||||
}
|
||||
|
||||
fn hidpi_factor(@mut self) -> f32 {
|
||||
fn hidpi_factor(&self) -> f32 {
|
||||
let (backing_size, _) = self.glfw_window.get_framebuffer_size();
|
||||
let (window_size, _) = self.glfw_window.get_size();
|
||||
(backing_size as f32) / (window_size as f32)
|
||||
|
@ -233,14 +244,14 @@ impl WindowMethods<Application> for Window {
|
|||
|
||||
impl Window {
|
||||
/// Helper function to set the window title in accordance with the ready state.
|
||||
fn update_window_title(&mut self) {
|
||||
fn update_window_title(&self) {
|
||||
let now = time::get_time();
|
||||
if now.sec == self.last_title_set_time.sec {
|
||||
if now.sec == self.last_title_set_time.get().sec {
|
||||
return
|
||||
}
|
||||
self.last_title_set_time = now;
|
||||
self.last_title_set_time.set(now);
|
||||
|
||||
match self.ready_state {
|
||||
match self.ready_state.get() {
|
||||
Blank => {
|
||||
self.glfw_window.set_title("blank — Servo")
|
||||
}
|
||||
|
@ -251,7 +262,7 @@ impl Window {
|
|||
self.glfw_window.set_title("Performing Layout — Servo")
|
||||
}
|
||||
FinishedLoading => {
|
||||
match self.render_state {
|
||||
match self.render_state.get() {
|
||||
RenderingRenderState => {
|
||||
self.glfw_window.set_title("Rendering — Servo")
|
||||
}
|
||||
|
@ -269,16 +280,16 @@ impl Window {
|
|||
glfw::KeyEscape => self.glfw_window.set_should_close(true),
|
||||
glfw::KeyL if mods.contains(glfw::Control) => self.load_url(), // Ctrl+L
|
||||
glfw::KeyEqual if mods.contains(glfw::Control) => { // Ctrl-+
|
||||
self.event_queue.push(ZoomWindowEvent(1.1));
|
||||
self.event_queue.with_mut(|queue| queue.push(ZoomWindowEvent(1.1)));
|
||||
}
|
||||
glfw::KeyMinus if mods.contains(glfw::Control) => { // Ctrl--
|
||||
self.event_queue.push(ZoomWindowEvent(0.90909090909));
|
||||
self.event_queue.with_mut(|queue| queue.push(ZoomWindowEvent(0.90909090909)));
|
||||
}
|
||||
glfw::KeyBackspace if mods.contains(glfw::Shift) => { // Shift-Backspace
|
||||
self.event_queue.push(NavigationWindowEvent(Forward));
|
||||
self.event_queue.with_mut(|queue| queue.push(NavigationWindowEvent(Forward)));
|
||||
}
|
||||
glfw::KeyBackspace => { // Backspace
|
||||
self.event_queue.push(NavigationWindowEvent(Back));
|
||||
self.event_queue.with_mut(|queue| queue.push(NavigationWindowEvent(Back)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -290,21 +301,21 @@ impl Window {
|
|||
let max_pixel_dist = 10f64;
|
||||
let event = match action {
|
||||
glfw::Press => {
|
||||
*self.mouse_down_point = Point2D(x, y);
|
||||
*self.mouse_down_button = Some(button);
|
||||
self.mouse_down_point.set(Point2D(x, y));
|
||||
self.mouse_down_button.set(Some(button));
|
||||
MouseWindowMouseDownEvent(button as uint, Point2D(x as f32, y as f32))
|
||||
}
|
||||
glfw::Release => {
|
||||
match *self.mouse_down_button {
|
||||
match self.mouse_down_button.get() {
|
||||
None => (),
|
||||
Some(but) if button == but => {
|
||||
let pixel_dist = *self.mouse_down_point - Point2D(x, y);
|
||||
let pixel_dist = self.mouse_down_point.get() - Point2D(x, y);
|
||||
let pixel_dist = ((pixel_dist.x * pixel_dist.x +
|
||||
pixel_dist.y * pixel_dist.y) as f64).sqrt();
|
||||
if pixel_dist < max_pixel_dist {
|
||||
let click_event = MouseWindowClickEvent(button as uint,
|
||||
Point2D(x as f32, y as f32));
|
||||
self.event_queue.push(MouseWindowEventClass(click_event));
|
||||
self.event_queue.with_mut(|queue| queue.push(MouseWindowEventClass(click_event)));
|
||||
}
|
||||
}
|
||||
Some(_) => (),
|
||||
|
@ -313,7 +324,7 @@ impl Window {
|
|||
}
|
||||
_ => fail!("I cannot recognize the type of mouse action that occured. :-(")
|
||||
};
|
||||
self.event_queue.push(MouseWindowEventClass(event));
|
||||
self.event_queue.with_mut(|queue| queue.push(MouseWindowEventClass(event)));
|
||||
}
|
||||
|
||||
/// Helper function to pop up an alert box prompting the user to load a URL.
|
||||
|
@ -323,16 +334,16 @@ impl Window {
|
|||
alert.run();
|
||||
let value = alert.prompt_value();
|
||||
if "" == value { // To avoid crashing on Linux.
|
||||
self.event_queue.push(LoadUrlWindowEvent(~"http://purple.com/"))
|
||||
self.event_queue.with_mut(|queue| queue.push(LoadUrlWindowEvent(~"http://purple.com/")))
|
||||
} else {
|
||||
self.event_queue.push(LoadUrlWindowEvent(value))
|
||||
self.event_queue.with_mut(|queue| queue.push(LoadUrlWindowEvent(value.clone())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static TLS_KEY: local_data::Key<@mut Window> = &local_data::Key;
|
||||
static TLS_KEY: local_data::Key<Rc<Window>> = &local_data::Key;
|
||||
|
||||
fn install_local_window(window: @mut Window) {
|
||||
fn install_local_window(window: Rc<Window>) {
|
||||
local_data::set(TLS_KEY, window);
|
||||
}
|
||||
|
||||
|
@ -340,6 +351,6 @@ fn drop_local_window() {
|
|||
local_data::pop(TLS_KEY);
|
||||
}
|
||||
|
||||
fn local_window() -> @mut Window {
|
||||
local_data::get(TLS_KEY, |v| *v.unwrap())
|
||||
fn local_window() -> Rc<Window> {
|
||||
local_data::get(TLS_KEY, |v| v.unwrap().clone())
|
||||
}
|
||||
|
|
|
@ -11,8 +11,10 @@ use windowing::{MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMou
|
|||
use windowing::{Forward, Back};
|
||||
|
||||
use alert::{Alert, AlertMethods};
|
||||
use std::cell::RefCell;
|
||||
use std::libc::{c_int, c_uchar};
|
||||
use std::local_data;
|
||||
use std::rc::Rc;
|
||||
use geom::point::Point2D;
|
||||
use geom::size::Size2D;
|
||||
use servo_msg::compositor_msg::{IdleRenderState, RenderState, RenderingRenderState};
|
||||
|
@ -45,43 +47,41 @@ impl Drop for Application {
|
|||
pub struct Window {
|
||||
glut_window: glut::Window,
|
||||
|
||||
event_queue: @mut ~[WindowEvent],
|
||||
event_queue: RefCell<~[WindowEvent]>,
|
||||
|
||||
drag_origin: Point2D<c_int>,
|
||||
|
||||
mouse_down_button: @mut c_int,
|
||||
mouse_down_point: @mut Point2D<c_int>,
|
||||
mouse_down_button: RefCell<c_int>,
|
||||
mouse_down_point: RefCell<Point2D<c_int>>,
|
||||
|
||||
ready_state: ReadyState,
|
||||
render_state: RenderState,
|
||||
throbber_frame: u8,
|
||||
ready_state: RefCell<ReadyState>,
|
||||
render_state: RefCell<RenderState>,
|
||||
throbber_frame: RefCell<u8>,
|
||||
}
|
||||
|
||||
impl WindowMethods<Application> for Window {
|
||||
/// Creates a new window.
|
||||
fn new(_: &Application) -> @mut Window {
|
||||
fn new(_: &Application) -> Rc<Window> {
|
||||
// Create the GLUT window.
|
||||
glut::init_window_size(800, 600);
|
||||
let glut_window = glut::create_window(~"Servo");
|
||||
|
||||
// Create our window object.
|
||||
let window = @mut Window {
|
||||
let window = Window {
|
||||
glut_window: glut_window,
|
||||
|
||||
event_queue: @mut ~[],
|
||||
event_queue: RefCell::new(~[]),
|
||||
|
||||
drag_origin: Point2D(0 as c_int, 0),
|
||||
|
||||
mouse_down_button: @mut 0,
|
||||
mouse_down_point: @mut Point2D(0 as c_int, 0),
|
||||
mouse_down_button: RefCell::new(0),
|
||||
mouse_down_point: RefCell::new(Point2D(0 as c_int, 0)),
|
||||
|
||||
ready_state: Blank,
|
||||
render_state: IdleRenderState,
|
||||
throbber_frame: 0,
|
||||
ready_state: RefCell::new(Blank),
|
||||
render_state: RefCell::new(IdleRenderState),
|
||||
throbber_frame: RefCell::new(0),
|
||||
};
|
||||
|
||||
install_local_window(window);
|
||||
|
||||
// Register event handlers.
|
||||
|
||||
//Added dummy display callback to freeglut. According to freeglut ref, we should register some kind of display callback after freeglut 3.0.
|
||||
|
@ -96,7 +96,7 @@ impl WindowMethods<Application> for Window {
|
|||
struct ReshapeCallbackState;
|
||||
impl glut::ReshapeCallback for ReshapeCallbackState {
|
||||
fn call(&self, width: c_int, height: c_int) {
|
||||
local_window().event_queue.push(ResizeWindowEvent(width as uint, height as uint))
|
||||
local_window().event_queue.with_mut(|queue| queue.push(ResizeWindowEvent(width as uint, height as uint)))
|
||||
}
|
||||
}
|
||||
glut::reshape_func(glut_window, ~ReshapeCallbackState);
|
||||
|
@ -115,10 +115,10 @@ impl WindowMethods<Application> for Window {
|
|||
} else {
|
||||
match button {
|
||||
3 => {
|
||||
local_window().event_queue.push(ScrollWindowEvent(Point2D(0.0, 5.0 as f32), Point2D(0.0 as i32, 5.0 as i32)));
|
||||
local_window().event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(0.0, 5.0 as f32), Point2D(0.0 as i32, 5.0 as i32))));
|
||||
},
|
||||
4 => {
|
||||
local_window().event_queue.push(ScrollWindowEvent(Point2D(0.0, -5.0 as f32), Point2D(0.0 as i32, -5.0 as i32)));
|
||||
local_window().event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(0.0, -5.0 as f32), Point2D(0.0 as i32, -5.0 as i32))));
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
@ -127,7 +127,11 @@ impl WindowMethods<Application> for Window {
|
|||
}
|
||||
glut::mouse_func(~MouseCallbackState);
|
||||
|
||||
window
|
||||
let wrapped_window = Rc::new(window);
|
||||
|
||||
install_local_window(wrapped_window);
|
||||
|
||||
wrapped_window
|
||||
}
|
||||
|
||||
/// Returns the size of the window.
|
||||
|
@ -136,44 +140,44 @@ impl WindowMethods<Application> for Window {
|
|||
}
|
||||
|
||||
/// Presents the window to the screen (perhaps by page flipping).
|
||||
fn present(&mut self) {
|
||||
fn present(&self) {
|
||||
glut::swap_buffers();
|
||||
}
|
||||
|
||||
fn recv(@mut self) -> WindowEvent {
|
||||
if !self.event_queue.is_empty() {
|
||||
return self.event_queue.shift()
|
||||
fn recv(@self) -> WindowEvent {
|
||||
if !self.event_queue.with_mut(|queue| queue.is_empty()) {
|
||||
return self.event_queue.with_mut(|queue| queue.shift())
|
||||
}
|
||||
glut::check_loop();
|
||||
if !self.event_queue.is_empty() {
|
||||
self.event_queue.shift()
|
||||
if !self.event_queue.with_mut(|queue| queue.is_empty()) {
|
||||
self.event_queue.with_mut(|queue| queue.shift())
|
||||
} else {
|
||||
IdleWindowEvent
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the ready state.
|
||||
fn set_ready_state(@mut self, ready_state: ReadyState) {
|
||||
self.ready_state = ready_state;
|
||||
fn set_ready_state(@self, ready_state: ReadyState) {
|
||||
self.ready_state.set(ready_state);
|
||||
//FIXME: set_window_title causes crash with Android version of freeGLUT. Temporarily blocked.
|
||||
//self.update_window_title()
|
||||
}
|
||||
|
||||
/// Sets the render state.
|
||||
fn set_render_state(@mut self, render_state: RenderState) {
|
||||
if self.ready_state == FinishedLoading &&
|
||||
self.render_state == RenderingRenderState &&
|
||||
fn set_render_state(@self, render_state: RenderState) {
|
||||
if self.ready_state.get() == FinishedLoading &&
|
||||
self.render_state.get() == RenderingRenderState &&
|
||||
render_state == IdleRenderState {
|
||||
// page loaded
|
||||
self.event_queue.push(FinishedWindowEvent);
|
||||
self.event_queue.with_mut(|queue| queue.push(FinishedWindowEvent));
|
||||
}
|
||||
|
||||
self.render_state = render_state;
|
||||
self.render_state.set(render_state);
|
||||
//FIXME: set_window_title causes crash with Android version of freeGLUT. Temporarily blocked.
|
||||
//self.update_window_title()
|
||||
}
|
||||
|
||||
fn hidpi_factor(@mut self) -> f32 {
|
||||
fn hidpi_factor(@self) -> f32 {
|
||||
//FIXME: Do nothing in GLUT now.
|
||||
0f32
|
||||
}
|
||||
|
@ -210,16 +214,16 @@ impl Window {
|
|||
let modifiers = glut::get_modifiers();
|
||||
match key {
|
||||
42 => self.load_url(),
|
||||
43 => self.event_queue.push(ZoomWindowEvent(1.1)),
|
||||
45 => self.event_queue.push(ZoomWindowEvent(0.909090909)),
|
||||
56 => self.event_queue.push(ScrollWindowEvent(Point2D(0.0, 5.0 as f32), Point2D(0.0 as i32, 5.0 as i32))),
|
||||
50 => self.event_queue.push(ScrollWindowEvent(Point2D(0.0, -5.0 as f32), Point2D(0.0 as i32, -5.0 as i32))),
|
||||
43 => self.event_queue.with_mut(|queue| queue.push(ZoomWindowEvent(1.1))),
|
||||
45 => self.event_queue.with_mut(|queue| queue.push(ZoomWindowEvent(0.909090909))),
|
||||
56 => self.event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(0.0, 5.0 as f32), Point2D(0.0 as i32, 5.0 as i32)))),
|
||||
50 => self.event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(0.0, -5.0 as f32), Point2D(0.0 as i32, -5.0 as i32)))),
|
||||
127 => {
|
||||
if (modifiers & ACTIVE_SHIFT) != 0 {
|
||||
self.event_queue.push(NavigationWindowEvent(Forward));
|
||||
self.event_queue.with_mut(|queue| queue.push(NavigationWindowEvent(Forward)));
|
||||
}
|
||||
else {
|
||||
self.event_queue.push(NavigationWindowEvent(Back));
|
||||
self.event_queue.with_mut(|queue| queue.push(NavigationWindowEvent(Back)));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -232,26 +236,26 @@ impl Window {
|
|||
let max_pixel_dist = 10f32;
|
||||
let event = match state {
|
||||
glut::MOUSE_DOWN => {
|
||||
*self.mouse_down_point = Point2D(x, y);
|
||||
*self.mouse_down_button = button;
|
||||
self.mouse_down_point.set(Point2D(x, y));
|
||||
self.mouse_down_button.set(button);
|
||||
MouseWindowMouseDownEvent(button as uint, Point2D(x as f32, y as f32))
|
||||
}
|
||||
glut::MOUSE_UP => {
|
||||
if *self.mouse_down_button == button {
|
||||
let pixel_dist = *self.mouse_down_point - Point2D(x, y);
|
||||
if self.mouse_down_button.get() == button {
|
||||
let pixel_dist = self.mouse_down_point.get() - Point2D(x, y);
|
||||
let pixel_dist = ((pixel_dist.x * pixel_dist.x +
|
||||
pixel_dist.y * pixel_dist.y) as f32).sqrt();
|
||||
if pixel_dist < max_pixel_dist {
|
||||
let click_event = MouseWindowClickEvent(button as uint,
|
||||
Point2D(x as f32, y as f32));
|
||||
self.event_queue.push(MouseWindowEventClass(click_event));
|
||||
self.event_queue.with_mut(|queue| queue.push(MouseWindowEventClass(click_event)));
|
||||
}
|
||||
}
|
||||
MouseWindowMouseUpEvent(button as uint, Point2D(x as f32, y as f32))
|
||||
}
|
||||
_ => fail!("I cannot recognize the type of mouse action that occured. :-(")
|
||||
};
|
||||
self.event_queue.push(MouseWindowEventClass(event));
|
||||
self.event_queue.with_mut(|queue| queue.push(MouseWindowEventClass(event)));
|
||||
}
|
||||
|
||||
/// Helper function to pop up an alert box prompting the user to load a URL.
|
||||
|
@ -261,16 +265,16 @@ impl Window {
|
|||
alert.run();
|
||||
let value = alert.prompt_value();
|
||||
if "" == value { // To avoid crashing on Linux.
|
||||
self.event_queue.push(LoadUrlWindowEvent(~"http://purple.com/"))
|
||||
self.event_queue.with_mut(|queue| queue.push(LoadUrlWindowEvent(~"http://purple.com/")))
|
||||
} else {
|
||||
self.event_queue.push(LoadUrlWindowEvent(value))
|
||||
self.event_queue.with_mut(|queue| queue.push(LoadUrlWindowEvent(value.clone())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static TLS_KEY: local_data::Key<@mut Window> = &local_data::Key;
|
||||
static TLS_KEY: local_data::Key<Rc<Window>> = &local_data::Key;
|
||||
|
||||
fn install_local_window(window: @mut Window) {
|
||||
fn install_local_window(window: Rc<Window>) {
|
||||
local_data::set(TLS_KEY, window);
|
||||
}
|
||||
|
||||
|
@ -278,6 +282,6 @@ fn drop_local_window() {
|
|||
local_data::pop(TLS_KEY);
|
||||
}
|
||||
|
||||
fn local_window() -> @mut Window {
|
||||
local_data::get(TLS_KEY, |v| *v.unwrap())
|
||||
fn local_window() -> Rc<Window> {
|
||||
local_data::get(TLS_KEY, |v| v.unwrap().clone())
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
use geom::point::Point2D;
|
||||
use geom::size::Size2D;
|
||||
use servo_msg::compositor_msg::{ReadyState, RenderState};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub enum MouseWindowEvent {
|
||||
MouseWindowClickEvent(uint, Point2D<f32>),
|
||||
|
@ -55,21 +56,21 @@ pub trait ApplicationMethods {
|
|||
|
||||
pub trait WindowMethods<A> {
|
||||
/// Creates a new window.
|
||||
fn new(app: &A) -> @mut Self;
|
||||
fn new(app: &A) -> Rc<Self>;
|
||||
/// Returns the size of the window.
|
||||
fn size(&self) -> Size2D<f32>;
|
||||
/// Presents the window to the screen (perhaps by page flipping).
|
||||
fn present(&mut self);
|
||||
fn present(&self);
|
||||
|
||||
/// Spins the event loop and returns the next event.
|
||||
fn recv(@mut self) -> WindowEvent;
|
||||
fn recv(&self) -> WindowEvent;
|
||||
|
||||
/// Sets the ready state of the current page.
|
||||
fn set_ready_state(@mut self, ready_state: ReadyState);
|
||||
fn set_ready_state(&self, ready_state: ReadyState);
|
||||
/// Sets the render state of the current page.
|
||||
fn set_render_state(@mut self, render_state: RenderState);
|
||||
fn set_render_state(&self, render_state: RenderState);
|
||||
|
||||
/// Returns the hidpi factor of the monitor.
|
||||
fn hidpi_factor(@mut self) -> f32;
|
||||
fn hidpi_factor(&self) -> f32;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,13 +45,13 @@ impl LayerBufferSet {
|
|||
}
|
||||
|
||||
/// The status of the renderer.
|
||||
#[deriving(Eq)]
|
||||
#[deriving(Eq, Clone)]
|
||||
pub enum RenderState {
|
||||
IdleRenderState,
|
||||
RenderingRenderState,
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
#[deriving(Eq, Clone)]
|
||||
pub enum ReadyState {
|
||||
/// Informs the compositor that nothing has been done yet. Used for setting status
|
||||
Blank,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue