Skip to content

Commit 63152c2

Browse files
committed
RedrawRequested
1 parent 27e475c commit 63152c2

File tree

4 files changed

+48
-7
lines changed

4 files changed

+48
-7
lines changed

examples/multithreaded.rs

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ fn main() {
6666
position.y += 10.0 * sign;
6767
position
6868
}),
69+
Q => window.request_redraw(),
6970
R => window.set_resizable(state),
7071
S => window.set_inner_size(match state {
7172
true => (WINDOW_SIZE.0 + 100, WINDOW_SIZE.1 + 100),

src/platform_impl/macos/app_state.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ use std::{
77
use cocoa::{appkit::NSApp, base::nil};
88

99
use {
10-
event::{Event, StartCause},
10+
event::{Event, StartCause, WindowEvent},
1111
event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget},
12+
window::WindowId,
1213
};
1314
use platform_impl::platform::{observer::EventLoopWaker, util::Never};
1415

@@ -86,6 +87,7 @@ struct Handler {
8687
start_time: Mutex<Option<Instant>>,
8788
callback: Mutex<Option<Box<dyn EventHandler>>>,
8889
pending_events: Mutex<VecDeque<Event<Never>>>,
90+
pending_redraw: Mutex<Vec<WindowId>>,
8991
waker: Mutex<EventLoopWaker>,
9092
}
9193

@@ -97,6 +99,10 @@ impl Handler {
9799
self.pending_events.lock().unwrap()
98100
}
99101

102+
fn redraw<'a>(&'a self) -> MutexGuard<'a, Vec<WindowId>> {
103+
self.pending_redraw.lock().unwrap()
104+
}
105+
100106
fn waker<'a>(&'a self) -> MutexGuard<'a, EventLoopWaker> {
101107
self.waker.lock().unwrap()
102108
}
@@ -137,6 +143,10 @@ impl Handler {
137143
mem::replace(&mut *self.events(), Default::default())
138144
}
139145

146+
fn should_redraw(&self) -> Vec<WindowId> {
147+
mem::replace(&mut *self.redraw(), Default::default())
148+
}
149+
140150
fn handle_nonuser_event(&self, event: Event<Never>) {
141151
if let Some(ref mut callback) = *self.callback.lock().unwrap() {
142152
callback.handle_nonuser_event(
@@ -207,6 +217,14 @@ impl AppState {
207217
HANDLER.handle_nonuser_event(Event::NewEvents(cause));
208218
}
209219

220+
// This is called from multiple threads at present
221+
pub fn queue_redraw(window_id: WindowId) {
222+
let mut pending_redraw = HANDLER.redraw();
223+
if !pending_redraw.contains(&window_id) {
224+
pending_redraw.push(window_id);
225+
}
226+
}
227+
210228
pub fn queue_event(event: Event<Never>) {
211229
if !unsafe { msg_send![class!(NSThread), isMainThread] } {
212230
panic!("uh-oh");
@@ -227,6 +245,12 @@ impl AppState {
227245
for event in HANDLER.take_events() {
228246
HANDLER.handle_nonuser_event(event);
229247
}
248+
for window_id in HANDLER.should_redraw() {
249+
HANDLER.handle_nonuser_event(Event::WindowEvent {
250+
window_id,
251+
event: WindowEvent::RedrawRequested,
252+
});
253+
}
230254
HANDLER.handle_nonuser_event(Event::EventsCleared);
231255
if HANDLER.should_exit() {
232256
let _: () = unsafe { msg_send![NSApp(), stop:nil] };

src/platform_impl/macos/view.rs

+16
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ lazy_static! {
9191
sel!(viewDidMoveToWindow),
9292
view_did_move_to_window as extern fn(&Object, Sel),
9393
);
94+
decl.add_method(
95+
sel!(drawRect:),
96+
draw_rect as extern fn(&Object, Sel, id),
97+
);
9498
decl.add_method(
9599
sel!(acceptsFirstResponder),
96100
accepts_first_responder as extern fn(&Object, Sel) -> BOOL,
@@ -276,6 +280,18 @@ extern fn view_did_move_to_window(this: &Object, _sel: Sel) {
276280
trace!("Completed `viewDidMoveToWindow`");
277281
}
278282

283+
extern fn draw_rect(this: &Object, _sel: Sel, rect: id) {
284+
unsafe {
285+
let state_ptr: *mut c_void = *this.get_ivar("winitState");
286+
let state = &mut *(state_ptr as *mut ViewState);
287+
288+
AppState::queue_redraw(WindowId(get_window_id(state.nswindow)));
289+
290+
let superclass = util::superclass(this);
291+
let () = msg_send![super(this, superclass), drawRect:rect];
292+
}
293+
}
294+
279295
extern fn accepts_first_responder(_this: &Object, _sel: Sel) -> BOOL {
280296
YES
281297
}

src/platform_impl/macos/window.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ use objc::{runtime::{Class, Object, Sel, BOOL, YES, NO}, declare::ClassDecl};
1818
use {
1919
dpi::{LogicalPosition, LogicalSize}, icon::Icon,
2020
monitor::MonitorHandle as RootMonitorHandle,
21-
window::{CreationError, MouseCursor, WindowAttributes},
21+
window::{
22+
CreationError, MouseCursor, WindowAttributes, WindowId as RootWindowId,
23+
},
2224
};
2325
use platform::macos::{ActivationPolicy, WindowExtMacOS};
2426
use platform_impl::platform::{
25-
{ffi, util::{self, IdRef}},
26-
monitor::{self, MonitorHandle},
27-
view::{self, new_view},
27+
app_state::AppState, ffi, monitor::{self, MonitorHandle},
28+
util::{self, IdRef}, view::{self, new_view},
2829
window_delegate::{WindowDelegate, WindowDelegateState},
2930
};
3031

@@ -377,7 +378,6 @@ impl UnownedWindow {
377378

378379
#[inline]
379380
pub fn show(&self) {
380-
//unsafe { NSWindow::makeKeyAndOrderFront_(*self.nswindow, nil); }
381381
unsafe { util::make_key_and_order_front_async(*self.nswindow) };
382382
}
383383

@@ -387,7 +387,7 @@ impl UnownedWindow {
387387
}
388388

389389
pub fn request_redraw(&self) {
390-
unimplemented!();
390+
AppState::queue_redraw(RootWindowId(self.id()));
391391
}
392392

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

0 commit comments

Comments
 (0)