Add WindowBuilder::with_parent_window (#2548)

* On macOS, add `WindowBuilderExtMacOS::with_parent_window`

* Replace Parent with Option<Id<NSWindow, Shared>>

* Add addChildWindow method on NSWindow instead

* Update with_parent_window to be unsafe fn

* Add unified `with_parent_window`

* Remove `WindowBuilderExtUnix::with_parent`

* Remove `WindowBuilderExtWindows::with_parent_window`

* Clean up CI warnings

* Update CHANGELOG.md

It's `WindowBuilderExtX11` rather than `WindowBuilderExtUnix`

* Rename parent to owner

* Make with_parent_window unsafe and update its doc

* Add another way to get window on mac

* Add more documentations

* Add match arm and panic on invalid varients

* Add Xcb arm

* Update child_window example to make it safer and work in i686

* Remove duplicate entry in CHANGELOG.md

* Propogate error instead of expect

* Replace unreachable to panic

* Add platform note to X11

Co-authored-by: Wu Yu Wei <wusyong9104@gmail.com>
This commit is contained in:
Ngo Iok Ui (Wu Yu Wei) 2022-12-22 08:07:13 +08:00 committed by GitHub
parent 8934d2765d
commit da7422c6e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 151 additions and 97 deletions

View file

@ -1,37 +1,39 @@
#[cfg(all(target_os = "linux", feature = "x11"))]
use std::collections::HashMap;
#[cfg(all(target_os = "linux", feature = "x11"))]
use winit::{
dpi::{LogicalPosition, LogicalSize, Position},
event::{ElementState, Event, KeyboardInput, WindowEvent},
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
platform::x11::{WindowBuilderExtX11, WindowExtX11},
window::{Window, WindowBuilder, WindowId},
};
#[cfg(all(target_os = "linux", feature = "x11"))]
fn spawn_child_window(
parent: u32,
event_loop: &EventLoopWindowTarget<()>,
windows: &mut HashMap<u32, Window>,
) {
let child_window = WindowBuilder::new()
.with_parent(WindowId::from(parent as u64))
.with_title("child window")
.with_inner_size(LogicalSize::new(200.0f32, 200.0f32))
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
.with_visible(true)
.build(event_loop)
.unwrap();
let id = child_window.xlib_window().unwrap() as u32;
windows.insert(id, child_window);
println!("child window created with id: {}", id);
}
#[cfg(all(target_os = "linux", feature = "x11"))]
#[cfg(any(
all(target_os = "linux", feature = "x11"),
target_os = "macos",
target_os = "windows"
))]
fn main() {
use std::collections::HashMap;
use raw_window_handle::HasRawWindowHandle;
use winit::{
dpi::{LogicalPosition, LogicalSize, Position},
event::{ElementState, Event, KeyboardInput, WindowEvent},
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
window::{Window, WindowBuilder, WindowId},
};
fn spawn_child_window(
parent: &Window,
event_loop: &EventLoopWindowTarget<()>,
windows: &mut HashMap<WindowId, Window>,
) {
let parent = parent.raw_window_handle();
let mut builder = WindowBuilder::new()
.with_title("child window")
.with_inner_size(LogicalSize::new(200.0f32, 200.0f32))
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
.with_visible(true);
// `with_parent_window` is unsafe. Parent window must a valid window.
builder = unsafe { builder.with_parent_window(Some(parent)) };
let child_window = builder.build(event_loop).unwrap();
let id = child_window.id();
windows.insert(id, child_window);
println!("child window created with id: {:?}", id);
}
let mut windows = HashMap::new();
let event_loop: EventLoop<()> = EventLoop::new();
@ -42,8 +44,8 @@ fn main() {
.build(&event_loop)
.unwrap();
let root = parent_window.xlib_window().unwrap() as u32;
println!("parent window id: {})", root);
let root = parent_window;
println!("parent window: {:?})", root);
event_loop.run(move |event: Event<'_, ()>, event_loop, control_flow| {
*control_flow = ControlFlow::Wait;
@ -55,7 +57,7 @@ fn main() {
*control_flow = ControlFlow::Exit;
}
WindowEvent::CursorEntered { device_id: _ } => {
// println when the cursor entered in a window even if the child window is created
// On x11, println when the cursor entered in a window even if the child window is created
// by some key inputs.
// the child windows are always placed at (0, 0) with size (200, 200) in the parent window,
// so we also can see this log when we move the cursor arround (200, 200) in parent window.
@ -69,7 +71,7 @@ fn main() {
},
..
} => {
spawn_child_window(root, event_loop, &mut windows);
spawn_child_window(&root, event_loop, &mut windows);
}
_ => (),
}
@ -77,7 +79,11 @@ fn main() {
})
}
#[cfg(not(all(target_os = "linux", feature = "x11")))]
#[cfg(not(any(
all(target_os = "linux", feature = "x11"),
target_os = "macos",
target_os = "windows"
)))]
fn main() {
panic!("This example is supported only on x11.");
panic!("This example is supported only on x11, macOS, and Windows.");
}