You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
use std::io::Cursor;
use bevy::{prelude::App, DefaultPlugins};
use image::{io::Reader as ImageReader, ImageFormat};
use winit::window::Icon;
use bevy::{prelude::Res, window::WindowId, winit::WinitWindows};
fn configure_icon(windows: Res<WinitWindows>) {
let window = windows.get_window(WindowId::primary()).unwrap();
let img_bytes = include_bytes!("..\\assets\\favicon.png");
let mut img_reader = ImageReader::new(Cursor::new(img_bytes));
img_reader.set_format(ImageFormat::Png);
if let Ok(image) = img_reader.decode() {
let image_data = image.into_rgba8();
let (width, height) = image_data.dimensions();
let rgba = image_data.into_raw();
let icon =
Icon::from_rgba(rgba, width, height).expect("Error creating icon from App Icon data");
window.set_window_icon(Some(icon));
}
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(configure_icon)
.run();
}
What you expected to happen
I expect the Window Icon at the top left hand corner of the application, and the window in the Task Bar to display the 16x16px png file located in the file assets/favicon.png. This should work 100% of the time.
What actually happened
This seems to work 50% of the time. Other times, the window opens with a blank white display, the default Windows window icon is shown, and the application is unresponsive. By clicking on the screen, Windows reports the application as (Not Responding).
The application never progresses after the call to window.set_window_icon(Some(icon)) .
Additional information
This isn't an issue with winit 0.26.1, as with the below code example just using Winit the issue doesn't occur, it works 100% of the time.
use std::io::Cursor;
use image::{io::Reader as ImageReader, ImageFormat};
use winit::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::{Icon, WindowBuilder},
};
fn main() {
let event_loop = EventLoop::new();
let window = WindowBuilder::new().build(&event_loop).unwrap();
let img_bytes = include_bytes!("..\\assets\\favicon.png");
let mut img_reader = ImageReader::new(Cursor::new(img_bytes));
img_reader.set_format(ImageFormat::Png);
if let Ok(image) = img_reader.decode() {
let image_data = image.into_rgba8();
let (width, height) = image_data.dimensions();
let rgba = image_data.into_raw();
let icon =
Icon::from_rgba(rgba, width, height).expect("Error creating icon from App Icon data");
window.set_window_icon(Some(icon));
}
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
window_id,
} if window_id == window.id() => *control_flow = ControlFlow::Exit,
_ => (),
}
});
}
Also worth noting, when doing the below via Bevy, as soon as the window is rendered the icon is immediately there. However, when using the Bevy example above, the default Windows application Icon flashes up for a second or so, before the rest of the game loads - but that could well just be overhead of the engine.
I'm aware this is the workaround, and talks / progress around setting the Window Icon via Bevy is being discussed under #2268 - however currently this workaround doesn't seem to be an option either.
Cheers! 😄
The text was updated successfully, but these errors were encountered:
This is caused by calling set_window_icon() outside of the main thread. You will need to ensure the configure_icon system is run on the main thread.
Solutions:
Change Res<WinitWindows> to NonSend<WinitWindows>
This works because systems with NonSend resources cannot be scheduled on another thread.
Change .add_startup_system(configure_icon) to .add_startup_system(configure_icon.exclusive_system())
This works because exclusive systems are scheduled on the main thread.
# Objective
- Fixesbevyengine#4010, as well as any similar issues in this class.
- Winit functions used outside of the main thread can cause the application to unexpectedly hang.
## Solution
- Make the `WinitWindows` resource `!Send`.
- This ensures that any systems that use `WinitWindows` must either be exclusive (run on the main thread), or the resource is explicitly marked with the `NonSend` parameter in user systems.
Bevy version
Bevy 0.6.1
Winit 0.26.1
Operating system & version
Tested on Windows 10 and 11
What you did
main.rs
What you expected to happen
I expect the Window Icon at the top left hand corner of the application, and the window in the Task Bar to display the 16x16px png file located in the file assets/favicon.png. This should work 100% of the time.
What actually happened
This seems to work 50% of the time. Other times, the window opens with a blank white display, the default Windows window icon is shown, and the application is unresponsive. By clicking on the screen, Windows reports the application as (Not Responding).
The application never progresses after the call to window.set_window_icon(Some(icon)) .
Additional information
This isn't an issue with winit 0.26.1, as with the below code example just using Winit the issue doesn't occur, it works 100% of the time.
Also worth noting, when doing the below via Bevy, as soon as the window is rendered the icon is immediately there. However, when using the Bevy example above, the default Windows application Icon flashes up for a second or so, before the rest of the game loads - but that could well just be overhead of the engine.
I'm aware this is the workaround, and talks / progress around setting the Window Icon via Bevy is being discussed under #2268 - however currently this workaround doesn't seem to be an option either.
Cheers! 😄
The text was updated successfully, but these errors were encountered: