Fix Window feedback loop between the OS and Bevy (#7517)
# Objective Fix #7377 Fix #7513 ## Solution Record the changes made to the Bevy `Window` from `winit` as 'canon' to avoid Bevy sending those changes back to `winit` again, causing a feedback loop. ## Changelog * Removed `ModifiesWindows` system label. Neither `despawn_window` nor `changed_window` actually modify the `Window` component so all the `.after(ModifiesWindows)` shouldn't be necessary. * Moved `changed_window` and `despawn_window` systems to `CoreStage::Last` to avoid systems making changes to the `Window` between `changed_window` and the end of the frame as they would be ignored. ## Migration Guide The `ModifiesWindows` system label was removed. Co-authored-by: devil-ira <justthecooldude@gmail.com>
This commit is contained in:
parent
6314f50e7b
commit
f69f1329e0
@ -11,7 +11,6 @@ mod render;
|
|||||||
|
|
||||||
pub use alpha::*;
|
pub use alpha::*;
|
||||||
use bevy_transform::TransformSystem;
|
use bevy_transform::TransformSystem;
|
||||||
use bevy_window::ModifiesWindows;
|
|
||||||
pub use bundle::*;
|
pub use bundle::*;
|
||||||
pub use fog::*;
|
pub use fog::*;
|
||||||
pub use light::*;
|
pub use light::*;
|
||||||
@ -199,8 +198,7 @@ impl Plugin for PbrPlugin {
|
|||||||
.in_set(SimulationLightSystems::AssignLightsToClusters)
|
.in_set(SimulationLightSystems::AssignLightsToClusters)
|
||||||
.after(TransformSystem::TransformPropagate)
|
.after(TransformSystem::TransformPropagate)
|
||||||
.after(VisibilitySystems::CheckVisibility)
|
.after(VisibilitySystems::CheckVisibility)
|
||||||
.after(CameraUpdateSystem)
|
.after(CameraUpdateSystem),
|
||||||
.after(ModifiesWindows),
|
|
||||||
)
|
)
|
||||||
.add_system(
|
.add_system(
|
||||||
update_directional_light_cascades
|
update_directional_light_cascades
|
||||||
|
|||||||
@ -7,7 +7,6 @@ use bevy_reflect::{
|
|||||||
std_traits::ReflectDefault, FromReflect, GetTypeRegistration, Reflect, ReflectDeserialize,
|
std_traits::ReflectDefault, FromReflect, GetTypeRegistration, Reflect, ReflectDeserialize,
|
||||||
ReflectSerialize,
|
ReflectSerialize,
|
||||||
};
|
};
|
||||||
use bevy_window::ModifiesWindows;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Adds [`Camera`](crate::camera::Camera) driver systems for a given projection type.
|
/// Adds [`Camera`](crate::camera::Camera) driver systems for a given projection type.
|
||||||
@ -43,7 +42,6 @@ impl<T: CameraProjection + Component + GetTypeRegistration> Plugin for CameraPro
|
|||||||
.add_system(
|
.add_system(
|
||||||
crate::camera::camera_system::<T>
|
crate::camera::camera_system::<T>
|
||||||
.in_set(CameraUpdateSystem)
|
.in_set(CameraUpdateSystem)
|
||||||
.after(ModifiesWindows)
|
|
||||||
// We assume that each camera will only have one projection,
|
// We assume that each camera will only have one projection,
|
||||||
// so we can ignore ambiguities with all other monomorphizations.
|
// so we can ignore ambiguities with all other monomorphizations.
|
||||||
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||||
|
|||||||
@ -28,7 +28,6 @@ use bevy_asset::AddAsset;
|
|||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use bevy_render::{camera::CameraUpdateSystem, ExtractSchedule, RenderApp};
|
use bevy_render::{camera::CameraUpdateSystem, ExtractSchedule, RenderApp};
|
||||||
use bevy_sprite::SpriteSystem;
|
use bevy_sprite::SpriteSystem;
|
||||||
use bevy_window::ModifiesWindows;
|
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -83,7 +82,6 @@ impl Plugin for TextPlugin {
|
|||||||
.add_system(
|
.add_system(
|
||||||
update_text2d_layout
|
update_text2d_layout
|
||||||
.in_base_set(CoreSet::PostUpdate)
|
.in_base_set(CoreSet::PostUpdate)
|
||||||
.after(ModifiesWindows)
|
|
||||||
// Potential conflict: `Assets<Image>`
|
// Potential conflict: `Assets<Image>`
|
||||||
// In practice, they run independently since `bevy_render::camera_update_system`
|
// In practice, they run independently since `bevy_render::camera_update_system`
|
||||||
// will only ever observe its own render target, and `update_text2d_layout`
|
// will only ever observe its own render target, and `update_text2d_layout`
|
||||||
|
|||||||
@ -34,7 +34,6 @@ use bevy_app::prelude::*;
|
|||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use bevy_input::InputSystem;
|
use bevy_input::InputSystem;
|
||||||
use bevy_transform::TransformSystem;
|
use bevy_transform::TransformSystem;
|
||||||
use bevy_window::ModifiesWindows;
|
|
||||||
use stack::ui_stack_system;
|
use stack::ui_stack_system;
|
||||||
pub use stack::UiStack;
|
pub use stack::UiStack;
|
||||||
use update::update_clipping_system;
|
use update::update_clipping_system;
|
||||||
@ -110,7 +109,6 @@ impl Plugin for UiPlugin {
|
|||||||
widget::text_system
|
widget::text_system
|
||||||
.in_base_set(CoreSet::PostUpdate)
|
.in_base_set(CoreSet::PostUpdate)
|
||||||
.before(UiSystem::Flex)
|
.before(UiSystem::Flex)
|
||||||
.after(ModifiesWindows)
|
|
||||||
// Potential conflict: `Assets<Image>`
|
// Potential conflict: `Assets<Image>`
|
||||||
// In practice, they run independently since `bevy_render::camera_update_system`
|
// In practice, they run independently since `bevy_render::camera_update_system`
|
||||||
// will only ever observe its own render target, and `widget::text_system`
|
// will only ever observe its own render target, and `widget::text_system`
|
||||||
@ -135,8 +133,7 @@ impl Plugin for UiPlugin {
|
|||||||
.add_system(
|
.add_system(
|
||||||
flex_node_system
|
flex_node_system
|
||||||
.in_set(UiSystem::Flex)
|
.in_set(UiSystem::Flex)
|
||||||
.before(TransformSystem::TransformPropagate)
|
.before(TransformSystem::TransformPropagate),
|
||||||
.after(ModifiesWindows),
|
|
||||||
)
|
)
|
||||||
.add_system(ui_stack_system.in_set(UiSystem::Stack))
|
.add_system(ui_stack_system.in_set(UiSystem::Stack))
|
||||||
.add_system(
|
.add_system(
|
||||||
|
|||||||
@ -137,9 +137,6 @@ impl Plugin for WindowPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
|
|
||||||
pub struct ModifiesWindows;
|
|
||||||
|
|
||||||
/// Defines the specific conditions the application should exit on
|
/// Defines the specific conditions the application should exit on
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum ExitCondition {
|
pub enum ExitCondition {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ mod winit_config;
|
|||||||
mod winit_windows;
|
mod winit_windows;
|
||||||
|
|
||||||
use bevy_ecs::system::{SystemParam, SystemState};
|
use bevy_ecs::system::{SystemParam, SystemState};
|
||||||
use system::{changed_window, create_window, despawn_window};
|
use system::{changed_window, create_window, despawn_window, CachedWindow};
|
||||||
|
|
||||||
pub use winit_config::*;
|
pub use winit_config::*;
|
||||||
pub use winit_windows::*;
|
pub use winit_windows::*;
|
||||||
@ -26,7 +26,7 @@ use bevy_utils::{
|
|||||||
};
|
};
|
||||||
use bevy_window::{
|
use bevy_window::{
|
||||||
exit_on_all_closed, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, Ime,
|
exit_on_all_closed, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, Ime,
|
||||||
ModifiesWindows, ReceivedCharacter, RequestRedraw, Window, WindowBackendScaleFactorChanged,
|
ReceivedCharacter, RequestRedraw, Window, WindowBackendScaleFactorChanged,
|
||||||
WindowCloseRequested, WindowCreated, WindowFocused, WindowMoved, WindowResized,
|
WindowCloseRequested, WindowCreated, WindowFocused, WindowMoved, WindowResized,
|
||||||
WindowScaleFactorChanged,
|
WindowScaleFactorChanged,
|
||||||
};
|
};
|
||||||
@ -39,7 +39,6 @@ use winit::{
|
|||||||
event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopWindowTarget},
|
event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopWindowTarget},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::system::WinitWindowInfo;
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use crate::web_resize::{CanvasParentResizeEventChannel, CanvasParentResizePlugin};
|
use crate::web_resize::{CanvasParentResizeEventChannel, CanvasParentResizePlugin};
|
||||||
|
|
||||||
@ -70,7 +69,6 @@ impl Plugin for WinitPlugin {
|
|||||||
app.init_non_send_resource::<WinitWindows>()
|
app.init_non_send_resource::<WinitWindows>()
|
||||||
.init_resource::<WinitSettings>()
|
.init_resource::<WinitSettings>()
|
||||||
.set_runner(winit_runner)
|
.set_runner(winit_runner)
|
||||||
.configure_set(ModifiesWindows.in_base_set(CoreSet::PostUpdate))
|
|
||||||
// exit_on_all_closed only uses the query to determine if the query is empty,
|
// exit_on_all_closed only uses the query to determine if the query is empty,
|
||||||
// and so doesn't care about ordering relative to changed_window
|
// and so doesn't care about ordering relative to changed_window
|
||||||
.add_systems(
|
.add_systems(
|
||||||
@ -79,7 +77,7 @@ impl Plugin for WinitPlugin {
|
|||||||
// Update the state of the window before attempting to despawn to ensure consistent event ordering
|
// Update the state of the window before attempting to despawn to ensure consistent event ordering
|
||||||
despawn_window.after(changed_window),
|
despawn_window.after(changed_window),
|
||||||
)
|
)
|
||||||
.in_set(ModifiesWindows),
|
.in_base_set(CoreSet::Last),
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
@ -349,7 +347,7 @@ pub fn winit_runner(mut app: App) {
|
|||||||
// Fetch and prepare details from the world
|
// Fetch and prepare details from the world
|
||||||
let mut system_state: SystemState<(
|
let mut system_state: SystemState<(
|
||||||
NonSend<WinitWindows>,
|
NonSend<WinitWindows>,
|
||||||
Query<(&mut Window, &mut WinitWindowInfo)>,
|
Query<(&mut Window, &mut CachedWindow)>,
|
||||||
WindowEvents,
|
WindowEvents,
|
||||||
InputEvents,
|
InputEvents,
|
||||||
CursorEvents,
|
CursorEvents,
|
||||||
@ -376,7 +374,7 @@ pub fn winit_runner(mut app: App) {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let (mut window, mut info) =
|
let (mut window, mut cache) =
|
||||||
if let Ok((window, info)) = window_query.get_mut(window_entity) {
|
if let Ok((window, info)) = window_query.get_mut(window_entity) {
|
||||||
(window, info)
|
(window, info)
|
||||||
} else {
|
} else {
|
||||||
@ -394,7 +392,6 @@ pub fn winit_runner(mut app: App) {
|
|||||||
window
|
window
|
||||||
.resolution
|
.resolution
|
||||||
.set_physical_resolution(size.width, size.height);
|
.set_physical_resolution(size.width, size.height);
|
||||||
info.last_winit_size = size;
|
|
||||||
|
|
||||||
window_events.window_resized.send(WindowResized {
|
window_events.window_resized.send(WindowResized {
|
||||||
window: window_entity,
|
window: window_entity,
|
||||||
@ -421,11 +418,7 @@ pub fn winit_runner(mut app: App) {
|
|||||||
window.resolution.physical_height() as f64 - position.y,
|
window.resolution.physical_height() as f64 - position.y,
|
||||||
);
|
);
|
||||||
|
|
||||||
// bypassing change detection to not trigger feedback loop with system `changed_window`
|
window.set_physical_cursor_position(Some(physical_position));
|
||||||
// this system change the cursor position in winit
|
|
||||||
window
|
|
||||||
.bypass_change_detection()
|
|
||||||
.set_physical_cursor_position(Some(physical_position));
|
|
||||||
|
|
||||||
cursor_events.cursor_moved.send(CursorMoved {
|
cursor_events.cursor_moved.send(CursorMoved {
|
||||||
window: window_entity,
|
window: window_entity,
|
||||||
@ -439,14 +432,7 @@ pub fn winit_runner(mut app: App) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
WindowEvent::CursorLeft { .. } => {
|
WindowEvent::CursorLeft { .. } => {
|
||||||
// Component
|
window.set_physical_cursor_position(None);
|
||||||
if let Ok((mut window, _)) = window_query.get_mut(window_entity) {
|
|
||||||
// bypassing change detection to not trigger feedback loop with system `changed_window`
|
|
||||||
// this system change the cursor position in winit
|
|
||||||
window
|
|
||||||
.bypass_change_detection()
|
|
||||||
.set_physical_cursor_position(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor_events.cursor_left.send(CursorLeft {
|
cursor_events.cursor_left.send(CursorLeft {
|
||||||
window: window_entity,
|
window: window_entity,
|
||||||
@ -594,6 +580,10 @@ pub fn winit_runner(mut app: App) {
|
|||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if window.is_changed() {
|
||||||
|
cache.window = window.clone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
event::Event::DeviceEvent {
|
event::Event::DeviceEvent {
|
||||||
event: DeviceEvent::MouseMotion { delta: (x, y) },
|
event: DeviceEvent::MouseMotion { delta: (x, y) },
|
||||||
|
|||||||
@ -39,20 +39,19 @@ pub(crate) fn create_window<'a>(
|
|||||||
mut winit_windows: NonSendMut<WinitWindows>,
|
mut winit_windows: NonSendMut<WinitWindows>,
|
||||||
#[cfg(target_arch = "wasm32")] event_channel: ResMut<CanvasParentResizeEventChannel>,
|
#[cfg(target_arch = "wasm32")] event_channel: ResMut<CanvasParentResizeEventChannel>,
|
||||||
) {
|
) {
|
||||||
for (entity, mut component) in created_windows {
|
for (entity, mut window) in created_windows {
|
||||||
if winit_windows.get_window(entity).is_some() {
|
if winit_windows.get_window(entity).is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Creating new window {:?} ({:?})",
|
"Creating new window {:?} ({:?})",
|
||||||
component.title.as_str(),
|
window.title.as_str(),
|
||||||
entity
|
entity
|
||||||
);
|
);
|
||||||
|
|
||||||
let winit_window = winit_windows.create_window(event_loop, entity, &component);
|
let winit_window = winit_windows.create_window(event_loop, entity, &window);
|
||||||
let current_size = winit_window.inner_size();
|
window
|
||||||
component
|
|
||||||
.resolution
|
.resolution
|
||||||
.set_scale_factor(winit_window.scale_factor());
|
.set_scale_factor(winit_window.scale_factor());
|
||||||
commands
|
commands
|
||||||
@ -61,18 +60,14 @@ pub(crate) fn create_window<'a>(
|
|||||||
window_handle: winit_window.raw_window_handle(),
|
window_handle: winit_window.raw_window_handle(),
|
||||||
display_handle: winit_window.raw_display_handle(),
|
display_handle: winit_window.raw_display_handle(),
|
||||||
})
|
})
|
||||||
.insert(WinitWindowInfo {
|
.insert(CachedWindow {
|
||||||
previous: component.clone(),
|
window: window.clone(),
|
||||||
last_winit_size: PhysicalSize {
|
|
||||||
width: current_size.width,
|
|
||||||
height: current_size.height,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
if component.fit_canvas_to_parent {
|
if window.fit_canvas_to_parent {
|
||||||
let selector = if let Some(selector) = &component.canvas {
|
let selector = if let Some(selector) = &window.canvas {
|
||||||
selector
|
selector
|
||||||
} else {
|
} else {
|
||||||
WINIT_CANVAS_SELECTOR
|
WINIT_CANVAS_SELECTOR
|
||||||
@ -106,11 +101,10 @@ pub(crate) fn despawn_window(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Previous state of the window so we can check sub-portions of what actually was changed.
|
/// The cached state of the window so we can check which properties were changed from within the app.
|
||||||
#[derive(Debug, Clone, Component)]
|
#[derive(Debug, Clone, Component)]
|
||||||
pub struct WinitWindowInfo {
|
pub struct CachedWindow {
|
||||||
pub previous: Window,
|
pub window: Window,
|
||||||
pub last_winit_size: PhysicalSize<u32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect changes to the window and update the winit window accordingly.
|
// Detect changes to the window and update the winit window accordingly.
|
||||||
@ -121,18 +115,16 @@ pub struct WinitWindowInfo {
|
|||||||
// - [`Window::canvas`] currently cannot be updated after startup, not entirely sure if it would work well with the
|
// - [`Window::canvas`] currently cannot be updated after startup, not entirely sure if it would work well with the
|
||||||
// event channel stuff.
|
// event channel stuff.
|
||||||
pub(crate) fn changed_window(
|
pub(crate) fn changed_window(
|
||||||
mut changed_windows: Query<(Entity, &mut Window, &mut WinitWindowInfo), Changed<Window>>,
|
mut changed_windows: Query<(Entity, &mut Window, &mut CachedWindow), Changed<Window>>,
|
||||||
winit_windows: NonSendMut<WinitWindows>,
|
winit_windows: NonSendMut<WinitWindows>,
|
||||||
) {
|
) {
|
||||||
for (entity, mut window, mut info) in &mut changed_windows {
|
for (entity, mut window, mut cache) in &mut changed_windows {
|
||||||
let previous = &info.previous;
|
|
||||||
|
|
||||||
if let Some(winit_window) = winit_windows.get_window(entity) {
|
if let Some(winit_window) = winit_windows.get_window(entity) {
|
||||||
if window.title != previous.title {
|
if window.title != cache.window.title {
|
||||||
winit_window.set_title(window.title.as_str());
|
winit_window.set_title(window.title.as_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.mode != previous.mode {
|
if window.mode != cache.window.mode {
|
||||||
let new_mode = match window.mode {
|
let new_mode = match window.mode {
|
||||||
bevy_window::WindowMode::BorderlessFullscreen => {
|
bevy_window::WindowMode::BorderlessFullscreen => {
|
||||||
Some(winit::window::Fullscreen::Borderless(None))
|
Some(winit::window::Fullscreen::Borderless(None))
|
||||||
@ -156,19 +148,15 @@ pub(crate) fn changed_window(
|
|||||||
winit_window.set_fullscreen(new_mode);
|
winit_window.set_fullscreen(new_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if window.resolution != previous.resolution {
|
if window.resolution != cache.window.resolution {
|
||||||
let physical_size = PhysicalSize::new(
|
let physical_size = PhysicalSize::new(
|
||||||
window.resolution.physical_width(),
|
window.resolution.physical_width(),
|
||||||
window.resolution.physical_height(),
|
window.resolution.physical_height(),
|
||||||
);
|
);
|
||||||
// Prevents "window.resolution values set from a winit resize event" from
|
|
||||||
// being set here, creating feedback loops.
|
|
||||||
if physical_size != info.last_winit_size {
|
|
||||||
winit_window.set_inner_size(physical_size);
|
winit_window.set_inner_size(physical_size);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if window.physical_cursor_position() != previous.physical_cursor_position() {
|
if window.physical_cursor_position() != cache.window.physical_cursor_position() {
|
||||||
if let Some(physical_position) = window.physical_cursor_position() {
|
if let Some(physical_position) = window.physical_cursor_position() {
|
||||||
let inner_size = winit_window.inner_size();
|
let inner_size = winit_window.inner_size();
|
||||||
|
|
||||||
@ -184,21 +172,21 @@ pub(crate) fn changed_window(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.cursor.icon != previous.cursor.icon {
|
if window.cursor.icon != cache.window.cursor.icon {
|
||||||
winit_window.set_cursor_icon(converters::convert_cursor_icon(window.cursor.icon));
|
winit_window.set_cursor_icon(converters::convert_cursor_icon(window.cursor.icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.cursor.grab_mode != previous.cursor.grab_mode {
|
if window.cursor.grab_mode != cache.window.cursor.grab_mode {
|
||||||
crate::winit_windows::attempt_grab(winit_window, window.cursor.grab_mode);
|
crate::winit_windows::attempt_grab(winit_window, window.cursor.grab_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.cursor.visible != previous.cursor.visible {
|
if window.cursor.visible != cache.window.cursor.visible {
|
||||||
winit_window.set_cursor_visible(window.cursor.visible);
|
winit_window.set_cursor_visible(window.cursor.visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.cursor.hit_test != previous.cursor.hit_test {
|
if window.cursor.hit_test != cache.window.cursor.hit_test {
|
||||||
if let Err(err) = winit_window.set_cursor_hittest(window.cursor.hit_test) {
|
if let Err(err) = winit_window.set_cursor_hittest(window.cursor.hit_test) {
|
||||||
window.cursor.hit_test = previous.cursor.hit_test;
|
window.cursor.hit_test = cache.window.cursor.hit_test;
|
||||||
warn!(
|
warn!(
|
||||||
"Could not set cursor hit test for window {:?}: {:?}",
|
"Could not set cursor hit test for window {:?}: {:?}",
|
||||||
window.title, err
|
window.title, err
|
||||||
@ -206,19 +194,19 @@ pub(crate) fn changed_window(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.decorations != previous.decorations
|
if window.decorations != cache.window.decorations
|
||||||
&& window.decorations != winit_window.is_decorated()
|
&& window.decorations != winit_window.is_decorated()
|
||||||
{
|
{
|
||||||
winit_window.set_decorations(window.decorations);
|
winit_window.set_decorations(window.decorations);
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.resizable != previous.resizable
|
if window.resizable != cache.window.resizable
|
||||||
&& window.resizable != winit_window.is_resizable()
|
&& window.resizable != winit_window.is_resizable()
|
||||||
{
|
{
|
||||||
winit_window.set_resizable(window.resizable);
|
winit_window.set_resizable(window.resizable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.resize_constraints != previous.resize_constraints {
|
if window.resize_constraints != cache.window.resize_constraints {
|
||||||
let constraints = window.resize_constraints.check_constraints();
|
let constraints = window.resize_constraints.check_constraints();
|
||||||
let min_inner_size = LogicalSize {
|
let min_inner_size = LogicalSize {
|
||||||
width: constraints.min_width,
|
width: constraints.min_width,
|
||||||
@ -235,7 +223,7 @@ pub(crate) fn changed_window(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.position != previous.position {
|
if window.position != cache.window.position {
|
||||||
if let Some(position) = crate::winit_window_position(
|
if let Some(position) = crate::winit_window_position(
|
||||||
&window.position,
|
&window.position,
|
||||||
&window.resolution,
|
&window.resolution,
|
||||||
@ -262,42 +250,42 @@ pub(crate) fn changed_window(
|
|||||||
winit_window.set_minimized(minimized);
|
winit_window.set_minimized(minimized);
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.focused != previous.focused && window.focused {
|
if window.focused != cache.window.focused && window.focused {
|
||||||
winit_window.focus_window();
|
winit_window.focus_window();
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.window_level != previous.window_level {
|
if window.window_level != cache.window.window_level {
|
||||||
winit_window.set_window_level(convert_window_level(window.window_level));
|
winit_window.set_window_level(convert_window_level(window.window_level));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently unsupported changes
|
// Currently unsupported changes
|
||||||
if window.transparent != previous.transparent {
|
if window.transparent != cache.window.transparent {
|
||||||
window.transparent = previous.transparent;
|
window.transparent = cache.window.transparent;
|
||||||
warn!(
|
warn!(
|
||||||
"Winit does not currently support updating transparency after window creation."
|
"Winit does not currently support updating transparency after window creation."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
if window.canvas != previous.canvas {
|
if window.canvas != cache.window.canvas {
|
||||||
window.canvas = previous.canvas.clone();
|
window.canvas = cache.window.canvas.clone();
|
||||||
warn!(
|
warn!(
|
||||||
"Bevy currently doesn't support modifying the window canvas after initialization."
|
"Bevy currently doesn't support modifying the window canvas after initialization."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.ime_enabled != previous.ime_enabled {
|
if window.ime_enabled != cache.window.ime_enabled {
|
||||||
winit_window.set_ime_allowed(window.ime_enabled);
|
winit_window.set_ime_allowed(window.ime_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
if window.ime_position != previous.ime_position {
|
if window.ime_position != cache.window.ime_position {
|
||||||
winit_window.set_ime_position(LogicalPosition::new(
|
winit_window.set_ime_position(LogicalPosition::new(
|
||||||
window.ime_position.x,
|
window.ime_position.x,
|
||||||
window.ime_position.y,
|
window.ime_position.y,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
info.previous = window.clone();
|
cache.window = window.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user