I have 2 windows:
- Display screen captured frames: in bevy (for doing cool things when displaying)
- Control panel: in tauri (for beautiful UI)
But things go wrong on macOS, because UI thread must only be on Main Thread. If I run one of them, main thread will be blocked, and another can have no place to be arranged.
What's worse, bevy based on winit while tauri based on TAO. It's hard to share the same window manager between them. And both have their own async runtimes, I may not able to use tokio::spawn_local to force them to run on main thread correctly.
So, the only method, I can come up with, is to use ipc-channel. However, it raises up the complexity to distribute and bundle my app.
If adopt this solution, I prefer the bevy be lauched by tauri, and contolled by tauri with ipc-channel.
(ps. the bevy part is hard to compile into wasm for it relies on OS api to capture screen)
Anyone knows a better way to solve this situation?
EDIT: by the way, although winit says it support creating window on any thread on waylad and x11, it actually fails if you recreate it (spawn a thread to run eventloop and stop, then spawn again. This fails.).
I expect that the best path forward would be to remove the WinitPlugin
from your Bevy App
initialization, and replace its functionality with your own code. Some possible approaches:
- Run the Bevy
App
on a separate thread from the main thread and keep it entirely separate from window management, only passing a wgpu::Surface
handle to it to enable rendering.
- Make a copy of
bevy_winit
and modify it to use tao
instead. This might work well, or it might get in the way of Tauri app management — I can’t say because I haven't used Tauri myself.
- Run the Bevy app from within Tauri's event loop.
This is like black magic
! I'll try it in the future if possible.
Because my app needs bevy's window position and size to decide the screen capture area... It will be complecated to control render outside of bevy.
The last two methods are so difficult for me that I believe it would take me 2.5 years to implement.
Anyway, thank you for your cool suggestions
! Now I think ipc-channel is not so bad
...
I don't mean that the Bevy side should be ignorant of any of the information it needs to render at the right size (and timing). I mean that it would be kept free of direct ownership of the window. Pass messages as needed.
I understand, you mean tauri side pass info (like window size, position) to some channel. And a bevy plugin is used to recv these info and import them into bevy ESC, so that it works like there's a "window" component. Then bevy draw things on the Surface...
This solution is graceful
I'll try it if possible, for rendering Surface in Tauri takes time to study.
Now I just finished with ipc-channel, and I need a quick prototype for my manager during intership.