Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macos: app hangs after pressing window close button #13208

Closed
rparrett opened this issue May 3, 2024 · 11 comments
Closed

macos: app hangs after pressing window close button #13208

rparrett opened this issue May 3, 2024 · 11 comments
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Bug An unexpected or incorrect behavior O-MacOS Specific to the MacOS (Apple) desktop operating system
Milestone

Comments

@rparrett
Copy link
Contributor

rparrett commented May 3, 2024

Bevy version

main, bisected to #12978

Relevant system information

SystemInfo { os: "MacOS 14.4.1 ", kernel: "23.4.0", cpu: "Apple M1 Max", core_count: "10", memory: "64.0 GiB" }
AdapterInfo { name: "Apple M1 Max", vendor: 0, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Metal }

What you did

cargo run --example sprite
cargo run --example button

Press close button in top left corner of title bar.

What went wrong

App hangs instead of closing

@rparrett rparrett added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels May 3, 2024
@mockersf
Copy link
Member

mockersf commented May 3, 2024

@Friz64 any idea on how to fix?

@mockersf mockersf added A-Windowing Platform-agnostic interface layer to run your app in O-MacOS Specific to the MacOS (Apple) desktop operating system and removed S-Needs-Triage This issue needs to be labelled labels May 3, 2024
@mockersf mockersf added this to the 0.14 milestone May 3, 2024
@Friz64
Copy link
Contributor

Friz64 commented May 3, 2024

Ouch, sorry about this. No idea why my PR would cause this. I unfortunately can't debug this by myself as I don't have access to appropriate hardware at the moment. Best I can do right now is to do some research, in the hopes that I find something useful.

But what we can always do is to put a #[cfg(not(target_os = "macos"))] over the _window variable in the RawHandleWrapper, so that the PR is essentially negated on macOS. It wouldn't be elegant, but it would work.

@BD103
Copy link
Member

BD103 commented May 4, 2024

I'm getting this when setting RUST_LOG=debug cargo run --example sprite:

2024-05-04T01:49:22.843807Z  INFO bevy_window::system: No windows are open, exiting
2024-05-04T01:49:22.845024Z  INFO bevy_winit::system: Closing window Entity { index: 0, generation: 1 }
2024-05-04T01:49:22.855889Z DEBUG wgpu_core::present: Created CURRENT Surface Texture Id(22,41,mtl)    
2024-05-04T01:49:22.855926Z DEBUG wgpu_core::device::resource: Create view for texture Id(22,41,mtl) filters usages to TextureUses(COLOR_TARGET)    
2024-05-04T01:49:22.857666Z DEBUG wgpu_core::device::life: Active submission 82 is done    
2024-05-04T01:49:22.857898Z DEBUG present_frames: wgpu_core::present: Removing swapchain texture Id(22,41,mtl) from the device tracker    
2024-05-04T01:49:22.857941Z DEBUG present_frames: wgpu_core::present: Presented. End of Frame
(it hangs from here, with no more info logged)

It looks like it's hanging before it creates the next surface texture after the previous was presented. After checking out the main branch from a week ago, we should additionally have the following logs after Presented. End of Frame before exiting the program:

2024-05-04T01:53:36.461981Z DEBUG wgpu_core::device::life: Active submission 77 is done    
2024-05-04T01:53:36.463780Z DEBUG wgpu_core::resource: Buffer Id(9,1,mtl) map state -> Idle    
2024-05-04T01:53:36.463831Z DEBUG wgpu_core::resource: Buffer Id(4,1,mtl) map state -> Idle    
2024-05-04T01:53:36.463980Z DEBUG wgpu_core::resource: Buffer Id(0,1,mtl) map state -> Idle    
2024-05-04T01:53:36.464853Z DEBUG wgpu_core::resource: Buffer Id(12,1,mtl) map state -> Idle    
2024-05-04T01:53:36.464870Z DEBUG wgpu_core::resource: Buffer Id(13,1,mtl) map state -> Idle    
2024-05-04T01:53:36.464902Z DEBUG wgpu_core::resource: Buffer Id(6,1,mtl) map state -> Idle    
2024-05-04T01:53:36.464924Z DEBUG wgpu_core::resource: Buffer Id(2,1,mtl) map state -> Idle    
2024-05-04T01:53:36.464958Z DEBUG wgpu_core::resource: Buffer Id(7,1,mtl) map state -> Idle    
2024-05-04T01:53:36.464990Z DEBUG wgpu_core::device::life: Active submission 78 is done    
2024-05-04T01:53:36.466244Z DEBUG wgpu_core::resource: Buffer Id(10,1,mtl) map state -> Idle    
2024-05-04T01:53:36.466300Z DEBUG wgpu_core::resource: Buffer Id(8,1,mtl) map state -> Idle
(program exits here)
And RUST_LOG=trace

2024-05-04T01:47:12.377846Z  INFO bevy_window::system: No windows are open, exiting
2024-05-04T01:47:12.379049Z  INFO bevy_winit::system: Closing window Entity { index: 0, generation: 1 }
2024-05-04T01:47:12.389174Z TRACE wgpu_core::storage: User is inserting TextureId(13,90,mtl)    
2024-05-04T01:47:12.389201Z DEBUG wgpu_core::present: Created CURRENT Surface Texture Id(13,90,mtl)    
2024-05-04T01:47:12.389213Z TRACE wgpu_core::track::texture:    tex 13: insert start TextureUses(UNINITIALIZED)    
2024-05-04T01:47:12.389245Z DEBUG wgpu_core::device::resource: Create view for texture Id(13,90,mtl) filters usages to TextureUses(COLOR_TARGET)    
2024-05-04T01:47:12.389257Z TRACE wgpu_core::storage: User is inserting TextureViewId(13,90,mtl)    
2024-05-04T01:47:12.389266Z TRACE wgpu_core::device::global: Texture::create_view(Id(13,90,mtl)) -> Id(13,90,mtl)    
2024-05-04T01:47:12.389893Z TRACE wgpu_core::storage: User is inserting StagingBufferId(3,90,mtl)    
2024-05-04T01:47:12.389898Z TRACE wgpu_core::device::queue: Queue::write_buffer Id(7,1,mtl) 16384bytes    
2024-05-04T01:47:12.389914Z TRACE wgpu_core::device::queue: Queue::create_staging_buffer Id(3,90,mtl)    
2024-05-04T01:47:12.389885Z TRACE wgpu_core::device::queue: Queue::write_buffer Id(5,1,mtl) 12bytes    
2024-05-04T01:47:12.389971Z TRACE wgpu_core::storage: User is removing StagingBufferId(3,90,mtl)    
2024-05-04T01:47:12.389979Z TRACE wgpu_core::track::buffer:     buf 7: transition BufferUses(COPY_DST) -> BufferUses(COPY_DST)    
2024-05-04T01:47:12.390086Z TRACE wgpu_core::storage: User is inserting StagingBufferId(9,90,mtl)    
2024-05-04T01:47:12.390095Z TRACE wgpu_core::device::queue: Queue::create_staging_buffer Id(9,90,mtl)    
2024-05-04T01:47:12.390080Z TRACE wgpu_core::track::buffer:     buf 4: transition BufferUses(UNIFORM) -> BufferUses(COPY_DST)    
2024-05-04T01:47:12.390127Z TRACE wgpu_core::storage: User is removing StagingBufferId(9,90,mtl)    
2024-05-04T01:47:12.390153Z TRACE wgpu_core::storage: User is inserting StagingBufferId(12,90,mtl)    
2024-05-04T01:47:12.390161Z TRACE wgpu_core::device::queue: Queue::create_staging_buffer Id(12,90,mtl)    
2024-05-04T01:47:12.390159Z TRACE wgpu_core::track::buffer:     buf 5: transition BufferUses(COPY_DST) -> BufferUses(COPY_DST)    
2024-05-04T01:47:12.390180Z TRACE wgpu_core::storage: User is removing StagingBufferId(12,90,mtl)    
2024-05-04T01:47:12.390189Z TRACE wgpu_core::track::buffer:     buf 8: transition BufferUses(COPY_DST) -> BufferUses(COPY_DST)    
2024-05-04T01:47:12.390214Z TRACE wgpu_core::track::buffer:     buf 9: transition BufferUses(COPY_DST) -> BufferUses(COPY_DST)    
2024-05-04T01:47:12.390478Z TRACE wgpu_core::storage: User is inserting BindGroupId(6,90,mtl)    
2024-05-04T01:47:12.390487Z TRACE wgpu_core::device::global: Device::create_bind_group -> Id(6,90,mtl)    
2024-05-04T01:47:12.390492Z TRACE wgpu_core::storage: User is inserting BindGroupId(3,90,mtl)    
2024-05-04T01:47:12.390500Z TRACE wgpu_core::device::global: Device::create_bind_group -> Id(3,90,mtl)    
2024-05-04T01:47:12.390501Z TRACE wgpu_core::device::global: BindGroup::drop Id(11,89,mtl)    
2024-05-04T01:47:12.390514Z TRACE wgpu_core::storage: User is inserting BindGroupId(2,90,mtl)    
2024-05-04T01:47:12.390525Z TRACE wgpu_core::device::global: Device::create_bind_group -> Id(2,90,mtl)    
2024-05-04T01:47:12.390533Z TRACE wgpu_core::device::global: BindGroup::drop Id(10,89,mtl)    
2024-05-04T01:47:12.390545Z TRACE wgpu_core::storage: User is removing BindGroupId(11,89,mtl)    
2024-05-04T01:47:12.390567Z TRACE wgpu_core::storage: User is inserting BindGroupId(4,90,mtl)    
2024-05-04T01:47:12.390572Z TRACE wgpu_core::device::queue: Queue::write_buffer Id(12,1,mtl) 80bytes    
2024-05-04T01:47:12.390577Z TRACE wgpu_core::device::global: Device::create_bind_group -> Id(4,90,mtl)    
2024-05-04T01:47:12.390586Z TRACE wgpu_core::storage: User is removing BindGroupId(10,89,mtl)    
2024-05-04T01:47:12.390603Z TRACE wgpu_core::track::buffer:     buf 12: transition BufferUses(VERTEX) -> BufferUses(COPY_DST)    
2024-05-04T01:47:12.390641Z TRACE wgpu_core::storage: User is inserting BindGroupId(5,90,mtl)    
2024-05-04T01:47:12.390649Z TRACE wgpu_core::device::global: Device::create_bind_group -> Id(5,90,mtl)    
2024-05-04T01:47:12.390660Z TRACE wgpu_core::device::global: BindGroup::drop Id(12,89,mtl)    
2024-05-04T01:47:12.390668Z TRACE wgpu_core::storage: User is removing BindGroupId(12,89,mtl)    
2024-05-04T01:47:12.390870Z TRACE wgpu_core::storage: User is inserting CommandBufferId(0,179,mtl)    
2024-05-04T01:47:12.390880Z TRACE wgpu_core::device::global: Device::create_command_encoder -> Id(0,179,mtl)    
2024-05-04T01:47:12.390940Z TRACE wgpu_core::command::render: Encoding render pass begin in command buffer Id(0,179,mtl)    
2024-05-04T01:47:12.391018Z TRACE wgpu_core::command::render: RenderPass::set_pipeline Id(3,1,mtl)    
2024-05-04T01:47:12.391044Z TRACE wgpu_core::command::render: RenderPass::set_bind_group 0 Id(6,90,mtl)    
2024-05-04T01:47:12.391056Z TRACE wgpu_core::track::buffer:     buf 4: insert BufferUses(UNIFORM)..BufferUses(UNIFORM)    
2024-05-04T01:47:12.391066Z TRACE wgpu_core::command::bind:     Binding [0] = group Id(6,90,mtl)    
2024-05-04T01:47:12.391078Z TRACE wgpu_core::command::render: RenderPass::set_bind_group 1 Id(13,1,mtl)    
2024-05-04T01:47:12.391087Z TRACE wgpu_core::track::texture:    tex 20: insert start TextureUses(RESOURCE)    
2024-05-04T01:47:12.391099Z TRACE wgpu_core::command::bind:     Binding [1] = group Id(13,1,mtl)    
2024-05-04T01:47:12.391108Z TRACE wgpu_core::command::render: RenderPass::set_index_buffer Id(11,1,mtl)    
2024-05-04T01:47:12.391115Z TRACE wgpu_core::track::buffer:     buf 11: insert BufferUses(INDEX)..BufferUses(INDEX)    
2024-05-04T01:47:12.391125Z TRACE wgpu_core::command::render: RenderPass::set_vertex_buffer 0 Id(12,1,mtl)    
2024-05-04T01:47:12.391132Z TRACE wgpu_core::track::buffer:     buf 12: insert BufferUses(VERTEX)..BufferUses(VERTEX)    
2024-05-04T01:47:12.391142Z TRACE wgpu_core::command::render: RenderPass::draw_indexed 6 1 0 0 0    
2024-05-04T01:47:12.391156Z TRACE wgpu_core::command::render: Merging renderpass into cmd_buf Id(0,179,mtl)    
2024-05-04T01:47:12.391165Z TRACE wgpu_core::track::texture:    tex 19: insert start TextureUses(COLOR_TARGET)    
2024-05-04T01:47:12.391173Z TRACE wgpu_core::track::texture:    tex 17: insert start TextureUses(COLOR_TARGET)    
2024-05-04T01:47:12.391195Z TRACE wgpu_core::track::buffer:     buf 4: insert BufferUses(UNIFORM)..BufferUses(UNIFORM)    
2024-05-04T01:47:12.391205Z TRACE wgpu_core::track::buffer:     buf 11: insert BufferUses(INDEX)..BufferUses(INDEX)    
2024-05-04T01:47:12.391213Z TRACE wgpu_core::track::buffer:     buf 12: insert BufferUses(VERTEX)..BufferUses(VERTEX)    
2024-05-04T01:47:12.391223Z TRACE wgpu_core::track::texture:    tex 17: insert start TextureUses(COLOR_TARGET)    
2024-05-04T01:47:12.391231Z TRACE wgpu_core::track::texture:    tex 19: insert start TextureUses(COLOR_TARGET)    
2024-05-04T01:47:12.391238Z TRACE wgpu_core::track::texture:    tex 20: insert start TextureUses(RESOURCE)    
2024-05-04T01:47:12.391338Z TRACE wgpu_core::command::render: Encoding render pass begin in command buffer Id(0,179,mtl)    
2024-05-04T01:47:12.391371Z TRACE wgpu_core::command::render: RenderPass::set_pipeline Id(2,1,mtl)    
2024-05-04T01:47:12.391383Z TRACE wgpu_core::command::render: RenderPass::set_bind_group 0 Id(7,1,mtl)    
2024-05-04T01:47:12.391393Z TRACE wgpu_core::track::texture:    tex 17: insert start TextureUses(RESOURCE)    
2024-05-04T01:47:12.391401Z TRACE wgpu_core::command::bind:     Binding [0] = group Id(7,1,mtl)    
2024-05-04T01:47:12.391410Z TRACE wgpu_core::command::render: RenderPass::draw 3 1 0 0    
2024-05-04T01:47:12.391419Z TRACE wgpu_core::command::render: Merging renderpass into cmd_buf Id(0,179,mtl)    
2024-05-04T01:47:12.391426Z TRACE wgpu_core::track::texture:    tex 13: insert start TextureUses(COLOR_TARGET)    
2024-05-04T01:47:12.391440Z TRACE wgpu_core::track::texture:    tex 13: insert start TextureUses(COLOR_TARGET)    
2024-05-04T01:47:12.391448Z TRACE wgpu_core::track::texture:    tex 17: transition simple TextureUses(COLOR_TARGET) -> TextureUses(RESOURCE)    
2024-05-04T01:47:12.391474Z TRACE wgpu_core::command: Command buffer Id(0,179,mtl)    
2024-05-04T01:47:12.391500Z TRACE wgpu_core::device::queue: Queue::submit Id(0,1,mtl)    
2024-05-04T01:47:12.391520Z TRACE wgpu_core::track::texture:    tex 13: insert start TextureUses(PRESENT)    
2024-05-04T01:47:12.391541Z TRACE wgpu_core::command: Extracting BakedCommands from CommandBuffer "<CommandBuffer>"    
2024-05-04T01:47:12.391552Z TRACE wgpu_core::device::queue: Stitching command buffer Id(0,179,mtl) before submission    
2024-05-04T01:47:12.391569Z TRACE wgpu_core::track::buffer:     buf 4: transition BufferUses(COPY_DST) -> BufferUses(UNIFORM)    
2024-05-04T01:47:12.391577Z TRACE wgpu_core::track::buffer:     buf 12: transition BufferUses(COPY_DST) -> BufferUses(VERTEX)    
2024-05-04T01:47:12.391586Z TRACE wgpu_core::track::texture:    tex 13: transition simple TextureUses(UNINITIALIZED) -> TextureUses(COLOR_TARGET)    
2024-05-04T01:47:12.391594Z TRACE wgpu_core::track::texture:    tex 17: transition simple TextureUses(RESOURCE) -> TextureUses(COLOR_TARGET)    
2024-05-04T01:47:12.391609Z TRACE wgpu_core::track::texture:    tex 13: transition simple TextureUses(COLOR_TARGET) -> TextureUses(PRESENT)    
2024-05-04T01:47:12.391624Z TRACE wgpu_core::device::queue: Device after submission 179    
2024-05-04T01:47:12.391679Z DEBUG wgpu_core::device::life: Active submission 178 is done    
2024-05-04T01:47:12.391697Z TRACE wgpu_core::resource: Destroy raw StagingBuffer "<StagingBuffer>"    
2024-05-04T01:47:12.391723Z TRACE wgpu_core::resource: Destroy raw StagingBuffer "<StagingBuffer>"    
2024-05-04T01:47:12.391745Z TRACE wgpu_core::resource: Destroy raw StagingBuffer "<StagingBuffer>"    
2024-05-04T01:47:12.391761Z TRACE wgpu_core::resource: Destroy raw StagingBuffer "<StagingBuffer>"    
2024-05-04T01:47:12.391770Z TRACE wgpu_core::resource: Destroy raw StagingBuffer "<StagingBuffer>"    
2024-05-04T01:47:12.391779Z TRACE wgpu_core::resource: Destroy raw StagingBuffer "<StagingBuffer>"    
2024-05-04T01:47:12.391807Z TRACE wgpu_core::track::stateless: StatelessTracker::remove_abandoned Id(8,89,mtl)    
2024-05-04T01:47:12.391815Z TRACE wgpu_core::track::stateless: BindGroup Id(8,89,mtl) is not tracked anymore    
2024-05-04T01:47:12.391823Z TRACE wgpu_core::track::stateless: StatelessTracker::remove_abandoned Id(10,89,mtl)    
2024-05-04T01:47:12.391830Z TRACE wgpu_core::track::stateless: BindGroup Id(10,89,mtl) is not tracked anymore    
2024-05-04T01:47:12.391837Z TRACE wgpu_core::track::stateless: StatelessTracker::remove_abandoned Id(12,89,mtl)    
2024-05-04T01:47:12.391843Z TRACE wgpu_core::track::stateless: BindGroup Id(12,89,mtl) is not tracked anymore    
2024-05-04T01:47:12.391849Z TRACE wgpu_core::track::stateless: StatelessTracker::remove_abandoned Id(9,89,mtl)    
2024-05-04T01:47:12.391855Z TRACE wgpu_core::track::stateless: BindGroup Id(9,89,mtl) is not tracked anymore    
2024-05-04T01:47:12.391862Z TRACE wgpu_core::track::stateless: StatelessTracker::remove_abandoned Id(11,89,mtl)    
2024-05-04T01:47:12.391868Z TRACE wgpu_core::track::stateless: BindGroup Id(11,89,mtl) is not tracked anymore    
2024-05-04T01:47:12.391885Z TRACE wgpu_core::binding_model: Destroy raw BindGroup "mesh2d_view_bind_group"    
2024-05-04T01:47:12.391899Z TRACE wgpu_core::binding_model: Destroy raw BindGroup "prepass_view_no_motion_vectors_bind_group"    
2024-05-04T01:47:12.391909Z TRACE wgpu_core::binding_model: Destroy raw BindGroup "ui_view_bind_group"    
2024-05-04T01:47:12.391918Z TRACE wgpu_core::binding_model: Destroy raw BindGroup "mesh2d_view_bind_group"    
2024-05-04T01:47:12.391928Z TRACE wgpu_core::binding_model: Destroy raw BindGroup "sprite_view_bind_group"    
2024-05-04T01:47:12.391940Z TRACE wgpu_core::track::stateless: StatelessTracker::remove_abandoned Id(21,89,mtl)    
2024-05-04T01:47:12.391949Z TRACE wgpu_core::track::stateless: TextureView Id(21,89,mtl) is not tracked anymore    
2024-05-04T01:47:12.391958Z TRACE wgpu_core::resource: Destroy raw TextureView Id(21,89,mtl)    
2024-05-04T01:47:12.391970Z TRACE wgpu_core::track::texture: Texture Id(11,1,mtl) is still referenced from 3    
2024-05-04T01:47:12.391977Z TRACE wgpu_core::resource: Destroy raw Texture "<Surface>"    
2024-05-04T01:47:12.391988Z TRACE wgpu_core::track::buffer: Buffer Id(4,1,mtl) is still referenced from 8    
2024-05-04T01:47:12.391994Z TRACE wgpu_core::track::buffer: Buffer Id(5,1,mtl) is still referenced from 6    
2024-05-04T01:47:12.392059Z DEBUG present_frames: wgpu_core::present: Removing swapchain texture Id(13,90,mtl) from the device tracker    
2024-05-04T01:47:12.392076Z TRACE present_frames: wgpu_core::storage: User is removing TextureId(13,90,mtl)    
2024-05-04T01:47:12.392099Z DEBUG present_frames: wgpu_core::present: Presented. End of Frame    
2024-05-04T01:47:12.392210Z TRACE wgpu_core::device::global: BindGroup::drop Id(3,90,mtl)    
2024-05-04T01:47:12.392220Z TRACE wgpu_core::storage: User is removing BindGroupId(3,90,mtl)    
2024-05-04T01:47:12.392232Z TRACE wgpu_core::device::global: BindGroup::drop Id(5,90,mtl)    
2024-05-04T01:47:12.392239Z TRACE wgpu_core::storage: User is removing BindGroupId(5,90,mtl)

@ids1024
Copy link

ids1024 commented May 4, 2024

Odd. It seems the Arc in WindowWrapper/RawHandleWrapper does eventually get freed, so the winit::Window is still being dropped, but dropping it later is somehow not working properly?

@BD103
Copy link
Member

BD103 commented May 4, 2024

I'm a bit new to using a debugger, but it seems to be blocking on a Condvar?

image

It occurs within TaskPool::scope_with_executor_inner:

block_on(async move {

So it appears that something is not waking up the main thread. Perhaps the window Arc is never being dropped because something else made a copy of it, but the event loop depends on it being dropped?

@ids1024
Copy link

ids1024 commented May 4, 2024

There are probably better ways to debug, but I tested with this:

impl Drop for RawHandleWrapper {
    fn drop(&mut self) {
        println!("Drop RawHandleWrapper: {}", Arc::strong_count(&self._window));
    }
}

And something similar for WindowWrapper.

That shows a drop of a RawHandleWrapper with a ref count of 1. So it seems the winit::Window should be closed at that point.

I'm not familiar enough with macOS APIs to know if there's any macOS-related reason this might happen.

@ids1024
Copy link

ids1024 commented May 4, 2024

Ah. It looks like the drop impl for the WindowWrapper is called on the main thread, while the drop impl for the RawHandleWrapper is not.

So it's probably an issue that happens when the winit::Window is dropped on a thread other than the main thread.

@ids1024
Copy link

ids1024 commented May 4, 2024

On macOS, Drop for winit::Window uses https://docs.rs/objc2-foundation/0.2.0/objc2_foundation/struct.MainThreadBound.html Apparently.

On Drop, the inner type is sent to the main thread’s runloop and dropped there. This may lead to deadlocks if the main runloop is not running, or if it is waiting on a lock that the dropping thread is holding. See run_on_main for some of the caveats around that.

@ids1024
Copy link

ids1024 commented May 4, 2024

Yeah. it looks like the worker thread is hanging in icrate::Foundation::additions::thread::MainThreadMarker::run_on_main. (In lldb, the thread command lets you list and change threads.)

While the main thread is blocked on

block_on(async move {
.

So I guess bevy is blocking the thread running EventLoop::run, which is a problem on platforms like macOS?

tychedelia added a commit to tychedelia/bevy that referenced this issue May 4, 2024
Fixes two issues related to bevyengine#13208.

First, we ensure render resources for a window are always dropped first
to ensure that the `winit::Window` always drops on the main thread when
it is removed from `WinitWindows`. Previously, changes in bevyengine#12978 caused
the window to drop in the render world, causing issues.

We accomplish this by delaying despawning the window by a frame by
inserting a marker component `ClosingWindow` that indicates the window
has been requested to close and is in the process of closing. The
render world now responds to the equivalent `WindowClosing` event
rather than `WindowCloseed` which now fires after the render resources
are guarunteed to be cleaned up.

Secondly, fixing the above caused (revealed?) that additional events
were being delivered to the the event loop handler after exit had
already been requested: in my testing `RedrawRequested` and
`LoopExiting`. This caused errors to be reported try to send an
exit event on the close channel. There are two options here:
    - Guard the handler so no additional events are delivered once the
    app is exiting. I considered this but worried it might be
    confusing or bug prone if in the future someone wants to handle
   `LoopExiting` or some other event to clean-up while exiting.
    - Only send an exit signal if we are not already exiting. It
    doesn't appear to cause any problems to handle the extra events
    so this seems safer.
Fixing this also appears to have fixed bevyengine#13231.
tychedelia added a commit to tychedelia/bevy that referenced this issue May 4, 2024
Fixes two issues related to bevyengine#13208.

First, we ensure render resources for a window are always dropped first
to ensure that the `winit::Window` always drops on the main thread when
it is removed from `WinitWindows`. Previously, changes in bevyengine#12978 caused
the window to drop in the render world, causing issues.

We accomplish this by delaying despawning the window by a frame by
inserting a marker component `ClosingWindow` that indicates the window
has been requested to close and is in the process of closing. The
render world now responds to the equivalent `WindowClosing` event
rather than `WindowCloseed` which now fires after the render resources
are guarunteed to be cleaned up.

Secondly, fixing the above caused (revealed?) that additional events
were being delivered to the the event loop handler after exit had
already been requested: in my testing `RedrawRequested` and
`LoopExiting`. This caused errors to be reported try to send an
exit event on the close channel. There are two options here:
    - Guard the handler so no additional events are delivered once the
    app is exiting. I considered this but worried it might be
    confusing or bug prone if in the future someone wants to handle
   `LoopExiting` or some other event to clean-up while exiting.
    - Only send an exit signal if we are not already exiting. It
    doesn't appear to cause any problems to handle the extra events
    so this seems safer.
Fixing this also appears to have fixed bevyengine#13231.
tychedelia added a commit to tychedelia/bevy that referenced this issue May 4, 2024
Fixes two issues related to bevyengine#13208.

First, we ensure render resources for a window are always dropped first
to ensure that the `winit::Window` always drops on the main thread when
it is removed from `WinitWindows`. Previously, changes in bevyengine#12978 caused
the window to drop in the render world, causing issues.

We accomplish this by delaying despawning the window by a frame by
inserting a marker component `ClosingWindow` that indicates the window
has been requested to close and is in the process of closing. The
render world now responds to the equivalent `WindowClosing` event
rather than `WindowCloseed` which now fires after the render resources
are guarunteed to be cleaned up.

Secondly, fixing the above caused (revealed?) that additional events
were being delivered to the the event loop handler after exit had
already been requested: in my testing `RedrawRequested` and
`LoopExiting`. This caused errors to be reported try to send an
exit event on the close channel. There are two options here:
    - Guard the handler so no additional events are delivered once the
    app is exiting. I considered this but worried it might be
    confusing or bug prone if in the future someone wants to handle
   `LoopExiting` or some other event to clean-up while exiting.
    - Only send an exit signal if we are not already exiting. It
    doesn't appear to cause any problems to handle the extra events
    so this seems safer.
Fixing this also appears to have fixed bevyengine#13231.
github-merge-queue bot pushed a commit that referenced this issue May 12, 2024
# Objective

Fixes two issues related to #13208.

First, we ensure render resources for a window are always dropped first
to ensure that the `winit::Window` always drops on the main thread when
it is removed from `WinitWindows`. Previously, changes in #12978 caused
the window to drop in the render world, causing issues.

We accomplish this by delaying despawning the window by a frame by
inserting a marker component `ClosingWindow` that indicates the window
has been requested to close and is in the process of closing. The render
world now responds to the equivalent `WindowClosing` event rather than
`WindowCloseed` which now fires after the render resources are
guarunteed to be cleaned up.

Secondly, fixing the above caused (revealed?) that additional events
were being delivered to the the event loop handler after exit had
already been requested: in my testing `RedrawRequested` and
`LoopExiting`. This caused errors to be reported try to send an exit
event on the close channel. There are two options here:
- Guard the handler so no additional events are delivered once the app
is exiting. I ~considered this but worried it might be confusing or bug
prone if in the future someone wants to handle `LoopExiting` or some
other event to clean-up while exiting.~ We are now taking this approach.
- Only send an exit signal if we are not already exiting. ~It doesn't
appear to cause any problems to handle the extra events so this seems
safer.~
 
Fixing this also appears to have fixed #13231.

Fixes #10260.

## Testing

Tested on mac only.

---

## Changelog

### Added
- A `WindowClosing` event has been added that indicates the window will
be despawned on the next frame.

### Changed
- Windows now close a frame after their exit has been requested.

## Migration Guide
- Ensure custom exit logic does not rely on the app exiting the same
frame as a window is closed.
@Friz64
Copy link
Contributor

Friz64 commented May 12, 2024

Can this now be closed after #13236?

@mockersf
Copy link
Member

works fine for me on macOS now 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Windowing Platform-agnostic interface layer to run your app in C-Bug An unexpected or incorrect behavior O-MacOS Specific to the MacOS (Apple) desktop operating system
Projects
None yet
Development

No branches or pull requests

5 participants