1
0
Fork 0

Merge pull request #44 from RustAudio/nonblocking-event-loop

Non-blocking Event Loop, separate WindowHandle::app_run_blocking() call
This commit is contained in:
william light 2020-09-11 18:59:21 +02:00 committed by GitHub
commit ce708a8515
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 47 deletions

View file

@ -1,16 +1,5 @@
use baseview::{Event, Window, WindowHandler};
fn main() {
let window_open_options = baseview::WindowOpenOptions {
title: "baseview",
width: 512,
height: 512,
parent: baseview::Parent::None,
};
let _handle = Window::open::<MyProgram>(window_open_options);
}
struct MyProgram {}
impl WindowHandler for MyProgram {
@ -22,7 +11,7 @@ impl WindowHandler for MyProgram {
fn on_frame(&mut self) {}
fn on_event(&mut self, window: &mut Window, event: Event) {
fn on_event(&mut self, _window: &mut Window, event: Event) {
match event {
Event::Mouse(e) => println!("Mouse event: {:?}", e),
Event::Keyboard(e) => println!("Keyboard event: {:?}", e),
@ -33,3 +22,15 @@ impl WindowHandler for MyProgram {
fn on_message(&mut self, _window: &mut Window, _message: Self::Message) {}
}
fn main() {
let window_open_options = baseview::WindowOpenOptions {
title: "baseview".into(),
width: 512,
height: 512,
parent: baseview::Parent::None,
};
let handle = Window::open::<MyProgram>(window_open_options);
handle.app_run_blocking();
}

View file

@ -28,8 +28,10 @@ pub enum Parent {
WithParent(*mut c_void),
}
pub struct WindowOpenOptions<'a> {
pub title: &'a str,
unsafe impl Send for Parent {}
pub struct WindowOpenOptions {
pub title: String,
pub width: usize,
pub height: usize,

View file

@ -20,14 +20,23 @@ pub struct Window {
ns_view: id,
}
pub struct WindowHandle;
impl WindowHandle {
pub fn app_run_blocking(self) {
unsafe {
let app = NSApp();
app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
app.run();
}
}
}
impl Window {
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
unsafe {
let _pool = NSAutoreleasePool::new(nil);
let app = NSApp();
app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
let rect = NSRect::new(
NSPoint::new(0.0, 0.0),
NSSize::new(options.width as f64, options.height as f64),
@ -42,7 +51,7 @@ impl Window {
)
.autorelease();
ns_window.center();
ns_window.setTitle_(NSString::alloc(nil).init_str(options.title));
ns_window.setTitle_(NSString::alloc(nil).init_str(&options.title));
ns_window.makeKeyAndOrderFront_(nil);
let ns_view = NSView::alloc(nil).init();
@ -52,9 +61,9 @@ impl Window {
let handler = H::build(&mut window);
// FIXME: only do this in the unparented case
let current_app = NSRunningApplication::currentApplication(nil);
current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps);
app.run();
WindowHandle
}
@ -70,5 +79,3 @@ unsafe impl HasRawWindowHandle for Window {
})
}
}
pub struct WindowHandle;

View file

@ -141,6 +141,29 @@ pub struct Window {
hwnd: HWND,
}
pub struct WindowHandle {
hwnd: HWND
}
impl WindowHandle {
pub fn app_run_blocking(self) {
unsafe {
let mut msg: MSG = std::mem::zeroed();
loop {
let status = GetMessageA(&mut msg, self.hwnd, 0, 0);
if status == -1 {
break;
}
TranslateMessage(&mut msg);
DispatchMessageA(&mut msg);
}
}
}
}
impl Window {
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
unsafe {
@ -166,13 +189,17 @@ impl Window {
};
// todo: add check flags https://github.com/wrl/rutabaga/blob/f30ff67e157375cafdbafe5fb549f1790443a3a8/src/platform/win/window.c#L351
let mut parent = null_mut();
if let WithParent(p) = options.parent {
parent = p;
flags = WS_CHILD | WS_VISIBLE;
} else {
AdjustWindowRectEx(&mut rect, flags, FALSE, 0);
}
let parent = match options.parent {
WithParent(p) => {
flags = WS_CHILD | WS_VISIBLE;
p
},
_ => {
AdjustWindowRectEx(&mut rect, flags, FALSE, 0);
null_mut()
}
};
let hwnd = CreateWindowExA(
0,
@ -203,24 +230,12 @@ impl Window {
let win = Rc::new(RefCell::new(window));
SetWindowLongPtrA(hwnd, GWLP_USERDATA, Rc::into_raw(win) as *const _ as _);
SetTimer(hwnd, 4242, 13, None);
// todo: decide what to do with the message pump
if parent.is_null() {
let mut msg: MSG = std::mem::zeroed();
loop {
let status = GetMessageA(&mut msg, hwnd, 0, 0);
if status == -1 {
break;
}
TranslateMessage(&mut msg);
DispatchMessageA(&mut msg);
}
WindowHandle {
hwnd
}
}
WindowHandle
}
}
@ -232,5 +247,3 @@ unsafe impl HasRawWindowHandle for Window {
})
}
}
pub struct WindowHandle;

View file

@ -1,5 +1,6 @@
use std::os::raw::{c_ulong, c_void};
use std::time::*;
use std::thread;
use raw_window_handle::{unix::XlibHandle, HasRawWindowHandle, RawWindowHandle};
@ -20,11 +21,27 @@ pub struct Window {
}
// FIXME: move to outer crate context
pub struct WindowHandle;
pub struct WindowHandle {
thread: std::thread::JoinHandle<()>
}
impl WindowHandle {
pub fn app_run_blocking(self) {
let _ = self.thread.join();
}
}
impl Window {
pub fn open<H: WindowHandler>(options: WindowOpenOptions) -> WindowHandle {
WindowHandle {
thread: thread::spawn(move || {
Self::window_thread::<H>(options);
})
}
}
fn window_thread<H: WindowHandler>(options: WindowOpenOptions) {
// Connect to the X server
// FIXME: baseview error type instead of unwrap()
let xcb_connection = XcbConnection::new().unwrap();
@ -119,8 +136,6 @@ impl Window {
let mut handler = H::build(&mut window);
window.run_event_loop(&mut handler);
WindowHandle
}
#[inline]