winit-core: move window

Create `WindowAttributes` for respective platform specific window
attributes in `winit` due to move of `WindowAttributes`.
This commit is contained in:
Kirill Chibisov 2025-05-03 18:24:44 +09:00
parent c8b9a86885
commit b4c5b76155
48 changed files with 843 additions and 808 deletions

View file

@ -10,9 +10,8 @@ use objc2_foundation::{
ns_string, NSData, NSDictionary, NSNumber, NSObject, NSPoint, NSSize, NSString,
};
use crate::cursor::{CursorImage, CustomCursorProvider, CustomCursorSource};
use crate::cursor::{CursorIcon, CursorImage, CustomCursorProvider, CustomCursorSource};
use crate::error::{NotSupportedError, RequestError};
use crate::window::CursorIcon;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct CustomCursor(pub(crate) Retained<NSCursor>);

View file

@ -24,6 +24,7 @@ use super::event::dummy_event;
use super::monitor;
use super::observer::setup_control_flow_observers;
use crate::application::ApplicationHandler;
use crate::cursor::{CustomCursor as CoreCustomCursor, CustomCursorSource};
use crate::error::{EventLoopError, RequestError};
use crate::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
@ -33,7 +34,7 @@ use crate::monitor::MonitorHandle as CoreMonitorHandle;
use crate::platform::macos::ActivationPolicy;
use crate::platform::pump_events::PumpStatus;
use crate::platform_impl::Window;
use crate::window::{CustomCursor as CoreCustomCursor, CustomCursorSource, Theme};
use crate::window::Theme;
#[derive(Default)]
pub struct PanicInfo {

View file

@ -20,4 +20,3 @@ pub(crate) use self::event_loop::{
};
pub(crate) use self::monitor::MonitorHandle;
pub(crate) use self::window::Window;
pub(crate) use self::window_delegate::PlatformSpecificWindowAttributes;

View file

@ -11,11 +11,13 @@ use objc2_foundation::NSObject;
use super::event_loop::ActiveEventLoop;
use super::window_delegate::WindowDelegate;
use crate::cursor::Cursor;
use crate::error::RequestError;
use crate::icon::Icon;
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
use crate::window::{
Cursor, Icon, ImePurpose, Theme, UserAttentionType, Window as CoreWindow, WindowAttributes,
WindowButtons, WindowId, WindowLevel,
ImePurpose, Theme, UserAttentionType, Window as CoreWindow, WindowAttributes, WindowButtons,
WindowId, WindowLevel,
};
#[derive(Debug)]

View file

@ -45,59 +45,21 @@ use super::util::cgerr;
use super::view::WinitView;
use super::window::{window_id, WinitPanel, WinitWindow};
use super::{ffi, MonitorHandle};
use crate::cursor::Cursor;
use crate::dpi::{
LogicalInsets, LogicalPosition, LogicalSize, PhysicalInsets, PhysicalPosition, PhysicalSize,
Position, Size,
};
use crate::error::{NotSupportedError, RequestError};
use crate::event::{SurfaceSizeWriter, WindowEvent};
use crate::icon::Icon;
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider};
use crate::platform::macos::{OptionAsAlt, WindowExtMacOS};
use crate::platform::macos::{OptionAsAlt, WindowAttributesMacOS, WindowExtMacOS};
use crate::window::{
Cursor, CursorGrabMode, Icon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
WindowAttributes, WindowButtons, WindowId, WindowLevel,
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
WindowButtons, WindowId, WindowLevel,
};
#[derive(Clone, Debug, PartialEq)]
pub struct PlatformSpecificWindowAttributes {
pub movable_by_window_background: bool,
pub titlebar_transparent: bool,
pub title_hidden: bool,
pub titlebar_hidden: bool,
pub titlebar_buttons_hidden: bool,
pub fullsize_content_view: bool,
pub disallow_hidpi: bool,
pub has_shadow: bool,
pub accepts_first_mouse: bool,
pub tabbing_identifier: Option<String>,
pub option_as_alt: OptionAsAlt,
pub borderless_game: bool,
pub unified_titlebar: bool,
pub panel: bool,
}
impl Default for PlatformSpecificWindowAttributes {
#[inline]
fn default() -> Self {
Self {
movable_by_window_background: false,
titlebar_transparent: false,
title_hidden: false,
titlebar_hidden: false,
titlebar_buttons_hidden: false,
fullsize_content_view: false,
disallow_hidpi: false,
has_shadow: true,
accepts_first_mouse: true,
tabbing_identifier: None,
option_as_alt: Default::default(),
borderless_game: false,
unified_titlebar: false,
panel: false,
}
}
}
#[derive(Debug)]
pub(crate) struct State {
/// Strong reference to the global application state.
@ -552,6 +514,7 @@ impl Drop for WindowDelegate {
fn new_window(
app_state: &Rc<AppState>,
attrs: &WindowAttributes,
macos_attrs: &WindowAttributesMacOS,
mtm: MainThreadMarker,
) -> Option<Retained<NSWindow>> {
autoreleasepool(|_| {
@ -592,9 +555,7 @@ fn new_window(
},
};
let mut masks = if (!attrs.decorations && screen.is_none())
|| attrs.platform_specific.titlebar_hidden
{
let mut masks = if (!attrs.decorations && screen.is_none()) || macos_attrs.titlebar_hidden {
// Resizable without a titlebar or borders
// if decorations is set to false, ignore pl_attrs
//
@ -622,7 +583,7 @@ fn new_window(
masks &= !NSWindowStyleMask::Closable;
}
if attrs.platform_specific.fullsize_content_view {
if macos_attrs.fullsize_content_view {
// NOTE: If we decide to add an option to change this at runtime, we must emit a
// `SurfaceResized` event to let applications know that the safe area changed.
//
@ -637,7 +598,7 @@ fn new_window(
// confusing issues with the window not being properly activated.
//
// Winit ensures this by not allowing access to `ActiveEventLoop` before handling events.
let window: Retained<NSWindow> = if attrs.platform_specific.panel {
let window: Retained<NSWindow> = if macos_attrs.panel {
masks |= NSWindowStyleMask::NonactivatingPanel;
let window: Option<Retained<WinitPanel>> = unsafe {
@ -673,7 +634,7 @@ fn new_window(
window.setTitle(&NSString::from_str(&attrs.title));
window.setAcceptsMouseMovedEvents(true);
if let Some(identifier) = &attrs.platform_specific.tabbing_identifier {
if let Some(identifier) = &macos_attrs.tabbing_identifier {
window.setTabbingIdentifier(&NSString::from_str(identifier));
window.setTabbingMode(NSWindowTabbingMode::Preferred);
}
@ -682,13 +643,13 @@ fn new_window(
window.setSharingType(NSWindowSharingType::None);
}
if attrs.platform_specific.titlebar_transparent {
if macos_attrs.titlebar_transparent {
window.setTitlebarAppearsTransparent(true);
}
if attrs.platform_specific.title_hidden {
if macos_attrs.title_hidden {
window.setTitleVisibility(NSWindowTitleVisibility::Hidden);
}
if attrs.platform_specific.titlebar_buttons_hidden {
if macos_attrs.titlebar_buttons_hidden {
for titlebar_button in &[
#[allow(deprecated)]
NSWindowFullScreenButton,
@ -701,10 +662,10 @@ fn new_window(
}
}
}
if attrs.platform_specific.movable_by_window_background {
if macos_attrs.movable_by_window_background {
window.setMovableByWindowBackground(true);
}
if attrs.platform_specific.unified_titlebar {
if macos_attrs.unified_titlebar {
unsafe {
// The toolbar style is ignored if there is no toolbar, so it is
// necessary to add one.
@ -719,7 +680,7 @@ fn new_window(
}
}
if !attrs.platform_specific.has_shadow {
if !macos_attrs.has_shadow {
window.setHasShadow(false);
}
if attrs.position.is_none() {
@ -728,8 +689,8 @@ fn new_window(
let view = WinitView::new(
app_state,
attrs.platform_specific.accepts_first_mouse,
attrs.platform_specific.option_as_alt,
macos_attrs.accepts_first_mouse,
macos_attrs.option_as_alt,
mtm,
);
@ -737,7 +698,7 @@ fn new_window(
// macos 10.14 and `true` after 10.15, we should set it to `YES` or `NO` to avoid
// always the default system value in favour of the user's code
#[allow(deprecated)]
view.setWantsBestResolutionOpenGLSurface(!attrs.platform_specific.disallow_hidpi);
view.setWantsBestResolutionOpenGLSurface(!macos_attrs.disallow_hidpi);
// On Mojave, views automatically become layer-backed shortly after being added to
// a window. Changing the layer-backedness of a view breaks the association between
@ -785,13 +746,19 @@ fn new_window(
impl WindowDelegate {
pub(super) fn new(
app_state: &Rc<AppState>,
attrs: WindowAttributes,
mut attrs: WindowAttributes,
mtm: MainThreadMarker,
) -> Result<Retained<Self>, RequestError> {
let window = new_window(app_state, &attrs, mtm)
let macos_attrs = attrs
.platform
.take()
.and_then(|attrs| attrs.cast::<WindowAttributesMacOS>().ok())
.unwrap_or_default();
let window = new_window(app_state, &attrs, &macos_attrs, mtm)
.ok_or_else(|| os_error!("couldn't create `NSWindow`"))?;
match attrs.parent_window.map(|handle| handle.0) {
match attrs.parent_window() {
Some(rwh_06::RawWindowHandle::AppKit(handle)) => {
// SAFETY: Caller ensures the pointer is valid or NULL
// Unwrap is fine, since the pointer comes from `NonNull`.
@ -843,7 +810,7 @@ impl WindowDelegate {
standard_frame: Cell::new(None),
is_simple_fullscreen: Cell::new(false),
saved_style: Cell::new(None),
is_borderless_game: Cell::new(attrs.platform_specific.borderless_game),
is_borderless_game: Cell::new(macos_attrs.borderless_game),
});
let delegate: Retained<WindowDelegate> = unsafe { msg_send![super(delegate), init] };

View file

@ -21,6 +21,7 @@ use super::super::notification_center::create_observer;
use super::app_state::{send_occluded_event_for_all_windows, AppState};
use super::{app_state, monitor, MonitorHandle};
use crate::application::ApplicationHandler;
use crate::cursor::{CustomCursor, CustomCursorSource};
use crate::error::{EventLoopError, NotSupportedError, RequestError};
use crate::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
@ -28,7 +29,7 @@ use crate::event_loop::{
};
use crate::monitor::MonitorHandle as CoreMonitorHandle;
use crate::platform_impl::Window;
use crate::window::{CustomCursor, CustomCursorSource, Theme, Window as CoreWindow};
use crate::window::{Theme, Window as CoreWindow};
#[derive(Debug)]
pub(crate) struct ActiveEventLoop {

View file

@ -13,7 +13,7 @@ pub(crate) use self::event_loop::{
ActiveEventLoop, EventLoop, PlatformSpecificEventLoopAttributes,
};
pub(crate) use self::monitor::MonitorHandle;
pub(crate) use self::window::{PlatformSpecificWindowAttributes, Window};
pub(crate) use self::window::Window;
#[derive(Debug)]
pub enum OsError {}

View file

@ -22,7 +22,6 @@ use crate::event::{
WindowEvent,
};
use crate::keyboard::{Key, KeyCode, KeyLocation, NamedKey, NativeKeyCode, PhysicalKey};
use crate::window::WindowAttributes;
pub struct WinitViewState {
pinch_gesture_recognizer: RefCell<Option<Retained<UIPinchGestureRecognizer>>>,
@ -337,7 +336,7 @@ define_class!(
impl WinitView {
pub(crate) fn new(
mtm: MainThreadMarker,
window_attributes: &WindowAttributes,
scale_factor: Option<f64>,
frame: CGRect,
) -> Retained<Self> {
let this = mtm.alloc().set_ivars(WinitViewState {
@ -357,7 +356,7 @@ impl WinitView {
this.setMultipleTouchEnabled(true);
if let Some(scale_factor) = window_attributes.platform_specific.scale_factor {
if let Some(scale_factor) = scale_factor {
this.setContentScaleFactor(scale_factor as _);
}

View file

@ -8,8 +8,7 @@ use objc2_ui_kit::{
UIUserInterfaceIdiom, UIView, UIViewController,
};
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations};
use crate::window::WindowAttributes;
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations, WindowAttributesIos};
pub struct ViewControllerState {
prefers_status_bar_hidden: Cell<bool>,
@ -129,7 +128,7 @@ impl WinitViewController {
pub(crate) fn new(
mtm: MainThreadMarker,
window_attributes: &WindowAttributes,
ios_attributes: &WindowAttributesIos,
view: &UIView,
) -> Retained<Self> {
// These are set properly below, we just to set them to something in the meantime.
@ -142,25 +141,16 @@ impl WinitViewController {
});
let this: Retained<Self> = unsafe { msg_send![super(this), init] };
this.set_prefers_status_bar_hidden(
window_attributes.platform_specific.prefers_status_bar_hidden,
);
this.set_prefers_status_bar_hidden(ios_attributes.prefers_status_bar_hidden);
this.set_preferred_status_bar_style(
window_attributes.platform_specific.preferred_status_bar_style,
);
this.set_preferred_status_bar_style(ios_attributes.preferred_status_bar_style);
this.set_supported_interface_orientations(
mtm,
window_attributes.platform_specific.valid_orientations,
);
this.set_supported_interface_orientations(mtm, ios_attributes.valid_orientations);
this.set_prefers_home_indicator_auto_hidden(
window_attributes.platform_specific.prefers_home_indicator_hidden,
);
this.set_prefers_home_indicator_auto_hidden(ios_attributes.prefers_home_indicator_hidden);
this.set_preferred_screen_edges_deferring_system_gestures(
window_attributes.platform_specific.preferred_screen_edges_deferring_system_gestures,
ios_attributes.preferred_screen_edges_deferring_system_gestures,
);
this.setView(Some(view));

View file

@ -27,7 +27,7 @@ use crate::error::{NotSupportedError, RequestError};
use crate::event::WindowEvent;
use crate::icon::Icon;
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations};
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations, WindowAttributesIos};
use crate::window::{
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow,
WindowAttributes, WindowButtons, WindowId, WindowLevel,
@ -473,7 +473,7 @@ pub struct Window {
impl Window {
pub(crate) fn new(
event_loop: &ActiveEventLoop,
window_attributes: WindowAttributes,
mut window_attributes: WindowAttributes,
) -> Result<Window, RequestError> {
let mtm = event_loop.mtm;
@ -484,6 +484,12 @@ impl Window {
warn!("`WindowAttributes::max_surface_size` is ignored on iOS");
}
let ios_attributes = window_attributes
.platform
.take()
.and_then(|attrs| attrs.cast::<WindowAttributesIos>().ok())
.unwrap_or_default();
// TODO: transparency, visible
#[allow(deprecated)]
@ -512,12 +518,12 @@ impl Window {
None => screen_bounds,
};
let view = WinitView::new(mtm, &window_attributes, frame);
let view = WinitView::new(mtm, ios_attributes.scale_factor, frame);
let gl_or_metal_backed =
view.isKindOfClass(class!(CAMetalLayer)) || view.isKindOfClass(class!(CAEAGLLayer));
let view_controller = WinitViewController::new(mtm, &window_attributes, &view);
let view_controller = WinitViewController::new(mtm, &ios_attributes, &view);
let window = WinitUIWindow::new(mtm, &window_attributes, frame, &view_controller);
window.makeKeyAndVisible();
@ -885,13 +891,3 @@ impl Inner {
self.window.convertRect_fromCoordinateSpace(rect, &screen_space)
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PlatformSpecificWindowAttributes {
pub scale_factor: Option<f64>,
pub valid_orientations: ValidOrientations,
pub prefers_home_indicator_hidden: bool,
pub prefers_status_bar_hidden: bool,
pub preferred_status_bar_style: StatusBarStyle,
pub preferred_screen_edges_deferring_system_gestures: ScreenEdge,
}