@@ -205,13 +205,18 @@ fn set_title_and_icon_mac(title: &str, icon_data: Option<&IconData>) -> AppIconS
205
205
206
206
use objc2:: ClassType as _;
207
207
use objc2_app_kit:: { NSApplication , NSImage } ;
208
- use objc2_foundation:: { NSData , NSString } ;
208
+ use objc2_foundation:: NSString ;
209
209
210
- let png_bytes = if let Some ( icon_data) = icon_data {
211
- match icon_data. to_png_bytes ( ) {
212
- Ok ( png_bytes) => Some ( png_bytes) ,
210
+ // Do NOT use png even though creating `NSImage` from it is much easier than from raw images data!
211
+ //
212
+ // Some MacOS versions have a bug where creating an `NSImage` from a png will cause it to load an arbitrary `libpng.dylib`.
213
+ // If this dylib isn't the right version, the application will crash with SIGBUS.
214
+ // For details see https://github.com/emilk/egui/issues/7155
215
+ let image = if let Some ( icon_data) = icon_data {
216
+ match icon_data. to_image ( ) {
217
+ Ok ( image) => Some ( image) ,
213
218
Err ( err) => {
214
- log:: warn!( "Failed to convert IconData to png : {err}" ) ;
219
+ log:: warn!( "Failed to read icon data : {err}" ) ;
215
220
return AppIconStatus :: NotSetIgnored ;
216
221
}
217
222
}
@@ -231,15 +236,39 @@ fn set_title_and_icon_mac(title: &str, icon_data: Option<&IconData>) -> AppIconS
231
236
return AppIconStatus :: NotSetIgnored ;
232
237
} ;
233
238
234
- if let Some ( png_bytes) = png_bytes {
235
- let data = NSData :: from_vec ( png_bytes) ;
239
+ if let Some ( image) = image {
240
+ use objc2_app_kit:: { NSBitmapImageRep , NSDeviceRGBColorSpace } ;
241
+ use objc2_foundation:: NSSize ;
242
+
243
+ log:: trace!( "NSBitmapImageRep::initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bytesPerRow_bitsPerPixel" ) ;
244
+ let Some ( image_rep) = NSBitmapImageRep :: initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bytesPerRow_bitsPerPixel (
245
+ NSBitmapImageRep :: alloc ( ) ,
246
+ [ image. as_raw ( ) . as_ptr ( ) . cast_mut ( ) ] . as_mut_ptr ( ) ,
247
+ image. width ( ) as isize ,
248
+ image. height ( ) as isize ,
249
+ 8 , // bits per sample
250
+ 4 , // samples per pixel
251
+ true , // has alpha
252
+ false , // is not planar
253
+ NSDeviceRGBColorSpace ,
254
+ ( image. width ( ) * 4 ) as isize , // bytes per row
255
+ 32 // bits per pixel
256
+ ) else {
257
+ log:: warn!( "Failed to create NSBitmapImageRep from app icon data." ) ;
258
+ return AppIconStatus :: NotSetIgnored ;
259
+ } ;
236
260
237
- log:: trace!( "NSImage::initWithData…" ) ;
238
- let app_icon = NSImage :: initWithData ( NSImage :: alloc ( ) , & data) ;
261
+ log:: trace!( "NSImage::initWithSize" ) ;
262
+ let app_icon = NSImage :: initWithSize (
263
+ NSImage :: alloc ( ) ,
264
+ NSSize :: new ( image. width ( ) as f64 , image. height ( ) as f64 ) ,
265
+ ) ;
266
+ log:: trace!( "NSImage::addRepresentation" ) ;
267
+ app_icon. addRepresentation ( & image_rep) ;
239
268
240
269
profiling:: scope!( "setApplicationIconImage_" ) ;
241
270
log:: trace!( "setApplicationIconImage…" ) ;
242
- app. setApplicationIconImage ( app_icon . as_deref ( ) ) ;
271
+ app. setApplicationIconImage ( Some ( & app_icon ) ) ;
243
272
}
244
273
245
274
// Change the title in the top bar - for python processes this would be again "python" otherwise.
0 commit comments