mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 12:50:04 -04:00
eframe: Use objc2 and its framework crates (#4395)
These are a replacement to the `objc` and `cocoa` crates. This PR prevents: - An extra copy when creating `NSData` - A memory leak when creating `NSImage` - A memory leak when creating `NSString` And is generally a readability improvement. Note that we define `NSApp` manually for now, the implementation in `objc2-app-kit` is currently suboptimal and wouldn't allow you to check whether the NSApplication has been created or not. Related: https://github.com/emilk/egui/issues/4219, this should nicely coincide with the Winit `0.30` release. --------- Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
@@ -203,12 +203,9 @@ fn set_title_and_icon_mac(title: &str, icon_data: Option<&IconData>) -> AppIconS
|
||||
use crate::icon_data::IconDataExt as _;
|
||||
crate::profile_function!();
|
||||
|
||||
use cocoa::{
|
||||
appkit::{NSApp, NSApplication, NSImage, NSMenu, NSWindow},
|
||||
base::{id, nil},
|
||||
foundation::{NSData, NSString},
|
||||
};
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
use objc2::ClassType;
|
||||
use objc2_app_kit::{NSApplication, NSImage};
|
||||
use objc2_foundation::{NSData, NSString};
|
||||
|
||||
let png_bytes = if let Some(icon_data) = icon_data {
|
||||
match icon_data.to_png_bytes() {
|
||||
@@ -222,38 +219,36 @@ fn set_title_and_icon_mac(title: &str, icon_data: Option<&IconData>) -> AppIconS
|
||||
None
|
||||
};
|
||||
|
||||
// SAFETY: Accessing raw data from icon in a read-only manner. Icon data is static!
|
||||
// TODO(madsmtm): Move this into `objc2-app-kit`
|
||||
extern "C" {
|
||||
static NSApp: Option<&'static NSApplication>;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let app = NSApp();
|
||||
if app.is_null() {
|
||||
let app = if let Some(app) = NSApp {
|
||||
app
|
||||
} else {
|
||||
log::debug!("NSApp is null");
|
||||
return AppIconStatus::NotSetIgnored;
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(png_bytes) = png_bytes {
|
||||
let data = NSData::dataWithBytes_length_(
|
||||
nil,
|
||||
png_bytes.as_ptr().cast::<std::ffi::c_void>(),
|
||||
png_bytes.len() as u64,
|
||||
);
|
||||
let data = NSData::from_vec(png_bytes);
|
||||
|
||||
log::trace!("NSImage::initWithData…");
|
||||
let app_icon = NSImage::initWithData_(NSImage::alloc(nil), data);
|
||||
let app_icon = NSImage::initWithData(NSImage::alloc(), &data);
|
||||
|
||||
crate::profile_scope!("setApplicationIconImage_");
|
||||
log::trace!("setApplicationIconImage…");
|
||||
app.setApplicationIconImage_(app_icon);
|
||||
app.setApplicationIconImage(app_icon.as_deref());
|
||||
}
|
||||
|
||||
// Change the title in the top bar - for python processes this would be again "python" otherwise.
|
||||
let main_menu = app.mainMenu();
|
||||
if !main_menu.is_null() {
|
||||
let item = main_menu.itemAtIndex_(0);
|
||||
if !item.is_null() {
|
||||
let app_menu: id = msg_send![item, submenu];
|
||||
if !app_menu.is_null() {
|
||||
if let Some(main_menu) = app.mainMenu() {
|
||||
if let Some(item) = main_menu.itemAtIndex(0) {
|
||||
if let Some(app_menu) = item.submenu() {
|
||||
crate::profile_scope!("setTitle_");
|
||||
app_menu.setTitle_(NSString::alloc(nil).init_str(title));
|
||||
app_menu.setTitle(&NSString::from_str(title));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user