Sending key events through script task before processing them in the compositor.

Fixes #4163
This commit is contained in:
Nathan E. Egge 2014-12-12 10:19:04 -05:00
parent f451005f4f
commit b0552cb98e
10 changed files with 131 additions and 66 deletions

View file

@ -4,6 +4,7 @@
use compositor_layer::{CompositorData, CompositorLayer, DoesntWantScrollEvents};
use compositor_layer::{WantsScrollEvents};
use compositor_task;
use compositor_task::{ChangePageLoadData, ChangePageTitle, ChangePaintState, ChangeReadyState};
use compositor_task::{CompositorEventListener, CompositorProxy, CompositorReceiver};
use compositor_task::{CompositorTask, CreateOrUpdateDescendantLayer, CreateOrUpdateRootLayer};
@ -336,6 +337,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
}
(compositor_task::KeyEvent(key, modified), NotShuttingDown) => {
self.window.handle_key(key, modified);
}
// 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

@ -20,6 +20,7 @@ use layers::layers::LayerBufferSet;
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::memory::MemoryProfilerChan;
use servo_util::time::TimeProfilerChan;
use std::comm::{channel, Sender, Receiver};
@ -85,6 +86,12 @@ impl ScriptListener for Box<CompositorProxy+'static+Send> {
fn set_title(&mut self, pipeline_id: PipelineId, title: Option<String>) {
self.send(ChangePageTitle(pipeline_id, title))
}
fn send_key_event(&mut self, key: Key, state: KeyState, modifiers: KeyModifiers) {
if state == Pressed {
self.send(KeyEvent(key, modifiers));
}
}
}
/// Information about each layer that the compositor keeps.
@ -204,6 +211,8 @@ pub enum Msg {
/// Indicates that the scrolling timeout with the given starting timestamp has happened and a
/// composite should happen. (See the `scrolling` module.)
ScrollTimeout(u64),
/// Sends an unconsumed key event back to the compositor.
KeyEvent(Key, KeyModifiers),
}
impl Show for Msg {
@ -226,6 +235,7 @@ impl Show for Msg {
FrameTreeUpdateMsg(..) => write!(f, "FrameTreeUpdateMsg"),
LoadComplete => write!(f, "LoadComplete"),
ScrollTimeout(..) => write!(f, "ScrollTimeout"),
KeyEvent(..) => write!(f, "KeyEvent"),
}
}
}

View file

@ -6,7 +6,7 @@ use compositor_task::{GetGraphicsMetadata, CreateOrUpdateRootLayer, CreateOrUpda
use compositor_task::{Exit, ChangeReadyState, LoadComplete, Paint, ScrollFragmentPoint, SetIds};
use compositor_task::{SetLayerOrigin, ShutdownComplete, ChangePaintState, PaintMsgDiscarded};
use compositor_task::{CompositorEventListener, CompositorReceiver, ScrollTimeout, ChangePageTitle};
use compositor_task::{ChangePageLoadData, FrameTreeUpdateMsg};
use compositor_task::{ChangePageLoadData, FrameTreeUpdateMsg, KeyEvent};
use windowing::WindowEvent;
use geom::scale_factor::ScaleFactor;
@ -106,7 +106,7 @@ impl CompositorEventListener for NullCompositor {
SetLayerOrigin(..) | Paint(..) |
ChangeReadyState(..) | ChangePaintState(..) | ScrollFragmentPoint(..) |
LoadComplete | PaintMsgDiscarded(..) | ScrollTimeout(..) | ChangePageTitle(..) |
ChangePageLoadData(..) => ()
ChangePageLoadData(..) | KeyEvent(..) => ()
}
true
}

View file

@ -123,5 +123,7 @@ pub trait WindowMethods {
/// some type of platform-specific graphics context current. Returns true if the composite may
/// proceed and false if it should not.
fn prepare_for_composite(&self) -> bool;
}
/// Process a key event.
fn handle_key(&self, key: Key, mods: KeyModifiers);
}