Skip to content

Commit abc9fcc

Browse files
committed
issue-1031: reimplement winit BadIcon error
1 parent 7380f0c commit abc9fcc

File tree

4 files changed

+82
-21
lines changed

4 files changed

+82
-21
lines changed

crates/bevy_render/src/lib.rs

+22-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ use bevy_ecs::{
2020
system::{IntoExclusiveSystem, IntoSystem, Res},
2121
};
2222
use bevy_transform::TransformSystem;
23-
use bevy_utils::{tracing::warn, HashMap};
23+
use bevy_utils::{
24+
tracing::{error, warn},
25+
HashMap,
26+
};
2427
use bevy_window::{WindowIcon, WindowIconBytes, WindowId, Windows};
2528
use draw::{OutsideFrustum, Visible};
2629

@@ -274,12 +277,24 @@ fn window_icon_changed(
274277
match asset_server.get_load_state(handle) {
275278
LoadState::Loaded => {
276279
if let Some(texture) = textures.get(handle) {
277-
let window_icon = WindowIcon::from(WindowIconBytes {
278-
bytes: texture.data.clone(),
279-
width: texture.size.width,
280-
height: texture.size.height,
281-
});
282-
window.set_icon(window_icon);
280+
/* TODO: Not actually sure if we need to check the error here
281+
Whatever Texture gives us might be fine */
282+
let window_icon_bytes = WindowIconBytes::new(
283+
texture.data.clone(),
284+
texture.size.width,
285+
texture.size.height,
286+
);
287+
288+
match window_icon_bytes {
289+
Ok(window_icon_bytes) => {
290+
let window_icon = WindowIcon::from(window_icon_bytes);
291+
window.set_icon(window_icon);
292+
}
293+
Err(e) => error!(
294+
"For handle {:?} the following error was produced: {}",
295+
handle, e
296+
),
297+
}
283298

284299
o.remove();
285300
}

crates/bevy_window/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ bevy_utils = { path = "../bevy_utils", version = "0.5.0" }
2121
bevy_asset = { path = "../bevy_asset", version = "0.5.0" }
2222

2323
# other
24+
thiserror = "1.0"
2425

2526
[target.'cfg(target_arch = "wasm32")'.dependencies]
2627
web-sys = "0.3"

crates/bevy_window/src/window.rs

+50-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use bevy_math::{IVec2, Vec2};
22
use bevy_utils::{tracing::warn, Uuid};
3+
use thiserror::Error;
34

45
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
56
pub struct WindowId(Uuid);
@@ -92,9 +93,20 @@ impl WindowResizeConstraints {
9293

9394
#[derive(Debug, Clone)]
9495
pub struct WindowIconBytes {
95-
pub bytes: Vec<u8>,
96-
pub width: u32,
97-
pub height: u32,
96+
bytes: Vec<u8>,
97+
width: u32,
98+
height: u32,
99+
}
100+
101+
#[derive(Error, Debug)]
102+
pub enum WindowIconBytesError {
103+
#[error("32bpp RGBA image buffer expected, but {bytes_length} is not divisible by 4")]
104+
NotRGBA { bytes_length: usize },
105+
#[error("Buffer size {bytes_length} does not match the expected size based on the dimensions {pixel_bytes_length}")]
106+
SizeMismatch {
107+
pixel_bytes_length: usize,
108+
bytes_length: usize,
109+
},
98110
}
99111

100112
#[derive(Debug, Clone)]
@@ -118,6 +130,41 @@ impl From<WindowIconBytes> for WindowIcon {
118130
}
119131
}
120132

133+
impl WindowIconBytes {
134+
pub fn new(bytes: Vec<u8>, width: u32, height: u32) -> Result<Self, WindowIconBytesError> {
135+
let pixel_count = (width * height) as usize;
136+
let pixel_bytes_length = pixel_count * 4;
137+
let bytes_length = bytes.len();
138+
139+
if bytes_length % 4 != 0 {
140+
Err(WindowIconBytesError::NotRGBA { bytes_length })
141+
} else if pixel_bytes_length != bytes_length {
142+
Err(WindowIconBytesError::SizeMismatch {
143+
pixel_bytes_length,
144+
bytes_length,
145+
})
146+
} else {
147+
Ok(Self {
148+
bytes,
149+
width,
150+
height,
151+
})
152+
}
153+
}
154+
155+
pub fn bytes(&self) -> &[u8] {
156+
&self.bytes
157+
}
158+
159+
pub fn width(&self) -> u32 {
160+
self.width
161+
}
162+
163+
pub fn height(&self) -> u32 {
164+
self.height
165+
}
166+
}
167+
121168
/// An operating system window that can present content and receive user input.
122169
///
123170
/// ## Window Sizes

crates/bevy_winit/src/lib.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -163,17 +163,15 @@ fn change_window(world: &mut World) {
163163
bevy_window::WindowCommand::SetIcon { window_icon_bytes } => {
164164
let window = winit_windows.get_window(id).unwrap();
165165

166-
match Icon::from_rgba(
167-
window_icon_bytes.bytes,
168-
window_icon_bytes.width,
169-
window_icon_bytes.height,
170-
) {
171-
Ok(winit_icon) => window.set_window_icon(Some(winit_icon)),
172-
Err(e) => {
173-
error!("Unable to create window icon: {}", e);
174-
return;
175-
}
176-
}
166+
/* Failures should already be covered in WindowIconBytes constructor */
167+
window.set_window_icon(
168+
Icon::from_rgba(
169+
window_icon_bytes.bytes().to_vec(),
170+
window_icon_bytes.width(),
171+
window_icon_bytes.height(),
172+
)
173+
.ok(),
174+
);
177175
}
178176
bevy_window::WindowCommand::ClearIcon => {
179177
let window = winit_windows.get_window(id).unwrap();

0 commit comments

Comments
 (0)