mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 13:51:30 +11:00
Remove icon loading feature (#799)
This commit is contained in:
parent
6513351e0c
commit
3cd40ef655
|
@ -51,11 +51,9 @@ install:
|
||||||
script:
|
script:
|
||||||
- cargo build --target $TARGET --verbose
|
- cargo build --target $TARGET --verbose
|
||||||
- cargo build --target $TARGET --features serde --verbose
|
- cargo build --target $TARGET --features serde --verbose
|
||||||
- cargo build --target $TARGET --features icon_loading --verbose
|
|
||||||
# Running iOS apps on OSX requires the simulator so we skip that for now
|
# Running iOS apps on OSX requires the simulator so we skip that for now
|
||||||
- if [ "$TARGET" != "x86_64-apple-ios" ]; then cargo test --target $TARGET --verbose; fi
|
- if [ "$TARGET" != "x86_64-apple-ios" ]; then cargo test --target $TARGET --verbose; fi
|
||||||
- if [ "$TARGET" != "x86_64-apple-ios" ]; then cargo test --target $TARGET --features serde --verbose; fi
|
- if [ "$TARGET" != "x86_64-apple-ios" ]; then cargo test --target $TARGET --features serde --verbose; fi
|
||||||
- if [ "$TARGET" != "x86_64-apple-ios" ]; then cargo test --target $TARGET --features icon_loading --verbose; fi
|
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- |
|
- |
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
- Removed `serde` implementations from `ControlFlow`.
|
- Removed `serde` implementations from `ControlFlow`.
|
||||||
- On Wayland, add `set_wayland_theme()` to control client decoration color theme
|
- On Wayland, add `set_wayland_theme()` to control client decoration color theme
|
||||||
- Added serde serialization to `os::unix::XWindowType`.
|
- Added serde serialization to `os::unix::XWindowType`.
|
||||||
- **Breaking:** `image` crate upgraded to 0.21. This is exposed as part of the `icon_loading` API.
|
- **Breaking:** Remove the `icon_loading` feature and the associated `image` dependency.
|
||||||
- On Windows, fix malformed function pointer typecast that could invoke undefined behavior.
|
- On Windows, fix malformed function pointer typecast that could invoke undefined behavior.
|
||||||
- Refactored Windows state/flag-setting code.
|
- Refactored Windows state/flag-setting code.
|
||||||
- On Windows, hiding the cursor no longer hides the cursor for all Winit windows - just the one `hide_cursor` was called on.
|
- On Windows, hiding the cursor no longer hides the cursor for all Winit windows - just the one `hide_cursor` was called on.
|
||||||
|
|
|
@ -11,18 +11,17 @@ documentation = "https://docs.rs/winit"
|
||||||
categories = ["gui"]
|
categories = ["gui"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["icon_loading", "serde"]
|
features = ["serde"]
|
||||||
|
|
||||||
[features]
|
|
||||||
icon_loading = ["image"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
image = { version = "0.21", optional = true }
|
|
||||||
serde = { version = "1", optional = true, features = ["serde_derive"] }
|
serde = { version = "1", optional = true, features = ["serde_derive"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
image = "0.21"
|
||||||
|
|
||||||
[target.'cfg(target_os = "android")'.dependencies.android_glue]
|
[target.'cfg(target_os = "android")'.dependencies.android_glue]
|
||||||
version = "0.2"
|
version = "0.2"
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ Winit is only officially supported on the latest stable version of the Rust comp
|
||||||
### Cargo Features
|
### Cargo Features
|
||||||
|
|
||||||
Winit provides the following features, which can be enabled in your `Cargo.toml` file:
|
Winit provides the following features, which can be enabled in your `Cargo.toml` file:
|
||||||
* `icon_loading`: Enables loading window icons directly from files. Depends on the [`image` crate](https://crates.io/crates/image).
|
|
||||||
* `serde`: Enables serialization/deserialization of certain types with [Serde](https://crates.io/crates/serde).
|
* `serde`: Enables serialization/deserialization of certain types with [Serde](https://crates.io/crates/serde).
|
||||||
|
|
||||||
### Platform-specific usage
|
### Platform-specific usage
|
||||||
|
|
|
@ -21,4 +21,3 @@ build: false
|
||||||
test_script:
|
test_script:
|
||||||
- cargo test --verbose
|
- cargo test --verbose
|
||||||
- cargo test --features serde --verbose
|
- cargo test --features serde --verbose
|
||||||
- cargo test --features icon_loading --verbose
|
|
||||||
|
|
|
@ -1,27 +1,30 @@
|
||||||
// Heads up: you need to compile this example with `--features icon_loading`.
|
|
||||||
// `Icon::from_path` won't be available otherwise, though for your own applications, you could use
|
|
||||||
// `Icon::from_rgba` if you don't want to depend on the `image` crate.
|
|
||||||
|
|
||||||
extern crate winit;
|
extern crate winit;
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
extern crate image;
|
extern crate image;
|
||||||
|
|
||||||
#[cfg(feature = "icon_loading")]
|
use std::path::Path;
|
||||||
|
use winit::window::{WindowBuilder, Icon};
|
||||||
|
use winit::event::Event;
|
||||||
|
use winit::event_loop::{EventLoop, ControlFlow};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
use winit::window::{WindowBuilder, Icon};
|
|
||||||
use winit::event::Event;
|
|
||||||
use winit::event_loop::{EventLoop, ControlFlow};
|
|
||||||
|
|
||||||
// You'll have to choose an icon size at your own discretion. On X11, the desired size varies
|
// You'll have to choose an icon size at your own discretion. On X11, the desired size varies
|
||||||
// by WM, and on Windows, you still have to account for screen scaling. Here we use 32px,
|
// by WM, and on Windows, you still have to account for screen scaling. Here we use 32px,
|
||||||
// since it seems to work well enough in most cases. Be careful about going too high, or
|
// since it seems to work well enough in most cases. Be careful about going too high, or
|
||||||
// you'll be bitten by the low-quality downscaling built into the WM.
|
// you'll be bitten by the low-quality downscaling built into the WM.
|
||||||
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/examples/icon.png");
|
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/examples/icon.png");
|
||||||
// While `Icon::from_path` is the most straightforward, you have a few other options. If you
|
|
||||||
// want to use the `include_bytes` macro, then pass the result to `Icon::from_bytes`. See the
|
let (icon_rgba, icon_width, icon_height) = {
|
||||||
// docs for the full list of options (you'll have to generate the docs with the `icon_loading`
|
let image = image::open(path).expect("Failed to open icon path");
|
||||||
// feature enabled).
|
use image::{GenericImageView, Pixel};
|
||||||
let icon = Icon::from_path(path).expect("Failed to open icon");
|
let (width, height) = image.dimensions();
|
||||||
|
let mut rgba = Vec::with_capacity((width * height) as usize * 4);
|
||||||
|
for (_, _, pixel) in image.pixels() {
|
||||||
|
rgba.extend_from_slice(&pixel.to_rgba().data);
|
||||||
|
}
|
||||||
|
(rgba, width, height)
|
||||||
|
};
|
||||||
|
let icon = Icon::from_rgba(icon_rgba, icon_width, icon_height).expect("Failed to open icon");
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
|
|
||||||
|
@ -42,45 +45,7 @@ fn main() {
|
||||||
DroppedFile(path) => {
|
DroppedFile(path) => {
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
|
|
||||||
let icon_image = image::open(path).expect("Failed to open window icon");
|
window.set_window_icon(Some(load_icon(&path)));
|
||||||
|
|
||||||
let (width, height) = icon_image.dimensions();
|
|
||||||
const DESIRED_SIZE: u32 = 32;
|
|
||||||
let (new_width, new_height) = if width == height {
|
|
||||||
(DESIRED_SIZE, DESIRED_SIZE)
|
|
||||||
} else {
|
|
||||||
// Note that this will never divide by zero, due to the previous condition.
|
|
||||||
let aspect_adjustment = DESIRED_SIZE as f64
|
|
||||||
/ std::cmp::max(width, height) as f64;
|
|
||||||
(
|
|
||||||
(width as f64 * aspect_adjustment) as u32,
|
|
||||||
(height as f64 * aspect_adjustment) as u32,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
// By scaling the icon ourselves, we get higher-quality filtering and save
|
|
||||||
// some memory.
|
|
||||||
let icon = image::imageops::resize(
|
|
||||||
&icon_image,
|
|
||||||
new_width,
|
|
||||||
new_height,
|
|
||||||
image::FilterType::Lanczos3,
|
|
||||||
);
|
|
||||||
|
|
||||||
let (offset_x, offset_y) = (
|
|
||||||
(DESIRED_SIZE - new_width) / 2,
|
|
||||||
(DESIRED_SIZE - new_height) / 2,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut canvas = image::ImageBuffer::new(DESIRED_SIZE, DESIRED_SIZE);
|
|
||||||
image::imageops::replace(
|
|
||||||
&mut canvas,
|
|
||||||
&icon,
|
|
||||||
offset_x,
|
|
||||||
offset_y,
|
|
||||||
);
|
|
||||||
|
|
||||||
window.set_window_icon(Some(canvas.into()));
|
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -88,10 +53,16 @@ fn main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "icon_loading"))]
|
fn load_icon(path: &Path) -> Icon {
|
||||||
fn main() {
|
let (icon_rgba, icon_width, icon_height) = {
|
||||||
print!(
|
let image = image::open(path).expect("Failed to open icon path");
|
||||||
r#"This example requires the `icon_loading` feature:
|
use image::{GenericImageView, Pixel};
|
||||||
cargo run --example window_icon --features icon_loading
|
let (width, height) = image.dimensions();
|
||||||
"#);
|
let mut rgba = Vec::with_capacity((width * height) as usize * 4);
|
||||||
|
for (_, _, pixel) in image.pixels() {
|
||||||
|
rgba.extend_from_slice(&pixel.to_rgba().data);
|
||||||
|
}
|
||||||
|
(rgba, width, height)
|
||||||
|
};
|
||||||
|
Icon::from_rgba(icon_rgba, icon_width, icon_height).expect("Failed to open icon")
|
||||||
}
|
}
|
||||||
|
|
77
src/icon.rs
77
src/icon.rs
|
@ -1,12 +1,5 @@
|
||||||
use std::{fmt, mem};
|
use std::{fmt, mem};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
use std::io::{BufRead, Seek};
|
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
use image;
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -70,10 +63,6 @@ impl Error for BadIcon {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
/// An icon used for the window titlebar, taskbar, etc.
|
/// An icon used for the window titlebar, taskbar, etc.
|
||||||
///
|
|
||||||
/// Enabling the `icon_loading` feature provides you with several convenience methods for creating
|
|
||||||
/// an `Icon` from any format supported by the [image](https://github.com/PistonDevelopers/image)
|
|
||||||
/// crate.
|
|
||||||
pub struct Icon {
|
pub struct Icon {
|
||||||
pub(crate) rgba: Vec<u8>,
|
pub(crate) rgba: Vec<u8>,
|
||||||
pub(crate) width: u32,
|
pub(crate) width: u32,
|
||||||
|
@ -101,70 +90,4 @@ impl Icon {
|
||||||
Ok(Icon { rgba, width, height })
|
Ok(Icon { rgba, width, height })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
/// Loads an `Icon` from the path of an image on the filesystem.
|
|
||||||
///
|
|
||||||
/// Requires the `icon_loading` feature.
|
|
||||||
pub fn from_path<P: AsRef<Path>>(path: P) -> image::ImageResult<Self> {
|
|
||||||
image::open(path).map(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
/// Loads an `Icon` from anything implementing `BufRead` and `Seek`.
|
|
||||||
///
|
|
||||||
/// Requires the `icon_loading` feature.
|
|
||||||
pub fn from_reader<R: BufRead + Seek>(
|
|
||||||
reader: R,
|
|
||||||
format: image::ImageFormat,
|
|
||||||
) -> image::ImageResult<Self> {
|
|
||||||
image::load(reader, format).map(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
/// Loads an `Icon` from the unprocessed bytes of an image file.
|
|
||||||
/// Uses heuristics to determine format.
|
|
||||||
///
|
|
||||||
/// Requires the `icon_loading` feature.
|
|
||||||
pub fn from_bytes(bytes: &[u8]) -> image::ImageResult<Self> {
|
|
||||||
image::load_from_memory(bytes).map(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
/// Loads an `Icon` from the unprocessed bytes of an image.
|
|
||||||
///
|
|
||||||
/// Requires the `icon_loading` feature.
|
|
||||||
pub fn from_bytes_with_format(
|
|
||||||
bytes: &[u8],
|
|
||||||
format: image::ImageFormat,
|
|
||||||
) -> image::ImageResult<Self> {
|
|
||||||
image::load_from_memory_with_format(bytes, format).map(Into::into)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
/// Requires the `icon_loading` feature.
|
|
||||||
impl From<image::DynamicImage> for Icon {
|
|
||||||
fn from(image: image::DynamicImage) -> Self {
|
|
||||||
use image::{GenericImageView, Pixel};
|
|
||||||
let (width, height) = image.dimensions();
|
|
||||||
let mut rgba = Vec::with_capacity((width * height) as usize * PIXEL_SIZE);
|
|
||||||
for (_, _, pixel) in image.pixels() {
|
|
||||||
rgba.extend_from_slice(&pixel.to_rgba().data);
|
|
||||||
}
|
|
||||||
Icon { rgba, width, height }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
/// Requires the `icon_loading` feature.
|
|
||||||
impl From<image::RgbaImage> for Icon {
|
|
||||||
fn from(buf: image::RgbaImage) -> Self {
|
|
||||||
let (width, height) = buf.dimensions();
|
|
||||||
let mut rgba = Vec::with_capacity((width * height) as usize * PIXEL_SIZE);
|
|
||||||
for (_, _, pixel) in buf.enumerate_pixels() {
|
|
||||||
rgba.extend_from_slice(&pixel.data);
|
|
||||||
}
|
|
||||||
Icon { rgba, width, height }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,8 +81,6 @@ extern crate lazy_static;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
#[cfg(feature = "icon_loading")]
|
|
||||||
extern crate image;
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
|
Loading…
Reference in a new issue