Skip to content

Commit 92ac3d6

Browse files
committed
Remove crossbeam dependency and make drop events work again
1 parent 8299eb2 commit 92ac3d6

File tree

7 files changed

+64
-54
lines changed

7 files changed

+64
-54
lines changed

Cargo.toml

-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ cocoa = "0.18.4"
3535
core-foundation = "0.6"
3636
core-graphics = "0.17.3"
3737

38-
[target.'cfg(target_os = "windows")'.dependencies.crossbeam-channel]
39-
version = "0.3"
40-
4138
[target.'cfg(target_os = "windows")'.dependencies.winapi]
4239
version = "0.3.6"
4340
features = [

src/event_loop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use monitor::{AvailableMonitorsIter, MonitorHandle};
2929
/// forbidding it), as such it is neither `Send` nor `Sync`. If you need cross-thread access, the
3030
/// `Window` created from this `EventLoop` _can_ be sent to an other thread, and the
3131
/// `EventLoopProxy` allows you to wake up an `EventLoop` from an other thread.
32-
pub struct EventLoop<T> {
32+
pub struct EventLoop<T: 'static> {
3333
pub(crate) event_loop: platform_impl::EventLoop<T>,
3434
pub(crate) _marker: ::std::marker::PhantomData<*mut ()> // Not Send nor Sync
3535
}

src/lib.rs

-3
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,6 @@ extern crate serde;
8989

9090
#[cfg(target_os = "windows")]
9191
extern crate winapi;
92-
#[cfg(target_os = "windows")]
93-
#[macro_use]
94-
extern crate crossbeam_channel;
9592
#[cfg(any(target_os = "macos", target_os = "ios"))]
9693
#[macro_use]
9794
extern crate objc;

src/platform_impl/windows/drop_handler.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::os::windows::ffi::OsStringExt;
33
use std::path::PathBuf;
44
use std::sync::atomic::{AtomicUsize, Ordering};
55
use std::{mem, ptr};
6-
use crossbeam_channel::Sender;
76

87
use winapi::ctypes::c_void;
98
use winapi::shared::guiddef::REFIID;
@@ -25,7 +24,7 @@ pub struct FileDropHandlerData {
2524
pub interface: IDropTarget,
2625
refcount: AtomicUsize,
2726
window: HWND,
28-
// event_sender: Sender<Event<()>>
27+
send_event: Box<Fn(Event<()>)>
2928
}
3029

3130
pub struct FileDropHandler {
@@ -34,14 +33,14 @@ pub struct FileDropHandler {
3433

3534
#[allow(non_snake_case)]
3635
impl FileDropHandler {
37-
pub fn new(window: HWND/*, event_sender: Sender<Event<()>>*/) -> FileDropHandler {
36+
pub fn new(window: HWND, send_event: Box<Fn(Event<()>)>) -> FileDropHandler {
3837
let data = Box::new(FileDropHandlerData {
3938
interface: IDropTarget {
4039
lpVtbl: &DROP_TARGET_VTBL as *const IDropTargetVtbl,
4140
},
4241
refcount: AtomicUsize::new(1),
4342
window,
44-
// event_sender,
43+
send_event,
4544
});
4645
FileDropHandler {
4746
data: Box::into_raw(data),
@@ -187,7 +186,7 @@ impl FileDropHandler {
187186

188187
impl FileDropHandlerData {
189188
fn send_event(&self, event: Event<()>) {
190-
// self.event_sender.send(event).ok();
189+
(self.send_event)(event);
191190
}
192191
}
193192

src/platform_impl/windows/event_loop.rs

+50-37
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ use winapi::shared::basetsd::UINT_PTR;
1717
use std::{mem, ptr};
1818
use std::sync::Arc;
1919
use std::sync::atomic::{AtomicBool, Ordering};
20+
use std::sync::mpsc::{self, Sender, Receiver};
2021
use std::time::{Duration, Instant};
2122
use std::rc::Rc;
2223
use std::cell::RefCell;
2324
use std::collections::VecDeque;
2425
use parking_lot::Mutex;
25-
use crossbeam_channel::{self, Sender, Receiver};
2626

2727
use winapi::ctypes::c_int;
2828
use winapi::shared::minwindef::{
@@ -147,7 +147,7 @@ pub struct EventLoop<T> {
147147
pub(crate) runner_shared: EventLoopRunnerShared<T>,
148148
}
149149

150-
impl<T> EventLoop<T> {
150+
impl<T: 'static> EventLoop<T> {
151151
pub fn new() -> EventLoop<T> {
152152
Self::with_dpi_awareness(true)
153153
}
@@ -181,27 +181,24 @@ impl<T> EventLoop<T> {
181181
where F: FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
182182
{
183183
unsafe{ winuser::IsGUIThread(1); }
184-
let mut runner = EventLoopRunner {
185-
event_loop: self,
186-
control_flow: ControlFlow::default(),
187-
runner_state: RunnerState::New,
188-
in_modal_loop: false,
189-
modal_redraw_window: self.thread_msg_target,
190-
event_handler: unsafe {
191-
// Transmute used to erase lifetimes.
192-
mem::transmute::<
193-
&mut FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow),
194-
*mut FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
195-
>(&mut event_handler)
184+
185+
assert_eq!(mem::size_of::<RootEventLoop<T>>(), mem::size_of::<EventLoop<T>>());
186+
let self_ptr = self as *const EventLoop<T>;
187+
188+
let mut runner = unsafe{ EventLoopRunner::new(
189+
self,
190+
move |event, control_flow| {
191+
let event_loop_ref = &*(self_ptr as *const RootEventLoop<T>);
192+
event_handler(event, event_loop_ref, control_flow)
196193
}
197-
};
194+
) };
198195
{
199196
let runner_shared = self.runner_shared.clone();
200197
let mut runner_ref = runner_shared.runner.borrow_mut();
201198
loop {
202199
let event = runner_shared.buffer.borrow_mut().pop_front();
203200
match event {
204-
Some(e) => unsafe{ runner.process_event(e); },
201+
Some(e) => { runner.process_event(e); },
205202
None => break
206203
}
207204
}
@@ -246,7 +243,7 @@ impl<T> EventLoop<T> {
246243
}
247244
}
248245

249-
unsafe{ runner!().call_event_handler(Event::LoopDestroyed) }
246+
runner!().call_event_handler(Event::LoopDestroyed);
250247
*self.runner_shared.runner.borrow_mut() = None;
251248
}
252249

@@ -272,16 +269,16 @@ pub(crate) struct ELRShared<T> {
272269
buffer: RefCell<VecDeque<Event<T>>>
273270
}
274271
pub(crate) struct EventLoopRunner<T> {
275-
event_loop: *const EventLoop<T>,
272+
trigger_newevents_on_redraw: Arc<AtomicBool>,
276273
control_flow: ControlFlow,
277274
runner_state: RunnerState,
278275
modal_redraw_window: HWND,
279276
in_modal_loop: bool,
280-
event_handler: *mut FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
277+
event_handler: Box<FnMut(Event<T>, &mut ControlFlow)>
281278
}
282279

283280
impl<T> ELRShared<T> {
284-
unsafe fn send_event(&self, event: Event<T>) {
281+
pub(crate) unsafe fn send_event(&self, event: Event<T>) {
285282
if let Ok(mut runner_ref) = self.runner.try_borrow_mut() {
286283
if let Some(ref mut runner) = *runner_ref {
287284
runner.process_event(event);
@@ -308,7 +305,23 @@ enum RunnerState {
308305
}
309306

310307
impl<T> EventLoopRunner<T> {
311-
unsafe fn new_events(&mut self) {
308+
unsafe fn new<F>(event_loop: &EventLoop<T>, f: F) -> EventLoopRunner<T>
309+
where F: FnMut(Event<T>, &mut ControlFlow)
310+
{
311+
EventLoopRunner {
312+
trigger_newevents_on_redraw: event_loop.trigger_newevents_on_redraw.clone(),
313+
control_flow: ControlFlow::default(),
314+
runner_state: RunnerState::New,
315+
in_modal_loop: false,
316+
modal_redraw_window: event_loop.thread_msg_target,
317+
event_handler: mem::transmute::<
318+
Box<FnMut(Event<T>, &mut ControlFlow)>,
319+
Box<FnMut(Event<T>, &mut ControlFlow)>
320+
>(Box::new(f))
321+
}
322+
}
323+
324+
fn new_events(&mut self) {
312325
self.runner_state = match self.runner_state {
313326
// If we're already handling events or have deferred `NewEvents`, we don't need to do
314327
// do any processing.
@@ -359,19 +372,21 @@ impl<T> EventLoopRunner<T> {
359372
};
360373
}
361374

362-
unsafe fn process_event(&mut self, event: Event<T>) {
375+
fn process_event(&mut self, event: Event<T>) {
363376
// If we're in the modal loop, we need to have some mechanism for finding when the event
364377
// queue has been cleared so we can call `events_cleared`. Windows doesn't give any utilities
365378
// for doing this, but it DOES guarantee that WM_PAINT will only occur after input events have
366379
// been processed. So, we send WM_PAINT to a dummy window which calls `events_cleared` when
367380
// the events queue has been emptied.
368381
if self.in_modal_loop {
369-
winuser::RedrawWindow(
370-
self.modal_redraw_window,
371-
ptr::null(),
372-
ptr::null_mut(),
373-
winuser::RDW_INTERNALPAINT
374-
);
382+
unsafe {
383+
winuser::RedrawWindow(
384+
self.modal_redraw_window,
385+
ptr::null(),
386+
ptr::null_mut(),
387+
winuser::RDW_INTERNALPAINT
388+
);
389+
}
375390
}
376391

377392
// If new event processing has to be done (i.e. call NewEvents or defer), do it. If we're
@@ -419,7 +434,7 @@ impl<T> EventLoopRunner<T> {
419434
self.call_event_handler(event);
420435
}
421436

422-
unsafe fn events_cleared(&mut self) {
437+
fn events_cleared(&mut self) {
423438
match self.runner_state {
424439
// If we were handling events, send the EventsCleared message.
425440
RunnerState::HandlingEvents => {
@@ -462,20 +477,18 @@ impl<T> EventLoopRunner<T> {
462477
}
463478
}
464479

465-
unsafe fn call_event_handler(&mut self, event: Event<T>) {
480+
fn call_event_handler(&mut self, event: Event<T>) {
466481
match event {
467-
Event::NewEvents(_) => (*self.event_loop).trigger_newevents_on_redraw.store(true, Ordering::Relaxed),
468-
Event::EventsCleared => (*self.event_loop).trigger_newevents_on_redraw.store(false, Ordering::Relaxed),
482+
Event::NewEvents(_) => self.trigger_newevents_on_redraw.store(true, Ordering::Relaxed),
483+
Event::EventsCleared => self.trigger_newevents_on_redraw.store(false, Ordering::Relaxed),
469484
_ => ()
470485
}
471486

472-
assert_eq!(mem::size_of::<RootEventLoop<T>>(), mem::size_of::<EventLoop<T>>());
473-
let event_loop_ref = &*(self.event_loop as *const RootEventLoop<T>);
474487

475488
if self.control_flow != ControlFlow::Exit {
476-
(*self.event_handler)(event, event_loop_ref, &mut self.control_flow);
489+
(*self.event_handler)(event, &mut self.control_flow);
477490
} else {
478-
(*self.event_handler)(event, event_loop_ref, &mut ControlFlow::Exit);
491+
(*self.event_handler)(event, &mut ControlFlow::Exit);
479492
}
480493
}
481494
}
@@ -699,7 +712,7 @@ fn thread_event_target_window<T>(event_loop_runner: EventLoopRunnerShared<T>) ->
699712
(winuser::WS_VISIBLE | winuser::WS_POPUP) as _
700713
);
701714

702-
let (tx, rx) = crossbeam_channel::unbounded();
715+
let (tx, rx) = mpsc::channel();
703716

704717
let subclass_input = ThreadMsgTargetSubclassInput {
705718
event_loop_runner,

src/platform_impl/windows/window.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ unsafe fn unjust_window_rect(prc: &mut RECT, style: DWORD, ex_style: DWORD) -> B
6868
}
6969

7070
impl Window {
71-
pub fn new<T>(
71+
pub fn new<T: 'static>(
7272
event_loop: &EventLoop<T>,
7373
w_attr: WindowAttributes,
7474
pl_attr: PlatformSpecificWindowBuilderAttributes,
@@ -91,7 +91,11 @@ impl Window {
9191
panic!("OleInitialize failed! Result was: `RPC_E_CHANGED_MODE`");
9292
}
9393

94-
let file_drop_handler = FileDropHandler::new(win.window.0/*, event_loop.event_send.clone()*/);
94+
let file_drop_runner = event_loop.runner_shared.clone();
95+
let file_drop_handler = FileDropHandler::new(
96+
win.window.0,
97+
Box::new(move |event| if let Ok(e) = event.map_nonuser_event() {file_drop_runner.send_event(e)})
98+
);
9599
let handler_interface_ptr = &mut (*file_drop_handler.data).interface as LPDROPTARGET;
96100

97101
assert_eq!(ole2::RegisterDragDrop(win.window.0, handler_interface_ptr), S_OK);
@@ -849,7 +853,7 @@ pub unsafe fn adjust_size(
849853
(rect.right - rect.left, rect.bottom - rect.top)
850854
}
851855

852-
unsafe fn init<T>(
856+
unsafe fn init<T: 'static>(
853857
mut attributes: WindowAttributes,
854858
mut pl_attribs: PlatformSpecificWindowBuilderAttributes,
855859
event_loop: &event_loop::EventLoop<T>,

src/window.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ impl WindowBuilder {
283283
/// Error should be very rare and only occur in case of permission denied, incompatible system,
284284
/// out of memory, etc.
285285
#[inline]
286-
pub fn build<T>(mut self, event_loop: &EventLoop<T>) -> Result<Window, CreationError> {
286+
pub fn build<T: 'static>(mut self, event_loop: &EventLoop<T>) -> Result<Window, CreationError> {
287287
self.window.dimensions = Some(self.window.dimensions.unwrap_or_else(|| {
288288
if let Some(ref monitor) = self.window.fullscreen {
289289
// resizing the window to the dimensions of the monitor when fullscreen
@@ -311,7 +311,7 @@ impl Window {
311311
/// Error should be very rare and only occur in case of permission denied, incompatible system,
312312
/// out of memory, etc.
313313
#[inline]
314-
pub fn new<T>(event_loop: &EventLoop<T>) -> Result<Window, CreationError> {
314+
pub fn new<T: 'static>(event_loop: &EventLoop<T>) -> Result<Window, CreationError> {
315315
let builder = WindowBuilder::new();
316316
builder.build(event_loop)
317317
}

0 commit comments

Comments
 (0)