compositing: Implement cursor per CSS3-UI § 8.1.1 in the CEF/Mac port.

I'm not sure how we want to handle Linux cursors, and GLFW has no
ability to set cursors (short of disabling it and managing it yourself).
This commit is contained in:
Patrick Walton 2014-12-12 07:18:16 -08:00
parent 636641f905
commit 7371e0b8e3
23 changed files with 564 additions and 171 deletions

View file

@ -3,8 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use compositor_layer::{CompositorData, CompositorLayer, WantsScrollEventsFlag};
use compositor_task::{CompositorEventListener, CompositorProxy, CompositorReceiver, CompositorTask};
use compositor_task::{LayerProperties, Msg};
use compositor_task::{CompositorEventListener, CompositorProxy, CompositorReceiver};
use compositor_task::{CompositorTask, LayerProperties, Msg};
use constellation::{FrameId, FrameTreeDiff, SendableFrameTree};
use pipeline::CompositionPipeline;
use scrolling::ScrollingTimerProxy;
@ -338,6 +338,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.window.handle_key(key, modified);
}
(Msg::SetCursor(cursor), ShutdownState::NotShuttingDown) => {
self.window.set_cursor(cursor)
}
// When we are shutting_down, we need to avoid performing operations
// such as Paint that may crash because we have begun tearing down
// the rest of our resources.

View file

@ -21,6 +21,7 @@ use servo_msg::compositor_msg::{Epoch, LayerId, LayerMetadata, ReadyState};
use servo_msg::compositor_msg::{PaintListener, PaintState, ScriptListener, ScrollPolicy};
use servo_msg::constellation_msg::{ConstellationChan, LoadData, PipelineId};
use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers, Pressed};
use servo_util::cursor::Cursor;
use servo_util::memory::MemoryProfilerChan;
use servo_util::time::TimeProfilerChan;
use std::comm::{channel, Sender, Receiver};
@ -213,6 +214,8 @@ pub enum Msg {
ScrollTimeout(u64),
/// Sends an unconsumed key event back to the compositor.
KeyEvent(Key, KeyModifiers),
/// Changes the cursor.
SetCursor(Cursor),
}
impl Show for Msg {
@ -231,11 +234,12 @@ impl Show for Msg {
Msg::ChangePageTitle(..) => write!(f, "ChangePageTitle"),
Msg::ChangePageLoadData(..) => write!(f, "ChangePageLoadData"),
Msg::PaintMsgDiscarded(..) => write!(f, "PaintMsgDiscarded"),
Msg::FrameTreeUpdate(..) => write!(f, "FrameTreeUpdate"),
Msg::SetIds(..) => write!(f, "SetIds"),
Msg::FrameTreeUpdate(..) => write!(f, "FrameTreeUpdateMsg"),
Msg::LoadComplete => write!(f, "LoadComplete"),
Msg::ScrollTimeout(..) => write!(f, "ScrollTimeout"),
Msg::KeyEvent(..) => write!(f, "KeyEvent"),
Msg::SetCursor(..) => write!(f, "SetCursor"),
}
}
}

View file

@ -18,20 +18,21 @@ use libc;
use script_traits::{mod, GetTitleMsg, ResizeMsg, ResizeInactiveMsg, ExitPipelineMsg, SendEventMsg};
use script_traits::{ScriptControlChan, ScriptTaskFactory};
use servo_msg::compositor_msg::LayerId;
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, Failure, FrameRectMsg};
use servo_msg::constellation_msg::{GetPipelineTitleMsg};
use servo_msg::constellation_msg::{mod, ConstellationChan, ExitMsg, FailureMsg, Failure};
use servo_msg::constellation_msg::{FrameRectMsg, GetPipelineTitleMsg};
use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg};
use servo_msg::constellation_msg::{KeyEvent, Key, KeyState, KeyModifiers, LoadCompleteMsg};
use servo_msg::constellation_msg::{LoadData, LoadUrlMsg, NavigateMsg, NavigationType};
use servo_msg::constellation_msg::{PainterReadyMsg, PipelineId, ResizedWindowMsg};
use servo_msg::constellation_msg::{ScriptLoadedURLInIFrameMsg, SubpageId, WindowSizeData};
use servo_msg::constellation_msg::{ScriptLoadedURLInIFrameMsg, SetCursorMsg, SubpageId};
use servo_msg::constellation_msg::{WindowSizeData};
use servo_msg::constellation_msg::Msg as ConstellationMsg;
use servo_msg::constellation_msg;
use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
use servo_net::resource_task::ResourceTask;
use servo_net::resource_task;
use servo_net::storage_task::StorageTask;
use servo_net::storage_task;
use servo_util::cursor::Cursor;
use servo_util::geometry::{PagePx, ViewportPx};
use servo_util::opts;
use servo_util::task::spawn_named;
@ -472,6 +473,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
subpage_id,
sandbox);
}
SetCursorMsg(cursor) => self.handle_set_cursor_msg(cursor),
// Load a new page, usually -- but not always -- from a mouse click or typed url
// If there is already a pending page (self.pending_frames), it will not be overridden;
// However, if the id is not encompassed by another change, it will be.
@ -754,6 +756,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
self.pipelines.insert(pipeline.id, pipeline);
}
fn handle_set_cursor_msg(&mut self, cursor: Cursor) {
self.compositor_proxy.send(CompositorMsg::SetCursor(cursor))
}
fn handle_load_url_msg(&mut self, source_id: PipelineId, load_data: LoadData) {
let url = load_data.url.to_string();
debug!("Constellation: received message to load {:s}", url);

View file

@ -99,10 +99,18 @@ impl CompositorEventListener for NullCompositor {
Msg::CreateOrUpdateRootLayer(..) |
Msg::CreateOrUpdateDescendantLayer(..) |
Msg::SetLayerOrigin(..) | Msg::Paint(..) |
Msg::ChangeReadyState(..) | Msg::ChangePaintState(..) | Msg::ScrollFragmentPoint(..) |
Msg::LoadComplete | Msg::PaintMsgDiscarded(..) | Msg::ScrollTimeout(..) | Msg::ChangePageTitle(..) |
Msg::ChangePageLoadData(..) | Msg::KeyEvent(..) => ()
Msg::SetLayerOrigin(..) |
Msg::Paint(..) |
Msg::ChangeReadyState(..) |
Msg::ChangePaintState(..) |
Msg::ScrollFragmentPoint(..) |
Msg::LoadComplete |
Msg::PaintMsgDiscarded(..) |
Msg::ScrollTimeout(..) |
Msg::ChangePageTitle(..) |
Msg::ChangePageLoadData(..) |
Msg::KeyEvent(..) |
Msg::SetCursor(..) => {}
}
true
}

View file

@ -13,6 +13,7 @@ use layers::geometry::DevicePixel;
use layers::platform::surface::NativeGraphicsMetadata;
use servo_msg::compositor_msg::{PaintState, ReadyState};
use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers, LoadData};
use servo_util::cursor::Cursor;
use servo_util::geometry::ScreenPx;
use std::fmt::{FormatError, Formatter, Show};
use std::rc::Rc;
@ -124,6 +125,9 @@ pub trait WindowMethods {
/// proceed and false if it should not.
fn prepare_for_composite(&self) -> bool;
/// Sets the cursor to be used in the window.
fn set_cursor(&self, cursor: Cursor);
/// Process a key event.
fn handle_key(&self, key: Key, mods: KeyModifiers);
}