From 5a09e8ba213f3153d8b1072033e338b64e91b9c3 Mon Sep 17 00:00:00 2001 From: k-brac Date: Fri, 25 Nov 2016 17:05:39 +0100 Subject: [PATCH 1/6] first try to allow child window on windows --- examples/child_window.rs | 44 ++++++++++++++++++++++++++++++++++++ src/os/windows.rs | 9 +++++++- src/platform/windows/init.rs | 30 +++++++++++++++++------- src/platform/windows/mod.rs | 12 ++++++---- src/window.rs | 2 +- 5 files changed, 83 insertions(+), 14 deletions(-) create mode 100644 examples/child_window.rs diff --git a/examples/child_window.rs b/examples/child_window.rs new file mode 100644 index 00000000..05469f4c --- /dev/null +++ b/examples/child_window.rs @@ -0,0 +1,44 @@ +extern crate winit; +use std::thread; +use winit::os::windows::WindowBuilderExt; + +fn resize_callback(width: u32, height: u32) { + println!("Window resized to {}x{}", width, height); +} + +fn main() { + let window = winit::WindowBuilder::new() + .with_title("A fantastic window!") + .with_window_resize_callback(resize_callback) + .build() + .unwrap(); + + let proxy = window.create_window_proxy(); + thread::spawn(move || { + let child = winit::WindowBuilder::new() + .with_title("child window!") + .with_window_resize_callback(resize_callback) + .with_decorations(false) + .with_parent_window(proxy) + .build() + .unwrap(); + + for event in child.wait_events() { + println!("child {:?}", event); + + match event { + winit::Event::Closed => break, + _ => (), + } + } + }); + + for event in window.wait_events() { + println!("parent {:?}", event); + + match event { + winit::Event::Closed => break, + _ => (), + } + } +} diff --git a/src/os/windows.rs b/src/os/windows.rs index e37b4185..dd4e595e 100644 --- a/src/os/windows.rs +++ b/src/os/windows.rs @@ -3,6 +3,7 @@ use libc; use Window; use WindowBuilder; +use window; /// Additional methods on `Window` that are specific to Windows. pub trait WindowExt { @@ -23,8 +24,14 @@ impl WindowExt for Window { /// Additional methods on `WindowBuilder` that are specific to Windows. pub trait WindowBuilderExt { - + fn with_parent_window(self, parent: window::WindowProxy) -> WindowBuilder; } impl WindowBuilderExt for WindowBuilder { + /// Sets a parent to the window to be created + #[inline] + fn with_parent_window(mut self, parent: window::WindowProxy) -> WindowBuilder { + self.platform_specific.parent = Some(parent); + self + } } diff --git a/src/platform/windows/init.rs b/src/platform/windows/init.rs index bc563847..fcfce2f4 100644 --- a/src/platform/windows/init.rs +++ b/src/platform/windows/init.rs @@ -9,6 +9,7 @@ use super::WindowState; use super::Window; use super::MonitorId; use super::WindowWrapper; +use super::PlatformSpecificWindowBuilderAttributes; use CreationError; use CreationError::OsError; @@ -24,9 +25,9 @@ use kernel32; use dwmapi; use user32; -pub fn new_window(window: &WindowAttributes) -> Result { +pub fn new_window(window: &WindowAttributes, pl_attribs: &PlatformSpecificWindowBuilderAttributes) -> Result { let window = window.clone(); - + let attribs = pl_attribs.clone(); // initializing variables to be sent to the task let title = OsStr::new(&window.title).encode_wide().chain(Some(0).into_iter()) @@ -39,7 +40,7 @@ pub fn new_window(window: &WindowAttributes) -> Result { thread::spawn(move || { unsafe { // creating and sending the `Window` - match init(title, &window) { + match init(title, &window, attribs) { Ok(w) => tx.send(Ok(w)).ok(), Err(e) => { tx.send(Err(e)).ok(); @@ -65,7 +66,7 @@ pub fn new_window(window: &WindowAttributes) -> Result { rx.recv().unwrap() } -unsafe fn init(title: Vec, window: &WindowAttributes) -> Result { +unsafe fn init(title: Vec, window: &WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes) -> Result { // registering the window class let class_name = register_window_class(); @@ -84,8 +85,16 @@ unsafe fn init(title: Vec, window: &WindowAttributes) -> Result, window: &WindowAttributes) -> Result, +} #[derive(Clone, Default)] pub struct PlatformSpecificHeadlessBuilderAttributes; @@ -76,7 +80,7 @@ impl Drop for WindowWrapper { #[derive(Clone)] pub struct WindowProxy { - hwnd: winapi::HWND, + pub hwnd: winapi::HWND, } unsafe impl Send for WindowProxy {} @@ -93,10 +97,10 @@ impl WindowProxy { impl Window { /// See the docs in the crate root file. - pub fn new(window: &WindowAttributes, _: &PlatformSpecificWindowBuilderAttributes) + pub fn new(window: &WindowAttributes, pl_attribs: &PlatformSpecificWindowBuilderAttributes) -> Result { - init::new_window(window) + init::new_window(window, pl_attribs) } /// See the docs in the crate root file. diff --git a/src/window.rs b/src/window.rs index cbc9731a..75ef53cc 100644 --- a/src/window.rs +++ b/src/window.rs @@ -361,7 +361,7 @@ impl Window { /// threads. #[derive(Clone)] pub struct WindowProxy { - proxy: platform::WindowProxy, + pub proxy: platform::WindowProxy, } impl WindowProxy { From 2b25bf1480206a5eae672719034f9b527d0e77e2 Mon Sep 17 00:00:00 2001 From: k-brac Date: Mon, 28 Nov 2016 13:50:07 +0100 Subject: [PATCH 2/6] child window creation improvement --- examples/child_window.rs | 8 +++++++- src/os/windows.rs | 10 ++++++++++ src/platform/windows/init.rs | 2 +- src/window.rs | 14 +++++++++++++- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/examples/child_window.rs b/examples/child_window.rs index 05469f4c..e48042d2 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -1,3 +1,5 @@ +#![cfg(target_os = "windows")] + extern crate winit; use std::thread; use winit::os::windows::WindowBuilderExt; @@ -5,7 +7,10 @@ use winit::os::windows::WindowBuilderExt; fn resize_callback(width: u32, height: u32) { println!("Window resized to {}x{}", width, height); } - +/** +* Creates a main window and a child within it and handle their events separetely. +* Currently windows only +*/ fn main() { let window = winit::WindowBuilder::new() .with_title("A fantastic window!") @@ -19,6 +24,7 @@ fn main() { .with_title("child window!") .with_window_resize_callback(resize_callback) .with_decorations(false) + .with_dimensions(100, 100) .with_parent_window(proxy) .build() .unwrap(); diff --git a/src/os/windows.rs b/src/os/windows.rs index dd4e595e..2eae8d48 100644 --- a/src/os/windows.rs +++ b/src/os/windows.rs @@ -4,6 +4,8 @@ use libc; use Window; use WindowBuilder; use window; +use winapi; +use platform; /// Additional methods on `Window` that are specific to Windows. pub trait WindowExt { @@ -35,3 +37,11 @@ impl WindowBuilderExt for WindowBuilder { self } } + +impl WindowBuilderExt { + /// Creates a new WindowProxy from a winapi::HWND + #[inline] + pub fn create_window_proxy_from_handle(handle: winapi::HWND) -> window::WindowProxy { + window::WindowProxy::create_proxy(platform::WindowProxy{hwnd: handle}) + } +} diff --git a/src/platform/windows/init.rs b/src/platform/windows/init.rs index fcfce2f4..4698dfc5 100644 --- a/src/platform/windows/init.rs +++ b/src/platform/windows/init.rs @@ -133,7 +133,7 @@ unsafe fn init(title: Vec, window: &WindowAttributes, pl_attribs: PlatformS style | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN, x.unwrap_or(winapi::CW_USEDEFAULT), y.unwrap_or(winapi::CW_USEDEFAULT), width.unwrap_or(winapi::CW_USEDEFAULT), height.unwrap_or(winapi::CW_USEDEFAULT), - pl_attribs.parent.map_or(ptr::null_mut(), |v| v.proxy.hwnd), + pl_attribs.parent.map_or(ptr::null_mut(), |v| v.get_proxy_data().hwnd), ptr::null_mut(), kernel32::GetModuleHandleW(ptr::null()), ptr::null_mut()); diff --git a/src/window.rs b/src/window.rs index 75ef53cc..3633966c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -361,7 +361,7 @@ impl Window { /// threads. #[derive(Clone)] pub struct WindowProxy { - pub proxy: platform::WindowProxy, + proxy: platform::WindowProxy, } impl WindowProxy { @@ -372,6 +372,18 @@ impl WindowProxy { pub fn wakeup_event_loop(&self) { self.proxy.wakeup_event_loop(); } + + /// Returns the platform specific proxy data + #[inline] + pub fn get_proxy_data(&self) -> &platform::WindowProxy { + &self.proxy + } + + /// Create a WindowProxy by directly setting its platform specific data + #[inline] + pub fn create_proxy(data: platform::WindowProxy) -> WindowProxy { + WindowProxy {proxy: data} + } } /// An iterator for the `poll_events` function. pub struct PollEventsIterator<'a>(platform::PollEventsIterator<'a>); From 3e2154a922f920c085e99ba83910d238a2c1d91a Mon Sep 17 00:00:00 2001 From: k-brac Date: Tue, 29 Nov 2016 13:02:42 +0100 Subject: [PATCH 3/6] child window created using a winapi::HWND instead of a WindowProxy --- examples/child_window.rs | 76 +++++++++++++++++++++--------------- src/os/windows.rs | 14 +------ src/platform/windows/init.rs | 2 +- src/platform/windows/mod.rs | 8 ++-- src/window.rs | 13 +----- 5 files changed, 54 insertions(+), 59 deletions(-) diff --git a/examples/child_window.rs b/examples/child_window.rs index e48042d2..56fb1694 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -1,50 +1,64 @@ -#![cfg(target_os = "windows")] - -extern crate winit; -use std::thread; -use winit::os::windows::WindowBuilderExt; - -fn resize_callback(width: u32, height: u32) { - println!("Window resized to {}x{}", width, height); -} -/** -* Creates a main window and a child within it and handle their events separetely. -* Currently windows only -*/ fn main() { - let window = winit::WindowBuilder::new() - .with_title("A fantastic window!") - .with_window_resize_callback(resize_callback) - .build() - .unwrap(); + child_window_exemple::child_window(); +} - let proxy = window.create_window_proxy(); - thread::spawn(move || { +#[cfg(windows)] +mod child_window_exemple { + + extern crate winit; + extern crate winapi; + use std::thread; + use self::winit::os::windows::{WindowBuilderExt, WindowExt}; + + fn resize_callback(width: u32, height: u32) { + println!("Window resized to {}x{}", width, height); + } + /** + * Creates a main window and a child within it and handle their events separetely. + * Currently windows only + */ + pub fn child_window() { + let window = winit::WindowBuilder::new() + .with_title("A fantastic window!") + .with_window_resize_callback(resize_callback) + .build() + .unwrap(); + + let parent = window.get_hwnd() as winapi::HWND; let child = winit::WindowBuilder::new() .with_title("child window!") .with_window_resize_callback(resize_callback) .with_decorations(false) .with_dimensions(100, 100) - .with_parent_window(proxy) + .with_parent_window(parent) .build() .unwrap(); - for event in child.wait_events() { - println!("child {:?}", event); + let child_thread = thread::spawn(move || { + for event in child.wait_events() { + println!("child {:?}", event); + + match event { + winit::Event::Closed => break, + _ => (), + } + } + }); + + for event in window.wait_events() { + println!("parent {:?}", event); match event { winit::Event::Closed => break, _ => (), } } - }); - for event in window.wait_events() { - println!("parent {:?}", event); - - match event { - winit::Event::Closed => break, - _ => (), - } + child_thread.join().unwrap(); } } + +#[cfg(not(windows))] +mod child_window_exemple { + pub fn child_window() {} +} diff --git a/src/os/windows.rs b/src/os/windows.rs index 2eae8d48..6d8b7981 100644 --- a/src/os/windows.rs +++ b/src/os/windows.rs @@ -3,9 +3,7 @@ use libc; use Window; use WindowBuilder; -use window; use winapi; -use platform; /// Additional methods on `Window` that are specific to Windows. pub trait WindowExt { @@ -26,22 +24,14 @@ impl WindowExt for Window { /// Additional methods on `WindowBuilder` that are specific to Windows. pub trait WindowBuilderExt { - fn with_parent_window(self, parent: window::WindowProxy) -> WindowBuilder; + fn with_parent_window(self, parent: winapi::HWND) -> WindowBuilder; } impl WindowBuilderExt for WindowBuilder { /// Sets a parent to the window to be created #[inline] - fn with_parent_window(mut self, parent: window::WindowProxy) -> WindowBuilder { + fn with_parent_window(mut self, parent: winapi::HWND) -> WindowBuilder { self.platform_specific.parent = Some(parent); self } } - -impl WindowBuilderExt { - /// Creates a new WindowProxy from a winapi::HWND - #[inline] - pub fn create_window_proxy_from_handle(handle: winapi::HWND) -> window::WindowProxy { - window::WindowProxy::create_proxy(platform::WindowProxy{hwnd: handle}) - } -} diff --git a/src/platform/windows/init.rs b/src/platform/windows/init.rs index 4698dfc5..2d3b1537 100644 --- a/src/platform/windows/init.rs +++ b/src/platform/windows/init.rs @@ -133,7 +133,7 @@ unsafe fn init(title: Vec, window: &WindowAttributes, pl_attribs: PlatformS style | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN, x.unwrap_or(winapi::CW_USEDEFAULT), y.unwrap_or(winapi::CW_USEDEFAULT), width.unwrap_or(winapi::CW_USEDEFAULT), height.unwrap_or(winapi::CW_USEDEFAULT), - pl_attribs.parent.map_or(ptr::null_mut(), |v| v.get_proxy_data().hwnd), + pl_attribs.parent.unwrap_or(ptr::null_mut()), ptr::null_mut(), kernel32::GetModuleHandleW(ptr::null()), ptr::null_mut()); diff --git a/src/platform/windows/mod.rs b/src/platform/windows/mod.rs index f461d72d..c453757e 100644 --- a/src/platform/windows/mod.rs +++ b/src/platform/windows/mod.rs @@ -15,12 +15,14 @@ use CursorState; use WindowAttributes; -use window; - #[derive(Clone, Default)] pub struct PlatformSpecificWindowBuilderAttributes { - pub parent: Option, + pub parent: Option, } + +unsafe impl Send for PlatformSpecificWindowBuilderAttributes {} +unsafe impl Sync for PlatformSpecificWindowBuilderAttributes {} + #[derive(Clone, Default)] pub struct PlatformSpecificHeadlessBuilderAttributes; diff --git a/src/window.rs b/src/window.rs index 3633966c..415541c5 100644 --- a/src/window.rs +++ b/src/window.rs @@ -372,19 +372,8 @@ impl WindowProxy { pub fn wakeup_event_loop(&self) { self.proxy.wakeup_event_loop(); } - - /// Returns the platform specific proxy data - #[inline] - pub fn get_proxy_data(&self) -> &platform::WindowProxy { - &self.proxy - } - - /// Create a WindowProxy by directly setting its platform specific data - #[inline] - pub fn create_proxy(data: platform::WindowProxy) -> WindowProxy { - WindowProxy {proxy: data} - } } + /// An iterator for the `poll_events` function. pub struct PollEventsIterator<'a>(platform::PollEventsIterator<'a>); From 7f2ee9a09a3fa8b9ee3172520c38ff0971025dbc Mon Sep 17 00:00:00 2001 From: k-brac Date: Tue, 29 Nov 2016 14:02:19 +0100 Subject: [PATCH 4/6] remove useless pub --- src/platform/windows/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/windows/mod.rs b/src/platform/windows/mod.rs index c453757e..ded27376 100644 --- a/src/platform/windows/mod.rs +++ b/src/platform/windows/mod.rs @@ -82,7 +82,7 @@ impl Drop for WindowWrapper { #[derive(Clone)] pub struct WindowProxy { - pub hwnd: winapi::HWND, + hwnd: winapi::HWND, } unsafe impl Send for WindowProxy {} From f66b533a959aeab4630ef735bbdb6f4674e794dc Mon Sep 17 00:00:00 2001 From: k-brac Date: Tue, 29 Nov 2016 16:27:23 +0100 Subject: [PATCH 5/6] fix typo --- examples/child_window.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/child_window.rs b/examples/child_window.rs index 56fb1694..423c6613 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -1,9 +1,9 @@ fn main() { - child_window_exemple::child_window(); + child_window_example::child_window(); } #[cfg(windows)] -mod child_window_exemple { +mod child_window_example { extern crate winit; extern crate winapi; @@ -59,6 +59,6 @@ mod child_window_exemple { } #[cfg(not(windows))] -mod child_window_exemple { +mod child_window_example { pub fn child_window() {} } From 5e387812d1865712389e535467ee7b82a3d390ff Mon Sep 17 00:00:00 2001 From: Baptiste AUBRY Date: Fri, 2 Dec 2016 12:54:06 +0100 Subject: [PATCH 6/6] remove useless example --- examples/child_window.rs | 64 ---------------------------------------- 1 file changed, 64 deletions(-) delete mode 100644 examples/child_window.rs diff --git a/examples/child_window.rs b/examples/child_window.rs deleted file mode 100644 index 423c6613..00000000 --- a/examples/child_window.rs +++ /dev/null @@ -1,64 +0,0 @@ -fn main() { - child_window_example::child_window(); -} - -#[cfg(windows)] -mod child_window_example { - - extern crate winit; - extern crate winapi; - use std::thread; - use self::winit::os::windows::{WindowBuilderExt, WindowExt}; - - fn resize_callback(width: u32, height: u32) { - println!("Window resized to {}x{}", width, height); - } - /** - * Creates a main window and a child within it and handle their events separetely. - * Currently windows only - */ - pub fn child_window() { - let window = winit::WindowBuilder::new() - .with_title("A fantastic window!") - .with_window_resize_callback(resize_callback) - .build() - .unwrap(); - - let parent = window.get_hwnd() as winapi::HWND; - let child = winit::WindowBuilder::new() - .with_title("child window!") - .with_window_resize_callback(resize_callback) - .with_decorations(false) - .with_dimensions(100, 100) - .with_parent_window(parent) - .build() - .unwrap(); - - let child_thread = thread::spawn(move || { - for event in child.wait_events() { - println!("child {:?}", event); - - match event { - winit::Event::Closed => break, - _ => (), - } - } - }); - - for event in window.wait_events() { - println!("parent {:?}", event); - - match event { - winit::Event::Closed => break, - _ => (), - } - } - - child_thread.join().unwrap(); - } -} - -#[cfg(not(windows))] -mod child_window_example { - pub fn child_window() {} -}