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

@ -11,7 +11,7 @@ use android_activity::{
use tracing::{debug, trace, warn};
use crate::application::ApplicationHandler;
use crate::cursor::Cursor;
use crate::cursor::{Cursor, CustomCursor, CustomCursorSource};
use crate::dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
use crate::error::{EventLoopError, NotSupportedError, RequestError};
use crate::event::{self, DeviceId, FingerId, Force, StartCause, SurfaceSizeWriter};
@ -23,8 +23,8 @@ use crate::event_loop::{
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
use crate::platform::pump_events::PumpStatus;
use crate::window::{
self, CursorGrabMode, CustomCursor, CustomCursorSource, ImePurpose, ResizeDirection, Theme,
Window as CoreWindow, WindowAttributes, WindowButtons, WindowId, WindowLevel,
self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, Window as CoreWindow,
WindowAttributes, WindowButtons, WindowId, WindowLevel,
};
mod keycodes;

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,
}

View file

@ -18,6 +18,7 @@ use sctk::reexports::client::{globals, Connection, QueueHandle};
use tracing::warn;
use crate::application::ApplicationHandler;
use crate::cursor::{CustomCursor as CoreCustomCursor, CustomCursorSource};
use crate::dpi::LogicalSize;
use crate::error::{EventLoopError, NotSupportedError, OsError, RequestError};
use crate::event::{DeviceEvent, StartCause, SurfaceSizeWriter, WindowEvent};
@ -29,7 +30,7 @@ use crate::monitor::MonitorHandle as CoreMonitorHandle;
use crate::platform::pump_events::PumpStatus;
use crate::platform_impl::platform::min_timeout;
use crate::platform_impl::wayland::types::cursor::WaylandCustomCursor;
use crate::window::{CustomCursor as CoreCustomCursor, CustomCursorSource, Theme};
use crate::window::Theme;
mod proxy;
pub mod sink;

View file

@ -163,9 +163,9 @@ pub trait ZwpTextInputV3Ext {
impl ZwpTextInputV3Ext for ZwpTextInputV3 {
fn set_content_type_by_purpose(&self, purpose: ImePurpose) {
let (hint, purpose) = match purpose {
ImePurpose::Normal => (ContentHint::None, ContentPurpose::Normal),
ImePurpose::Password => (ContentHint::SensitiveData, ContentPurpose::Password),
ImePurpose::Terminal => (ContentHint::None, ContentPurpose::Terminal),
_ => (ContentHint::None, ContentPurpose::Normal),
};
self.set_content_type(hint, purpose);
}

View file

@ -19,15 +19,17 @@ use super::output::MonitorHandle;
use super::state::WinitState;
use super::types::xdg_activation::XdgActivationTokenData;
use super::ActiveEventLoop;
use crate::cursor::Cursor;
use crate::dpi::{LogicalSize, PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
use crate::error::{NotSupportedError, RequestError};
use crate::event::{Ime, WindowEvent};
use crate::event_loop::AsyncRequestSerial;
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
use crate::platform::wayland::WindowAttributesWayland;
use crate::platform_impl::wayland::output;
use crate::window::{
Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType,
Window as CoreWindow, WindowAttributes, WindowButtons, WindowId, WindowLevel,
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow,
WindowAttributes, WindowButtons, WindowId, WindowLevel,
};
pub(crate) mod state;
@ -78,7 +80,7 @@ pub struct Window {
impl Window {
pub(crate) fn new(
event_loop_window_target: &ActiveEventLoop,
attributes: WindowAttributes,
mut attributes: WindowAttributes,
) -> Result<Self, RequestError> {
let queue_handle = event_loop_window_target.queue_handle.clone();
let mut state = event_loop_window_target.state.borrow_mut();
@ -121,8 +123,15 @@ impl Window {
// Set the decorations hint.
window_state.set_decorate(attributes.decorations);
let (app_name, activation_token) =
match attributes.platform.take().and_then(|p| p.cast::<WindowAttributesWayland>().ok())
{
Some(attrs) => (attrs.name, attrs.activation_token),
None => (None, None),
};
// Set the app_id.
if let Some(name) = attributes.platform_specific.name.map(|name| name.general) {
if let Some(name) = app_name.map(|name| name.general) {
window.set_app_id(name);
}
@ -162,10 +171,8 @@ impl Window {
}
// Activate the window when the token is passed.
if let (Some(xdg_activation), Some(token)) =
(xdg_activation.as_ref(), attributes.platform_specific.activation_token)
{
xdg_activation.activate(token.token, &surface);
if let (Some(xdg_activation), Some(token)) = (xdg_activation.as_ref(), activation_token) {
xdg_activation.activate(token.into_raw(), &surface);
}
// XXX Do initial commit.
@ -497,7 +504,7 @@ impl CoreWindow for Window {
fn set_window_level(&self, _level: WindowLevel) {}
fn set_window_icon(&self, _window_icon: Option<crate::window::Icon>) {}
fn set_window_icon(&self, _window_icon: Option<crate::icon::Icon>) {}
#[inline]
fn set_ime_cursor_area(&self, position: Position, size: Size) {
@ -678,23 +685,3 @@ impl WindowRequests {
self.redraw_requested.swap(false, Ordering::Relaxed)
}
}
impl TryFrom<&str> for Theme {
type Error = ();
/// ```
/// use winit::window::Theme;
///
/// assert_eq!("dark".try_into(), Ok(Theme::Dark));
/// assert_eq!("lIghT".try_into(), Ok(Theme::Light));
/// ```
fn try_from(theme: &str) -> Result<Self, Self::Error> {
if theme.eq_ignore_ascii_case("dark") {
Ok(Self::Dark)
} else if theme.eq_ignore_ascii_case("light") {
Ok(Self::Light)
} else {
Err(())
}
}
}

View file

@ -28,7 +28,7 @@ use sctk::subcompositor::SubcompositorState;
use tracing::{info, warn};
use wayland_protocols_plasma::blur::client::org_kde_kwin_blur::OrgKdeKwinBlur;
use crate::cursor::CustomCursor as CoreCustomCursor;
use crate::cursor::{CursorIcon, CustomCursor as CoreCustomCursor};
use crate::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Size};
use crate::error::{NotSupportedError, RequestError};
use crate::platform_impl::wayland::event_loop::OwnedDisplayHandle;
@ -41,7 +41,7 @@ use crate::platform_impl::wayland::types::cursor::{
CustomCursor, SelectedCursor, WaylandCustomCursor,
};
use crate::platform_impl::wayland::types::kwin_blur::KWinBlurManager;
use crate::window::{CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme, WindowId};
use crate::window::{CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowId};
#[cfg(feature = "sctk-adwaita")]
pub type WinitFrame = sctk_adwaita::AdwaitaFrame<WinitState>;
@ -398,7 +398,7 @@ impl WindowState {
self.apply_on_pointer(|_, data| {
let serial = data.latest_button_serial();
let seat = data.seat();
xdg_toplevel.resize(seat, serial, direction.into());
xdg_toplevel.resize(seat, serial, resize_direction_to_xdg(direction));
});
Ok(())
@ -1148,18 +1148,16 @@ pub enum FrameCallbackState {
Received,
}
impl From<ResizeDirection> for XdgResizeEdge {
fn from(value: ResizeDirection) -> Self {
match value {
ResizeDirection::North => XdgResizeEdge::Top,
ResizeDirection::West => XdgResizeEdge::Left,
ResizeDirection::NorthWest => XdgResizeEdge::TopLeft,
ResizeDirection::NorthEast => XdgResizeEdge::TopRight,
ResizeDirection::East => XdgResizeEdge::Right,
ResizeDirection::SouthWest => XdgResizeEdge::BottomLeft,
ResizeDirection::SouthEast => XdgResizeEdge::BottomRight,
ResizeDirection::South => XdgResizeEdge::Bottom,
}
fn resize_direction_to_xdg(direction: ResizeDirection) -> XdgResizeEdge {
match direction {
ResizeDirection::North => XdgResizeEdge::Top,
ResizeDirection::West => XdgResizeEdge::Left,
ResizeDirection::NorthWest => XdgResizeEdge::TopLeft,
ResizeDirection::NorthEast => XdgResizeEdge::TopRight,
ResizeDirection::East => XdgResizeEdge::Right,
ResizeDirection::SouthWest => XdgResizeEdge::BottomLeft,
ResizeDirection::SouthEast => XdgResizeEdge::BottomRight,
ResizeDirection::South => XdgResizeEdge::Bottom,
}
}

View file

@ -23,6 +23,7 @@ use x11rb::x11_utils::X11Error as LogicalError;
use x11rb::xcb_ffi::ReplyOrIdError;
use crate::application::ApplicationHandler;
use crate::cursor::{CustomCursor as CoreCustomCursor, CustomCursorSource};
use crate::error::{EventLoopError, RequestError};
use crate::event::{DeviceId, StartCause, WindowEvent};
use crate::event_loop::{
@ -36,10 +37,7 @@ use crate::platform::x11::XlibErrorHook;
use crate::platform_impl::common::xkb::Context;
use crate::platform_impl::platform::min_timeout;
use crate::platform_impl::x11::window::Window;
use crate::window::{
CustomCursor as CoreCustomCursor, CustomCursorSource, Theme, Window as CoreWindow,
WindowAttributes, WindowId,
};
use crate::window::{Theme, Window as CoreWindow, WindowAttributes, WindowId};
mod activation;
mod atoms;

View file

@ -9,9 +9,8 @@ use x11rb::protocol::xproto;
use super::super::ActiveEventLoop;
use super::*;
use crate::cursor::{CustomCursorProvider, CustomCursorSource};
use crate::cursor::{CursorIcon, CustomCursorProvider, CustomCursorSource};
use crate::error::{NotSupportedError, RequestError};
use crate::window::CursorIcon;
impl XConnection {
pub fn set_cursor_icon(

View file

@ -32,7 +32,7 @@ use crate::icon::RgbaIcon;
use crate::monitor::{
Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider, VideoMode,
};
use crate::platform::x11::WindowType;
use crate::platform::x11::{WindowAttributesX11, WindowType};
use crate::platform_impl::common;
use crate::platform_impl::x11::atoms::*;
use crate::platform_impl::x11::util::rgba_to_cardinals;
@ -204,7 +204,7 @@ impl CoreWindow for Window {
self.0.set_window_level(level);
}
fn set_window_icon(&self, window_icon: Option<crate::window::Icon>) {
fn set_window_icon(&self, window_icon: Option<crate::icon::Icon>) {
let icon = match window_icon.as_ref() {
Some(icon) => icon.cast_ref::<RgbaIcon>(),
None => None,
@ -443,12 +443,18 @@ impl UnownedWindow {
#[allow(clippy::unnecessary_cast)]
pub(crate) fn new(
event_loop: &ActiveEventLoop,
window_attrs: WindowAttributes,
mut window_attrs: WindowAttributes,
) -> Result<UnownedWindow, RequestError> {
let xconn = &event_loop.xconn;
let atoms = xconn.atoms();
let screen_id = match window_attrs.platform_specific.x11.screen_id {
let x11_attributes = window_attrs
.platform
.take()
.and_then(|attrs| attrs.cast::<WindowAttributesX11>().ok())
.unwrap_or_default();
let screen_id = match x11_attributes.screen_id {
Some(id) => id,
None => xconn.default_screen_index() as c_int,
};
@ -461,7 +467,7 @@ impl UnownedWindow {
)?
};
let root = match window_attrs.parent_window.as_ref().map(|handle| handle.0) {
let root = match window_attrs.parent_window() {
Some(rwh_06::RawWindowHandle::Xlib(handle)) => handle.window as xproto::Window,
Some(rwh_06::RawWindowHandle::Xcb(handle)) => handle.window.get(),
Some(raw) => unreachable!("Invalid raw window handle {raw:?} on X11"),
@ -528,33 +534,32 @@ impl UnownedWindow {
.flat_map(|depth| depth.visuals.iter().map(move |visual| (visual, depth.depth)));
// creating
let (visualtype, depth, require_colormap) =
match window_attrs.platform_specific.x11.visual_id {
Some(vi) => {
// Find this specific visual.
let (visualtype, depth) = all_visuals
.find(|(visual, _)| visual.visual_id == vi)
.ok_or_else(|| os_error!(X11Error::NoSuchVisual(vi)))?;
let (visualtype, depth, require_colormap) = match x11_attributes.visual_id {
Some(vi) => {
// Find this specific visual.
let (visualtype, depth) = all_visuals
.find(|(visual, _)| visual.visual_id == vi)
.ok_or_else(|| os_error!(X11Error::NoSuchVisual(vi)))?;
(Some(visualtype), depth, true)
},
None if window_attrs.transparent => {
// Find a suitable visual, true color with 32 bits of depth.
all_visuals
.find_map(|(visual, depth)| {
(depth == 32 && visual.class == xproto::VisualClass::TRUE_COLOR)
.then_some((Some(visual), depth, true))
})
.unwrap_or_else(|| {
debug!(
"Could not set transparency, because XMatchVisualInfo returned \
zero for the required parameters"
);
(None as _, x11rb::COPY_FROM_PARENT as _, false)
})
},
_ => (None, x11rb::COPY_FROM_PARENT as _, false),
};
(Some(visualtype), depth, true)
},
None if window_attrs.transparent => {
// Find a suitable visual, true color with 32 bits of depth.
all_visuals
.find_map(|(visual, depth)| {
(depth == 32 && visual.class == xproto::VisualClass::TRUE_COLOR)
.then_some((Some(visual), depth, true))
})
.unwrap_or_else(|| {
debug!(
"Could not set transparency, because XMatchVisualInfo returned zero \
for the required parameters"
);
(None as _, x11rb::COPY_FROM_PARENT as _, false)
})
},
_ => (None, x11rb::COPY_FROM_PARENT as _, false),
};
let mut visual = visualtype.map_or(x11rb::COPY_FROM_PARENT, |v| v.visual_id);
let window_attributes = {
@ -574,12 +579,12 @@ impl UnownedWindow {
aux = aux.event_mask(event_mask).border_pixel(0);
if window_attrs.platform_specific.x11.override_redirect {
if x11_attributes.override_redirect {
aux = aux.override_redirect(true as u32);
}
// Add a colormap if needed.
let colormap_visual = match window_attrs.platform_specific.x11.visual_id {
let colormap_visual = match x11_attributes.visual_id {
Some(vi) => Some(vi),
None if require_colormap => Some(visual),
_ => None,
@ -602,7 +607,7 @@ impl UnownedWindow {
};
// Figure out the window's parent.
let parent = window_attrs.platform_specific.x11.embed_window.unwrap_or(root);
let parent = x11_attributes.embed_window.unwrap_or(root);
// finally creating the window
let xwindow = {
@ -665,7 +670,7 @@ impl UnownedWindow {
}
// Embed the window if needed.
if window_attrs.platform_specific.x11.embed_window.is_some() {
if x11_attributes.embed_window.is_some() {
window.embed_window()?;
}
@ -686,7 +691,7 @@ impl UnownedWindow {
// WM_CLASS must be set *before* mapping the window, as per ICCCM!
{
let (instance, class) = if let Some(name) = window_attrs.platform_specific.name {
let (instance, class) = if let Some(name) = x11_attributes.name {
(name.instance, name.general)
} else {
let class = env::args_os()
@ -717,8 +722,7 @@ impl UnownedWindow {
flusher.ignore_error()
}
leap!(window.set_window_types(window_attrs.platform_specific.x11.x11_window_types))
.ignore_error();
leap!(window.set_window_types(x11_attributes.x11_window_types)).ignore_error();
// Set size hints.
let mut min_surface_size =
@ -739,7 +743,7 @@ impl UnownedWindow {
shared_state.min_surface_size = min_surface_size.map(Into::into);
shared_state.max_surface_size = max_surface_size.map(Into::into);
shared_state.surface_resize_increments = window_attrs.surface_resize_increments;
shared_state.base_size = window_attrs.platform_specific.x11.base_size;
shared_state.base_size = x11_attributes.base_size;
let normal_hints = WmSizeHints {
position: position.map(|PhysicalPosition { x, y }| {
@ -755,9 +759,7 @@ impl UnownedWindow {
size_increment: window_attrs
.surface_resize_increments
.map(|size| cast_size_to_hint(size, scale_factor)),
base_size: window_attrs
.platform_specific
.x11
base_size: x11_attributes
.base_size
.map(|size| cast_size_to_hint(size, scale_factor)),
aspect: None,
@ -884,8 +886,8 @@ impl UnownedWindow {
window.set_cursor(window_attrs.cursor);
// Remove the startup notification if we have one.
if let Some(startup) = window_attrs.platform_specific.activation_token.as_ref() {
leap!(xconn.remove_activation_token(xwindow, &startup.token));
if let Some(startup) = x11_attributes.activation_token.as_ref() {
leap!(xconn.remove_activation_token(xwindow, startup.as_raw()));
}
// We never want to give the user a broken window, since by then, it's too late to handle.

View file

@ -16,7 +16,7 @@ use x11rb::xcb_ffi::XCBConnection;
use super::atoms::Atoms;
use super::ffi;
use super::monitor::MonitorHandle;
use crate::window::CursorIcon;
use crate::cursor::CursorIcon;
/// A connection to an X server.
pub struct XConnection {

View file

@ -13,6 +13,7 @@ use smol_str::SmolStr;
use super::{PlatformSpecificEventLoopAttributes, RedoxSocket, TimeSocket, WindowProperties};
use crate::application::ApplicationHandler;
use crate::cursor::{CustomCursor, CustomCursorSource};
use crate::error::{EventLoopError, NotSupportedError, RequestError};
use crate::event::{self, Ime, Modifiers, StartCause};
use crate::event_loop::{
@ -25,9 +26,7 @@ use crate::keyboard::{
PhysicalKey,
};
use crate::platform_impl::Window;
use crate::window::{
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as CoreWindow, WindowId,
};
use crate::window::{Theme, Window as CoreWindow, WindowId};
fn convert_scancode(scancode: u8) -> (PhysicalKey, Option<NamedKey>) {
// Key constants from https://docs.rs/orbclient/latest/orbclient/event/index.html
@ -699,10 +698,7 @@ impl RootActiveEventLoop for ActiveEventLoop {
Ok(Box::new(Window::new(self, window_attributes)?))
}
fn create_custom_cursor(
&self,
_: CustomCursorSource,
) -> Result<RootCustomCursor, RequestError> {
fn create_custom_cursor(&self, _: CustomCursorSource) -> Result<CustomCursor, RequestError> {
Err(NotSupportedError::new("create_custom_cursor is not supported").into())
}

View file

@ -11,6 +11,7 @@ use super::super::monitor::MonitorPermissionFuture;
use super::runner::Event;
use super::{backend, runner};
use crate::application::ApplicationHandler;
use crate::cursor::{CustomCursor as CoreCustomCursor, CustomCursorSource};
use crate::error::{NotSupportedError, RequestError};
use crate::event::{ElementState, KeyEvent, TouchPhase, WindowEvent};
use crate::event_loop::{
@ -23,7 +24,7 @@ use crate::platform::web::{CustomCursorFuture, PollStrategy, WaitUntilStrategy};
use crate::platform_impl::platform::cursor::CustomCursor;
use crate::platform_impl::web::event_loop::proxy::EventLoopProxy;
use crate::platform_impl::Window;
use crate::window::{CustomCursor as CoreCustomCursor, CustomCursorSource, Theme, WindowId};
use crate::window::{Theme, WindowId};
#[derive(Default, Debug)]
struct ModifiersShared(Rc<Cell<ModifiersState>>);

View file

@ -24,13 +24,13 @@ mod r#async;
mod cursor;
mod error;
mod event;
mod event_loop;
pub(crate) mod event_loop;
mod keyboard;
mod lock;
mod main_thread;
pub(crate) mod main_thread;
mod monitor;
mod web_sys;
mod window;
pub(crate) mod web_sys;
pub(crate) mod window;
pub(crate) use cursor::CustomCursorFuture;
@ -41,4 +41,4 @@ pub(crate) use self::monitor::{
HasMonitorPermissionFuture, MonitorHandle, MonitorPermissionFuture, OrientationLockFuture,
};
use self::web_sys as backend;
pub use self::window::{PlatformSpecificWindowAttributes, Window};
pub use self::window::Window;

View file

@ -28,6 +28,7 @@ use crate::event::{
};
use crate::keyboard::{Key, KeyLocation, ModifiersState, PhysicalKey};
use crate::monitor::Fullscreen;
use crate::platform::web::WindowAttributesWeb;
use crate::window::{WindowAttributes, WindowId};
#[allow(dead_code)]
@ -84,9 +85,15 @@ impl Canvas {
window: web_sys::Window,
navigator: Navigator,
document: Document,
attr: WindowAttributes,
mut attr: WindowAttributes,
) -> Result<Self, RequestError> {
let canvas = match attr.platform_specific.canvas.map(Arc::try_unwrap) {
let web_attributes = attr
.platform
.take()
.and_then(|attrs| attrs.cast::<WindowAttributesWeb>().ok())
.unwrap_or_default();
let canvas = match web_attributes.canvas.map(Arc::try_unwrap) {
Some(Ok(canvas)) => canvas.into_inner(main_thread),
Some(Err(canvas)) => canvas.get(main_thread).clone(),
None => document
@ -95,7 +102,7 @@ impl Canvas {
.unchecked_into(),
};
if attr.platform_specific.append && !document.contains(Some(&canvas)) {
if web_attributes.append && !document.contains(Some(&canvas)) {
document
.body()
.expect("Failed to get body from document")
@ -108,7 +115,7 @@ impl Canvas {
// sequential keyboard navigation, but its order is defined by the
// document's source order.
// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
if attr.platform_specific.focusable {
if web_attributes.focusable {
canvas
.set_attribute("tabindex", "0")
.map_err(|_| os_error!("Failed to set a tabindex"))?;
@ -161,7 +168,7 @@ impl Canvas {
common,
id,
has_focus: Rc::new(Cell::new(false)),
prevent_default: Rc::new(Cell::new(attr.platform_specific.prevent_default)),
prevent_default: Rc::new(Cell::new(web_attributes.prevent_default)),
is_intersecting: Cell::new(None),
cursor,
handlers: RefCell::new(Handlers {
@ -517,7 +524,7 @@ impl Canvas {
self.set_old_size(new_size);
runner.send_event(runner::Event::WindowEvent {
window_id: self.id,
event: crate::event::WindowEvent::SurfaceResized(new_size),
event: WindowEvent::SurfaceResized(new_size),
})
}
}

View file

@ -1,22 +1,22 @@
use std::cell::Ref;
use std::fmt;
use std::rc::Rc;
use std::sync::Arc;
use dpi::{LogicalPosition, LogicalSize};
use web_sys::HtmlCanvasElement;
use super::main_thread::{MainThreadMarker, MainThreadSafe};
use super::main_thread::MainThreadMarker;
use super::monitor::MonitorHandler;
use super::r#async::Dispatcher;
use super::{backend, lock, ActiveEventLoop};
use crate::cursor::Cursor;
use crate::dpi::{LogicalInsets, PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
use crate::error::{NotSupportedError, RequestError};
use crate::icon::Icon;
use crate::monitor::{Fullscreen, MonitorHandle as CoremMonitorHandle};
use crate::window::{
Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType,
Window as RootWindow, WindowAttributes, WindowButtons, WindowId, WindowLevel,
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as RootWindow,
WindowAttributes, WindowButtons, WindowId, WindowLevel,
};
pub struct Window {
@ -462,42 +462,3 @@ impl Drop for Inner {
}
}
}
#[derive(Clone, Debug)]
pub struct PlatformSpecificWindowAttributes {
pub(crate) canvas: Option<Arc<MainThreadSafe<backend::RawCanvasType>>>,
pub(crate) prevent_default: bool,
pub(crate) focusable: bool,
pub(crate) append: bool,
}
impl PartialEq for PlatformSpecificWindowAttributes {
fn eq(&self, other: &Self) -> bool {
(match (&self.canvas, &other.canvas) {
(Some(this), Some(other)) => Arc::ptr_eq(this, other),
(None, None) => true,
_ => false,
}) && self.prevent_default.eq(&other.prevent_default)
&& self.focusable.eq(&other.focusable)
&& self.append.eq(&other.append)
}
}
impl PlatformSpecificWindowAttributes {
pub(crate) fn set_canvas(&mut self, canvas: Option<backend::RawCanvasType>) {
let Some(canvas) = canvas else {
self.canvas = None;
return;
};
let main_thread = MainThreadMarker::new()
.expect("received a `HtmlCanvasElement` outside the window context");
self.canvas = Some(Arc::new(MainThreadSafe::new(main_thread, canvas)));
}
}
impl Default for PlatformSpecificWindowAttributes {
fn default() -> Self {
Self { canvas: None, prevent_default: true, focusable: true, append: false }
}
}

View file

@ -63,6 +63,7 @@ pub(super) use self::runner::{Event, EventLoopRunner};
use super::window::set_skip_taskbar;
use super::SelectedCursor;
use crate::application::ApplicationHandler;
use crate::cursor::{CustomCursor, CustomCursorSource};
use crate::dpi::{PhysicalPosition, PhysicalSize};
use crate::error::{EventLoopError, NotSupportedError, RequestError};
use crate::event::{
@ -91,10 +92,7 @@ use crate::platform_impl::platform::window_state::{
};
use crate::platform_impl::platform::{raw_input, util, wrap_device_id};
use crate::platform_impl::Window;
use crate::window::{
CustomCursor as CoreCustomCursor, CustomCursorSource, Theme, Window as CoreWindow,
WindowAttributes, WindowId,
};
use crate::window::{Theme, Window as CoreWindow, WindowAttributes, WindowId};
pub(crate) struct WindowData {
pub window_state: Arc<Mutex<WindowState>>,
@ -420,7 +418,7 @@ impl RootActiveEventLoop for ActiveEventLoop {
fn create_custom_cursor(
&self,
source: CustomCursorSource,
) -> Result<CoreCustomCursor, RequestError> {
) -> Result<CustomCursor, RequestError> {
let cursor = match source {
CustomCursorSource::Image(cursor) => cursor,
CustomCursorSource::Animation { .. } | CustomCursorSource::Url { .. } => {
@ -428,7 +426,7 @@ impl RootActiveEventLoop for ActiveEventLoop {
},
};
Ok(CoreCustomCursor(Arc::new(WinCursor::new(&cursor)?)))
Ok(CustomCursor(Arc::new(WinCursor::new(&cursor)?)))
}
fn available_monitors(&self) -> Box<dyn Iterator<Item = CoreMonitorHandle>> {

View file

@ -1,5 +1,5 @@
use windows_sys::Win32::Foundation::HWND;
use windows_sys::Win32::UI::WindowsAndMessaging::{HMENU, WINDOW_LONG_PTR_INDEX};
use windows_sys::Win32::UI::WindowsAndMessaging::WINDOW_LONG_PTR_INDEX;
pub(crate) use self::event_loop::{EventLoop, PlatformSpecificEventLoopAttributes};
pub(crate) use self::icon::{RaiiIcon, SelectedCursor};
@ -7,50 +7,6 @@ pub(crate) use self::keyboard::{physicalkey_to_scancode, scancode_to_physicalkey
pub(crate) use self::monitor::MonitorHandle;
pub(crate) use self::window::Window;
use crate::event::DeviceId;
use crate::icon::Icon;
use crate::platform::windows::{BackdropType, Color, CornerPreference};
#[derive(Clone, Debug)]
pub struct PlatformSpecificWindowAttributes {
pub owner: Option<HWND>,
pub menu: Option<HMENU>,
pub taskbar_icon: Option<Icon>,
pub no_redirection_bitmap: bool,
pub drag_and_drop: bool,
pub skip_taskbar: bool,
pub class_name: String,
pub decoration_shadow: bool,
pub backdrop_type: BackdropType,
pub clip_children: bool,
pub border_color: Option<Color>,
pub title_background_color: Option<Color>,
pub title_text_color: Option<Color>,
pub corner_preference: Option<CornerPreference>,
}
impl Default for PlatformSpecificWindowAttributes {
fn default() -> Self {
Self {
owner: None,
menu: None,
taskbar_icon: None,
no_redirection_bitmap: false,
drag_and_drop: true,
skip_taskbar: false,
class_name: "Window Class".to_string(),
decoration_shadow: false,
backdrop_type: BackdropType::default(),
clip_children: true,
border_color: None,
title_background_color: None,
title_text_color: None,
corner_preference: None,
}
}
}
unsafe impl Send for PlatformSpecificWindowAttributes {}
unsafe impl Sync for PlatformSpecificWindowAttributes {}
fn wrap_device_id(id: u32) -> DeviceId {
DeviceId::from_raw(id as i64)

View file

@ -24,7 +24,7 @@ use windows_sys::Win32::UI::WindowsAndMessaging::{
WINDOWPLACEMENT,
};
use crate::window::CursorIcon;
use crate::cursor::CursorIcon;
pub fn encode_wide(string: impl AsRef<OsStr>) -> Vec<u16> {
string.as_ref().encode_wide().chain(once(0)).collect()

View file

@ -55,7 +55,9 @@ use crate::dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size}
use crate::error::RequestError;
use crate::icon::{Icon, RgbaIcon};
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider};
use crate::platform::windows::{BackdropType, Color, CornerPreference, WinIcon};
use crate::platform::windows::{
BackdropType, Color, CornerPreference, WinIcon, WindowAttributesWindows,
};
use crate::platform_impl::platform::dark_mode::try_theme;
use crate::platform_impl::platform::definitions::{
CLSID_TaskbarList, IID_ITaskbarList, IID_ITaskbarList2, ITaskbarList, ITaskbarList2,
@ -1137,6 +1139,7 @@ pub(super) struct InitData<'a> {
// inputs
pub runner: &'a Rc<EventLoopRunner>,
pub attributes: WindowAttributes,
pub win_attributes: Box<WindowAttributesWindows>,
pub window_flags: WindowFlags,
// outputs
pub window: Option<Window>,
@ -1186,7 +1189,7 @@ impl InitData<'_> {
}
unsafe fn create_window_data(&self, win: &Window) -> event_loop::WindowData {
let file_drop_handler = if self.attributes.platform_specific.drag_and_drop {
let file_drop_handler = if self.win_attributes.drag_and_drop {
let ole_init_result = unsafe { OleInitialize(ptr::null_mut()) };
// It is ok if the initialize result is `S_FALSE` because it might happen that
// multiple windows are created on the same thread.
@ -1250,7 +1253,7 @@ impl InitData<'_> {
let win = self.window.as_mut().expect("failed window creation");
// making the window transparent
if self.attributes.transparent && !self.attributes.platform_specific.no_redirection_bitmap {
if self.attributes.transparent && !self.win_attributes.no_redirection_bitmap {
// Empty region for the blur effect, so the window is fully transparent
let region = unsafe { CreateRectRgn(0, 0, -1, -1) };
@ -1267,9 +1270,9 @@ impl InitData<'_> {
unsafe { DeleteObject(region) };
}
win.set_skip_taskbar(self.attributes.platform_specific.skip_taskbar);
win.set_skip_taskbar(self.win_attributes.skip_taskbar);
win.set_window_icon(self.attributes.window_icon.clone());
win.set_taskbar_icon(self.attributes.platform_specific.taskbar_icon.clone());
win.set_taskbar_icon(self.win_attributes.taskbar_icon.clone());
let attributes = self.attributes.clone();
@ -1306,43 +1309,45 @@ impl InitData<'_> {
win.set_outer_position(position);
}
win.set_system_backdrop(self.attributes.platform_specific.backdrop_type);
win.set_system_backdrop(self.win_attributes.backdrop_type);
if let Some(color) = self.attributes.platform_specific.border_color {
if let Some(color) = self.win_attributes.border_color {
win.set_border_color(color);
}
if let Some(color) = self.attributes.platform_specific.title_background_color {
if let Some(color) = self.win_attributes.title_background_color {
win.set_title_background_color(color);
}
if let Some(color) = self.attributes.platform_specific.title_text_color {
if let Some(color) = self.win_attributes.title_text_color {
win.set_title_text_color(color);
}
if let Some(corner) = self.attributes.platform_specific.corner_preference {
if let Some(corner) = self.win_attributes.corner_preference {
win.set_corner_preference(corner);
}
}
}
unsafe fn init(
attributes: WindowAttributes,
mut attributes: WindowAttributes,
runner: &Rc<EventLoopRunner>,
) -> Result<Window, RequestError> {
let title = util::encode_wide(&attributes.title);
let class_name = util::encode_wide(&attributes.platform_specific.class_name);
let win_attributes = attributes
.platform
.take()
.and_then(|attrs| attrs.cast::<WindowAttributesWindows>().ok())
.unwrap_or_default();
let class_name = util::encode_wide(&win_attributes.class_name);
unsafe { register_window_class(&class_name) };
let mut window_flags = WindowFlags::empty();
window_flags.set(WindowFlags::MARKER_DECORATIONS, attributes.decorations);
window_flags.set(
WindowFlags::MARKER_UNDECORATED_SHADOW,
attributes.platform_specific.decoration_shadow,
);
window_flags.set(WindowFlags::MARKER_UNDECORATED_SHADOW, win_attributes.decoration_shadow);
window_flags
.set(WindowFlags::ALWAYS_ON_TOP, attributes.window_level == WindowLevel::AlwaysOnTop);
window_flags
.set(WindowFlags::ALWAYS_ON_BOTTOM, attributes.window_level == WindowLevel::AlwaysOnBottom);
window_flags
.set(WindowFlags::NO_BACK_BUFFER, attributes.platform_specific.no_redirection_bitmap);
window_flags.set(WindowFlags::NO_BACK_BUFFER, win_attributes.no_redirection_bitmap);
window_flags.set(WindowFlags::MARKER_ACTIVATE, attributes.active);
window_flags.set(WindowFlags::TRANSPARENT, attributes.transparent);
// WindowFlags::VISIBLE and MAXIMIZED are set down below after the window has been configured.
@ -1350,9 +1355,9 @@ unsafe fn init(
// Will be changed later using `window.set_enabled_buttons` but we need to set a default here
// so the diffing later can work.
window_flags.set(WindowFlags::CLOSABLE, true);
window_flags.set(WindowFlags::CLIP_CHILDREN, attributes.platform_specific.clip_children);
window_flags.set(WindowFlags::CLIP_CHILDREN, win_attributes.clip_children);
let mut fallback_parent = || match attributes.platform_specific.owner {
let mut fallback_parent = || match win_attributes.owner {
Some(parent) => {
window_flags.set(WindowFlags::POPUP, true);
Some(parent)
@ -1363,10 +1368,10 @@ unsafe fn init(
},
};
let parent = match attributes.parent_window.as_ref().map(|handle| handle.0) {
let parent = match attributes.parent_window() {
Some(rwh_06::RawWindowHandle::Win32(handle)) => {
window_flags.set(WindowFlags::CHILD, true);
if attributes.platform_specific.menu.is_some() {
if win_attributes.menu.is_some() {
warn!("Setting a menu on a child window is unsupported");
}
Some(handle.hwnd.get() as HWND)
@ -1375,10 +1380,10 @@ unsafe fn init(
None => fallback_parent(),
};
let menu = attributes.platform_specific.menu;
let menu = win_attributes.menu;
let fullscreen = attributes.fullscreen.clone();
let maximized = attributes.maximized;
let mut initdata = InitData { runner, attributes, window_flags, window: None };
let mut initdata = InitData { runner, attributes, win_attributes, window_flags, window: None };
let (style, ex_style) = window_flags.to_window_styles();
let handle = unsafe {