diff --git a/examples/open_window.rs b/examples/open_window.rs index 04e2b73..9459c5c 100644 --- a/examples/open_window.rs +++ b/examples/open_window.rs @@ -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::(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::(window_open_options); + handle.app_run_blocking(); +} diff --git a/src/lib.rs b/src/lib.rs index ce1fde1..d03dc60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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, diff --git a/src/macos/window.rs b/src/macos/window.rs index 6ae0ae6..3add2ef 100644 --- a/src/macos/window.rs +++ b/src/macos/window.rs @@ -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(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; diff --git a/src/win/window.rs b/src/win/window.rs index 944a012..0d69f00 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -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(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; diff --git a/src/x11/window.rs b/src/x11/window.rs index dc28bc0..25c6a4d 100644 --- a/src/x11/window.rs +++ b/src/x11/window.rs @@ -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(options: WindowOpenOptions) -> WindowHandle { + WindowHandle { + thread: thread::spawn(move || { + Self::window_thread::(options); + }) + } + } + + fn window_thread(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]