Files
pdfcraft/vendor/winit/src/icon.rs
cyfung1031andClaude Opus 5.5 24ba8385f8 Issue #324: on Windows 11, a window dragged to another monitor takes its scale (#544)
* Issue #324: vendor winit 0.30.13 as published

The crate as released on crates.io, without its asset files (docs/res/*.svg and
examples/data/*.png, AGENTS.md §1). Not used yet: the next commit patches it and
adds it to [patch.crates-io].

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Issue #324: on Windows 11, a window dragged to another monitor takes its scale

winit 0.30.13 handles WM_DPICHANGED by checking that the new window rect is on
the monitor `MonitorFromWindow` names. During a drag that is still the monitor
being left, so winit nudged the window back onto it, which sent another
WM_DPICHANGED: the window grew and stayed on the wrong monitor at the wrong
scale. From Windows 11 (build 22000) on, apply the rect Windows suggests, as
winit master does since 488c036a (rust-windowing/winit#4341); no 0.30 release
has it. Windows 10 keeps the old adjustment, as on winit master.

The vendored copy goes in [patch.crates-io]; a test fails if winit resolves
from crates.io again or the vendored copy loses the patch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 12:19:41 -04:00

118 lines
4.0 KiB
Rust

use crate::platform_impl::PlatformIcon;
use std::error::Error;
use std::{fmt, io, mem};
#[repr(C)]
#[derive(Debug)]
pub(crate) struct Pixel {
pub(crate) r: u8,
pub(crate) g: u8,
pub(crate) b: u8,
pub(crate) a: u8,
}
pub(crate) const PIXEL_SIZE: usize = mem::size_of::<Pixel>();
#[derive(Debug)]
/// An error produced when using [`Icon::from_rgba`] with invalid arguments.
pub enum BadIcon {
/// Produced when the length of the `rgba` argument isn't divisible by 4, thus `rgba` can't be
/// safely interpreted as 32bpp RGBA pixels.
ByteCountNotDivisibleBy4 { byte_count: usize },
/// Produced when the number of pixels (`rgba.len() / 4`) isn't equal to `width * height`.
/// At least one of your arguments is incorrect.
DimensionsVsPixelCount { width: u32, height: u32, width_x_height: usize, pixel_count: usize },
/// Produced when underlying OS functionality failed to create the icon
OsError(io::Error),
}
impl fmt::Display for BadIcon {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BadIcon::ByteCountNotDivisibleBy4 { byte_count } => write!(
f,
"The length of the `rgba` argument ({byte_count:?}) isn't divisible by 4, making \
it impossible to interpret as 32bpp RGBA pixels.",
),
BadIcon::DimensionsVsPixelCount { width, height, width_x_height, pixel_count } => {
write!(
f,
"The specified dimensions ({width:?}x{height:?}) don't match the number of \
pixels supplied by the `rgba` argument ({pixel_count:?}). For those \
dimensions, the expected pixel count is {width_x_height:?}.",
)
},
BadIcon::OsError(e) => write!(f, "OS error when instantiating the icon: {e:?}"),
}
}
}
impl Error for BadIcon {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct RgbaIcon {
pub(crate) rgba: Vec<u8>,
pub(crate) width: u32,
pub(crate) height: u32,
}
/// For platforms which don't have window icons (e.g. web)
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct NoIcon;
#[allow(dead_code)] // These are not used on every platform
mod constructors {
use super::*;
impl RgbaIcon {
pub fn from_rgba(rgba: Vec<u8>, width: u32, height: u32) -> Result<Self, BadIcon> {
if rgba.len() % PIXEL_SIZE != 0 {
return Err(BadIcon::ByteCountNotDivisibleBy4 { byte_count: rgba.len() });
}
let pixel_count = rgba.len() / PIXEL_SIZE;
if pixel_count != (width * height) as usize {
Err(BadIcon::DimensionsVsPixelCount {
width,
height,
width_x_height: (width * height) as usize,
pixel_count,
})
} else {
Ok(RgbaIcon { rgba, width, height })
}
}
}
impl NoIcon {
pub fn from_rgba(rgba: Vec<u8>, width: u32, height: u32) -> Result<Self, BadIcon> {
// Create the rgba icon anyway to validate the input
let _ = RgbaIcon::from_rgba(rgba, width, height)?;
Ok(NoIcon)
}
}
}
/// An icon used for the window titlebar, taskbar, etc.
#[derive(Clone)]
pub struct Icon {
pub(crate) inner: PlatformIcon,
}
impl fmt::Debug for Icon {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
fmt::Debug::fmt(&self.inner, formatter)
}
}
impl Icon {
/// Creates an icon from 32bpp RGBA data.
///
/// The length of `rgba` must be divisible by 4, and `width * height` must equal
/// `rgba.len() / 4`. Otherwise, this will return a `BadIcon` error.
pub fn from_rgba(rgba: Vec<u8>, width: u32, height: u32) -> Result<Self, BadIcon> {
let _span = tracing::debug_span!("winit::Icon::from_rgba", width, height).entered();
Ok(Icon { inner: PlatformIcon::from_rgba(rgba, width, height)? })
}
}