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:
parent
8934d2765d
commit
da7422c6e1
13 changed files with 151 additions and 97 deletions
|
|
@ -54,7 +54,7 @@ pub(crate) use self::version::NSAppKitVersion;
|
|||
pub(crate) use self::view::{NSTrackingRectTag, NSView};
|
||||
pub(crate) use self::window::{
|
||||
NSBackingStoreType, NSWindow, NSWindowButton, NSWindowLevel, NSWindowOcclusionState,
|
||||
NSWindowSharingType, NSWindowStyleMask, NSWindowTitleVisibility,
|
||||
NSWindowOrderingMode, NSWindowSharingType, NSWindowStyleMask, NSWindowTitleVisibility,
|
||||
};
|
||||
|
||||
#[link(name = "AppKit", kind = "framework")]
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use objc2::rc::{Id, Shared};
|
|||
use objc2::runtime::Object;
|
||||
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
|
||||
|
||||
use super::{NSCursor, NSResponder, NSTextInputContext};
|
||||
use super::{NSCursor, NSResponder, NSTextInputContext, NSWindow};
|
||||
|
||||
extern_class!(
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
|
|
@ -52,6 +52,10 @@ extern_methods!(
|
|||
|
||||
#[sel(convertPoint:fromView:)]
|
||||
pub fn convertPoint_fromView(&self, point: NSPoint, view: Option<&NSView>) -> NSPoint;
|
||||
|
||||
pub fn window(&self) -> Option<Id<NSWindow, Shared>> {
|
||||
unsafe { msg_send_id![self, window] }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl NSView {
|
||||
|
|
|
|||
|
|
@ -213,6 +213,9 @@ extern_methods!(
|
|||
|
||||
#[sel(sendEvent:)]
|
||||
pub unsafe fn sendEvent(&self, event: &NSEvent);
|
||||
|
||||
#[sel(addChildWindow:ordered:)]
|
||||
pub unsafe fn addChildWindow(&self, child: &NSWindow, ordered: NSWindowOrderingMode);
|
||||
}
|
||||
);
|
||||
|
||||
|
|
@ -379,3 +382,16 @@ pub enum NSWindowSharingType {
|
|||
unsafe impl Encode for NSWindowSharingType {
|
||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(isize)] // NSInteger
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum NSWindowOrderingMode {
|
||||
NSWindowAbove = 1,
|
||||
NSWindowBelow = -1,
|
||||
NSWindowOut = 0,
|
||||
}
|
||||
|
||||
unsafe impl Encode for NSWindowOrderingMode {
|
||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use crate::{
|
|||
platform::macos::WindowExtMacOS,
|
||||
platform_impl::platform::{
|
||||
app_state::AppState,
|
||||
appkit::NSWindowOrderingMode,
|
||||
ffi,
|
||||
monitor::{self, MonitorHandle, VideoMode},
|
||||
util,
|
||||
|
|
@ -45,7 +46,7 @@ use objc2::{declare_class, msg_send, msg_send_id, sel, ClassType};
|
|||
use super::appkit::{
|
||||
NSApp, NSAppKitVersion, NSAppearance, NSApplicationPresentationOptions, NSBackingStoreType,
|
||||
NSColor, NSCursor, NSFilenamesPboardType, NSRequestUserAttentionType, NSResponder, NSScreen,
|
||||
NSWindow, NSWindowButton, NSWindowLevel, NSWindowSharingType, NSWindowStyleMask,
|
||||
NSView, NSWindow, NSWindowButton, NSWindowLevel, NSWindowSharingType, NSWindowStyleMask,
|
||||
NSWindowTitleVisibility,
|
||||
};
|
||||
|
||||
|
|
@ -369,6 +370,38 @@ impl WinitWindow {
|
|||
})
|
||||
.ok_or_else(|| os_error!(OsError::CreationError("Couldn't create `NSWindow`")))?;
|
||||
|
||||
match attrs.parent_window {
|
||||
Some(RawWindowHandle::AppKit(handle)) => {
|
||||
// SAFETY: Caller ensures the pointer is valid or NULL
|
||||
let parent: Id<NSWindow, Shared> =
|
||||
match unsafe { Id::retain(handle.ns_window.cast()) } {
|
||||
Some(window) => window,
|
||||
None => {
|
||||
// SAFETY: Caller ensures the pointer is valid or NULL
|
||||
let parent_view: Id<NSView, Shared> =
|
||||
match unsafe { Id::retain(handle.ns_view.cast()) } {
|
||||
Some(view) => view,
|
||||
None => {
|
||||
return Err(os_error!(OsError::CreationError(
|
||||
"raw window handle should be non-empty"
|
||||
)))
|
||||
}
|
||||
};
|
||||
parent_view.window().ok_or_else(|| {
|
||||
os_error!(OsError::CreationError(
|
||||
"parent view should be installed in a window"
|
||||
))
|
||||
})?
|
||||
}
|
||||
};
|
||||
// SAFETY: We know that there are no parent -> child -> parent cycles since the only place in `winit`
|
||||
// where we allow making a window a child window is right here, just after it's been created.
|
||||
unsafe { parent.addChildWindow(&this, NSWindowOrderingMode::NSWindowAbove) };
|
||||
}
|
||||
Some(raw) => panic!("Invalid raw window handle {raw:?} on macOS"),
|
||||
None => (),
|
||||
}
|
||||
|
||||
let view = WinitView::new(&this, pl_attrs.accepts_first_mouse);
|
||||
|
||||
// The default value of `setWantsBestResolutionOpenGLSurface:` was `false` until
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue