Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Child window #96

Merged
merged 6 commits into from
Dec 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/os/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use libc;
use Window;
use WindowBuilder;
use winapi;

/// Additional methods on `Window` that are specific to Windows.
pub trait WindowExt {
Expand All @@ -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: winapi::HWND) -> WindowBuilder;
}

impl WindowBuilderExt for WindowBuilder {
/// Sets a parent to the window to be created
#[inline]
fn with_parent_window(mut self, parent: winapi::HWND) -> WindowBuilder {
self.platform_specific.parent = Some(parent);
self
}
}
30 changes: 22 additions & 8 deletions src/platform/windows/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use super::WindowState;
use super::Window;
use super::MonitorId;
use super::WindowWrapper;
use super::PlatformSpecificWindowBuilderAttributes;

use CreationError;
use CreationError::OsError;
Expand All @@ -24,9 +25,9 @@ use kernel32;
use dwmapi;
use user32;

pub fn new_window(window: &WindowAttributes) -> Result<Window, CreationError> {
pub fn new_window(window: &WindowAttributes, pl_attribs: &PlatformSpecificWindowBuilderAttributes) -> Result<Window, CreationError> {
let window = window.clone();

let attribs = pl_attribs.clone();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not pass the attributes by reference to init instead of cloning?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing by reference causes a lifetime error that I don't know how to fix. Since we are cloning WindowAttributes I did the same.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right I forgot we were spawning a thread, so nevermind.

// initializing variables to be sent to the task

let title = OsStr::new(&window.title).encode_wide().chain(Some(0).into_iter())
Expand All @@ -39,7 +40,7 @@ pub fn new_window(window: &WindowAttributes) -> Result<Window, CreationError> {
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();
Expand All @@ -65,7 +66,7 @@ pub fn new_window(window: &WindowAttributes) -> Result<Window, CreationError> {
rx.recv().unwrap()
}

unsafe fn init(title: Vec<u16>, window: &WindowAttributes) -> Result<Window, CreationError> {
unsafe fn init(title: Vec<u16>, window: &WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes) -> Result<Window, CreationError> {
// registering the window class
let class_name = register_window_class();

Expand All @@ -84,8 +85,16 @@ unsafe fn init(title: Vec<u16>, window: &WindowAttributes) -> Result<Window, Cre
}

// computing the style and extended style of the window
let (ex_style, style) = if window.monitor.is_some() || window.decorations == false {
(winapi::WS_EX_APPWINDOW, winapi::WS_POPUP | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN)
let (ex_style, style) = if window.monitor.is_some() || !window.decorations {
(winapi::WS_EX_APPWINDOW,
//winapi::WS_POPUP is incompatible with winapi::WS_CHILD
if pl_attribs.parent.is_some() {
winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN
}
else {
winapi::WS_POPUP | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN
}
)
} else {
(winapi::WS_EX_APPWINDOW | winapi::WS_EX_WINDOWEDGE,
winapi::WS_OVERLAPPEDWINDOW | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN)
Expand All @@ -108,19 +117,24 @@ unsafe fn init(title: Vec<u16>, window: &WindowAttributes) -> Result<Window, Cre
(None, None)
};

let style = if !window.visible {
let mut style = if !window.visible {
style
} else {
style | winapi::WS_VISIBLE
};

if pl_attribs.parent.is_some() {
style |= winapi::WS_CHILD;
}

let handle = user32::CreateWindowExW(ex_style | winapi::WS_EX_ACCEPTFILES,
class_name.as_ptr(),
title.as_ptr() as winapi::LPCWSTR,
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),
ptr::null_mut(), ptr::null_mut(), kernel32::GetModuleHandleW(ptr::null()),
pl_attribs.parent.unwrap_or(ptr::null_mut()),
ptr::null_mut(), kernel32::GetModuleHandleW(ptr::null()),
ptr::null_mut());

if handle.is_null() {
Expand Down
12 changes: 9 additions & 3 deletions src/platform/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ use CursorState;
use WindowAttributes;

#[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes;
pub struct PlatformSpecificWindowBuilderAttributes {
pub parent: Option<winapi::HWND>,
}

unsafe impl Send for PlatformSpecificWindowBuilderAttributes {}
unsafe impl Sync for PlatformSpecificWindowBuilderAttributes {}

#[derive(Clone, Default)]
pub struct PlatformSpecificHeadlessBuilderAttributes;

Expand Down Expand Up @@ -93,10 +99,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<Window, CreationError>
{
init::new_window(window)
init::new_window(window, pl_attribs)
}

/// See the docs in the crate root file.
Expand Down
1 change: 1 addition & 0 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ impl WindowProxy {
self.proxy.wakeup_event_loop();
}
}

/// An iterator for the `poll_events` function.
pub struct PollEventsIterator<'a>(platform::PollEventsIterator<'a>);

Expand Down