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::*;
 | 
			
		||||
use bevy_transform::TransformSystem;
 | 
			
		||||
use bevy_window::ModifiesWindows;
 | 
			
		||||
pub use bundle::*;
 | 
			
		||||
pub use fog::*;
 | 
			
		||||
pub use light::*;
 | 
			
		||||
@ -199,8 +198,7 @@ impl Plugin for PbrPlugin {
 | 
			
		||||
                    .in_set(SimulationLightSystems::AssignLightsToClusters)
 | 
			
		||||
                    .after(TransformSystem::TransformPropagate)
 | 
			
		||||
                    .after(VisibilitySystems::CheckVisibility)
 | 
			
		||||
                    .after(CameraUpdateSystem)
 | 
			
		||||
                    .after(ModifiesWindows),
 | 
			
		||||
                    .after(CameraUpdateSystem),
 | 
			
		||||
            )
 | 
			
		||||
            .add_system(
 | 
			
		||||
                update_directional_light_cascades
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,6 @@ use bevy_reflect::{
 | 
			
		||||
    std_traits::ReflectDefault, FromReflect, GetTypeRegistration, Reflect, ReflectDeserialize,
 | 
			
		||||
    ReflectSerialize,
 | 
			
		||||
};
 | 
			
		||||
use bevy_window::ModifiesWindows;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
/// 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(
 | 
			
		||||
                crate::camera::camera_system::<T>
 | 
			
		||||
                    .in_set(CameraUpdateSystem)
 | 
			
		||||
                    .after(ModifiesWindows)
 | 
			
		||||
                    // We assume that each camera will only have one projection,
 | 
			
		||||
                    // so we can ignore ambiguities with all other monomorphizations.
 | 
			
		||||
                    // 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_render::{camera::CameraUpdateSystem, ExtractSchedule, RenderApp};
 | 
			
		||||
use bevy_sprite::SpriteSystem;
 | 
			
		||||
use bevy_window::ModifiesWindows;
 | 
			
		||||
use std::num::NonZeroUsize;
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
@ -83,7 +82,6 @@ impl Plugin for TextPlugin {
 | 
			
		||||
            .add_system(
 | 
			
		||||
                update_text2d_layout
 | 
			
		||||
                    .in_base_set(CoreSet::PostUpdate)
 | 
			
		||||
                    .after(ModifiesWindows)
 | 
			
		||||
                    // Potential conflict: `Assets<Image>`
 | 
			
		||||
                    // In practice, they run independently since `bevy_render::camera_update_system`
 | 
			
		||||
                    // 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_input::InputSystem;
 | 
			
		||||
use bevy_transform::TransformSystem;
 | 
			
		||||
use bevy_window::ModifiesWindows;
 | 
			
		||||
use stack::ui_stack_system;
 | 
			
		||||
pub use stack::UiStack;
 | 
			
		||||
use update::update_clipping_system;
 | 
			
		||||
@ -110,7 +109,6 @@ impl Plugin for UiPlugin {
 | 
			
		||||
                widget::text_system
 | 
			
		||||
                    .in_base_set(CoreSet::PostUpdate)
 | 
			
		||||
                    .before(UiSystem::Flex)
 | 
			
		||||
                    .after(ModifiesWindows)
 | 
			
		||||
                    // Potential conflict: `Assets<Image>`
 | 
			
		||||
                    // In practice, they run independently since `bevy_render::camera_update_system`
 | 
			
		||||
                    // will only ever observe its own render target, and `widget::text_system`
 | 
			
		||||
@ -135,8 +133,7 @@ impl Plugin for UiPlugin {
 | 
			
		||||
            .add_system(
 | 
			
		||||
                flex_node_system
 | 
			
		||||
                    .in_set(UiSystem::Flex)
 | 
			
		||||
                    .before(TransformSystem::TransformPropagate)
 | 
			
		||||
                    .after(ModifiesWindows),
 | 
			
		||||
                    .before(TransformSystem::TransformPropagate),
 | 
			
		||||
            )
 | 
			
		||||
            .add_system(ui_stack_system.in_set(UiSystem::Stack))
 | 
			
		||||
            .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
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
pub enum ExitCondition {
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ mod winit_config;
 | 
			
		||||
mod winit_windows;
 | 
			
		||||
 | 
			
		||||
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_windows::*;
 | 
			
		||||
@ -26,7 +26,7 @@ use bevy_utils::{
 | 
			
		||||
};
 | 
			
		||||
use bevy_window::{
 | 
			
		||||
    exit_on_all_closed, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, Ime,
 | 
			
		||||
    ModifiesWindows, ReceivedCharacter, RequestRedraw, Window, WindowBackendScaleFactorChanged,
 | 
			
		||||
    ReceivedCharacter, RequestRedraw, Window, WindowBackendScaleFactorChanged,
 | 
			
		||||
    WindowCloseRequested, WindowCreated, WindowFocused, WindowMoved, WindowResized,
 | 
			
		||||
    WindowScaleFactorChanged,
 | 
			
		||||
};
 | 
			
		||||
@ -39,7 +39,6 @@ use winit::{
 | 
			
		||||
    event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopWindowTarget},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::system::WinitWindowInfo;
 | 
			
		||||
#[cfg(target_arch = "wasm32")]
 | 
			
		||||
use crate::web_resize::{CanvasParentResizeEventChannel, CanvasParentResizePlugin};
 | 
			
		||||
 | 
			
		||||
@ -70,7 +69,6 @@ impl Plugin for WinitPlugin {
 | 
			
		||||
        app.init_non_send_resource::<WinitWindows>()
 | 
			
		||||
            .init_resource::<WinitSettings>()
 | 
			
		||||
            .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,
 | 
			
		||||
            // and so doesn't care about ordering relative to changed_window
 | 
			
		||||
            .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
 | 
			
		||||
                    despawn_window.after(changed_window),
 | 
			
		||||
                )
 | 
			
		||||
                    .in_set(ModifiesWindows),
 | 
			
		||||
                    .in_base_set(CoreSet::Last),
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        #[cfg(target_arch = "wasm32")]
 | 
			
		||||
@ -349,7 +347,7 @@ pub fn winit_runner(mut app: App) {
 | 
			
		||||
                // Fetch and prepare details from the world
 | 
			
		||||
                let mut system_state: SystemState<(
 | 
			
		||||
                    NonSend<WinitWindows>,
 | 
			
		||||
                    Query<(&mut Window, &mut WinitWindowInfo)>,
 | 
			
		||||
                    Query<(&mut Window, &mut CachedWindow)>,
 | 
			
		||||
                    WindowEvents,
 | 
			
		||||
                    InputEvents,
 | 
			
		||||
                    CursorEvents,
 | 
			
		||||
@ -376,7 +374,7 @@ pub fn winit_runner(mut app: App) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                let (mut window, mut info) =
 | 
			
		||||
                let (mut window, mut cache) =
 | 
			
		||||
                    if let Ok((window, info)) = window_query.get_mut(window_entity) {
 | 
			
		||||
                        (window, info)
 | 
			
		||||
                    } else {
 | 
			
		||||
@ -394,7 +392,6 @@ pub fn winit_runner(mut app: App) {
 | 
			
		||||
                        window
 | 
			
		||||
                            .resolution
 | 
			
		||||
                            .set_physical_resolution(size.width, size.height);
 | 
			
		||||
                        info.last_winit_size = size;
 | 
			
		||||
 | 
			
		||||
                        window_events.window_resized.send(WindowResized {
 | 
			
		||||
                            window: window_entity,
 | 
			
		||||
@ -421,11 +418,7 @@ pub fn winit_runner(mut app: App) {
 | 
			
		||||
                            window.resolution.physical_height() as f64 - position.y,
 | 
			
		||||
                        );
 | 
			
		||||
 | 
			
		||||
                        // 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(Some(physical_position));
 | 
			
		||||
                        window.set_physical_cursor_position(Some(physical_position));
 | 
			
		||||
 | 
			
		||||
                        cursor_events.cursor_moved.send(CursorMoved {
 | 
			
		||||
                            window: window_entity,
 | 
			
		||||
@ -439,14 +432,7 @@ pub fn winit_runner(mut app: App) {
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                    WindowEvent::CursorLeft { .. } => {
 | 
			
		||||
                        // Component
 | 
			
		||||
                        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);
 | 
			
		||||
                        }
 | 
			
		||||
                        window.set_physical_cursor_position(None);
 | 
			
		||||
 | 
			
		||||
                        cursor_events.cursor_left.send(CursorLeft {
 | 
			
		||||
                            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: DeviceEvent::MouseMotion { delta: (x, y) },
 | 
			
		||||
 | 
			
		||||
@ -39,20 +39,19 @@ pub(crate) fn create_window<'a>(
 | 
			
		||||
    mut winit_windows: NonSendMut<WinitWindows>,
 | 
			
		||||
    #[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() {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        info!(
 | 
			
		||||
            "Creating new window {:?} ({:?})",
 | 
			
		||||
            component.title.as_str(),
 | 
			
		||||
            window.title.as_str(),
 | 
			
		||||
            entity
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        let winit_window = winit_windows.create_window(event_loop, entity, &component);
 | 
			
		||||
        let current_size = winit_window.inner_size();
 | 
			
		||||
        component
 | 
			
		||||
        let winit_window = winit_windows.create_window(event_loop, entity, &window);
 | 
			
		||||
        window
 | 
			
		||||
            .resolution
 | 
			
		||||
            .set_scale_factor(winit_window.scale_factor());
 | 
			
		||||
        commands
 | 
			
		||||
@ -61,18 +60,14 @@ pub(crate) fn create_window<'a>(
 | 
			
		||||
                window_handle: winit_window.raw_window_handle(),
 | 
			
		||||
                display_handle: winit_window.raw_display_handle(),
 | 
			
		||||
            })
 | 
			
		||||
            .insert(WinitWindowInfo {
 | 
			
		||||
                previous: component.clone(),
 | 
			
		||||
                last_winit_size: PhysicalSize {
 | 
			
		||||
                    width: current_size.width,
 | 
			
		||||
                    height: current_size.height,
 | 
			
		||||
                },
 | 
			
		||||
            .insert(CachedWindow {
 | 
			
		||||
                window: window.clone(),
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        #[cfg(target_arch = "wasm32")]
 | 
			
		||||
        {
 | 
			
		||||
            if component.fit_canvas_to_parent {
 | 
			
		||||
                let selector = if let Some(selector) = &component.canvas {
 | 
			
		||||
            if window.fit_canvas_to_parent {
 | 
			
		||||
                let selector = if let Some(selector) = &window.canvas {
 | 
			
		||||
                    selector
 | 
			
		||||
                } else {
 | 
			
		||||
                    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)]
 | 
			
		||||
pub struct WinitWindowInfo {
 | 
			
		||||
    pub previous: Window,
 | 
			
		||||
    pub last_winit_size: PhysicalSize<u32>,
 | 
			
		||||
pub struct CachedWindow {
 | 
			
		||||
    pub window: Window,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
//   event channel stuff.
 | 
			
		||||
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>,
 | 
			
		||||
) {
 | 
			
		||||
    for (entity, mut window, mut info) in &mut changed_windows {
 | 
			
		||||
        let previous = &info.previous;
 | 
			
		||||
 | 
			
		||||
    for (entity, mut window, mut cache) in &mut changed_windows {
 | 
			
		||||
        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());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if window.mode != previous.mode {
 | 
			
		||||
            if window.mode != cache.window.mode {
 | 
			
		||||
                let new_mode = match window.mode {
 | 
			
		||||
                    bevy_window::WindowMode::BorderlessFullscreen => {
 | 
			
		||||
                        Some(winit::window::Fullscreen::Borderless(None))
 | 
			
		||||
@ -156,19 +148,15 @@ pub(crate) fn changed_window(
 | 
			
		||||
                    winit_window.set_fullscreen(new_mode);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if window.resolution != previous.resolution {
 | 
			
		||||
            if window.resolution != cache.window.resolution {
 | 
			
		||||
                let physical_size = PhysicalSize::new(
 | 
			
		||||
                    window.resolution.physical_width(),
 | 
			
		||||
                    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() {
 | 
			
		||||
                    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));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if window.cursor.visible != previous.cursor.visible {
 | 
			
		||||
            if window.cursor.visible != cache.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) {
 | 
			
		||||
                    window.cursor.hit_test = previous.cursor.hit_test;
 | 
			
		||||
                    window.cursor.hit_test = cache.window.cursor.hit_test;
 | 
			
		||||
                    warn!(
 | 
			
		||||
                        "Could not set cursor hit test for window {:?}: {:?}",
 | 
			
		||||
                        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()
 | 
			
		||||
            {
 | 
			
		||||
                winit_window.set_decorations(window.decorations);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if window.resizable != previous.resizable
 | 
			
		||||
            if window.resizable != cache.window.resizable
 | 
			
		||||
                && window.resizable != winit_window.is_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 min_inner_size = LogicalSize {
 | 
			
		||||
                    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(
 | 
			
		||||
                    &window.position,
 | 
			
		||||
                    &window.resolution,
 | 
			
		||||
@ -262,42 +250,42 @@ pub(crate) fn changed_window(
 | 
			
		||||
                winit_window.set_minimized(minimized);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if window.focused != previous.focused && window.focused {
 | 
			
		||||
            if window.focused != cache.window.focused && window.focused {
 | 
			
		||||
                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));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Currently unsupported changes
 | 
			
		||||
            if window.transparent != previous.transparent {
 | 
			
		||||
                window.transparent = previous.transparent;
 | 
			
		||||
            if window.transparent != cache.window.transparent {
 | 
			
		||||
                window.transparent = cache.window.transparent;
 | 
			
		||||
                warn!(
 | 
			
		||||
                    "Winit does not currently support updating transparency after window creation."
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[cfg(target_arch = "wasm32")]
 | 
			
		||||
            if window.canvas != previous.canvas {
 | 
			
		||||
                window.canvas = previous.canvas.clone();
 | 
			
		||||
            if window.canvas != cache.window.canvas {
 | 
			
		||||
                window.canvas = cache.window.canvas.clone();
 | 
			
		||||
                warn!(
 | 
			
		||||
                    "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);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if window.ime_position != previous.ime_position {
 | 
			
		||||
            if window.ime_position != cache.window.ime_position {
 | 
			
		||||
                winit_window.set_ime_position(LogicalPosition::new(
 | 
			
		||||
                    window.ime_position.x,
 | 
			
		||||
                    window.ime_position.y,
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            info.previous = window.clone();
 | 
			
		||||
            cache.window = window.clone();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user