@@ -23,7 +23,6 @@ use tauri_runtime::SystemTrayEvent;
2323#[ cfg( feature = "system-tray" ) ]
2424use wry:: application:: platform:: system_tray:: SystemTrayBuilder ;
2525
26- use image:: { GenericImageView , Pixel } ;
2726use tauri_utils:: config:: WindowConfig ;
2827use uuid:: Uuid ;
2928use wry:: {
@@ -47,6 +46,7 @@ use wry::{
4746use std:: {
4847 collections:: HashMap ,
4948 convert:: TryFrom ,
49+ fs:: read,
5050 sync:: {
5151 mpsc:: { channel, Receiver , Sender } ,
5252 Arc , Mutex ,
@@ -64,38 +64,42 @@ type MainThreadTask = Box<dyn FnOnce() + Send>;
6464type WindowEventHandler = Box < dyn Fn ( & WindowEvent ) + Send > ;
6565type WindowEventListeners = Arc < Mutex < HashMap < Uuid , WindowEventHandler > > > ;
6666
67- #[ repr( C ) ]
68- #[ derive( Debug ) ]
69- struct PixelValue {
70- r : u8 ,
71- g : u8 ,
72- b : u8 ,
73- a : u8 ,
74- }
75-
76- const PIXEL_SIZE : usize = std:: mem:: size_of :: < PixelValue > ( ) ;
77-
7867/// Wrapper around a [`wry::application::window::Icon`] that can be created from an [`Icon`].
7968pub struct WryIcon ( WindowIcon ) ;
8069
70+ fn icon_err < E : std:: error:: Error + Send + ' static > ( e : E ) -> Error {
71+ Error :: InvalidIcon ( Box :: new ( e) )
72+ }
73+
8174impl TryFrom < Icon > for WryIcon {
8275 type Error = Error ;
8376 fn try_from ( icon : Icon ) -> std:: result:: Result < Self , Self :: Error > {
84- let image = match icon {
85- Icon :: File ( path) => image:: open ( path) . map_err ( |e| Error :: InvalidIcon ( Box :: new ( e) ) ) ?,
86- Icon :: Raw ( raw) => {
87- image:: load_from_memory ( & raw ) . map_err ( |e| Error :: InvalidIcon ( Box :: new ( e) ) ) ?
88- }
77+ let image_bytes = match icon {
78+ Icon :: File ( path) => read ( path) . map_err ( icon_err) ?,
79+ Icon :: Raw ( raw) => raw,
8980 _ => unimplemented ! ( ) ,
9081 } ;
91- let ( width, height) = image. dimensions ( ) ;
92- let mut rgba = Vec :: with_capacity ( ( width * height) as usize * PIXEL_SIZE ) ;
93- for ( _, _, pixel) in image. pixels ( ) {
94- rgba. extend_from_slice ( & pixel. to_rgba ( ) . 0 ) ;
82+ let extension = infer:: get ( & image_bytes)
83+ . expect ( "could not determine icon extension" )
84+ . extension ( ) ;
85+ match extension {
86+ #[ cfg( windows) ]
87+ "ico" => {
88+ let icon_dir = ico:: IconDir :: read ( std:: io:: Cursor :: new ( image_bytes) ) . map_err ( icon_err) ?;
89+ let entry = & icon_dir. entries ( ) [ 0 ] ;
90+ let icon = WindowIcon :: from_rgba (
91+ entry. decode ( ) . map_err ( icon_err) ?. rgba_data ( ) . to_vec ( ) ,
92+ entry. width ( ) ,
93+ entry. height ( ) ,
94+ )
95+ . map_err ( icon_err) ?;
96+ Ok ( Self ( icon) )
97+ }
98+ _ => panic ! (
99+ "image `{}` extension not supported; please file a Tauri feature request" ,
100+ extension
101+ ) ,
95102 }
96- let icon =
97- WindowIcon :: from_rgba ( rgba, width, height) . map_err ( |e| Error :: InvalidIcon ( Box :: new ( e) ) ) ?;
98- Ok ( Self ( icon) )
99103 }
100104}
101105
0 commit comments