mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
separate waking the event loop, from communicating with a compositor
This commit is contained in:
parent
eac4f407e2
commit
3a693c7a23
9 changed files with 103 additions and 108 deletions
|
@ -103,7 +103,7 @@ pub struct IOCompositor<Window: WindowMethods> {
|
||||||
window: Rc<Window>,
|
window: Rc<Window>,
|
||||||
|
|
||||||
/// The port on which we receive messages.
|
/// The port on which we receive messages.
|
||||||
port: Box<CompositorReceiver>,
|
port: CompositorReceiver,
|
||||||
|
|
||||||
/// The root pipeline.
|
/// The root pipeline.
|
||||||
root_pipeline: Option<CompositionPipeline>,
|
root_pipeline: Option<CompositionPipeline>,
|
||||||
|
@ -133,7 +133,7 @@ pub struct IOCompositor<Window: WindowMethods> {
|
||||||
/// The device pixel ratio for this window.
|
/// The device pixel ratio for this window.
|
||||||
scale_factor: ScaleFactor<f32, DeviceIndependentPixel, DevicePixel>,
|
scale_factor: ScaleFactor<f32, DeviceIndependentPixel, DevicePixel>,
|
||||||
|
|
||||||
channel_to_self: Box<CompositorProxy + Send>,
|
channel_to_self: CompositorProxy,
|
||||||
|
|
||||||
/// A handle to the delayed composition timer.
|
/// A handle to the delayed composition timer.
|
||||||
delayed_composition_timer: DelayedCompositionTimerProxy,
|
delayed_composition_timer: DelayedCompositionTimerProxy,
|
||||||
|
@ -317,11 +317,11 @@ fn initialize_png(gl: &gl::Gl, width: usize, height: usize) -> RenderTargetInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RenderNotifier {
|
struct RenderNotifier {
|
||||||
compositor_proxy: Box<CompositorProxy>,
|
compositor_proxy: CompositorProxy,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderNotifier {
|
impl RenderNotifier {
|
||||||
fn new(compositor_proxy: Box<CompositorProxy>,
|
fn new(compositor_proxy: CompositorProxy,
|
||||||
_: Sender<ConstellationMsg>) -> RenderNotifier {
|
_: Sender<ConstellationMsg>) -> RenderNotifier {
|
||||||
RenderNotifier {
|
RenderNotifier {
|
||||||
compositor_proxy: compositor_proxy,
|
compositor_proxy: compositor_proxy,
|
||||||
|
@ -341,7 +341,7 @@ impl webrender_traits::RenderNotifier for RenderNotifier {
|
||||||
|
|
||||||
// Used to dispatch functions from webrender to the main thread's event loop.
|
// Used to dispatch functions from webrender to the main thread's event loop.
|
||||||
struct CompositorThreadDispatcher {
|
struct CompositorThreadDispatcher {
|
||||||
compositor_proxy: Box<CompositorProxy>
|
compositor_proxy: CompositorProxy
|
||||||
}
|
}
|
||||||
|
|
||||||
impl webrender_traits::RenderDispatcher for CompositorThreadDispatcher {
|
impl webrender_traits::RenderDispatcher for CompositorThreadDispatcher {
|
||||||
|
|
|
@ -22,32 +22,46 @@ use style_traits::viewport::ViewportConstraints;
|
||||||
use webrender;
|
use webrender;
|
||||||
use webrender_traits;
|
use webrender_traits;
|
||||||
|
|
||||||
/// Sends messages to the compositor. This is a trait supplied by the port because the method used
|
|
||||||
/// to communicate with the compositor may have to kick OS event loops awake, communicate cross-
|
/// Used to wake up the event loop, provided by the servo port/embedder.
|
||||||
/// process, and so forth.
|
pub trait EventLoopWaker : 'static + Send {
|
||||||
pub trait CompositorProxy : 'static + Send {
|
fn clone(&self) -> Box<EventLoopWaker + Send>;
|
||||||
/// Sends a message to the compositor.
|
fn wake(&self);
|
||||||
fn send(&self, msg: Msg);
|
|
||||||
/// Clones the compositor proxy.
|
|
||||||
fn clone_compositor_proxy(&self) -> Box<CompositorProxy + 'static + Send>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The port that the compositor receives messages on. As above, this is a trait supplied by the
|
/// Sends messages to the compositor.
|
||||||
/// Servo port.
|
pub struct CompositorProxy {
|
||||||
pub trait CompositorReceiver : 'static {
|
pub sender: Sender<Msg>,
|
||||||
/// Receives the next message inbound for the compositor. This must not block.
|
pub event_loop_waker: Box<EventLoopWaker>,
|
||||||
fn try_recv_compositor_msg(&mut self) -> Option<Msg>;
|
|
||||||
/// Synchronously waits for, and returns, the next message inbound for the compositor.
|
|
||||||
fn recv_compositor_msg(&mut self) -> Msg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A convenience implementation of `CompositorReceiver` for a plain old Rust `Receiver`.
|
impl CompositorProxy {
|
||||||
impl CompositorReceiver for Receiver<Msg> {
|
pub fn send(&self, msg: Msg) {
|
||||||
fn try_recv_compositor_msg(&mut self) -> Option<Msg> {
|
// Send a message and kick the OS event loop awake.
|
||||||
self.try_recv().ok()
|
if let Err(err) = self.sender.send(msg) {
|
||||||
|
warn!("Failed to send response ({}).", err);
|
||||||
|
}
|
||||||
|
self.event_loop_waker.wake();
|
||||||
}
|
}
|
||||||
fn recv_compositor_msg(&mut self) -> Msg {
|
pub fn clone_compositor_proxy(&self) -> CompositorProxy {
|
||||||
self.recv().unwrap()
|
CompositorProxy {
|
||||||
|
sender: self.sender.clone(),
|
||||||
|
event_loop_waker: self.event_loop_waker.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The port that the compositor receives messages on.
|
||||||
|
pub struct CompositorReceiver {
|
||||||
|
pub receiver: Receiver<Msg>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CompositorReceiver {
|
||||||
|
pub fn try_recv_compositor_msg(&mut self) -> Option<Msg> {
|
||||||
|
self.receiver.try_recv().ok()
|
||||||
|
}
|
||||||
|
pub fn recv_compositor_msg(&mut self) -> Msg {
|
||||||
|
self.receiver.recv().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +69,7 @@ pub trait RenderListener {
|
||||||
fn recomposite(&mut self, reason: CompositingReason);
|
fn recomposite(&mut self, reason: CompositingReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderListener for Box<CompositorProxy + 'static> {
|
impl RenderListener for CompositorProxy {
|
||||||
fn recomposite(&mut self, reason: CompositingReason) {
|
fn recomposite(&mut self, reason: CompositingReason) {
|
||||||
self.send(Msg::Recomposite(reason));
|
self.send(Msg::Recomposite(reason));
|
||||||
}
|
}
|
||||||
|
@ -173,9 +187,9 @@ impl Debug for Msg {
|
||||||
/// Data used to construct a compositor.
|
/// Data used to construct a compositor.
|
||||||
pub struct InitialCompositorState {
|
pub struct InitialCompositorState {
|
||||||
/// A channel to the compositor.
|
/// A channel to the compositor.
|
||||||
pub sender: Box<CompositorProxy + Send>,
|
pub sender: CompositorProxy,
|
||||||
/// A port on which messages inbound to the compositor can be received.
|
/// A port on which messages inbound to the compositor can be received.
|
||||||
pub receiver: Box<CompositorReceiver>,
|
pub receiver: CompositorReceiver,
|
||||||
/// A channel to the constellation.
|
/// A channel to the constellation.
|
||||||
pub constellation_chan: Sender<ConstellationMsg>,
|
pub constellation_chan: Sender<ConstellationMsg>,
|
||||||
/// A channel to the time profiler thread.
|
/// A channel to the time profiler thread.
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub struct DelayedCompositionTimerProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DelayedCompositionTimer {
|
struct DelayedCompositionTimer {
|
||||||
compositor_proxy: Box<CompositorProxy>,
|
compositor_proxy: CompositorProxy,
|
||||||
receiver: Receiver<ToDelayedCompositionTimerMsg>,
|
receiver: Receiver<ToDelayedCompositionTimerMsg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ enum ToDelayedCompositionTimerMsg {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DelayedCompositionTimerProxy {
|
impl DelayedCompositionTimerProxy {
|
||||||
pub fn new(compositor_proxy: Box<CompositorProxy + Send>) -> DelayedCompositionTimerProxy {
|
pub fn new(compositor_proxy: CompositorProxy) -> DelayedCompositionTimerProxy {
|
||||||
let (to_timer_sender, to_timer_receiver) = channel();
|
let (to_timer_sender, to_timer_receiver) = channel();
|
||||||
Builder::new().spawn(move || {
|
Builder::new().spawn(move || {
|
||||||
let mut timer = DelayedCompositionTimer {
|
let mut timer = DelayedCompositionTimer {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
|
//! Abstract windowing methods. The concrete implementations of these can be found in `platform/`.
|
||||||
|
|
||||||
use compositor_thread::{CompositorProxy, CompositorReceiver};
|
use compositor_thread::EventLoopWaker;
|
||||||
use euclid::{Point2D, Size2D};
|
use euclid::{Point2D, Size2D};
|
||||||
use euclid::point::TypedPoint2D;
|
use euclid::point::TypedPoint2D;
|
||||||
use euclid::rect::TypedRect;
|
use euclid::rect::TypedRect;
|
||||||
|
@ -144,12 +144,8 @@ pub trait WindowMethods {
|
||||||
/// Returns the scale factor of the system (device pixels / device independent pixels).
|
/// Returns the scale factor of the system (device pixels / device independent pixels).
|
||||||
fn hidpi_factor(&self) -> ScaleFactor<f32, DeviceIndependentPixel, DevicePixel>;
|
fn hidpi_factor(&self) -> ScaleFactor<f32, DeviceIndependentPixel, DevicePixel>;
|
||||||
|
|
||||||
/// Creates a channel to the compositor. The dummy parameter is needed because we don't have
|
/// Returns a thread-safe object to wake up the window's event loop.
|
||||||
/// UFCS in Rust yet.
|
fn create_event_loop_waker(&self) -> Box<EventLoopWaker>;
|
||||||
///
|
|
||||||
/// This is part of the windowing system because its implementation often involves OS-specific
|
|
||||||
/// magic to wake the up window's event loop.
|
|
||||||
fn create_compositor_channel(&self) -> (Box<CompositorProxy + Send>, Box<CompositorReceiver>);
|
|
||||||
|
|
||||||
/// Requests that the window system prepare a composite. Typically this will involve making
|
/// Requests that the window system prepare a composite. Typically this will involve making
|
||||||
/// some type of platform-specific graphics context current. Returns true if the composite may
|
/// some type of platform-specific graphics context current. Returns true if the composite may
|
||||||
|
|
|
@ -172,7 +172,7 @@ pub struct Constellation<Message, LTF, STF> {
|
||||||
|
|
||||||
/// A channel (the implementation of which is port-specific) for the
|
/// A channel (the implementation of which is port-specific) for the
|
||||||
/// constellation to send messages to the compositor thread.
|
/// constellation to send messages to the compositor thread.
|
||||||
compositor_proxy: Box<CompositorProxy>,
|
compositor_proxy: CompositorProxy,
|
||||||
|
|
||||||
/// Channels for the constellation to send messages to the public
|
/// Channels for the constellation to send messages to the public
|
||||||
/// resource-related threads. There are two groups of resource
|
/// resource-related threads. There are two groups of resource
|
||||||
|
@ -302,7 +302,7 @@ pub struct Constellation<Message, LTF, STF> {
|
||||||
/// State needed to construct a constellation.
|
/// State needed to construct a constellation.
|
||||||
pub struct InitialConstellationState {
|
pub struct InitialConstellationState {
|
||||||
/// A channel through which messages can be sent to the compositor.
|
/// A channel through which messages can be sent to the compositor.
|
||||||
pub compositor_proxy: Box<CompositorProxy + Send>,
|
pub compositor_proxy: CompositorProxy,
|
||||||
|
|
||||||
/// A channel to the debugger, if applicable.
|
/// A channel to the debugger, if applicable.
|
||||||
pub debugger_chan: Option<debugger::Sender>,
|
pub debugger_chan: Option<debugger::Sender>,
|
||||||
|
|
|
@ -69,7 +69,7 @@ pub struct Pipeline {
|
||||||
pub layout_chan: IpcSender<LayoutControlMsg>,
|
pub layout_chan: IpcSender<LayoutControlMsg>,
|
||||||
|
|
||||||
/// A channel to the compositor.
|
/// A channel to the compositor.
|
||||||
pub compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
pub compositor_proxy: CompositorProxy,
|
||||||
|
|
||||||
/// The most recently loaded URL in this pipeline.
|
/// The most recently loaded URL in this pipeline.
|
||||||
/// Note that this URL can change, for example if the page navigates
|
/// Note that this URL can change, for example if the page navigates
|
||||||
|
@ -123,7 +123,7 @@ pub struct InitialPipelineState {
|
||||||
pub scheduler_chan: IpcSender<TimerSchedulerMsg>,
|
pub scheduler_chan: IpcSender<TimerSchedulerMsg>,
|
||||||
|
|
||||||
/// A channel to the compositor.
|
/// A channel to the compositor.
|
||||||
pub compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
pub compositor_proxy: CompositorProxy,
|
||||||
|
|
||||||
/// A channel to the developer tools, if applicable.
|
/// A channel to the developer tools, if applicable.
|
||||||
pub devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
pub devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||||
|
@ -303,7 +303,7 @@ impl Pipeline {
|
||||||
parent_info: Option<(PipelineId, FrameType)>,
|
parent_info: Option<(PipelineId, FrameType)>,
|
||||||
event_loop: Rc<EventLoop>,
|
event_loop: Rc<EventLoop>,
|
||||||
layout_chan: IpcSender<LayoutControlMsg>,
|
layout_chan: IpcSender<LayoutControlMsg>,
|
||||||
compositor_proxy: Box<CompositorProxy + 'static + Send>,
|
compositor_proxy: CompositorProxy,
|
||||||
is_private: bool,
|
is_private: bool,
|
||||||
url: ServoUrl,
|
url: ServoUrl,
|
||||||
visible: bool)
|
visible: bool)
|
||||||
|
|
|
@ -68,8 +68,8 @@ fn webdriver(_port: u16, _constellation: Sender<ConstellationMsg>) { }
|
||||||
|
|
||||||
use bluetooth::BluetoothThreadFactory;
|
use bluetooth::BluetoothThreadFactory;
|
||||||
use bluetooth_traits::BluetoothRequest;
|
use bluetooth_traits::BluetoothRequest;
|
||||||
use compositing::{CompositorProxy, IOCompositor};
|
use compositing::IOCompositor;
|
||||||
use compositing::compositor_thread::InitialCompositorState;
|
use compositing::compositor_thread::{self, CompositorProxy, CompositorReceiver, InitialCompositorState};
|
||||||
use compositing::windowing::WindowEvent;
|
use compositing::windowing::WindowEvent;
|
||||||
use compositing::windowing::WindowMethods;
|
use compositing::windowing::WindowMethods;
|
||||||
use constellation::{Constellation, InitialConstellationState, UnprivilegedPipelineContent};
|
use constellation::{Constellation, InitialConstellationState, UnprivilegedPipelineContent};
|
||||||
|
@ -97,7 +97,7 @@ use std::borrow::Cow;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::{Sender, channel};
|
||||||
use webrender::renderer::RendererKind;
|
use webrender::renderer::RendererKind;
|
||||||
use webvr::{WebVRThread, WebVRCompositorHandler};
|
use webvr::{WebVRThread, WebVRCompositorHandler};
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static {
|
||||||
// messages to client may need to pump a platform-specific event loop
|
// messages to client may need to pump a platform-specific event loop
|
||||||
// to deliver the message.
|
// to deliver the message.
|
||||||
let (compositor_proxy, compositor_receiver) =
|
let (compositor_proxy, compositor_receiver) =
|
||||||
window.create_compositor_channel();
|
create_compositor_channel(window.create_event_loop_waker());
|
||||||
let supports_clipboard = window.supports_clipboard();
|
let supports_clipboard = window.supports_clipboard();
|
||||||
let time_profiler_chan = profile_time::Profiler::create(&opts.time_profiling,
|
let time_profiler_chan = profile_time::Profiler::create(&opts.time_profiling,
|
||||||
opts.time_profiler_trace_path.clone());
|
opts.time_profiler_trace_path.clone());
|
||||||
|
@ -273,10 +273,22 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_compositor_channel(event_loop_waker: Box<compositor_thread::EventLoopWaker>)
|
||||||
|
-> (CompositorProxy, CompositorReceiver) {
|
||||||
|
let (sender, receiver) = channel();
|
||||||
|
(CompositorProxy {
|
||||||
|
sender: sender,
|
||||||
|
event_loop_waker: event_loop_waker,
|
||||||
|
},
|
||||||
|
CompositorReceiver {
|
||||||
|
receiver: receiver
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn create_constellation(user_agent: Cow<'static, str>,
|
fn create_constellation(user_agent: Cow<'static, str>,
|
||||||
config_dir: Option<PathBuf>,
|
config_dir: Option<PathBuf>,
|
||||||
url: Option<ServoUrl>,
|
url: Option<ServoUrl>,
|
||||||
compositor_proxy: Box<CompositorProxy + Send>,
|
compositor_proxy: CompositorProxy,
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
debugger_chan: Option<debugger::Sender>,
|
debugger_chan: Option<debugger::Sender>,
|
||||||
|
|
|
@ -17,7 +17,7 @@ use render_handler::CefRenderHandlerExtensions;
|
||||||
use types::{cef_cursor_handle_t, cef_cursor_type_t, cef_rect_t};
|
use types::{cef_cursor_handle_t, cef_cursor_type_t, cef_rect_t};
|
||||||
use wrappers::CefWrap;
|
use wrappers::CefWrap;
|
||||||
|
|
||||||
use compositing::compositor_thread::{self, CompositorProxy, CompositorReceiver};
|
use compositing::compositor_thread::EventLoopWaker;
|
||||||
use compositing::windowing::{WindowEvent, WindowMethods};
|
use compositing::windowing::{WindowEvent, WindowMethods};
|
||||||
use euclid::point::{Point2D, TypedPoint2D};
|
use euclid::point::{Point2D, TypedPoint2D};
|
||||||
use euclid::rect::TypedRect;
|
use euclid::rect::TypedRect;
|
||||||
|
@ -295,13 +295,17 @@ impl WindowMethods for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_compositor_channel(&self)
|
fn create_event_loop_waker(&self) -> Box<EventLoopWaker> {
|
||||||
-> (Box<CompositorProxy+Send>, Box<CompositorReceiver>) {
|
struct CefEventLoopWaker;
|
||||||
let (sender, receiver) = channel();
|
impl EventLoopWaker for CefEventLoopWaker {
|
||||||
(box CefCompositorProxy {
|
fn wake(&self) {
|
||||||
sender: sender,
|
app_wakeup();
|
||||||
} as Box<CompositorProxy+Send>,
|
}
|
||||||
box receiver as Box<CompositorReceiver>)
|
fn clone(&self) -> Box<EventLoopWaker + Send> {
|
||||||
|
box CefEventLoopWaker
|
||||||
|
}
|
||||||
|
}
|
||||||
|
box CefEventLoopWaker
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_for_composite(&self, width: usize, height: usize) -> bool {
|
fn prepare_for_composite(&self, width: usize, height: usize) -> bool {
|
||||||
|
@ -500,23 +504,6 @@ impl WindowMethods for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CefCompositorProxy {
|
|
||||||
sender: Sender<compositor_thread::Msg>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CompositorProxy for CefCompositorProxy {
|
|
||||||
fn send(&self, msg: compositor_thread::Msg) {
|
|
||||||
self.sender.send(msg).unwrap();
|
|
||||||
app_wakeup();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clone_compositor_proxy(&self) -> Box<CompositorProxy+Send> {
|
|
||||||
box CefCompositorProxy {
|
|
||||||
sender: self.sender.clone(),
|
|
||||||
} as Box<CompositorProxy+Send>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os="macos")]
|
#[cfg(target_os="macos")]
|
||||||
pub fn app_wakeup() {
|
pub fn app_wakeup() {
|
||||||
use cocoa::appkit::{NSApp, NSApplication, NSApplicationDefined};
|
use cocoa::appkit::{NSApp, NSApplication, NSApplicationDefined};
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//! A windowing implementation using glutin.
|
//! A windowing implementation using glutin.
|
||||||
|
|
||||||
use NestedEventLoopListener;
|
use NestedEventLoopListener;
|
||||||
use compositing::compositor_thread::{self, CompositorProxy, CompositorReceiver};
|
use compositing::compositor_thread::EventLoopWaker;
|
||||||
use compositing::windowing::{MouseWindowEvent, WindowNavigateMsg};
|
use compositing::windowing::{MouseWindowEvent, WindowNavigateMsg};
|
||||||
use compositing::windowing::{WindowEvent, WindowMethods};
|
use compositing::windowing::{WindowEvent, WindowMethods};
|
||||||
use euclid::{Point2D, Size2D, TypedPoint2D};
|
use euclid::{Point2D, Size2D, TypedPoint2D};
|
||||||
|
@ -41,7 +41,6 @@ use std::mem;
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::{Sender, channel};
|
|
||||||
use style_traits::cursor::Cursor;
|
use style_traits::cursor::Cursor;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use user32;
|
use user32;
|
||||||
|
@ -1047,17 +1046,27 @@ impl WindowMethods for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_compositor_channel(&self)
|
fn create_event_loop_waker(&self) -> Box<EventLoopWaker> {
|
||||||
-> (Box<CompositorProxy + Send>, Box<CompositorReceiver>) {
|
struct GlutinEventLoopWaker {
|
||||||
let (sender, receiver) = channel();
|
window_proxy: Option<glutin::WindowProxy>,
|
||||||
|
}
|
||||||
|
impl EventLoopWaker for GlutinEventLoopWaker {
|
||||||
|
fn wake(&self) {
|
||||||
|
// kick the OS event loop awake.
|
||||||
|
if let Some(ref window_proxy) = self.window_proxy {
|
||||||
|
window_proxy.wakeup_event_loop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn clone(&self) -> Box<EventLoopWaker + Send> {
|
||||||
|
box GlutinEventLoopWaker {
|
||||||
|
window_proxy: self.window_proxy.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let window_proxy = create_window_proxy(self);
|
let window_proxy = create_window_proxy(self);
|
||||||
|
box GlutinEventLoopWaker {
|
||||||
(box GlutinCompositorProxy {
|
window_proxy: window_proxy,
|
||||||
sender: sender,
|
}
|
||||||
window_proxy: window_proxy,
|
|
||||||
} as Box<CompositorProxy + Send>,
|
|
||||||
box receiver as Box<CompositorReceiver>)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
@ -1289,29 +1298,6 @@ impl WindowMethods for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GlutinCompositorProxy {
|
|
||||||
sender: Sender<compositor_thread::Msg>,
|
|
||||||
window_proxy: Option<glutin::WindowProxy>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CompositorProxy for GlutinCompositorProxy {
|
|
||||||
fn send(&self, msg: compositor_thread::Msg) {
|
|
||||||
// Send a message and kick the OS event loop awake.
|
|
||||||
if let Err(err) = self.sender.send(msg) {
|
|
||||||
warn!("Failed to send response ({}).", err);
|
|
||||||
}
|
|
||||||
if let Some(ref window_proxy) = self.window_proxy {
|
|
||||||
window_proxy.wakeup_event_loop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn clone_compositor_proxy(&self) -> Box<CompositorProxy + Send> {
|
|
||||||
box GlutinCompositorProxy {
|
|
||||||
sender: self.sender.clone(),
|
|
||||||
window_proxy: self.window_proxy.clone(),
|
|
||||||
} as Box<CompositorProxy + Send>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn glutin_phase_to_touch_event_type(phase: TouchPhase) -> TouchEventType {
|
fn glutin_phase_to_touch_event_type(phase: TouchPhase) -> TouchEventType {
|
||||||
match phase {
|
match phase {
|
||||||
TouchPhase::Started => TouchEventType::Down,
|
TouchPhase::Started => TouchEventType::Down,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue