Skip to content

Commit

Permalink
RedrawRequested
Browse files Browse the repository at this point in the history
  • Loading branch information
francesca64 committed Dec 20, 2018
1 parent 27e475c commit 63152c2
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 7 deletions.
1 change: 1 addition & 0 deletions examples/multithreaded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ fn main() {
position.y += 10.0 * sign;
position
}),
Q => window.request_redraw(),
R => window.set_resizable(state),
S => window.set_inner_size(match state {
true => (WINDOW_SIZE.0 + 100, WINDOW_SIZE.1 + 100),
Expand Down
26 changes: 25 additions & 1 deletion src/platform_impl/macos/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use std::{
use cocoa::{appkit::NSApp, base::nil};

use {
event::{Event, StartCause},
event::{Event, StartCause, WindowEvent},
event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget},
window::WindowId,
};
use platform_impl::platform::{observer::EventLoopWaker, util::Never};

Expand Down Expand Up @@ -86,6 +87,7 @@ struct Handler {
start_time: Mutex<Option<Instant>>,
callback: Mutex<Option<Box<dyn EventHandler>>>,
pending_events: Mutex<VecDeque<Event<Never>>>,
pending_redraw: Mutex<Vec<WindowId>>,
waker: Mutex<EventLoopWaker>,
}

Expand All @@ -97,6 +99,10 @@ impl Handler {
self.pending_events.lock().unwrap()
}

fn redraw<'a>(&'a self) -> MutexGuard<'a, Vec<WindowId>> {
self.pending_redraw.lock().unwrap()
}

fn waker<'a>(&'a self) -> MutexGuard<'a, EventLoopWaker> {
self.waker.lock().unwrap()
}
Expand Down Expand Up @@ -137,6 +143,10 @@ impl Handler {
mem::replace(&mut *self.events(), Default::default())
}

fn should_redraw(&self) -> Vec<WindowId> {
mem::replace(&mut *self.redraw(), Default::default())
}

fn handle_nonuser_event(&self, event: Event<Never>) {
if let Some(ref mut callback) = *self.callback.lock().unwrap() {
callback.handle_nonuser_event(
Expand Down Expand Up @@ -207,6 +217,14 @@ impl AppState {
HANDLER.handle_nonuser_event(Event::NewEvents(cause));
}

// This is called from multiple threads at present
pub fn queue_redraw(window_id: WindowId) {
let mut pending_redraw = HANDLER.redraw();
if !pending_redraw.contains(&window_id) {
pending_redraw.push(window_id);
}
}

pub fn queue_event(event: Event<Never>) {
if !unsafe { msg_send![class!(NSThread), isMainThread] } {
panic!("uh-oh");
Expand All @@ -227,6 +245,12 @@ impl AppState {
for event in HANDLER.take_events() {
HANDLER.handle_nonuser_event(event);
}
for window_id in HANDLER.should_redraw() {
HANDLER.handle_nonuser_event(Event::WindowEvent {
window_id,
event: WindowEvent::RedrawRequested,
});
}
HANDLER.handle_nonuser_event(Event::EventsCleared);
if HANDLER.should_exit() {
let _: () = unsafe { msg_send![NSApp(), stop:nil] };
Expand Down
16 changes: 16 additions & 0 deletions src/platform_impl/macos/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ lazy_static! {
sel!(viewDidMoveToWindow),
view_did_move_to_window as extern fn(&Object, Sel),
);
decl.add_method(
sel!(drawRect:),
draw_rect as extern fn(&Object, Sel, id),
);
decl.add_method(
sel!(acceptsFirstResponder),
accepts_first_responder as extern fn(&Object, Sel) -> BOOL,
Expand Down Expand Up @@ -276,6 +280,18 @@ extern fn view_did_move_to_window(this: &Object, _sel: Sel) {
trace!("Completed `viewDidMoveToWindow`");
}

extern fn draw_rect(this: &Object, _sel: Sel, rect: id) {
unsafe {
let state_ptr: *mut c_void = *this.get_ivar("winitState");
let state = &mut *(state_ptr as *mut ViewState);

AppState::queue_redraw(WindowId(get_window_id(state.nswindow)));

let superclass = util::superclass(this);
let () = msg_send![super(this, superclass), drawRect:rect];
}
}

extern fn accepts_first_responder(_this: &Object, _sel: Sel) -> BOOL {
YES
}
Expand Down
12 changes: 6 additions & 6 deletions src/platform_impl/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ use objc::{runtime::{Class, Object, Sel, BOOL, YES, NO}, declare::ClassDecl};
use {
dpi::{LogicalPosition, LogicalSize}, icon::Icon,
monitor::MonitorHandle as RootMonitorHandle,
window::{CreationError, MouseCursor, WindowAttributes},
window::{
CreationError, MouseCursor, WindowAttributes, WindowId as RootWindowId,
},
};
use platform::macos::{ActivationPolicy, WindowExtMacOS};
use platform_impl::platform::{
{ffi, util::{self, IdRef}},
monitor::{self, MonitorHandle},
view::{self, new_view},
app_state::AppState, ffi, monitor::{self, MonitorHandle},
util::{self, IdRef}, view::{self, new_view},
window_delegate::{WindowDelegate, WindowDelegateState},
};

Expand Down Expand Up @@ -377,7 +378,6 @@ impl UnownedWindow {

#[inline]
pub fn show(&self) {
//unsafe { NSWindow::makeKeyAndOrderFront_(*self.nswindow, nil); }
unsafe { util::make_key_and_order_front_async(*self.nswindow) };
}

Expand All @@ -387,7 +387,7 @@ impl UnownedWindow {
}

pub fn request_redraw(&self) {
unimplemented!();
AppState::queue_redraw(RootWindowId(self.id()));
}

pub fn get_position(&self) -> Option<LogicalPosition> {
Expand Down

0 comments on commit 63152c2

Please sign in to comment.