win32: Copy icon pixels to BGRA instead of mutating the shared buffer

This commit is contained in:
Sena
2026-09-03 22:01:35 +08:00
committed by GitHub
parent 98562ae862
commit 729985877a
2 changed files with 9 additions and 24 deletions

View File

@@ -20,7 +20,7 @@ use winit_core::icon::*;
use super::util;
use crate::WinIcon;
pub(crate) const PIXEL_SIZE: usize = mem::size_of::<Pixel>();
pub(crate) const PIXEL_SIZE: usize = mem::size_of::<u32>();
unsafe impl Send for WinIcon {}
@@ -96,14 +96,11 @@ impl WinIcon {
pub(crate) fn from_rgba(rgba: &RgbaIcon) -> Result<Self, BadIcon> {
let pixel_count = rgba.buffer().len() / PIXEL_SIZE;
let mut and_mask = Vec::with_capacity(pixel_count);
let pixels = unsafe {
std::slice::from_raw_parts_mut(rgba.buffer().as_ptr() as *mut Pixel, pixel_count)
};
for pixel in pixels {
and_mask.push(pixel.a.wrapping_sub(u8::MAX)); // invert alpha channel
pixel.convert_to_bgra();
let mut bgra = Vec::with_capacity(rgba.buffer().len());
for pixel in rgba.buffer().chunks_exact(PIXEL_SIZE) {
and_mask.push(pixel[3].wrapping_sub(u8::MAX)); // invert alpha channel
bgra.extend_from_slice(&[pixel[2], pixel[1], pixel[0], pixel[3]]);
}
assert_eq!(and_mask.len(), pixel_count);
let handle = unsafe {
CreateIcon(
ptr::null_mut(),
@@ -112,7 +109,7 @@ impl WinIcon {
1,
(PIXEL_SIZE * 8) as u8,
and_mask.as_ptr(),
rgba.buffer().as_ptr(),
bgra.as_ptr(),
)
};
if !handle.is_null() {
@@ -135,12 +132,6 @@ impl fmt::Debug for WinIcon {
}
}
impl Pixel {
fn convert_to_bgra(&mut self) {
mem::swap(&mut self.r, &mut self.b);
}
}
#[derive(Debug, Clone, Copy)]
pub enum IconType {
Small = ICON_SMALL as isize,
@@ -252,12 +243,3 @@ impl RaiiCursor {
self.handle
}
}
#[repr(C)]
#[derive(Debug)]
pub(crate) struct Pixel {
pub(crate) r: u8,
pub(crate) g: u8,
pub(crate) b: u8,
pub(crate) a: u8,
}

View File

@@ -117,6 +117,9 @@ changelog entry.
`DefWindowProc` for normal propagation.
- On Windows, fix getting the window's DPI internally leaks `HDC` handles.
Also only call `GetDC` when on < Windows 8.1 which improves its performance.
- On Windows, fix window icons rendering with red and blue swapped when the same `Icon` is
applied more than once (e.g. sharing one icon between the window and the taskbar). The RGBA
to BGRA conversion no longer mutates the shared pixel buffer.
- On Redox, handle `EINTR` when reading from `event_socket` instead of panicking.
- On X11, fix all pointer input being dropped for absolute pointing devices
without pressure or tilt axes, such as the emulated tablets of