Skip to content

Commit

Permalink
issue-1031: reimplement winit BadIcon error
Browse files Browse the repository at this point in the history
  • Loading branch information
KirmesBude committed Jun 6, 2021
1 parent 7380f0c commit abc9fcc
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 21 deletions.
29 changes: 22 additions & 7 deletions crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ use bevy_ecs::{
system::{IntoExclusiveSystem, IntoSystem, Res},
};
use bevy_transform::TransformSystem;
use bevy_utils::{tracing::warn, HashMap};
use bevy_utils::{
tracing::{error, warn},
HashMap,
};
use bevy_window::{WindowIcon, WindowIconBytes, WindowId, Windows};
use draw::{OutsideFrustum, Visible};

Expand Down Expand Up @@ -274,12 +277,24 @@ fn window_icon_changed(
match asset_server.get_load_state(handle) {
LoadState::Loaded => {
if let Some(texture) = textures.get(handle) {
let window_icon = WindowIcon::from(WindowIconBytes {
bytes: texture.data.clone(),
width: texture.size.width,
height: texture.size.height,
});
window.set_icon(window_icon);
/* TODO: Not actually sure if we need to check the error here
Whatever Texture gives us might be fine */
let window_icon_bytes = WindowIconBytes::new(
texture.data.clone(),
texture.size.width,
texture.size.height,
);

match window_icon_bytes {
Ok(window_icon_bytes) => {
let window_icon = WindowIcon::from(window_icon_bytes);
window.set_icon(window_icon);
}
Err(e) => error!(
"For handle {:?} the following error was produced: {}",
handle, e
),
}

o.remove();
}
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_window/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ bevy_utils = { path = "../bevy_utils", version = "0.5.0" }
bevy_asset = { path = "../bevy_asset", version = "0.5.0" }

# other
thiserror = "1.0"

[target.'cfg(target_arch = "wasm32")'.dependencies]
web-sys = "0.3"
53 changes: 50 additions & 3 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use bevy_math::{IVec2, Vec2};
use bevy_utils::{tracing::warn, Uuid};
use thiserror::Error;

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

#[derive(Debug, Clone)]
pub struct WindowIconBytes {
pub bytes: Vec<u8>,
pub width: u32,
pub height: u32,
bytes: Vec<u8>,
width: u32,
height: u32,
}

#[derive(Error, Debug)]
pub enum WindowIconBytesError {
#[error("32bpp RGBA image buffer expected, but {bytes_length} is not divisible by 4")]
NotRGBA { bytes_length: usize },
#[error("Buffer size {bytes_length} does not match the expected size based on the dimensions {pixel_bytes_length}")]
SizeMismatch {
pixel_bytes_length: usize,
bytes_length: usize,
},
}

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

impl WindowIconBytes {
pub fn new(bytes: Vec<u8>, width: u32, height: u32) -> Result<Self, WindowIconBytesError> {
let pixel_count = (width * height) as usize;
let pixel_bytes_length = pixel_count * 4;
let bytes_length = bytes.len();

if bytes_length % 4 != 0 {
Err(WindowIconBytesError::NotRGBA { bytes_length })
} else if pixel_bytes_length != bytes_length {
Err(WindowIconBytesError::SizeMismatch {
pixel_bytes_length,
bytes_length,
})
} else {
Ok(Self {
bytes,
width,
height,
})
}
}

pub fn bytes(&self) -> &[u8] {
&self.bytes
}

pub fn width(&self) -> u32 {
self.width
}

pub fn height(&self) -> u32 {
self.height
}
}

/// An operating system window that can present content and receive user input.
///
/// ## Window Sizes
Expand Down
20 changes: 9 additions & 11 deletions crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,15 @@ fn change_window(world: &mut World) {
bevy_window::WindowCommand::SetIcon { window_icon_bytes } => {
let window = winit_windows.get_window(id).unwrap();

match Icon::from_rgba(
window_icon_bytes.bytes,
window_icon_bytes.width,
window_icon_bytes.height,
) {
Ok(winit_icon) => window.set_window_icon(Some(winit_icon)),
Err(e) => {
error!("Unable to create window icon: {}", e);
return;
}
}
/* Failures should already be covered in WindowIconBytes constructor */
window.set_window_icon(
Icon::from_rgba(
window_icon_bytes.bytes().to_vec(),
window_icon_bytes.width(),
window_icon_bytes.height(),
)
.ok(),
);
}
bevy_window::WindowCommand::ClearIcon => {
let window = winit_windows.get_window(id).unwrap();
Expand Down

0 comments on commit abc9fcc

Please sign in to comment.