Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions winit-appkit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ objc2.workspace = true
objc2-app-kit = { workspace = true, features = [
"std",
"objc2-core-foundation",
"objc2-core-graphics",
"NSAppearance",
"NSApplication",
"NSBitmapImageRep",
Expand Down Expand Up @@ -70,6 +71,8 @@ objc2-core-foundation = { workspace = true, features = [
objc2-core-graphics = { workspace = true, features = [
"std",
"libc",
"CGColorSpace",
"CGDataProvider",
"CGDirectDisplay",
"CGDisplayConfiguration",
"CGDisplayFade",
Expand Down
67 changes: 52 additions & 15 deletions winit-appkit/src/window_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ use dpi::{
use objc2::rc::{autoreleasepool, Retained};
use objc2::runtime::{AnyObject, ProtocolObject};
use objc2::{
available, define_class, msg_send, sel, ClassType, DefinedClass, MainThreadMarker,
available, define_class, msg_send, sel, AnyThread, ClassType, DefinedClass, MainThreadMarker,
MainThreadOnly, Message,
};
use objc2_app_kit::{
NSAppKitVersionNumber, NSAppKitVersionNumber10_12, NSAppearance, NSAppearanceCustomization,
NSAppearanceNameAqua, NSApplication, NSApplicationPresentationOptions, NSBackingStoreType,
NSColor, NSDraggingDestination, NSDraggingInfo, NSRequestUserAttentionType, NSScreen,
NSColor, NSDraggingDestination, NSDraggingInfo, NSImage, NSRequestUserAttentionType, NSScreen,
NSToolbar, NSView, NSViewFrameDidChangeNotification, NSWindow, NSWindowButton,
NSWindowDelegate, NSWindowLevel, NSWindowOcclusionState, NSWindowOrderingMode,
NSWindowSharingType, NSWindowStyleMask, NSWindowTabbingMode, NSWindowTitleVisibility,
Expand All @@ -31,9 +31,11 @@ use objc2_core_foundation::{CGFloat, CGPoint};
use objc2_core_graphics::{
kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, kCGDisplayFadeReservationInvalidToken,
kCGFloatingWindowLevel, kCGNormalWindowLevel, CGAcquireDisplayFadeReservation,
CGAssociateMouseAndMouseCursorPosition, CGDisplayCapture, CGDisplayFade, CGDisplayRelease,
CGDisplaySetDisplayMode, CGReleaseDisplayFadeReservation,
CGRestorePermanentDisplayConfiguration, CGShieldingWindowLevel, CGWarpMouseCursorPosition,
CGAssociateMouseAndMouseCursorPosition, CGBitmapInfo, CGColorRenderingIntent, CGColorSpace,
CGDataProvider, CGDataProviderReleaseDataCallback, CGDisplayCapture, CGDisplayFade,
CGDisplayRelease, CGDisplaySetDisplayMode, CGImage, CGImageAlphaInfo, CGImageByteOrderInfo,
CGReleaseDisplayFadeReservation, CGRestorePermanentDisplayConfiguration,
CGShieldingWindowLevel, CGWarpMouseCursorPosition,
};
use objc2_foundation::{
ns_string, NSArray, NSDictionary, NSEdgeInsets, NSKeyValueChangeKey, NSKeyValueChangeNewKey,
Expand All @@ -45,7 +47,7 @@ use tracing::{trace, warn};
use winit_core::cursor::Cursor;
use winit_core::error::{NotSupportedError, RequestError};
use winit_core::event::{SurfaceSizeWriter, WindowEvent};
use winit_core::icon::Icon;
use winit_core::icon::{Icon, RgbaIcon};
use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider};
use winit_core::window::{
CursorGrabMode, ImeCapabilities, ImeRequest, ImeRequestError, ResizeDirection, Theme,
Expand Down Expand Up @@ -842,6 +844,8 @@ impl WindowDelegate {

delegate.set_window_level(attrs.window_level);

delegate.set_window_icon(attrs.window_icon);

delegate.set_cursor(attrs.cursor);

// Set fullscreen mode after we setup everything
Expand Down Expand Up @@ -1657,15 +1661,48 @@ impl WindowDelegate {
}

#[inline]
pub fn set_window_icon(&self, _icon: Option<Icon>) {
// macOS doesn't have window icons. Though, there is
// `setRepresentedFilename`, but that's semantically distinct and should
// only be used when the window is in some way representing a specific
// file/directory. For instance, Terminal.app uses this for the CWD.
// Anyway, that should eventually be implemented as
// `WindowAttributesExt::with_represented_file` or something, and doesn't
// have anything to do with `set_window_icon`.
// https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/WinPanel/Tasks/SettingWindowTitle.html
pub fn set_window_icon(&self, icon: Option<Icon>) {
let icon = icon.map(|icon| {
let icon = icon.cast_ref::<RgbaIcon>().unwrap();

let data_provider = unsafe {
&CGDataProvider::with_data(
ptr::null_mut(),
icon.buffer().as_ptr() as _,
icon.buffer().len(),
CGDataProviderReleaseDataCallback::None,
)
.unwrap()
};

let image = unsafe {
CGImage::new(
icon.width() as usize,
icon.height() as usize,
8,
8 * 4,
4 * icon.width() as usize,
Some(&CGColorSpace::new_device_rgb().unwrap()),
CGBitmapInfo(CGImageByteOrderInfo::Order32Big.0 | CGImageAlphaInfo::Last.0),
Some(data_provider),
ptr::null(),
true,
CGColorRenderingIntent::RenderingIntentDefault,
)
}
.unwrap();

NSImage::initWithCGImage_size(
NSImage::alloc(),
&image,
NSSize::new(icon.width() as f64, icon.height() as f64),
)
});

let mtm = MainThreadMarker::from(self);
let app = NSApplication::sharedApplication(mtm);

unsafe { app.setApplicationIconImage(icon.as_deref()) };
}

pub fn request_ime_update(&self, request: ImeRequest) -> Result<(), ImeRequestError> {
Expand Down
4 changes: 3 additions & 1 deletion winit-core/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,9 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
///
/// ## Platform-specific
///
/// - **iOS / Android / Web / / macOS / Orbital:** Unsupported.
/// - **iOS / Android / Web / Orbital:** Unsupported.
///
/// - **macOS:** Sets the application icon (NSApplication.applicationIconImage).
///
/// - **Windows:** Sets `ICON_SMALL`. The base size for a window icon is 16x16, but it's
/// recommended to account for screen scaling and pick a multiple of that, i.e. 32x32.
Expand Down
1 change: 1 addition & 0 deletions winit/src/changelog/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ changelog entry.
- Add more `ImePurpose` values.
- Add `ImeHints` to request particular IME behaviour.
- Add Pen input support on Wayland, Windows, and Web via new Pointer event.
- On macOS, added implementation for `Window::set_window_icon`

### Changed

Expand Down